Version 1.21.0-dev.0.0
Merge bb91445e7e3ec2c74dd6025b31c1c2f2e61daeff into dev
diff --git a/.gitignore b/.gitignore
index d399850..a0b469f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -34,6 +34,7 @@
# IntelliJ project files
*.iml
.idea
+CMakeLists.txt
# Built by chromebot and downloaded from Google Storage
client/tests/drt
diff --git a/.travis.yml b/.travis.yml
index b8f5a00..f6c7f53 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -30,6 +30,15 @@
- if [ "$CXX" ]; then $CXX --version ; fi
+ # Chrome install
+ - wget https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb
+ - wget https://dl.google.com/linux/direct/google-chrome-unstable_current_amd64.deb
+ - sudo dpkg -i google-chrome*.deb
+ - /usr/bin/google-chrome --version
+ - export CHROME_BIN=/usr/bin/google-chrome
+ - /usr/bin/google-chrome-unstable --version
+ - export CHROME_CANARY_BIN=/usr/bin/google-chrome-unstable
+
# Install Depot Tools
- git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
- export PATH=`pwd`/depot_tools:"$PATH"
@@ -48,7 +57,6 @@
# DDC setup
- cd pkg/dev_compiler
- pub global activate dart_coveralls
- - export CHROME_CANARY_BIN=`./tool/get_chrome_canary.sh`
- export DISPLAY=:99.0
- sh -e /etc/init.d/xvfb start
install:
@@ -65,10 +73,10 @@
env:
- ANALYZER=master
- ANALYZER=master DDC_BROWSERS=Firefox
+ - ANALYZER=master DDC_BROWSERS=ChromeCanaryTravis
- ANALYZER=master CXX=g++
- ANALYZER=master CXX=clang++
- TEST=coverage
- - TEST=node
matrix:
allow_failures:
- env: TEST=node
diff --git a/BUILD.gn b/BUILD.gn
index d86d84a..da04aef 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -9,13 +9,149 @@
]
}
+group("most") {
+ deps = [
+ ":analysis_server",
+ ":create_sdk",
+ ":dart2js",
+ ":dartanalyzer",
+ ":dartdevc",
+ ":runtime",
+ ":samples",
+ ]
+}
+
group("runtime") {
deps = [
- "//runtime/bin:dart",
- "//runtime/bin:dart_bootstrap($host_toolchain)",
- "//runtime/bin:run_vm_tests",
- "//runtime/bin:process_test",
- "//runtime/bin:test_extension",
- "//runtime/bin:sample_extension",
+ "runtime/bin:dart",
+ "runtime/bin:dart_bootstrap($host_toolchain)",
+ "runtime/bin:run_vm_tests",
+ "runtime/bin:process_test",
+ "runtime/bin:test_extension",
+ "runtime/bin:sample_extension",
+ ]
+}
+
+group("runtime_precompiled") {
+ deps = [
+ "runtime/bin:dart_precompiled_runtime",
+ "runtime/bin:dart_bootstrap($host_toolchain)",
+ ]
+}
+
+group("runtime_and_noopt") {
+ deps = [
+ "runtime/bin:dart",
+ "runtime/bin:dart_noopt",
+ "runtime/bin:dart_bootstrap($host_toolchain)",
+ "runtime/bin:run_vm_tests",
+ "runtime/bin:process_test",
+ "runtime/bin:test_extension",
+ "runtime/bin:sample_extension",
+ ]
+}
+
+
+action("create_sdk") {
+ deps = [
+ "runtime/bin:dart",
+ "utils/analysis_server",
+ "utils/compiler:dart2js",
+ "utils/dartanalyzer:generate_dartanalyzer_snapshot",
+ "utils/dartanalyzer:generate_summary_spec",
+ "utils/dartanalyzer:generate_summary_strong",
+ "utils/dartdevc",
+ "utils/dartdoc",
+ "utils/dartfmt",
+ "utils/pub",
+ ]
+
+ sdk_lib_files = exec_script("tools/list_dart_files.py",
+ [rebase_path("sdk/lib")],
+ "list lines")
+
+ preamble_files = exec_script("tools/list_files.py",
+ ["", rebase_path("sdk/lib/_internal/js_runtime/lib/preambles")],
+ "list lines")
+
+ sdk_bin_files = exec_script("tools/list_files.py",
+ ["", rebase_path("sdk/bin")],
+ "list lines")
+
+ inputs = rebase_path(sdk_lib_files, "", "sdk/lib") +
+ rebase_path(preamble_files, "", "sdk/lib") +
+ rebase_path(sdk_bin_files, "", "sdk/bin") + [
+ "sdk/lib/dart_client.platform",
+ "sdk/lib/dart_server.platform",
+ "sdk/lib/dart_shared.platform",
+ "$root_gen_dir/dart2js.dart.snapshot",
+ "$root_gen_dir/utils_wrapper.dart.snapshot",
+ "$root_gen_dir/pub.dart.snapshot",
+ "$root_gen_dir/dartanalyzer.dart.snapshot",
+ "$root_gen_dir/dartdevc.dart.snapshot",
+ "$root_gen_dir/dartfmt.dart.snapshot",
+ "$root_gen_dir/analysis_server.dart.snapshot",
+ "$root_gen_dir/dartdoc.dart.snapshot",
+ "$root_gen_dir/spec.sum",
+ "$root_gen_dir/strong.sum",
+ "tools/VERSION"
+ ]
+
+ outputs = [
+ "$root_out_dir/dart-sdk/README",
+ ]
+
+ script = "tools/create_sdk.py"
+ args = [
+ "--sdk_output_dir",
+ rebase_path("$root_out_dir/dart-sdk"),
+ "--snapshot_location",
+ rebase_path("$root_gen_dir"),
+ ]
+}
+
+
+group("dart2js") {
+ deps = [
+ "utils/compiler:dart2js"
+ ]
+}
+
+group("dartanalyzer") {
+ deps = [
+ "utils/dartanalyzer"
+ ]
+}
+
+group("dartdevc") {
+ deps = [
+ "utils/dartdevc"
+ ]
+}
+
+group("dartfmt") {
+ deps = [
+ "utils/dartfmt"
+ ]
+}
+
+group("analysis_server") {
+ deps = [
+ "utils/analysis_server"
+ ]
+}
+
+# This is the target that is built on the dart2js build bots.
+# It must depend on anything that is required by the dart2js
+# test suites.
+group("dart2js_bot") {
+ deps = [
+ ":create_sdk"
+ ]
+}
+
+group("samples") {
+ deps = [
+ "runtime/bin:sample_extension"
]
}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7a38288..f561166 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,16 @@
-## 1.20.0
+## 1.21.0
+
+### Language
+
+* Allow `=` as well as `:` as separator for named parameter default values.
+
+## 1.20.1 - 2016-10-13
+
+Patch release, resolves one issue:
+
+* Dartium: Fixes a bug that caused crashes. No issue filed
+
+## 1.20.0 - 2016-10-11
### Dart VM
@@ -124,7 +136,14 @@
a `packages/` directory in addition to the package spec, use the
`--packages-dir` flag with `pub get`, `pub upgrade`, and `pub downgrade`.
-## 1.19.0
+## 1.19.1 - 2016-09-08
+
+Patch release, resolves one issue:
+
+* Dartdoc: Fixes a bug that prevented generation of docs
+(Dartdoc issue [1233](https://github.com/dart-lang/dartdoc/issues/1233))
+
+## 1.19.0 - 2016-08-26
### Language changes
diff --git a/DEPS b/DEPS
index 83b2770..c3db0eb 100644
--- a/DEPS
+++ b/DEPS
@@ -31,20 +31,20 @@
"co19_rev": "@d4767b4caea3c5828ad8e053cd051d44a59061af",
# Revisions of GN related dependencies.
- "buildtools_revision": "@3d2e47bf14e4e67816a53e304dea422fa18f9180",
+ "buildtools_revision": "@39b1db2ab4aa4b2ccaa263c29bdf63e7c1ee28aa",
- "gperftools_revision": "@7822b5b0b9fa7e016e1f6b46ea86f26f4691a457",
+ "gperftools_revision": "@02eeed29df112728564a5dde6417fa4622b57a06",
# Revisions of /third_party/* dependencies.
"args_tag": "@0.13.5",
- "async_tag": "@1.11.1",
+ "async_tag": "@1.11.2",
"barback-0.13.0_rev": "@34853",
"barback-0.14.0_rev": "@36398",
"barback-0.14.1_rev": "@38525",
"barback_tag" : "@0.15.2+9",
"bazel_worker_tag": "@0.1.1",
"boolean_selector_tag" : "@1.0.2",
- "boringssl_gen_rev": "@922830c0aad900dd3d143eef1ba06faa83fe263b",
+ "boringssl_gen_rev": "@62c20247d582444cb2804f9ea4e3abaa6e47f6a5",
"boringssl_rev" : "@8d343b44bbab829d1a28fdef650ca95f7db4412e",
"charcode_tag": "@1.1.0",
"chrome_rev" : "@19997",
@@ -54,7 +54,7 @@
"convert_tag": "@2.0.1",
"crypto_tag" : "@2.0.1",
"csslib_tag" : "@0.13.2",
- "dart2js_info_tag" : "@0.2.7+1",
+ "dart2js_info_tag" : "@0.5.0",
"dart_services_rev" : "@7aea2574e6f3924bf409a80afb8ad52aa2be4f97",
"dart_style_tag": "@0.2.10",
"dartdoc_tag" : "@v0.9.7+6",
@@ -68,14 +68,14 @@
"http_throttle_rev" : "@284344cd357e435c6c8ff9a4a21f02b9e384a541",
"idl_parser_rev": "@7fbe68cab90c38147dee4f48c30ad0d496c17915",
"initialize_tag": "@v0.6.2+2",
- "intl_tag": "@0.13.1",
+ "intl_tag": "@0.14.0",
"isolate_tag": "@0.2.3",
"jinja2_rev": "@2222b31554f03e62600cd7e383376a7c187967a1",
"json_rpc_2_tag": "@2.0.2",
- "kernel_rev": "@449803b82e850a41148e636db1a6e4a848284aed",
- "linter_tag": "@0.1.27",
+ "kernel_rev": "@1906e420431656d351a9f4ee9a36b8ca9a4da1db",
+ "linter_tag": "@0.1.28",
"logging_tag": "@0.11.3+1",
- "markdown_rev": "@4aaadf3d940bb172e1f6285af4d2b1710d309982",
+ "markdown_tag": "@0.11.0",
"matcher_tag": "@0.12.0+2",
"metatest_tag": "@0.2.2+2",
"mime_rev": "@75890811d4af5af080351ba8a2853ad4c8df98dd",
@@ -110,7 +110,7 @@
"stream_channel_tag": "@1.5.0",
"string_scanner_tag": "@1.0.0",
"sunflower_rev": "@879b704933413414679396b129f5dfa96f7a0b1e",
- "test_reflective_loader_tag": "@0.0.4",
+ "test_reflective_loader_tag": "@0.1.0",
"test_tag": "@0.12.15+6",
"typed_data_tag": "@1.1.3",
"usage_tag": "@v2.2.2",
@@ -239,7 +239,7 @@
Var("dart_root") + "/third_party/pkg/logging":
(Var("github_mirror") % "logging") + Var("logging_tag"),
Var("dart_root") + "/third_party/pkg/markdown":
- (Var("github_mirror") % "markdown") + Var("markdown_rev"),
+ (Var("github_mirror") % "markdown") + Var("markdown_tag"),
Var("dart_root") + "/third_party/pkg/matcher":
(Var("github_mirror") % "matcher") + Var("matcher_tag"),
Var("dart_root") + "/third_party/pkg/metatest":
@@ -496,20 +496,6 @@
],
},
{
- "name": "petitparser",
- "pattern": ".",
- "action": [
- "download_from_google_storage",
- "--no_auth",
- "--no_resume",
- "--bucket",
- "dart-dependencies",
- "--extract",
- "-s",
- Var('dart_root') + "/third_party/pkg/petitparser.tar.gz.sha1",
- ],
- },
- {
"name": "unittest",
# Unittest is an early version, 0.11.6, of the package "test"
# Do not use it in any new tests.
@@ -576,7 +562,13 @@
'action': ['python', 'sdk/tools/clang/scripts/update.py', '--if-needed'],
},
{
+ # Update the Windows toolchain if necessary.
+ 'name': 'win_toolchain',
+ 'pattern': '.',
+ 'action': ['python', 'sdk/build/vs_toolchain.py', 'update'],
+ },
+ {
"pattern": ".",
- "action": ["python", Var("dart_root") + "/tools/gyp_dart.py"],
+ "action": ["python", Var("dart_root") + "/tools/generate_buildfiles.py"],
},
]
diff --git a/build/.gitignore b/build/.gitignore
new file mode 100644
index 0000000..6e337fe
--- /dev/null
+++ b/build/.gitignore
@@ -0,0 +1,2 @@
+# Generated file containing information about the VS toolchain on Windows
+win_toolchain.json
diff --git a/build/OWNERS b/build/OWNERS
deleted file mode 100644
index 17d067c..0000000
--- a/build/OWNERS
+++ /dev/null
@@ -1,5 +0,0 @@
-cjhopman@chromium.org
-dpranke@chromium.org
-jochen@chromium.org
-scottmg@chromium.org
-thakis@chromium.org
diff --git a/build/PRESUBMIT.py b/build/PRESUBMIT.py
deleted file mode 100644
index fca962f..0000000
--- a/build/PRESUBMIT.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-
-def _RunTests(input_api, output_api):
- return (input_api.canned_checks.RunUnitTestsInDirectory(
- input_api, output_api, '.', whitelist=[r'.+_test.py$']))
-
-
-def CheckChangeOnUpload(input_api, output_api):
- return _RunTests(input_api, output_api)
-
-
-def CheckChangeOnCommit(input_api, output_api):
- return _RunTests(input_api, output_api)
diff --git a/build/README.chromium b/build/README.chromium
deleted file mode 100644
index 012df35..0000000
--- a/build/README.chromium
+++ /dev/null
@@ -1,15 +0,0 @@
-List of property sheets to be included by projects:
- common.vsprops
- Not used anymore. No-op. Kept for compatibility with current projects.
-
- debug.vsprops
- Enables debug settings. Must be included directly in Debug configuration. Includes internal\essential.vsprops.
-
- external_code.vsprops
- Contains settings made to simplify usage of external (non-Google) code. It relaxes the warning levels. Should be included after debug.vsprops or release.vsprops to override their settings.
-
- output_dll_copy.rules
- Run to enable automatic copy of DLL when they are as an input file in a vcproj project.
-
- release.vsprops
- Enables release settings. Must be included directly in Release configuration. Includes internal\essential.vsprops. Also includes "internal\release_impl$(CHROME_BUILD_TYPE).vsprops". So the behavior is dependant on the CHROME_BUILD_TYPE environment variable.
diff --git a/build/all.gyp b/build/all.gyp
deleted file mode 100644
index b36fae6..0000000
--- a/build/all.gyp
+++ /dev/null
@@ -1,1442 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
- 'variables': {
- # A hook that can be overridden in other repositories to add additional
- # compilation targets to 'All'.
- 'app_targets%': [],
- # For Android-specific targets.
- 'android_app_targets%': [],
- },
- 'targets': [
- {
- 'target_name': 'All',
- 'type': 'none',
- 'xcode_create_dependents_test_runner': 1,
- 'dependencies': [
- '<@(app_targets)',
- 'some.gyp:*',
- '../base/base.gyp:*',
- '../components/components.gyp:*',
- '../components/components_tests.gyp:*',
- '../content/content.gyp:*',
- '../crypto/crypto.gyp:*',
- '../net/net.gyp:*',
- '../sdch/sdch.gyp:*',
- '../sql/sql.gyp:*',
- '../testing/gmock.gyp:*',
- '../testing/gtest.gyp:*',
- '../third_party/icu/icu.gyp:*',
- '../third_party/libxml/libxml.gyp:*',
- '../third_party/sqlite/sqlite.gyp:*',
- '../third_party/zlib/zlib.gyp:*',
- '../ui/accessibility/accessibility.gyp:*',
- '../ui/base/ui_base.gyp:*',
- '../ui/display/display.gyp:display_unittests',
- '../ui/snapshot/snapshot.gyp:*',
- '../url/url.gyp:*',
- ],
- 'conditions': [
- ['OS!="ios" and OS!="mac"', {
- 'dependencies': [
- '../ui/touch_selection/ui_touch_selection.gyp:*',
- ],
- }],
- ['OS=="ios"', {
- 'dependencies': [
- '../chrome/chrome.gyp:browser',
- '../chrome/chrome.gyp:browser_ui',
- '../ios/ios.gyp:*',
- # NOTE: This list of targets is present because
- # mojo_base.gyp:mojo_base cannot be built on iOS, as
- # javascript-related targets cause v8 to be built.
- '../mojo/mojo_base.gyp:mojo_common_lib',
- '../mojo/mojo_base.gyp:mojo_common_unittests',
- '../google_apis/google_apis.gyp:google_apis_unittests',
- '../skia/skia_tests.gyp:skia_unittests',
- '../third_party/mojo/mojo_edk.gyp:mojo_system_impl',
- '../third_party/mojo/mojo_edk_tests.gyp:mojo_public_bindings_unittests',
- '../third_party/mojo/mojo_edk_tests.gyp:mojo_public_environment_unittests',
- '../third_party/mojo/mojo_edk_tests.gyp:mojo_public_system_unittests',
- '../third_party/mojo/mojo_edk_tests.gyp:mojo_public_utility_unittests',
- '../third_party/mojo/mojo_edk_tests.gyp:mojo_system_unittests',
- '../third_party/mojo/mojo_public.gyp:mojo_cpp_bindings',
- '../third_party/mojo/mojo_public.gyp:mojo_public_test_utils',
- '../third_party/mojo/mojo_public.gyp:mojo_system',
- '../ui/base/ui_base_tests.gyp:ui_base_unittests',
- '../ui/gfx/gfx_tests.gyp:gfx_unittests',
- ],
- }],
- ['OS=="android"', {
- 'dependencies': [
- '../content/content_shell_and_tests.gyp:content_shell_apk',
- '<@(android_app_targets)',
- 'android_builder_tests',
- '../tools/telemetry/telemetry.gyp:*#host',
- # TODO(nyquist) This should instead by a target for sync when all of
- # the sync-related code for Android has been upstreamed.
- # See http://crbug.com/159203
- '../third_party/cacheinvalidation/cacheinvalidation.gyp:cacheinvalidation_javalib',
- ],
- 'conditions': [
- ['chromecast==0', {
- 'dependencies': [
- '../android_webview/android_webview.gyp:android_webview_apk',
- '../android_webview/android_webview.gyp:system_webview_apk',
- '../android_webview/android_webview_shell.gyp:android_webview_shell_apk',
- '../chrome/android/chrome_apk.gyp:chrome_public_apk',
- '../chrome/chrome.gyp:chrome_shell_apk',
- '../chrome/chrome.gyp:chrome_sync_shell_apk',
- '../remoting/remoting.gyp:remoting_apk',
- ],
- }],
- # TODO: Enable packed relocations for x64. See: b/20532404
- ['target_arch != "x64"', {
- 'dependencies': [
- '../third_party/android_platform/relocation_packer.gyp:android_relocation_packer_unittests#host',
- ],
- }],
- ],
- }, {
- 'dependencies': [
- '../content/content_shell_and_tests.gyp:*',
- # TODO: This should build on Android and the target should move to the list above.
- '../sync/sync.gyp:*',
- ],
- }],
- ['OS!="ios" and OS!="android" and chromecast==0', {
- 'dependencies': [
- '../third_party/re2/re2.gyp:re2',
- '../chrome/chrome.gyp:*',
- '../chrome/tools/profile_reset/jtl_compiler.gyp:*',
- '../cc/blink/cc_blink_tests.gyp:*',
- '../cc/cc_tests.gyp:*',
- '../device/usb/usb.gyp:*',
- '../extensions/extensions.gyp:*',
- '../extensions/extensions_tests.gyp:*',
- '../gin/gin.gyp:*',
- '../gpu/gpu.gyp:*',
- '../gpu/tools/tools.gyp:*',
- '../ipc/ipc.gyp:*',
- '../ipc/mojo/ipc_mojo.gyp:*',
- '../jingle/jingle.gyp:*',
- '../media/cast/cast.gyp:*',
- '../media/media.gyp:*',
- '../media/midi/midi.gyp:*',
- '../mojo/mojo.gyp:*',
- '../mojo/mojo_base.gyp:*',
- '../ppapi/ppapi.gyp:*',
- '../ppapi/ppapi_internal.gyp:*',
- '../ppapi/tools/ppapi_tools.gyp:*',
- '../printing/printing.gyp:*',
- '../skia/skia.gyp:*',
- '../sync/tools/sync_tools.gyp:*',
- '../third_party/WebKit/public/all.gyp:*',
- '../third_party/cacheinvalidation/cacheinvalidation.gyp:*',
- '../third_party/codesighs/codesighs.gyp:*',
- '../third_party/ffmpeg/ffmpeg.gyp:*',
- '../third_party/iccjpeg/iccjpeg.gyp:*',
- '../third_party/libpng/libpng.gyp:*',
- '../third_party/libusb/libusb.gyp:*',
- '../third_party/libwebp/libwebp.gyp:*',
- '../third_party/libxslt/libxslt.gyp:*',
- '../third_party/lzma_sdk/lzma_sdk.gyp:*',
- '../third_party/mesa/mesa.gyp:*',
- '../third_party/modp_b64/modp_b64.gyp:*',
- '../third_party/npapi/npapi.gyp:*',
- '../third_party/ots/ots.gyp:*',
- '../third_party/pdfium/samples/samples.gyp:*',
- '../third_party/qcms/qcms.gyp:*',
- '../tools/gn/gn.gyp:*',
- '../tools/perf/clear_system_cache/clear_system_cache.gyp:*',
- '../tools/telemetry/telemetry.gyp:*',
- '../v8/tools/gyp/v8.gyp:*',
- '<(libjpeg_gyp_path):*',
- ],
- }],
- ['OS!="ios"', {
- 'dependencies': [
- '../device/bluetooth/bluetooth.gyp:*',
- '../device/device_tests.gyp:*',
- '../gpu/skia_runner/skia_runner.gyp:*',
- ],
- }],
- ['use_openssl==0 and (OS=="mac" or OS=="ios" or OS=="win")', {
- 'dependencies': [
- '../third_party/nss/nss.gyp:*',
- ],
- }],
- ['OS=="win" or OS=="ios" or OS=="linux"', {
- 'dependencies': [
- '../breakpad/breakpad.gyp:*',
- ],
- }],
- ['OS=="mac"', {
- 'dependencies': [
- '../sandbox/sandbox.gyp:*',
- '../third_party/crashpad/crashpad/crashpad.gyp:*',
- '../third_party/ocmock/ocmock.gyp:*',
- ],
- }],
- ['OS=="linux"', {
- 'dependencies': [
- '../courgette/courgette.gyp:*',
- '../sandbox/sandbox.gyp:*',
- ],
- 'conditions': [
- ['branding=="Chrome"', {
- 'dependencies': [
- '../chrome/chrome.gyp:linux_packages_<(channel)',
- ],
- }],
- ['enable_ipc_fuzzer==1', {
- 'dependencies': [
- '../tools/ipc_fuzzer/ipc_fuzzer.gyp:*',
- ],
- }],
- ['use_dbus==1', {
- 'dependencies': [
- '../dbus/dbus.gyp:*',
- ],
- }],
- ],
- }],
- ['chromecast==1', {
- 'dependencies': [
- '../chromecast/chromecast.gyp:*',
- ],
- }],
- ['use_x11==1', {
- 'dependencies': [
- '../tools/xdisplaycheck/xdisplaycheck.gyp:*',
- ],
- }],
- ['OS=="win"', {
- 'conditions': [
- ['win_use_allocator_shim==1', {
- 'dependencies': [
- '../base/allocator/allocator.gyp:*',
- ],
- }],
- ],
- 'dependencies': [
- '../chrome/tools/crash_service/caps/caps.gyp:*',
- '../chrome_elf/chrome_elf.gyp:*',
- '../cloud_print/cloud_print.gyp:*',
- '../courgette/courgette.gyp:*',
- '../rlz/rlz.gyp:*',
- '../sandbox/sandbox.gyp:*',
- '<(angle_path)/src/angle.gyp:*',
- '../third_party/bspatch/bspatch.gyp:*',
- '../tools/win/static_initializers/static_initializers.gyp:*',
- ],
- }, {
- 'dependencies': [
- '../third_party/libevent/libevent.gyp:*',
- ],
- }],
- ['toolkit_views==1', {
- 'dependencies': [
- '../ui/views/controls/webview/webview.gyp:*',
- '../ui/views/views.gyp:*',
- ],
- }],
- ['use_aura==1', {
- 'dependencies': [
- '../ui/aura/aura.gyp:*',
- '../ui/aura_extra/aura_extra.gyp:*',
- ],
- }],
- ['use_ash==1', {
- 'dependencies': [
- '../ash/ash.gyp:*',
- ],
- }],
- ['remoting==1', {
- 'dependencies': [
- '../remoting/remoting_all.gyp:remoting_all',
- ],
- }],
- ['use_openssl==0', {
- 'dependencies': [
- '../net/third_party/nss/ssl.gyp:*',
- ],
- }],
- ['use_openssl==1', {
- 'dependencies': [
- '../third_party/boringssl/boringssl.gyp:*',
- '../third_party/boringssl/boringssl_tests.gyp:*',
- ],
- }],
- ['enable_app_list==1', {
- 'dependencies': [
- '../ui/app_list/app_list.gyp:*',
- ],
- }],
- ['OS!="android" and OS!="ios"', {
- 'dependencies': [
- '../google_apis/gcm/gcm.gyp:*',
- ],
- }],
- ['(chromeos==1 or OS=="linux" or OS=="win" or OS=="mac") and chromecast==0', {
- 'dependencies': [
- '../extensions/shell/app_shell.gyp:*',
- ],
- }],
- ['envoy==1', {
- 'dependencies': [
- '../envoy/envoy.gyp:*',
- ],
- }],
- ],
- }, # target_name: All
- {
- 'target_name': 'All_syzygy',
- 'type': 'none',
- 'conditions': [
- ['OS=="win" and fastbuild==0 and target_arch=="ia32" and '
- '(syzyasan==1 or syzygy_optimize==1)', {
- 'dependencies': [
- '../chrome/installer/mini_installer_syzygy.gyp:*',
- ],
- }],
- ],
- }, # target_name: All_syzygy
- {
- # Note: Android uses android_builder_tests below.
- # TODO: Consider merging that with this target.
- 'target_name': 'chromium_builder_tests',
- 'type': 'none',
- 'dependencies': [
- '../base/base.gyp:base_unittests',
- '../components/components_tests.gyp:components_unittests',
- '../crypto/crypto.gyp:crypto_unittests',
- '../net/net.gyp:net_unittests',
- '../skia/skia_tests.gyp:skia_unittests',
- '../sql/sql.gyp:sql_unittests',
- '../sync/sync.gyp:sync_unit_tests',
- '../ui/base/ui_base_tests.gyp:ui_base_unittests',
- '../ui/display/display.gyp:display_unittests',
- '../ui/gfx/gfx_tests.gyp:gfx_unittests',
- '../url/url.gyp:url_unittests',
- ],
- 'conditions': [
- ['OS!="ios"', {
- 'dependencies': [
- '../ui/gl/gl_tests.gyp:gl_unittests',
- ],
- }],
- ['OS!="ios" and OS!="mac"', {
- 'dependencies': [
- '../ui/touch_selection/ui_touch_selection.gyp:ui_touch_selection_unittests',
- ],
- }],
- ['OS!="ios" and OS!="android"', {
- 'dependencies': [
- '../cc/blink/cc_blink_tests.gyp:cc_blink_unittests',
- '../cc/cc_tests.gyp:cc_unittests',
- '../cloud_print/cloud_print.gyp:cloud_print_unittests',
- '../content/content_shell_and_tests.gyp:content_browsertests',
- '../content/content_shell_and_tests.gyp:content_shell',
- '../content/content_shell_and_tests.gyp:content_unittests',
- '../device/device_tests.gyp:device_unittests',
- '../gin/gin.gyp:gin_unittests',
- '../google_apis/google_apis.gyp:google_apis_unittests',
- '../gpu/gles2_conform_support/gles2_conform_support.gyp:gles2_conform_support',
- '../gpu/gpu.gyp:gpu_unittests',
- '../ipc/ipc.gyp:ipc_tests',
- '../ipc/mojo/ipc_mojo.gyp:ipc_mojo_unittests',
- '../jingle/jingle.gyp:jingle_unittests',
- '../media/cast/cast.gyp:cast_unittests',
- '../media/media.gyp:media_unittests',
- '../media/midi/midi.gyp:midi_unittests',
- '../mojo/mojo.gyp:mojo',
- '../ppapi/ppapi_internal.gyp:ppapi_unittests',
- '../remoting/remoting.gyp:remoting_unittests',
- '../third_party/WebKit/public/all.gyp:all_blink',
- '../third_party/cacheinvalidation/cacheinvalidation.gyp:cacheinvalidation_unittests',
- '../third_party/leveldatabase/leveldatabase.gyp:env_chromium_unittests',
- '../third_party/libaddressinput/libaddressinput.gyp:libaddressinput_unittests',
- '../third_party/libphonenumber/libphonenumber.gyp:libphonenumber_unittests',
- '../tools/telemetry/telemetry.gyp:*',
- ],
- }],
- ['OS!="ios" and OS!="android" and chromecast==0', {
- 'dependencies': [
- '../chrome/chrome.gyp:browser_tests',
- '../chrome/chrome.gyp:chromedriver_tests',
- '../chrome/chrome.gyp:chromedriver_unittests',
- '../chrome/chrome.gyp:interactive_ui_tests',
- '../chrome/chrome.gyp:sync_integration_tests',
- '../chrome/chrome.gyp:unit_tests',
- '../extensions/extensions_tests.gyp:extensions_browsertests',
- '../extensions/extensions_tests.gyp:extensions_unittests',
- ],
- }],
- ['OS=="win"', {
- 'dependencies': [
- '../chrome/chrome.gyp:crash_service',
- '../chrome/chrome.gyp:installer_util_unittests',
- '../chrome/chrome.gyp:setup_unittests',
- # ../chrome/test/mini_installer requires mini_installer.
- '../chrome/installer/mini_installer.gyp:mini_installer',
- '../chrome_elf/chrome_elf.gyp:chrome_elf_unittests',
- '../content/content_shell_and_tests.gyp:copy_test_netscape_plugin',
- '../courgette/courgette.gyp:courgette_unittests',
- '../sandbox/sandbox.gyp:sbox_integration_tests',
- '../sandbox/sandbox.gyp:sbox_unittests',
- '../sandbox/sandbox.gyp:sbox_validation_tests',
- '../ui/app_list/app_list.gyp:app_list_unittests',
- ],
- 'conditions': [
- # remoting_host_installation uses lots of non-trivial GYP that tend
- # to break because of differences between ninja and msbuild. Make
- # sure this target is built by the builders on the main waterfall.
- # See http://crbug.com/180600.
- ['wix_exists == "True" and sas_dll_exists == "True"', {
- 'dependencies': [
- '../remoting/remoting.gyp:remoting_host_installation',
- ],
- }],
- ['syzyasan==1', {
- 'variables': {
- # Disable incremental linking for all modules.
- # 0: inherit, 1: disabled, 2: enabled.
- 'msvs_debug_link_incremental': '1',
- 'msvs_large_module_debug_link_mode': '1',
- # Disable RTC. Syzygy explicitly doesn't support RTC
- # instrumented binaries for now.
- 'win_debug_RuntimeChecks': '0',
- },
- 'defines': [
- # Disable iterator debugging (huge speed boost).
- '_HAS_ITERATOR_DEBUGGING=0',
- ],
- 'msvs_settings': {
- 'VCLinkerTool': {
- # Enable profile information (necessary for SyzyAsan
- # instrumentation). This is incompatible with incremental
- # linking.
- 'Profile': 'true',
- },
- }
- }],
- ],
- }],
- ['chromeos==1', {
- 'dependencies': [
- '../ui/chromeos/ui_chromeos.gyp:ui_chromeos_unittests',
- ],
- }],
- ['OS=="linux"', {
- 'dependencies': [
- '../sandbox/sandbox.gyp:sandbox_linux_unittests',
- ],
- }],
- ['OS=="linux" and use_dbus==1', {
- 'dependencies': [
- '../dbus/dbus.gyp:dbus_unittests',
- ],
- }],
- ['OS=="mac"', {
- 'dependencies': [
- '../ui/app_list/app_list.gyp:app_list_unittests',
- '../ui/message_center/message_center.gyp:*',
- ],
- }],
- ['test_isolation_mode != "noop"', {
- 'dependencies': [
- 'chromium_swarm_tests',
- ],
- }],
- ['OS!="android"', {
- 'dependencies': [
- '../google_apis/gcm/gcm.gyp:gcm_unit_tests',
- ],
- }],
- ['enable_basic_printing==1 or enable_print_preview==1', {
- 'dependencies': [
- '../printing/printing.gyp:printing_unittests',
- ],
- }],
- ['use_aura==1', {
- 'dependencies': [
- '../ui/app_list/app_list.gyp:app_list_unittests',
- '../ui/aura/aura.gyp:aura_unittests',
- '../ui/compositor/compositor.gyp:compositor_unittests',
- ],
- }],
- ['use_aura==1 and chromecast==0', {
- 'dependencies': [
- '../ui/keyboard/keyboard.gyp:keyboard_unittests',
- '../ui/views/views.gyp:views_unittests',
- ],
- }],
- ['use_aura==1 or toolkit_views==1', {
- 'dependencies': [
- '../ui/events/events.gyp:events_unittests',
- ],
- }],
- ['use_ash==1', {
- 'dependencies': [
- '../ash/ash.gyp:ash_unittests',
- ],
- }],
- ['disable_nacl==0', {
- 'dependencies': [
- '../components/nacl.gyp:nacl_loader_unittests',
- ],
- }],
- ['disable_nacl==0 and disable_nacl_untrusted==0 and enable_nacl_nonsfi_test==1', {
- 'dependencies': [
- '../components/nacl.gyp:nacl_helper_nonsfi_unittests',
- ],
- }],
- ['disable_nacl==0 and disable_nacl_untrusted==0', {
- 'dependencies': [
- '../mojo/mojo_nacl_untrusted.gyp:libmojo',
- '../mojo/mojo_nacl.gyp:monacl_codegen',
- '../mojo/mojo_nacl.gyp:monacl_sel',
- '../mojo/mojo_nacl.gyp:monacl_shell',
- ],
- }],
- ],
- }, # target_name: chromium_builder_tests
- ],
- 'conditions': [
- # TODO(GYP): make gn_migration.gypi work unconditionally.
- ['OS=="mac" or OS=="win" or (OS=="linux" and target_arch=="x64" and chromecast==0)', {
- 'includes': [
- 'gn_migration.gypi',
- ],
- }],
- ['OS!="ios"', {
- 'targets': [
- {
- 'target_name': 'blink_tests',
- 'type': 'none',
- 'dependencies': [
- '../third_party/WebKit/public/all.gyp:all_blink',
- ],
- 'conditions': [
- ['OS=="android"', {
- 'dependencies': [
- '../content/content_shell_and_tests.gyp:content_shell_apk',
- '../breakpad/breakpad.gyp:dump_syms#host',
- '../breakpad/breakpad.gyp:minidump_stackwalk#host',
- ],
- }, { # OS!="android"
- 'dependencies': [
- '../content/content_shell_and_tests.gyp:content_shell',
- ],
- }],
- ['OS=="win"', {
- 'dependencies': [
- '../components/test_runner/test_runner.gyp:layout_test_helper',
- '../content/content_shell_and_tests.gyp:content_shell_crash_service',
- ],
- }],
- ['OS!="win" and OS!="android"', {
- 'dependencies': [
- '../breakpad/breakpad.gyp:minidump_stackwalk',
- ],
- }],
- ['OS=="mac"', {
- 'dependencies': [
- '../components/test_runner/test_runner.gyp:layout_test_helper',
- '../breakpad/breakpad.gyp:dump_syms#host',
- ],
- }],
- ['OS=="linux"', {
- 'dependencies': [
- '../breakpad/breakpad.gyp:dump_syms#host',
- ],
- }],
- ],
- }, # target_name: blink_tests
- ],
- }], # OS!=ios
- ['OS!="ios" and OS!="android" and chromecast==0', {
- 'targets': [
- {
- 'target_name': 'chromium_builder_nacl_win_integration',
- 'type': 'none',
- 'dependencies': [
- 'chromium_builder_tests',
- ],
- }, # target_name: chromium_builder_nacl_win_integration
- {
- 'target_name': 'chromium_builder_perf',
- 'type': 'none',
- 'dependencies': [
- '../cc/cc_tests.gyp:cc_perftests',
- '../chrome/chrome.gyp:chrome',
- '../chrome/chrome.gyp:load_library_perf_tests',
- '../chrome/chrome.gyp:performance_browser_tests',
- '../chrome/chrome.gyp:sync_performance_tests',
- '../content/content_shell_and_tests.gyp:content_shell',
- '../gpu/gpu.gyp:gpu_perftests',
- '../media/media.gyp:media_perftests',
- '../media/midi/midi.gyp:midi_unittests',
- '../tools/perf/clear_system_cache/clear_system_cache.gyp:*',
- '../tools/telemetry/telemetry.gyp:*',
- ],
- 'conditions': [
- ['OS!="ios" and OS!="win"', {
- 'dependencies': [
- '../breakpad/breakpad.gyp:minidump_stackwalk',
- ],
- }],
- ['OS=="linux"', {
- 'dependencies': [
- '../chrome/chrome.gyp:linux_symbols'
- ],
- }],
- ['OS=="win"', {
- 'dependencies': [
- '../chrome/chrome.gyp:crash_service',
- '../gpu/gpu.gyp:angle_perftests',
- ],
- }],
- ['OS=="win" and target_arch=="ia32"', {
- 'dependencies': [
- '../chrome/chrome.gyp:crash_service_win64',
- ],
- }],
- ],
- }, # target_name: chromium_builder_perf
- {
- 'target_name': 'chromium_gpu_builder',
- 'type': 'none',
- 'dependencies': [
- '../chrome/chrome.gyp:chrome',
- '../chrome/chrome.gyp:performance_browser_tests',
- '../content/content_shell_and_tests.gyp:content_browsertests',
- '../content/content_shell_and_tests.gyp:content_gl_tests',
- '../gpu/gles2_conform_support/gles2_conform_test.gyp:gles2_conform_test',
- '../gpu/khronos_glcts_support/khronos_glcts_test.gyp:khronos_glcts_test',
- '../gpu/gpu.gyp:gl_tests',
- '../gpu/gpu.gyp:angle_unittests',
- '../gpu/gpu.gyp:gpu_unittests',
- '../tools/telemetry/telemetry.gyp:*',
- ],
- 'conditions': [
- ['OS!="ios" and OS!="win"', {
- 'dependencies': [
- '../breakpad/breakpad.gyp:minidump_stackwalk',
- ],
- }],
- ['OS=="linux"', {
- 'dependencies': [
- '../chrome/chrome.gyp:linux_symbols'
- ],
- }],
- ['OS=="win"', {
- 'dependencies': [
- '../chrome/chrome.gyp:crash_service',
- ],
- }],
- ['OS=="win" and target_arch=="ia32"', {
- 'dependencies': [
- '../chrome/chrome.gyp:crash_service_win64',
- ],
- }],
- ],
- }, # target_name: chromium_gpu_builder
- {
- 'target_name': 'chromium_gpu_debug_builder',
- 'type': 'none',
- 'dependencies': [
- '../chrome/chrome.gyp:chrome',
- '../content/content_shell_and_tests.gyp:content_browsertests',
- '../content/content_shell_and_tests.gyp:content_gl_tests',
- '../gpu/gles2_conform_support/gles2_conform_test.gyp:gles2_conform_test',
- '../gpu/khronos_glcts_support/khronos_glcts_test.gyp:khronos_glcts_test',
- '../gpu/gpu.gyp:gl_tests',
- '../gpu/gpu.gyp:angle_unittests',
- '../gpu/gpu.gyp:gpu_unittests',
- '../tools/telemetry/telemetry.gyp:*',
- ],
- 'conditions': [
- ['OS!="ios" and OS!="win"', {
- 'dependencies': [
- '../breakpad/breakpad.gyp:minidump_stackwalk',
- ],
- }],
- ['OS=="linux"', {
- 'dependencies': [
- '../chrome/chrome.gyp:linux_symbols'
- ],
- }],
- ['OS=="win"', {
- 'dependencies': [
- '../chrome/chrome.gyp:crash_service',
- ],
- }],
- ['OS=="win" and target_arch=="ia32"', {
- 'dependencies': [
- '../chrome/chrome.gyp:crash_service_win64',
- ],
- }],
- ],
- }, # target_name: chromium_gpu_debug_builder
- {
- # This target contains everything we need to run tests on the special
- # device-equipped WebRTC bots. We have device-requiring tests in
- # browser_tests and content_browsertests.
- 'target_name': 'chromium_builder_webrtc',
- 'type': 'none',
- 'dependencies': [
- 'chromium_builder_perf',
- '../chrome/chrome.gyp:browser_tests',
- '../content/content_shell_and_tests.gyp:content_browsertests',
- '../content/content_shell_and_tests.gyp:content_unittests',
- '../media/media.gyp:media_unittests',
- '../media/midi/midi.gyp:midi_unittests',
- '../third_party/webrtc/tools/tools.gyp:frame_analyzer',
- '../third_party/webrtc/tools/tools.gyp:rgba_to_i420_converter',
- ],
- 'conditions': [
- ['remoting==1', {
- 'dependencies': [
- '../remoting/remoting.gyp:*',
- ],
- }],
- ],
- }, # target_name: chromium_builder_webrtc
- {
- 'target_name': 'chromium_builder_chromedriver',
- 'type': 'none',
- 'dependencies': [
- '../chrome/chrome.gyp:chromedriver',
- '../chrome/chrome.gyp:chromedriver_tests',
- '../chrome/chrome.gyp:chromedriver_unittests',
- ],
- }, # target_name: chromium_builder_chromedriver
- {
- 'target_name': 'chromium_builder_asan',
- 'type': 'none',
- 'dependencies': [
- '../chrome/chrome.gyp:chrome',
-
- # We refer to content_shell directly rather than blink_tests
- # because we don't want the _unittests binaries.
- '../content/content_shell_and_tests.gyp:content_shell',
- ],
- 'conditions': [
- ['OS!="win"', {
- 'dependencies': [
- '../net/net.gyp:hpack_fuzz_wrapper',
- '../net/net.gyp:dns_fuzz_stub',
- '../skia/skia.gyp:filter_fuzz_stub',
- ],
- }],
- ['enable_ipc_fuzzer==1 and component!="shared_library" and '
- '(OS=="linux" or OS=="win")', {
- 'dependencies': [
- '../tools/ipc_fuzzer/ipc_fuzzer.gyp:*',
- ],
- }],
- ['chromeos==0', {
- 'dependencies': [
- '../v8/src/d8.gyp:d8#host',
- '../third_party/pdfium/samples/samples.gyp:pdfium_test',
- ],
- }],
- ['internal_filter_fuzzer==1', {
- 'dependencies': [
- '../skia/tools/clusterfuzz-data/fuzzers/filter_fuzzer/filter_fuzzer.gyp:filter_fuzzer',
- ],
- }], # internal_filter_fuzzer
- ['clang==1', {
- 'dependencies': [
- 'sanitizers/sanitizers.gyp:llvm-symbolizer',
- ],
- }],
- ['OS=="win" and fastbuild==0 and target_arch=="ia32" and syzyasan==1', {
- 'dependencies': [
- '../chrome/chrome_syzygy.gyp:chrome_dll_syzygy',
- '../content/content_shell_and_tests.gyp:content_shell_syzyasan',
- ],
- 'conditions': [
- ['chrome_multiple_dll==1', {
- 'dependencies': [
- '../chrome/chrome_syzygy.gyp:chrome_child_dll_syzygy',
- ],
- }],
- ],
- }],
- ],
- },
- {
- 'target_name': 'chromium_builder_nacl_sdk',
- 'type': 'none',
- 'dependencies': [
- '../chrome/chrome.gyp:chrome',
- ],
- 'conditions': [
- ['OS=="win"', {
- 'dependencies': [
- '../chrome/chrome.gyp:chrome_nacl_win64',
- ]
- }],
- ],
- }, #target_name: chromium_builder_nacl_sdk
- ], # targets
- }], #OS!=ios and OS!=android
- ['OS=="android"', {
- 'targets': [
- {
- # The current list of tests for android. This is temporary
- # until the full set supported. If adding a new test here,
- # please also add it to build/android/pylib/gtest/gtest_config.py,
- # else the test is not run.
- #
- # WARNING:
- # Do not add targets here without communicating the implications
- # on tryserver triggers and load. Discuss with
- # chrome-infrastructure-team please.
- 'target_name': 'android_builder_tests',
- 'type': 'none',
- 'dependencies': [
- '../base/android/jni_generator/jni_generator.gyp:jni_generator_tests',
- '../base/base.gyp:base_unittests',
- '../breakpad/breakpad.gyp:breakpad_unittests_deps',
- # Also compile the tools needed to deal with minidumps, they are
- # needed to run minidump tests upstream.
- '../breakpad/breakpad.gyp:dump_syms#host',
- '../breakpad/breakpad.gyp:symupload#host',
- '../breakpad/breakpad.gyp:minidump_dump#host',
- '../breakpad/breakpad.gyp:minidump_stackwalk#host',
- '../build/android/pylib/device/commands/commands.gyp:chromium_commands',
- '../cc/blink/cc_blink_tests.gyp:cc_blink_unittests',
- '../cc/cc_tests.gyp:cc_perftests_apk',
- '../cc/cc_tests.gyp:cc_unittests',
- '../components/components_tests.gyp:components_unittests',
- '../content/content_shell_and_tests.gyp:content_browsertests',
- '../content/content_shell_and_tests.gyp:content_gl_tests',
- '../content/content_shell_and_tests.gyp:content_junit_tests',
- '../content/content_shell_and_tests.gyp:chromium_linker_test_apk',
- '../content/content_shell_and_tests.gyp:content_shell_test_apk',
- '../content/content_shell_and_tests.gyp:content_unittests',
- '../gpu/gpu.gyp:gl_tests',
- '../gpu/gpu.gyp:gpu_perftests_apk',
- '../gpu/gpu.gyp:gpu_unittests',
- '../ipc/ipc.gyp:ipc_tests',
- '../media/media.gyp:media_perftests_apk',
- '../media/media.gyp:media_unittests',
- '../media/midi/midi.gyp:midi_unittests_apk',
- '../media/midi/midi.gyp:midi_unittests',
- '../net/net.gyp:net_unittests',
- '../sandbox/sandbox.gyp:sandbox_linux_unittests_deps',
- '../skia/skia_tests.gyp:skia_unittests',
- '../sql/sql.gyp:sql_unittests',
- '../sync/sync.gyp:sync_unit_tests',
- '../testing/android/junit/junit_test.gyp:junit_unit_tests',
- '../third_party/leveldatabase/leveldatabase.gyp:env_chromium_unittests',
- '../third_party/WebKit/public/all.gyp:*',
- '../tools/android/android_tools.gyp:android_tools',
- '../tools/android/android_tools.gyp:memconsumer',
- '../tools/android/findbugs_plugin/findbugs_plugin.gyp:findbugs_plugin_test',
- '../ui/android/ui_android.gyp:ui_android_unittests',
- '../ui/base/ui_base_tests.gyp:ui_base_unittests',
- '../ui/events/events.gyp:events_unittests',
- '../ui/touch_selection/ui_touch_selection.gyp:ui_touch_selection_unittests',
- # Unit test bundles packaged as an apk.
- '../base/base.gyp:base_unittests_apk',
- '../cc/blink/cc_blink_tests.gyp:cc_blink_unittests_apk',
- '../cc/cc_tests.gyp:cc_unittests_apk',
- '../components/components_tests.gyp:components_browsertests_apk',
- '../components/components_tests.gyp:components_unittests_apk',
- '../content/content_shell_and_tests.gyp:content_browsertests_apk',
- '../content/content_shell_and_tests.gyp:content_gl_tests_apk',
- '../content/content_shell_and_tests.gyp:content_unittests_apk',
- '../content/content_shell_and_tests.gyp:video_decode_accelerator_unittest_apk',
- '../gpu/gpu.gyp:gl_tests_apk',
- '../gpu/gpu.gyp:gpu_unittests_apk',
- '../ipc/ipc.gyp:ipc_tests_apk',
- '../media/media.gyp:media_unittests_apk',
- '../media/midi/midi.gyp:midi_unittests_apk',
- '../net/net.gyp:net_unittests_apk',
- '../sandbox/sandbox.gyp:sandbox_linux_jni_unittests_apk',
- '../skia/skia_tests.gyp:skia_unittests_apk',
- '../sql/sql.gyp:sql_unittests_apk',
- '../sync/sync.gyp:sync_unit_tests_apk',
- '../tools/android/heap_profiler/heap_profiler.gyp:heap_profiler_unittests_apk',
- '../ui/android/ui_android.gyp:ui_android_unittests_apk',
- '../ui/base/ui_base_tests.gyp:ui_base_unittests_apk',
- '../ui/events/events.gyp:events_unittests_apk',
- '../ui/gfx/gfx_tests.gyp:gfx_unittests_apk',
- '../ui/gl/gl_tests.gyp:gl_unittests_apk',
- '../ui/touch_selection/ui_touch_selection.gyp:ui_touch_selection_unittests_apk',
- ],
- 'conditions': [
- ['chromecast==0', {
- 'dependencies': [
- '../android_webview/android_webview.gyp:android_webview_unittests',
- '../chrome/chrome.gyp:unit_tests',
- # Unit test bundles packaged as an apk.
- '../android_webview/android_webview.gyp:android_webview_test_apk',
- '../android_webview/android_webview.gyp:android_webview_unittests_apk',
- '../chrome/android/chrome_apk.gyp:chrome_public_test_apk',
- '../chrome/chrome.gyp:chrome_junit_tests',
- '../chrome/chrome.gyp:chrome_shell_test_apk',
- '../chrome/chrome.gyp:chrome_sync_shell_test_apk',
- '../chrome/chrome.gyp:chrome_shell_uiautomator_tests',
- '../chrome/chrome.gyp:chromedriver_webview_shell_apk',
- '../chrome/chrome.gyp:unit_tests_apk',
- '../third_party/custom_tabs_client/src/custom_tabs_client.gyp:custom_tabs_client_example_apk',
- ],
- }],
- ],
- },
- {
- # WebRTC Chromium tests to run on Android.
- 'target_name': 'android_builder_chromium_webrtc',
- 'type': 'none',
- 'dependencies': [
- '../build/android/pylib/device/commands/commands.gyp:chromium_commands',
- '../content/content_shell_and_tests.gyp:content_browsertests',
- '../tools/android/android_tools.gyp:android_tools',
- '../tools/android/android_tools.gyp:memconsumer',
- '../content/content_shell_and_tests.gyp:content_browsertests_apk',
- ],
- }, # target_name: android_builder_chromium_webrtc
- ], # targets
- }], # OS="android"
- ['OS=="mac"', {
- 'targets': [
- {
- # Target to build everything plus the dmg. We don't put the dmg
- # in the All target because developers really don't need it.
- 'target_name': 'all_and_dmg',
- 'type': 'none',
- 'dependencies': [
- 'All',
- '../chrome/chrome.gyp:build_app_dmg',
- ],
- },
- # These targets are here so the build bots can use them to build
- # subsets of a full tree for faster cycle times.
- {
- 'target_name': 'chromium_builder_dbg',
- 'type': 'none',
- 'dependencies': [
- '../cc/blink/cc_blink_tests.gyp:cc_blink_unittests',
- '../cc/cc_tests.gyp:cc_unittests',
- '../chrome/chrome.gyp:browser_tests',
- '../chrome/chrome.gyp:interactive_ui_tests',
- '../chrome/chrome.gyp:sync_integration_tests',
- '../chrome/chrome.gyp:unit_tests',
- '../cloud_print/cloud_print.gyp:cloud_print_unittests',
- '../components/components_tests.gyp:components_unittests',
- '../content/content_shell_and_tests.gyp:content_browsertests',
- '../content/content_shell_and_tests.gyp:content_unittests',
- '../device/device_tests.gyp:device_unittests',
- '../google_apis/gcm/gcm.gyp:gcm_unit_tests',
- '../gpu/gpu.gyp:gpu_unittests',
- '../ipc/ipc.gyp:ipc_tests',
- '../ipc/mojo/ipc_mojo.gyp:ipc_mojo_unittests',
- '../jingle/jingle.gyp:jingle_unittests',
- '../media/media.gyp:media_unittests',
- '../media/midi/midi.gyp:midi_unittests',
- '../ppapi/ppapi_internal.gyp:ppapi_unittests',
- '../printing/printing.gyp:printing_unittests',
- '../remoting/remoting.gyp:remoting_unittests',
- '../rlz/rlz.gyp:*',
- '../skia/skia_tests.gyp:skia_unittests',
- '../sql/sql.gyp:sql_unittests',
- '../sync/sync.gyp:sync_unit_tests',
- '../third_party/cacheinvalidation/cacheinvalidation.gyp:cacheinvalidation_unittests',
- '../third_party/leveldatabase/leveldatabase.gyp:env_chromium_unittests',
- '../third_party/libaddressinput/libaddressinput.gyp:libaddressinput_unittests',
- '../third_party/libphonenumber/libphonenumber.gyp:libphonenumber_unittests',
- '../tools/perf/clear_system_cache/clear_system_cache.gyp:*',
- '../tools/telemetry/telemetry.gyp:*',
- '../ui/base/ui_base_tests.gyp:ui_base_unittests',
- '../ui/gfx/gfx_tests.gyp:gfx_unittests',
- '../ui/gl/gl_tests.gyp:gl_unittests',
- '../url/url.gyp:url_unittests',
- ],
- },
- {
- 'target_name': 'chromium_builder_rel',
- 'type': 'none',
- 'dependencies': [
- '../cc/blink/cc_blink_tests.gyp:cc_blink_unittests',
- '../cc/cc_tests.gyp:cc_unittests',
- '../chrome/chrome.gyp:browser_tests',
- '../chrome/chrome.gyp:performance_browser_tests',
- '../chrome/chrome.gyp:sync_integration_tests',
- '../chrome/chrome.gyp:unit_tests',
- '../cloud_print/cloud_print.gyp:cloud_print_unittests',
- '../components/components_tests.gyp:components_unittests',
- '../content/content_shell_and_tests.gyp:content_browsertests',
- '../content/content_shell_and_tests.gyp:content_unittests',
- '../device/device_tests.gyp:device_unittests',
- '../google_apis/gcm/gcm.gyp:gcm_unit_tests',
- '../gpu/gpu.gyp:gpu_unittests',
- '../ipc/ipc.gyp:ipc_tests',
- '../ipc/mojo/ipc_mojo.gyp:ipc_mojo_unittests',
- '../jingle/jingle.gyp:jingle_unittests',
- '../media/media.gyp:media_unittests',
- '../media/midi/midi.gyp:midi_unittests',
- '../ppapi/ppapi_internal.gyp:ppapi_unittests',
- '../printing/printing.gyp:printing_unittests',
- '../remoting/remoting.gyp:remoting_unittests',
- '../skia/skia_tests.gyp:skia_unittests',
- '../sql/sql.gyp:sql_unittests',
- '../sync/sync.gyp:sync_unit_tests',
- '../third_party/cacheinvalidation/cacheinvalidation.gyp:cacheinvalidation_unittests',
- '../third_party/leveldatabase/leveldatabase.gyp:env_chromium_unittests',
- '../third_party/libaddressinput/libaddressinput.gyp:libaddressinput_unittests',
- '../third_party/libphonenumber/libphonenumber.gyp:libphonenumber_unittests',
- '../tools/perf/clear_system_cache/clear_system_cache.gyp:*',
- '../tools/telemetry/telemetry.gyp:*',
- '../ui/base/ui_base_tests.gyp:ui_base_unittests',
- '../ui/gfx/gfx_tests.gyp:gfx_unittests',
- '../ui/gl/gl_tests.gyp:gl_unittests',
- '../url/url.gyp:url_unittests',
- ],
- },
- {
- 'target_name': 'chromium_builder_dbg_tsan_mac',
- 'type': 'none',
- 'dependencies': [
- '../base/base.gyp:base_unittests',
- '../cloud_print/cloud_print.gyp:cloud_print_unittests',
- '../crypto/crypto.gyp:crypto_unittests',
- '../ipc/ipc.gyp:ipc_tests',
- '../jingle/jingle.gyp:jingle_unittests',
- '../media/media.gyp:media_unittests',
- '../media/midi/midi.gyp:midi_unittests',
- '../net/net.gyp:net_unittests',
- '../printing/printing.gyp:printing_unittests',
- '../remoting/remoting.gyp:remoting_unittests',
- '../third_party/cacheinvalidation/cacheinvalidation.gyp:cacheinvalidation_unittests',
- '../third_party/libaddressinput/libaddressinput.gyp:libaddressinput_unittests',
- '../third_party/libphonenumber/libphonenumber.gyp:libphonenumber_unittests',
- '../url/url.gyp:url_unittests',
- ],
- },
- {
- 'target_name': 'chromium_builder_dbg_valgrind_mac',
- 'type': 'none',
- 'dependencies': [
- '../base/base.gyp:base_unittests',
- '../chrome/chrome.gyp:unit_tests',
- '../cloud_print/cloud_print.gyp:cloud_print_unittests',
- '../components/components_tests.gyp:components_unittests',
- '../content/content_shell_and_tests.gyp:content_unittests',
- '../crypto/crypto.gyp:crypto_unittests',
- '../device/device_tests.gyp:device_unittests',
- '../ipc/ipc.gyp:ipc_tests',
- '../jingle/jingle.gyp:jingle_unittests',
- '../media/media.gyp:media_unittests',
- '../media/midi/midi.gyp:midi_unittests',
- '../net/net.gyp:net_unittests',
- '../google_apis/gcm/gcm.gyp:gcm_unit_tests',
- '../printing/printing.gyp:printing_unittests',
- '../remoting/remoting.gyp:remoting_unittests',
- '../skia/skia_tests.gyp:skia_unittests',
- '../sql/sql.gyp:sql_unittests',
- '../sync/sync.gyp:sync_unit_tests',
- '../third_party/cacheinvalidation/cacheinvalidation.gyp:cacheinvalidation_unittests',
- '../third_party/leveldatabase/leveldatabase.gyp:env_chromium_unittests',
- '../third_party/libaddressinput/libaddressinput.gyp:libaddressinput_unittests',
- '../third_party/libphonenumber/libphonenumber.gyp:libphonenumber_unittests',
- '../ui/base/ui_base_tests.gyp:ui_base_unittests',
- '../ui/gfx/gfx_tests.gyp:gfx_unittests',
- '../ui/gl/gl_tests.gyp:gl_unittests',
- '../url/url.gyp:url_unittests',
- ],
- },
- ], # targets
- }], # OS="mac"
- ['OS=="win"', {
- 'targets': [
- # These targets are here so the build bots can use them to build
- # subsets of a full tree for faster cycle times.
- {
- 'target_name': 'chromium_builder',
- 'type': 'none',
- 'dependencies': [
- '../cc/blink/cc_blink_tests.gyp:cc_blink_unittests',
- '../cc/cc_tests.gyp:cc_unittests',
- '../chrome/chrome.gyp:browser_tests',
- '../chrome/chrome.gyp:crash_service',
- '../chrome/chrome.gyp:gcapi_test',
- '../chrome/chrome.gyp:installer_util_unittests',
- '../chrome/chrome.gyp:interactive_ui_tests',
- '../chrome/chrome.gyp:performance_browser_tests',
- '../chrome/chrome.gyp:setup_unittests',
- '../chrome/chrome.gyp:sync_integration_tests',
- '../chrome/chrome.gyp:unit_tests',
- '../cloud_print/cloud_print.gyp:cloud_print_unittests',
- '../components/components_tests.gyp:components_unittests',
- '../content/content_shell_and_tests.gyp:content_browsertests',
- '../content/content_shell_and_tests.gyp:content_unittests',
- '../content/content_shell_and_tests.gyp:copy_test_netscape_plugin',
- # ../chrome/test/mini_installer requires mini_installer.
- '../chrome/installer/mini_installer.gyp:mini_installer',
- '../courgette/courgette.gyp:courgette_unittests',
- '../device/device_tests.gyp:device_unittests',
- '../google_apis/gcm/gcm.gyp:gcm_unit_tests',
- '../gpu/gpu.gyp:gpu_unittests',
- '../ipc/ipc.gyp:ipc_tests',
- '../ipc/mojo/ipc_mojo.gyp:ipc_mojo_unittests',
- '../jingle/jingle.gyp:jingle_unittests',
- '../media/media.gyp:media_unittests',
- '../media/midi/midi.gyp:midi_unittests',
- '../ppapi/ppapi_internal.gyp:ppapi_unittests',
- '../printing/printing.gyp:printing_unittests',
- '../remoting/remoting.gyp:remoting_unittests',
- '../skia/skia_tests.gyp:skia_unittests',
- '../sql/sql.gyp:sql_unittests',
- '../sync/sync.gyp:sync_unit_tests',
- '../third_party/cacheinvalidation/cacheinvalidation.gyp:cacheinvalidation_unittests',
- '../third_party/leveldatabase/leveldatabase.gyp:env_chromium_unittests',
- '../third_party/libaddressinput/libaddressinput.gyp:libaddressinput_unittests',
- '../third_party/libphonenumber/libphonenumber.gyp:libphonenumber_unittests',
- '../tools/perf/clear_system_cache/clear_system_cache.gyp:*',
- '../tools/telemetry/telemetry.gyp:*',
- '../ui/base/ui_base_tests.gyp:ui_base_unittests',
- '../ui/events/events.gyp:events_unittests',
- '../ui/gfx/gfx_tests.gyp:gfx_unittests',
- '../ui/gl/gl_tests.gyp:gl_unittests',
- '../ui/touch_selection/ui_touch_selection.gyp:ui_touch_selection_unittests',
- '../ui/views/views.gyp:views_unittests',
- '../url/url.gyp:url_unittests',
- ],
- 'conditions': [
- ['target_arch=="ia32"', {
- 'dependencies': [
- '../chrome/chrome.gyp:crash_service_win64',
- ],
- }],
- ],
- },
- {
- 'target_name': 'chromium_builder_dbg_tsan_win',
- 'type': 'none',
- 'dependencies': [
- '../base/base.gyp:base_unittests',
- '../cloud_print/cloud_print.gyp:cloud_print_unittests',
- '../components/components_tests.gyp:components_unittests',
- '../content/content_shell_and_tests.gyp:content_unittests',
- '../crypto/crypto.gyp:crypto_unittests',
- '../ipc/ipc.gyp:ipc_tests',
- '../jingle/jingle.gyp:jingle_unittests',
- '../media/media.gyp:media_unittests',
- '../media/midi/midi.gyp:midi_unittests',
- '../net/net.gyp:net_unittests',
- '../printing/printing.gyp:printing_unittests',
- '../remoting/remoting.gyp:remoting_unittests',
- '../sql/sql.gyp:sql_unittests',
- '../third_party/cacheinvalidation/cacheinvalidation.gyp:cacheinvalidation_unittests',
- '../third_party/leveldatabase/leveldatabase.gyp:env_chromium_unittests',
- '../third_party/libaddressinput/libaddressinput.gyp:libaddressinput_unittests',
- '../third_party/libphonenumber/libphonenumber.gyp:libphonenumber_unittests',
- '../url/url.gyp:url_unittests',
- ],
- },
- {
- 'target_name': 'chromium_builder_lkgr_drmemory_win',
- 'type': 'none',
- 'dependencies': [
- '../components/test_runner/test_runner.gyp:layout_test_helper',
- '../content/content_shell_and_tests.gyp:content_shell',
- '../content/content_shell_and_tests.gyp:content_shell_crash_service',
- ],
- },
- {
- 'target_name': 'chromium_builder_dbg_drmemory_win',
- 'type': 'none',
- 'dependencies': [
- '../ash/ash.gyp:ash_shell_unittests',
- '../ash/ash.gyp:ash_unittests',
- '../base/base.gyp:base_unittests',
- '../cc/blink/cc_blink_tests.gyp:cc_blink_unittests',
- '../cc/cc_tests.gyp:cc_unittests',
- '../chrome/chrome.gyp:browser_tests',
- '../chrome/chrome.gyp:chrome_app_unittests',
- '../chrome/chrome.gyp:chromedriver_unittests',
- '../chrome/chrome.gyp:installer_util_unittests',
- '../chrome/chrome.gyp:setup_unittests',
- '../chrome/chrome.gyp:unit_tests',
- '../chrome_elf/chrome_elf.gyp:chrome_elf_unittests',
- '../cloud_print/cloud_print.gyp:cloud_print_unittests',
- '../components/components_tests.gyp:components_unittests',
- '../components/test_runner/test_runner.gyp:layout_test_helper',
- '../content/content_shell_and_tests.gyp:content_browsertests',
- '../content/content_shell_and_tests.gyp:content_shell',
- '../content/content_shell_and_tests.gyp:content_shell_crash_service',
- '../content/content_shell_and_tests.gyp:content_unittests',
- '../courgette/courgette.gyp:courgette_unittests',
- '../crypto/crypto.gyp:crypto_unittests',
- '../device/device_tests.gyp:device_unittests',
- '../extensions/extensions_tests.gyp:extensions_browsertests',
- '../extensions/extensions_tests.gyp:extensions_unittests',
- '../gin/gin.gyp:gin_shell',
- '../gin/gin.gyp:gin_unittests',
- '../google_apis/gcm/gcm.gyp:gcm_unit_tests',
- '../google_apis/google_apis.gyp:google_apis_unittests',
- '../gpu/gpu.gyp:angle_unittests',
- '../gpu/gpu.gyp:gpu_unittests',
- '../ipc/ipc.gyp:ipc_tests',
- '../ipc/mojo/ipc_mojo.gyp:ipc_mojo_unittests',
- '../jingle/jingle.gyp:jingle_unittests',
- '../media/cast/cast.gyp:cast_unittests',
- '../media/media.gyp:media_unittests',
- '../media/midi/midi.gyp:midi_unittests',
- '../mojo/mojo.gyp:mojo',
- '../net/net.gyp:net_unittests',
- '../printing/printing.gyp:printing_unittests',
- '../remoting/remoting.gyp:remoting_unittests',
- '../skia/skia_tests.gyp:skia_unittests',
- '../sql/sql.gyp:sql_unittests',
- '../sync/sync.gyp:sync_unit_tests',
- '../third_party/cacheinvalidation/cacheinvalidation.gyp:cacheinvalidation_unittests',
- '../third_party/leveldatabase/leveldatabase.gyp:env_chromium_unittests',
- '../third_party/libaddressinput/libaddressinput.gyp:libaddressinput_unittests',
- '../third_party/libphonenumber/libphonenumber.gyp:libphonenumber_unittests',
- '../third_party/WebKit/Source/platform/blink_platform_tests.gyp:blink_heap_unittests',
- '../third_party/WebKit/Source/platform/blink_platform_tests.gyp:blink_platform_unittests',
- '../ui/accessibility/accessibility.gyp:accessibility_unittests',
- '../ui/app_list/app_list.gyp:app_list_unittests',
- '../ui/aura/aura.gyp:aura_unittests',
- '../ui/compositor/compositor.gyp:compositor_unittests',
- '../ui/display/display.gyp:display_unittests',
- '../ui/events/events.gyp:events_unittests',
- '../ui/gfx/gfx_tests.gyp:gfx_unittests',
- '../ui/gl/gl_tests.gyp:gl_unittests',
- '../ui/keyboard/keyboard.gyp:keyboard_unittests',
- '../ui/touch_selection/ui_touch_selection.gyp:ui_touch_selection_unittests',
- '../url/url.gyp:url_unittests',
- ],
- },
- ], # targets
- 'conditions': [
- ['branding=="Chrome"', {
- 'targets': [
- {
- 'target_name': 'chrome_official_builder_no_unittests',
- 'type': 'none',
- 'dependencies': [
- '../chrome/chrome.gyp:crash_service',
- '../chrome/chrome.gyp:gcapi_dll',
- '../chrome/chrome.gyp:pack_policy_templates',
- '../chrome/installer/mini_installer.gyp:mini_installer',
- '../cloud_print/cloud_print.gyp:cloud_print',
- '../courgette/courgette.gyp:courgette',
- '../courgette/courgette.gyp:courgette64',
- '../remoting/remoting.gyp:remoting_webapp',
- '../third_party/widevine/cdm/widevine_cdm.gyp:widevinecdmadapter',
- ],
- 'conditions': [
- ['target_arch=="ia32"', {
- 'dependencies': [
- '../chrome/chrome.gyp:crash_service_win64',
- ],
- }],
- ['component != "shared_library" and wix_exists == "True" and \
- sas_dll_exists == "True"', {
- 'dependencies': [
- '../remoting/remoting.gyp:remoting_host_installation',
- ],
- }], # component != "shared_library"
- ]
- }, {
- 'target_name': 'chrome_official_builder',
- 'type': 'none',
- 'dependencies': [
- 'chrome_official_builder_no_unittests',
- '../base/base.gyp:base_unittests',
- '../chrome/chrome.gyp:browser_tests',
- '../chrome/chrome.gyp:sync_integration_tests',
- '../ipc/ipc.gyp:ipc_tests',
- '../media/media.gyp:media_unittests',
- '../media/midi/midi.gyp:midi_unittests',
- '../net/net.gyp:net_unittests',
- '../printing/printing.gyp:printing_unittests',
- '../sql/sql.gyp:sql_unittests',
- '../sync/sync.gyp:sync_unit_tests',
- '../ui/base/ui_base_tests.gyp:ui_base_unittests',
- '../ui/gfx/gfx_tests.gyp:gfx_unittests',
- '../ui/gl/gl_tests.gyp:gl_unittests',
- '../ui/touch_selection/ui_touch_selection.gyp:ui_touch_selection_unittests',
- '../ui/views/views.gyp:views_unittests',
- '../url/url.gyp:url_unittests',
- ],
- },
- ], # targets
- }], # branding=="Chrome"
- ], # conditions
- }], # OS="win"
- ['chromeos==1', {
- 'targets': [
- {
- 'target_name': 'chromiumos_preflight',
- 'type': 'none',
- 'dependencies': [
- '../breakpad/breakpad.gyp:minidump_stackwalk',
- '../chrome/chrome.gyp:chrome',
- '../chrome/chrome.gyp:chromedriver',
- '../content/content_shell_and_tests.gyp:video_decode_accelerator_unittest',
- '../content/content_shell_and_tests.gyp:video_encode_accelerator_unittest',
- '../media/media.gyp:media_unittests',
- '../ppapi/ppapi_internal.gyp:ppapi_example_video_decode',
- '../sandbox/sandbox.gyp:chrome_sandbox',
- '../sandbox/sandbox.gyp:sandbox_linux_unittests',
- '../third_party/mesa/mesa.gyp:osmesa',
- '../tools/telemetry/telemetry.gyp:bitmaptools#host',
- '../tools/perf/clear_system_cache/clear_system_cache.gyp:clear_system_cache',
- ],
- 'conditions': [
- ['disable_nacl==0', {
- 'dependencies': [
- '../components/nacl.gyp:nacl_helper',
- '../native_client/src/trusted/service_runtime/linux/nacl_bootstrap.gyp:nacl_helper_bootstrap',
- ],
- }],
- ],
- },
- ], # targets
- }], # "chromeos==1"
- ['use_aura==1', {
- 'targets': [
- {
- 'target_name': 'aura_builder',
- 'type': 'none',
- 'dependencies': [
- '../cc/blink/cc_blink_tests.gyp:cc_blink_unittests',
- '../cc/cc_tests.gyp:cc_unittests',
- '../components/components_tests.gyp:components_unittests',
- '../content/content_shell_and_tests.gyp:content_browsertests',
- '../content/content_shell_and_tests.gyp:content_unittests',
- '../device/device_tests.gyp:device_unittests',
- '../google_apis/gcm/gcm.gyp:gcm_unit_tests',
- '../ppapi/ppapi_internal.gyp:ppapi_unittests',
- '../remoting/remoting.gyp:remoting_unittests',
- '../skia/skia_tests.gyp:skia_unittests',
- '../ui/app_list/app_list.gyp:*',
- '../ui/aura/aura.gyp:*',
- '../ui/aura_extra/aura_extra.gyp:*',
- '../ui/base/ui_base_tests.gyp:ui_base_unittests',
- '../ui/compositor/compositor.gyp:*',
- '../ui/display/display.gyp:display_unittests',
- '../ui/events/events.gyp:*',
- '../ui/gfx/gfx_tests.gyp:gfx_unittests',
- '../ui/gl/gl_tests.gyp:gl_unittests',
- '../ui/keyboard/keyboard.gyp:*',
- '../ui/snapshot/snapshot.gyp:snapshot_unittests',
- '../ui/touch_selection/ui_touch_selection.gyp:ui_touch_selection_unittests',
- '../ui/wm/wm.gyp:*',
- 'blink_tests',
- ],
- 'conditions': [
- ['OS=="win"', {
- 'dependencies': [
- '../chrome/chrome.gyp:crash_service',
- ],
- }],
- ['OS=="win" and target_arch=="ia32"', {
- 'dependencies': [
- '../chrome/chrome.gyp:crash_service_win64',
- ],
- }],
- ['use_ash==1', {
- 'dependencies': [
- '../ash/ash.gyp:ash_shell',
- '../ash/ash.gyp:ash_unittests',
- ],
- }],
- ['OS=="linux"', {
- # Tests that currently only work on Linux.
- 'dependencies': [
- '../base/base.gyp:base_unittests',
- '../ipc/ipc.gyp:ipc_tests',
- '../sql/sql.gyp:sql_unittests',
- '../sync/sync.gyp:sync_unit_tests',
- ],
- }],
- ['chromeos==1', {
- 'dependencies': [
- '../chromeos/chromeos.gyp:chromeos_unittests',
- '../ui/chromeos/ui_chromeos.gyp:ui_chromeos_unittests',
- ],
- }],
- ['use_ozone==1', {
- 'dependencies': [
- '../ui/ozone/ozone.gyp:*',
- '../ui/ozone/demo/ozone_demos.gyp:*',
- ],
- }],
- ['chromecast==0', {
- 'dependencies': [
- '../chrome/chrome.gyp:browser_tests',
- '../chrome/chrome.gyp:chrome',
- '../chrome/chrome.gyp:interactive_ui_tests',
- '../chrome/chrome.gyp:unit_tests',
- '../ui/message_center/message_center.gyp:*',
- '../ui/views/examples/examples.gyp:views_examples_with_content_exe',
- '../ui/views/views.gyp:views',
- '../ui/views/views.gyp:views_unittests',
- ],
- }],
- ],
- },
- ], # targets
- }], # "use_aura==1"
- ['test_isolation_mode != "noop"', {
- 'targets': [
- {
- 'target_name': 'chromium_swarm_tests',
- 'type': 'none',
- 'dependencies': [
- '../base/base.gyp:base_unittests_run',
- '../content/content_shell_and_tests.gyp:content_browsertests_run',
- '../content/content_shell_and_tests.gyp:content_unittests_run',
- '../net/net.gyp:net_unittests_run',
- ],
- 'conditions': [
- ['chromecast==0', {
- 'dependencies': [
- '../chrome/chrome.gyp:browser_tests_run',
- '../chrome/chrome.gyp:interactive_ui_tests_run',
- '../chrome/chrome.gyp:sync_integration_tests_run',
- '../chrome/chrome.gyp:unit_tests_run',
- ],
- }],
- ],
- }, # target_name: chromium_swarm_tests
- ],
- }],
- ['archive_chromoting_tests==1', {
- 'targets': [
- {
- 'target_name': 'chromoting_swarm_tests',
- 'type': 'none',
- 'dependencies': [
- '../testing/chromoting/integration_tests.gyp:*',
- ],
- }, # target_name: chromoting_swarm_tests
- ]
- }],
- ['OS=="mac" and toolkit_views==1', {
- 'targets': [
- {
- 'target_name': 'macviews_builder',
- 'type': 'none',
- 'dependencies': [
- '../ui/views/examples/examples.gyp:views_examples_with_content_exe',
- '../ui/views/views.gyp:views',
- '../ui/views/views.gyp:views_unittests',
- ],
- }, # target_name: macviews_builder
- ], # targets
- }], # os=='mac' and toolkit_views==1
- ], # conditions
-}
diff --git a/build/android/AndroidManifest.xml b/build/android/AndroidManifest.xml
deleted file mode 100644
index f27872e..0000000
--- a/build/android/AndroidManifest.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- Copyright (c) 2012 The Chromium Authors. All rights reserved. Use of this
- source code is governed by a BSD-style license that can be found in the
- LICENSE file.
--->
-
-<!--
- This is a dummy manifest which is required by:
- 1. aapt when generating R.java in java.gypi:
- Nothing in the manifest is used, but it is still required by aapt.
- 2. lint: [min|target]SdkVersion are required by lint and should
- be kept up-to-date.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="dummy.package">
-
- <uses-sdk android:minSdkVersion="16" android:targetSdkVersion="22" />
-
-</manifest>
diff --git a/build/android/BUILD.gn b/build/android/BUILD.gn
deleted file mode 100644
index d90ad70..0000000
--- a/build/android/BUILD.gn
+++ /dev/null
@@ -1,56 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/config/android/rules.gni")
-
-sun_tools_jar_path = "$root_gen_dir/sun_tools_jar/tools.jar"
-
-action("find_sun_tools_jar") {
- script = "//build/android/gyp/find_sun_tools_jar.py"
- depfile = "$target_gen_dir/$target_name.d"
- outputs = [
- depfile,
- sun_tools_jar_path,
- ]
- args = [
- "--depfile",
- rebase_path(depfile, root_build_dir),
- "--output",
- rebase_path(sun_tools_jar_path, root_build_dir),
- ]
-}
-
-java_prebuilt("sun_tools_java") {
- jar_path = sun_tools_jar_path
- jar_dep = ":find_sun_tools_jar"
-}
-
-action("cpplib_stripped") {
- _strip_bin = "${android_tool_prefix}strip"
- _soname = "libc++_shared.so"
- _input_so = "${android_libcpp_root}/libs/${android_app_abi}/${_soname}"
- _output_so = "${root_out_dir}/lib.stripped/${_soname}"
-
- script = "//build/gn_run_binary.py"
- inputs = [
- _strip_bin,
- ]
- sources = [
- _input_so,
- ]
- outputs = [
- _output_so,
- ]
-
- _rebased_strip_bin = rebase_path(_strip_bin, root_out_dir)
- _rebased_input_so = rebase_path(_input_so, root_out_dir)
- _rebased_output_so = rebase_path(_output_so, root_out_dir)
- args = [
- _rebased_strip_bin,
- "--strip-unneeded",
- "-o",
- _rebased_output_so,
- _rebased_input_so,
- ]
-}
diff --git a/build/android/CheckInstallApk-debug.apk b/build/android/CheckInstallApk-debug.apk
deleted file mode 100644
index 3dc31910..0000000
--- a/build/android/CheckInstallApk-debug.apk
+++ /dev/null
Binary files differ
diff --git a/build/android/OWNERS b/build/android/OWNERS
deleted file mode 100644
index 9a5d270..0000000
--- a/build/android/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-jbudorick@chromium.org
-klundberg@chromium.org
-pasko@chromium.org
diff --git a/build/android/PRESUBMIT.py b/build/android/PRESUBMIT.py
deleted file mode 100644
index 6e0a3de..0000000
--- a/build/android/PRESUBMIT.py
+++ /dev/null
@@ -1,64 +0,0 @@
-# Copyright (c) 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Presubmit script for android buildbot.
-
-See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts for
-details on the presubmit API built into depot_tools.
-"""
-
-
-def CommonChecks(input_api, output_api):
- output = []
-
- def J(*dirs):
- """Returns a path relative to presubmit directory."""
- return input_api.os_path.join(input_api.PresubmitLocalPath(), *dirs)
-
- output.extend(input_api.canned_checks.RunPylint(
- input_api,
- output_api,
- black_list=[r'pylib/symbols/.*\.py$', r'gyp/.*\.py$', r'gn/.*\.py'],
- extra_paths_list=[
- J(), J('..', '..', 'third_party', 'android_testrunner'),
- J('buildbot')]))
- output.extend(input_api.canned_checks.RunPylint(
- input_api,
- output_api,
- white_list=[r'gyp/.*\.py$', r'gn/.*\.py'],
- extra_paths_list=[J('gyp'), J('gn')]))
-
- # Disabled due to http://crbug.com/410936
- #output.extend(input_api.canned_checks.RunUnitTestsInDirectory(
- #input_api, output_api, J('buildbot', 'tests')))
-
- pylib_test_env = dict(input_api.environ)
- pylib_test_env.update({
- 'PYTHONPATH': input_api.PresubmitLocalPath(),
- 'PYTHONDONTWRITEBYTECODE': '1',
- })
- output.extend(input_api.canned_checks.RunUnitTests(
- input_api,
- output_api,
- unit_tests=[
- J('pylib', 'base', 'test_dispatcher_unittest.py'),
- J('pylib', 'device', 'battery_utils_test.py'),
- J('pylib', 'device', 'device_utils_test.py'),
- J('pylib', 'device', 'logcat_monitor_test.py'),
- J('pylib', 'gtest', 'gtest_test_instance_test.py'),
- J('pylib', 'instrumentation',
- 'instrumentation_test_instance_test.py'),
- J('pylib', 'results', 'json_results_test.py'),
- J('pylib', 'utils', 'md5sum_test.py'),
- ],
- env=pylib_test_env))
- return output
-
-
-def CheckChangeOnUpload(input_api, output_api):
- return CommonChecks(input_api, output_api)
-
-
-def CheckChangeOnCommit(input_api, output_api):
- return CommonChecks(input_api, output_api)
diff --git a/build/android/adb_android_webview_command_line b/build/android/adb_android_webview_command_line
deleted file mode 100755
index 791e270..0000000
--- a/build/android/adb_android_webview_command_line
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# If no flags are given, prints the current content shell flags.
-#
-# Otherwise, the given flags are used to REPLACE (not modify) the content shell
-# flags. For example:
-# adb_android_webview_command_line --enable-webgl
-#
-# To remove all content shell flags, pass an empty string for the flags:
-# adb_android_webview_command_line ""
-
-. $(dirname $0)/adb_command_line_functions.sh
-CMD_LINE_FILE=/data/local/tmp/android-webview-command-line
-REQUIRES_SU=0
-set_command_line "$@"
-
diff --git a/build/android/adb_chrome_public_command_line b/build/android/adb_chrome_public_command_line
deleted file mode 100755
index 9bf91c6..0000000
--- a/build/android/adb_chrome_public_command_line
+++ /dev/null
@@ -1,19 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# If no flags are given, prints the current Chrome flags.
-#
-# Otherwise, the given flags are used to REPLACE (not modify) the Chrome
-# flags. For example:
-# adb_chrome_public_command_line --enable-webgl
-#
-# To remove all Chrome flags, pass an empty string for the flags:
-# adb_chrome_public_command_line ""
-
-. $(dirname $0)/adb_command_line_functions.sh
-CMD_LINE_FILE=/data/local/chrome-command-line
-REQUIRES_SU=1
-set_command_line "$@"
diff --git a/build/android/adb_chrome_shell_command_line b/build/android/adb_chrome_shell_command_line
deleted file mode 100755
index 750f906..0000000
--- a/build/android/adb_chrome_shell_command_line
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# If no flags are given, prints the current chrome shell flags.
-#
-# Otherwise, the given flags are used to REPLACE (not modify) the chrome shell
-# flags. For example:
-# adb_chrome_shell_command_line --enable-webgl
-#
-# To remove all chrome shell flags, pass an empty string for the flags:
-# adb_chrome_shell_command_line ""
-
-. $(dirname $0)/adb_command_line_functions.sh
-CMD_LINE_FILE=/data/local/tmp/chrome-shell-command-line
-REQUIRES_SU=0
-set_command_line "$@"
-
diff --git a/build/android/adb_command_line_functions.sh b/build/android/adb_command_line_functions.sh
deleted file mode 100755
index 7ea98b09..0000000
--- a/build/android/adb_command_line_functions.sh
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# Variables must be set before calling:
-# CMD_LINE_FILE - Path on device to flags file.
-# REQUIRES_SU - Set to 1 if path requires root.
-function set_command_line() {
- SU_CMD=""
- if [[ "$REQUIRES_SU" = 1 ]]; then
- # Older androids accept "su -c", while newer use "su uid".
- SDK_LEVEL=$(adb shell getprop ro.build.version.sdk | tr -d '\r')
- # E.g. if no device connected.
- if [[ -z "$SDK_LEVEL" ]]; then
- exit 1
- fi
- SU_CMD="su -c"
- if (( $SDK_LEVEL >= 21 )); then
- SU_CMD="su 0"
- fi
- fi
-
- if [ $# -eq 0 ] ; then
- # If nothing specified, print the command line (stripping off "chrome ")
- adb shell "cat $CMD_LINE_FILE 2>/dev/null" | cut -d ' ' -s -f2-
- elif [ $# -eq 1 ] && [ "$1" = '' ] ; then
- # If given an empty string, delete the command line.
- set -x
- adb shell $SU_CMD rm $CMD_LINE_FILE >/dev/null
- else
- # Else set it.
- set -x
- adb shell "echo 'chrome $*' | $SU_CMD dd of=$CMD_LINE_FILE"
- # Prevent other apps from modifying flags (this can create security issues).
- adb shell $SU_CMD chmod 0664 $CMD_LINE_FILE
- fi
-}
-
diff --git a/build/android/adb_content_shell_command_line b/build/android/adb_content_shell_command_line
deleted file mode 100755
index 2ac7ece..0000000
--- a/build/android/adb_content_shell_command_line
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# If no flags are given, prints the current content shell flags.
-#
-# Otherwise, the given flags are used to REPLACE (not modify) the content shell
-# flags. For example:
-# adb_content_shell_command_line --enable-webgl
-#
-# To remove all content shell flags, pass an empty string for the flags:
-# adb_content_shell_command_line ""
-
-. $(dirname $0)/adb_command_line_functions.sh
-CMD_LINE_FILE=/data/local/tmp/content-shell-command-line
-REQUIRES_SU=0
-set_command_line "$@"
-
diff --git a/build/android/adb_device_functions.sh b/build/android/adb_device_functions.sh
deleted file mode 100755
index 66cc32f..0000000
--- a/build/android/adb_device_functions.sh
+++ /dev/null
@@ -1,139 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-#
-# A collection of functions useful for maintaining android devices
-
-
-# Run an adb command on all connected device in parallel.
-# Usage: adb_all command line to eval. Quoting is optional.
-#
-# Examples:
-# adb_all install Chrome.apk
-# adb_all 'shell cat /path/to/file'
-#
-adb_all() {
- if [[ $# == 0 ]]; then
- echo "Usage: adb_all <adb command>. Quoting is optional."
- echo "Example: adb_all install Chrome.apk"
- return 1
- fi
- local DEVICES=$(adb_get_devices -b)
- local NUM_DEVICES=$(echo $DEVICES | wc -w)
- if (( $NUM_DEVICES > 1 )); then
- echo "Looping over $NUM_DEVICES devices"
- fi
- _adb_multi "$DEVICES" "$*"
-}
-
-
-# Run a command on each connected device. Quoting the command is suggested but
-# not required. The script setups up variable DEVICE to correspond to the
-# current serial number. Intended for complex one_liners that don't work in
-# adb_all
-# Usage: adb_device_loop 'command line to eval'
-adb_device_loop() {
- if [[ $# == 0 ]]; then
- echo "Intended for more complex one-liners that cannot be done with" \
- "adb_all."
- echo 'Usage: adb_device_loop "echo $DEVICE: $(adb root &&' \
- 'adb shell cat /data/local.prop)"'
- return 1
- fi
- local DEVICES=$(adb_get_devices)
- if [[ -z $DEVICES ]]; then
- return
- fi
- # Do not change DEVICE variable name - part of api
- for DEVICE in $DEVICES; do
- DEV_TYPE=$(adb -s $DEVICE shell getprop ro.product.device | sed 's/\r//')
- echo "Running on $DEVICE ($DEV_TYPE)"
- ANDROID_SERIAL=$DEVICE eval "$*"
- done
-}
-
-# Erases data from any devices visible on adb. To preserve a device,
-# disconnect it or:
-# 1) Reboot it into fastboot with 'adb reboot bootloader'
-# 2) Run wipe_all_devices to wipe remaining devices
-# 3) Restore device it with 'fastboot reboot'
-#
-# Usage: wipe_all_devices [-f]
-#
-wipe_all_devices() {
- if [[ -z $(which adb) || -z $(which fastboot) ]]; then
- echo "aborting: adb and fastboot not in path"
- return 1
- elif ! $(groups | grep -q 'plugdev'); then
- echo "If fastboot fails, run: 'sudo adduser $(whoami) plugdev'"
- fi
-
- local DEVICES=$(adb_get_devices -b)
-
- if [[ $1 != '-f' ]]; then
- echo "This will ERASE ALL DATA from $(echo $DEVICES | wc -w) device."
- read -p "Hit enter to continue"
- fi
-
- _adb_multi "$DEVICES" "reboot bootloader"
- # Subshell to isolate job list
- (
- for DEVICE in $DEVICES; do
- fastboot_erase $DEVICE &
- done
- wait
- )
-
- # Reboot devices together
- for DEVICE in $DEVICES; do
- fastboot -s $DEVICE reboot
- done
-}
-
-# Wipe a device in fastboot.
-# Usage fastboot_erase [serial]
-fastboot_erase() {
- if [[ -n $1 ]]; then
- echo "Wiping $1"
- local SERIAL="-s $1"
- else
- if [ -z $(fastboot devices) ]; then
- echo "No devices in fastboot, aborting."
- echo "Check out wipe_all_devices to see if sufficient"
- echo "You can put a device in fastboot using adb reboot bootloader"
- return 1
- fi
- local SERIAL=""
- fi
- fastboot $SERIAL erase cache
- fastboot $SERIAL erase userdata
-}
-
-# Get list of devices connected via adb
-# Args: -b block until adb detects a device
-adb_get_devices() {
- local DEVICES="$(adb devices | grep 'device$')"
- if [[ -z $DEVICES && $1 == '-b' ]]; then
- echo '- waiting for device -' >&2
- local DEVICES="$(adb wait-for-device devices | grep 'device$')"
- fi
- echo "$DEVICES" | awk -vORS=' ' '{print $1}' | sed 's/ $/\n/'
-}
-
-###################################################
-## HELPER FUNCTIONS
-###################################################
-
-# Run an adb command in parallel over a device list
-_adb_multi() {
- local DEVICES=$1
- local ADB_ARGS=$2
- (
- for DEVICE in $DEVICES; do
- adb -s $DEVICE $ADB_ARGS &
- done
- wait
- )
-}
diff --git a/build/android/adb_gdb b/build/android/adb_gdb
deleted file mode 100755
index 65ec7b2..0000000
--- a/build/android/adb_gdb
+++ /dev/null
@@ -1,1047 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-#
-
-# A generic script used to attach to a running Chromium process and
-# debug it. Most users should not use this directly, but one of the
-# wrapper scripts like adb_gdb_content_shell
-#
-# Use --help to print full usage instructions.
-#
-
-PROGNAME=$(basename "$0")
-PROGDIR=$(dirname "$0")
-
-# Location of Chromium-top-level sources.
-CHROMIUM_SRC=$(cd "$PROGDIR"/../.. >/dev/null && pwd 2>/dev/null)
-
-# Location of Chromium out/ directory.
-if [ -z "$CHROMIUM_OUT_DIR" ]; then
- CHROMIUM_OUT_DIR=out
-fi
-
-TMPDIR=
-GDBSERVER_PIDFILE=
-TARGET_GDBSERVER=
-COMMAND_PREFIX=
-
-clean_exit () {
- if [ "$TMPDIR" ]; then
- GDBSERVER_PID=$(cat $GDBSERVER_PIDFILE 2>/dev/null)
- if [ "$GDBSERVER_PID" ]; then
- log "Killing background gdbserver process: $GDBSERVER_PID"
- kill -9 $GDBSERVER_PID >/dev/null 2>&1
- fi
- if [ "$TARGET_GDBSERVER" ]; then
- log "Removing target gdbserver binary: $TARGET_GDBSERVER."
- "$ADB" shell "$COMMAND_PREFIX" rm "$TARGET_GDBSERVER" >/dev/null 2>&1
- fi
- log "Cleaning up: $TMPDIR"
- rm -rf "$TMPDIR"
- fi
- trap "" EXIT
- exit $1
-}
-
-# Ensure clean exit on Ctrl-C or normal exit.
-trap "clean_exit 1" INT HUP QUIT TERM
-trap "clean_exit \$?" EXIT
-
-panic () {
- echo "ERROR: $@" >&2
- exit 1
-}
-
-fail_panic () {
- if [ $? != 0 ]; then panic "$@"; fi
-}
-
-log () {
- if [ "$VERBOSE" -gt 0 ]; then
- echo "$@"
- fi
-}
-
-DEFAULT_PULL_LIBS_DIR=/tmp/$USER-adb-gdb-libs
-
-# NOTE: Allow wrapper scripts to set various default through ADB_GDB_XXX
-# environment variables. This is only for cosmetic reasons, i.e. to
-# display proper
-
-# Allow wrapper scripts to set the default activity through
-# the ADB_GDB_ACTIVITY variable. Users are still able to change the
-# final activity name through --activity=<name> option.
-#
-# This is only for cosmetic reasons, i.e. to display the proper default
-# in the --help output.
-#
-DEFAULT_ACTIVITY=${ADB_GDB_ACTIVITY:-".Main"}
-
-# Allow wrapper scripts to set the program name through ADB_GDB_PROGNAME
-PROGNAME=${ADB_GDB_PROGNAME:-$(basename "$0")}
-
-ACTIVITY=$DEFAULT_ACTIVITY
-ADB=
-ANNOTATE=
-# Note: Ignore BUILDTYPE variable, because the Ninja build doesn't use it.
-BUILDTYPE=
-FORCE=
-GDBEXEPOSTFIX=gdb
-GDBINIT=
-GDBSERVER=
-HELP=
-NDK_DIR=
-NO_PULL_LIBS=
-PACKAGE_NAME=
-PID=
-PORT=
-PRIVILEGED=
-PRIVILEGED_INDEX=
-PROGRAM_NAME="activity"
-PULL_LIBS=
-PULL_LIBS_DIR=
-SANDBOXED=
-SANDBOXED_INDEX=
-START=
-SU_PREFIX=
-SYMBOL_DIR=
-TARGET_ARCH=
-TOOLCHAIN=
-VERBOSE=0
-
-for opt; do
- optarg=$(expr "x$opt" : 'x[^=]*=\(.*\)')
- case $opt in
- --adb=*)
- ADB=$optarg
- ;;
- --activity=*)
- ACTIVITY=$optarg
- ;;
- --annotate=3)
- ANNOTATE=$optarg
- ;;
- --force)
- FORCE=true
- ;;
- --gdbserver=*)
- GDBSERVER=$optarg
- ;;
- --gdb=*)
- GDB=$optarg
- ;;
- --help|-h|-?)
- HELP=true
- ;;
- --ndk-dir=*)
- NDK_DIR=$optarg
- ;;
- --no-pull-libs)
- NO_PULL_LIBS=true
- ;;
- --package-name=*)
- PACKAGE_NAME=$optarg
- ;;
- --pid=*)
- PID=$optarg
- ;;
- --port=*)
- PORT=$optarg
- ;;
- --privileged)
- PRIVILEGED=true
- ;;
- --privileged=*)
- PRIVILEGED=true
- PRIVILEGED_INDEX=$optarg
- ;;
- --program-name=*)
- PROGRAM_NAME=$optarg
- ;;
- --pull-libs)
- PULL_LIBS=true
- ;;
- --pull-libs-dir=*)
- PULL_LIBS_DIR=$optarg
- ;;
- --sandboxed)
- SANDBOXED=true
- ;;
- --sandboxed=*)
- SANDBOXED=true
- SANDBOXED_INDEX=$optarg
- ;;
- --script=*)
- GDBINIT=$optarg
- ;;
- --start)
- START=true
- ;;
- --su-prefix=*)
- SU_PREFIX=$optarg
- ;;
- --symbol-dir=*)
- SYMBOL_DIR=$optarg
- ;;
- --out-dir=*)
- CHROMIUM_OUT_DIR=$optarg
- ;;
- --target-arch=*)
- TARGET_ARCH=$optarg
- ;;
- --toolchain=*)
- TOOLCHAIN=$optarg
- ;;
- --ui)
- GDBEXEPOSTFIX=gdbtui
- ;;
- --verbose)
- VERBOSE=$(( $VERBOSE + 1 ))
- ;;
- --debug)
- BUILDTYPE=Debug
- ;;
- --release)
- BUILDTYPE=Release
- ;;
- -*)
- panic "Unknown option $OPT, see --help." >&2
- ;;
- *)
- if [ "$PACKAGE_NAME" ]; then
- panic "You can only provide a single package name as argument!\
- See --help."
- fi
- PACKAGE_NAME=$opt
- ;;
- esac
-done
-
-print_help_options () {
- cat <<EOF
-EOF
-}
-
-if [ "$HELP" ]; then
- if [ "$ADB_GDB_PROGNAME" ]; then
- # Assume wrapper scripts all provide a default package name.
- cat <<EOF
-Usage: $PROGNAME [options]
-
-Attach gdb to a running Android $PROGRAM_NAME process.
-EOF
- else
- # Assume this is a direct call to adb_gdb
- cat <<EOF
-Usage: $PROGNAME [options] [<package-name>]
-
-Attach gdb to a running Android $PROGRAM_NAME process.
-
-If provided, <package-name> must be the name of the Android application's
-package name to be debugged. You can also use --package-name=<name> to
-specify it.
-EOF
- fi
-
- cat <<EOF
-
-This script is used to debug a running $PROGRAM_NAME process.
-This can be a regular Android application process, sandboxed (if you use the
---sandboxed or --sandboxed=<num> option) or a privileged (--privileged or
---privileged=<num>) service.
-
-This script needs several things to work properly. It will try to pick
-them up automatically for you though:
-
- - target gdbserver binary
- - host gdb client (e.g. arm-linux-androideabi-gdb)
- - directory with symbolic version of $PROGRAM_NAME's shared libraries.
-
-You can also use --ndk-dir=<path> to specify an alternative NDK installation
-directory.
-
-The script tries to find the most recent version of the debug version of
-shared libraries under one of the following directories:
-
- \$CHROMIUM_SRC/<out>/Release/lib/ (used by Ninja builds)
- \$CHROMIUM_SRC/<out>/Debug/lib/ (used by Ninja builds)
- \$CHROMIUM_SRC/<out>/Release/lib.target/ (used by Make builds)
- \$CHROMIUM_SRC/<out>/Debug/lib.target/ (used by Make builds)
-
-Where <out> is 'out' by default, unless the --out=<name> option is used or
-the CHROMIUM_OUT_DIR environment variable is defined.
-
-You can restrict this search by using --release or --debug to specify the
-build type, or simply use --symbol-dir=<path> to specify the file manually.
-
-The script tries to extract the target architecture from your target device,
-but if this fails, will default to 'arm'. Use --target-arch=<name> to force
-its value.
-
-Otherwise, the script will complain, but you can use the --gdbserver,
---gdb and --symbol-lib options to specify everything manually.
-
-An alternative to --gdb=<file> is to use --toollchain=<path> to specify
-the path to the host target-specific cross-toolchain.
-
-You will also need the 'adb' tool in your path. Otherwise, use the --adb
-option. The script will complain if there is more than one device connected
-and ANDROID_SERIAL is not defined.
-
-The first time you use it on a device, the script will pull many system
-libraries required by the process into a temporary directory. This
-is done to strongly improve the debugging experience, like allowing
-readable thread stacks and more. The libraries are copied to the following
-directory by default:
-
- $DEFAULT_PULL_LIBS_DIR/
-
-But you can use the --pull-libs-dir=<path> option to specify an
-alternative. The script can detect when you change the connected device,
-and will re-pull the libraries only in this case. You can however force it
-with the --pull-libs option.
-
-Any local .gdbinit script will be ignored, but it is possible to pass a
-gdb command script with the --script=<file> option. Note that its commands
-will be passed to gdb after the remote connection and library symbol
-loading have completed.
-
-Valid options:
- --help|-h|-? Print this message.
- --verbose Increase verbosity.
-
- --sandboxed Debug first sandboxed process we find.
- --sandboxed=<num> Debug specific sandboxed process.
- --symbol-dir=<path> Specify directory with symbol shared libraries.
- --out-dir=<path> Specify the out directory.
- --package-name=<name> Specify package name (alternative to 1st argument).
- --privileged Debug first privileged process we find.
- --privileged=<num> Debug specific privileged process.
- --program-name=<name> Specify program name (cosmetic only).
- --pid=<pid> Specify application process pid.
- --force Kill any previous debugging session, if any.
- --start Start package's activity on device.
- --ui Use gdbtui instead of gdb
- --activity=<name> Activity name for --start [$DEFAULT_ACTIVITY].
- --annotate=<num> Enable gdb annotation.
- --script=<file> Specify extra GDB init script.
-
- --gdbserver=<file> Specify target gdbserver binary.
- --gdb=<file> Specify host gdb client binary.
- --target-arch=<name> Specify NDK target arch.
- --adb=<file> Specify host ADB binary.
- --port=<port> Specify the tcp port to use.
-
- --su-prefix=<prefix> Prepend <prefix> to 'adb shell' commands that are
- run by this script. This can be useful to use
- the 'su' program on rooted production devices.
- e.g. --su-prefix="su -c"
-
- --pull-libs Force system libraries extraction.
- --no-pull-libs Do not extract any system library.
- --libs-dir=<path> Specify system libraries extraction directory.
-
- --debug Use libraries under out/Debug.
- --release Use libraries under out/Release.
-
-EOF
- exit 0
-fi
-
-if [ -z "$PACKAGE_NAME" ]; then
- panic "Please specify a package name on the command line. See --help."
-fi
-
-if [ -z "$NDK_DIR" ]; then
- ANDROID_NDK_ROOT=$(PYTHONPATH=$CHROMIUM_SRC/build/android python -c \
-'from pylib.constants import ANDROID_NDK_ROOT; print ANDROID_NDK_ROOT,')
-else
- if [ ! -d "$NDK_DIR" ]; then
- panic "Invalid directory: $NDK_DIR"
- fi
- if [ ! -f "$NDK_DIR/ndk-build" ]; then
- panic "Not a valid NDK directory: $NDK_DIR"
- fi
- ANDROID_NDK_ROOT=$NDK_DIR
-fi
-
-if [ "$GDBINIT" -a ! -f "$GDBINIT" ]; then
- panic "Unknown --script file: $GDBINIT"
-fi
-
-# Check that ADB is in our path
-if [ -z "$ADB" ]; then
- ADB=$(which adb 2>/dev/null)
- if [ -z "$ADB" ]; then
- panic "Can't find 'adb' tool in your path. Install it or use \
---adb=<file>"
- fi
- log "Auto-config: --adb=$ADB"
-fi
-
-# Check that it works minimally
-ADB_VERSION=$($ADB version 2>/dev/null)
-echo "$ADB_VERSION" | fgrep -q -e "Android Debug Bridge"
-if [ $? != 0 ]; then
- panic "Your 'adb' tool seems invalid, use --adb=<file> to specify a \
-different one: $ADB"
-fi
-
-# If there are more than one device connected, and ANDROID_SERIAL is not
-# defined, print an error message.
-NUM_DEVICES_PLUS2=$($ADB devices 2>/dev/null | wc -l)
-if [ "$NUM_DEVICES_PLUS2" -lt 3 -a -z "$ANDROID_SERIAL" ]; then
- echo "ERROR: There is more than one Android device connected to ADB."
- echo "Please define ANDROID_SERIAL to specify which one to use."
- exit 1
-fi
-
-# Run a command through adb shell, strip the extra \r from the output
-# and return the correct status code to detect failures. This assumes
-# that the adb shell command prints a final \n to stdout.
-# $1+: command to run
-# Out: command's stdout
-# Return: command's status
-# Note: the command's stderr is lost
-adb_shell () {
- local TMPOUT="$(mktemp)"
- local LASTLINE RET
- local ADB=${ADB:-adb}
-
- # The weird sed rule is to strip the final \r on each output line
- # Since 'adb shell' never returns the command's proper exit/status code,
- # we force it to print it as '%%<status>' in the temporary output file,
- # which we will later strip from it.
- $ADB shell $@ ";" echo "%%\$?" 2>/dev/null | \
- sed -e 's![[:cntrl:]]!!g' > $TMPOUT
- # Get last line in log, which contains the exit code from the command
- LASTLINE=$(sed -e '$!d' $TMPOUT)
- # Extract the status code from the end of the line, which must
- # be '%%<code>'.
- RET=$(echo "$LASTLINE" | \
- awk '{ if (match($0, "%%[0-9]+$")) { print substr($0,RSTART+2); } }')
- # Remove the status code from the last line. Note that this may result
- # in an empty line.
- LASTLINE=$(echo "$LASTLINE" | \
- awk '{ if (match($0, "%%[0-9]+$")) { print substr($0,1,RSTART-1); } }')
- # The output itself: all lines except the status code.
- sed -e '$d' $TMPOUT && printf "%s" "$LASTLINE"
- # Remove temp file.
- rm -f $TMPOUT
- # Exit with the appropriate status.
- return $RET
-}
-
-# Find the target architecture from the target device.
-# This returns an NDK-compatible architecture name.
-# out: NDK Architecture name, or empty string.
-get_gyp_target_arch () {
- local ARCH=$(adb_shell getprop ro.product.cpu.abi)
- case $ARCH in
- mips|x86|x86_64) echo "$ARCH";;
- arm64*) echo "arm64";;
- arm*) echo "arm";;
- *) echo "";
- esac
-}
-
-if [ -z "$TARGET_ARCH" ]; then
- TARGET_ARCH=$(get_gyp_target_arch)
- if [ -z "$TARGET_ARCH" ]; then
- TARGET_ARCH=arm
- fi
-else
- # Nit: accept Chromium's 'ia32' as a valid target architecture. This
- # script prefers the NDK 'x86' name instead because it uses it to find
- # NDK-specific files (host gdb) with it.
- if [ "$TARGET_ARCH" = "ia32" ]; then
- TARGET_ARCH=x86
- log "Auto-config: --arch=$TARGET_ARCH (equivalent to ia32)"
- fi
-fi
-
-# Detect the NDK system name, i.e. the name used to identify the host.
-# out: NDK system name (e.g. 'linux' or 'darwin')
-get_ndk_host_system () {
- local HOST_OS
- if [ -z "$NDK_HOST_SYSTEM" ]; then
- HOST_OS=$(uname -s)
- case $HOST_OS in
- Linux) NDK_HOST_SYSTEM=linux;;
- Darwin) NDK_HOST_SYSTEM=darwin;;
- *) panic "You can't run this script on this system: $HOST_OS";;
- esac
- fi
- echo "$NDK_HOST_SYSTEM"
-}
-
-# Detect the NDK host architecture name.
-# out: NDK arch name (e.g. 'x86' or 'x86_64')
-get_ndk_host_arch () {
- local HOST_ARCH HOST_OS
- if [ -z "$NDK_HOST_ARCH" ]; then
- HOST_OS=$(get_ndk_host_system)
- HOST_ARCH=$(uname -p)
- case $HOST_ARCH in
- i?86) NDK_HOST_ARCH=x86;;
- x86_64|amd64) NDK_HOST_ARCH=x86_64;;
- *) panic "You can't run this script on this host architecture: $HOST_ARCH";;
- esac
- # Darwin trick: "uname -p" always returns i386 on 64-bit installations.
- if [ "$HOST_OS" = darwin -a "$NDK_HOST_ARCH" = "x86" ]; then
- # Use '/usr/bin/file', not just 'file' to avoid buggy MacPorts
- # implementations of the tool. See http://b.android.com/53769
- HOST_64BITS=$(/usr/bin/file -L "$SHELL" | grep -e "x86[_-]64")
- if [ "$HOST_64BITS" ]; then
- NDK_HOST_ARCH=x86_64
- fi
- fi
- fi
- echo "$NDK_HOST_ARCH"
-}
-
-# Convert an NDK architecture name into a GNU configure triplet.
-# $1: NDK architecture name (e.g. 'arm')
-# Out: Android GNU configure triplet (e.g. 'arm-linux-androideabi')
-get_arch_gnu_config () {
- case $1 in
- arm)
- echo "arm-linux-androideabi"
- ;;
- arm64)
- echo "aarch64-linux-android"
- ;;
- x86)
- echo "i686-linux-android"
- ;;
- x86_64)
- echo "x86_64-linux-android"
- ;;
- mips)
- echo "mipsel-linux-android"
- ;;
- *)
- echo "$ARCH-linux-android"
- ;;
- esac
-}
-
-# Convert an NDK architecture name into a toolchain name prefix
-# $1: NDK architecture name (e.g. 'arm')
-# Out: NDK toolchain name prefix (e.g. 'arm-linux-androideabi')
-get_arch_toolchain_prefix () {
- # Return the configure triplet, except for x86!
- if [ "$1" = "x86" ]; then
- echo "$1"
- else
- get_arch_gnu_config $1
- fi
-}
-
-# Find a NDK toolchain prebuilt file or sub-directory.
-# This will probe the various arch-specific toolchain directories
-# in the NDK for the needed file.
-# $1: NDK install path
-# $2: NDK architecture name
-# $3: prebuilt sub-path to look for.
-# Out: file path, or empty if none is found.
-get_ndk_toolchain_prebuilt () {
- local NDK_DIR="${1%/}"
- local ARCH="$2"
- local SUBPATH="$3"
- local NAME="$(get_arch_toolchain_prefix $ARCH)"
- local FILE TARGET
- FILE=$NDK_DIR/toolchains/$NAME-4.9/prebuilt/$SUBPATH
- if [ ! -f "$FILE" ]; then
- FILE=$NDK_DIR/toolchains/$NAME-4.8/prebuilt/$SUBPATH
- if [ ! -f "$FILE" ]; then
- FILE=
- fi
- fi
- echo "$FILE"
-}
-
-# Find the path to an NDK's toolchain full prefix for a given architecture
-# $1: NDK install path
-# $2: NDK target architecture name
-# Out: install path + binary prefix (e.g.
-# ".../path/to/bin/arm-linux-androideabi-")
-get_ndk_toolchain_fullprefix () {
- local NDK_DIR="$1"
- local ARCH="$2"
- local TARGET NAME HOST_OS HOST_ARCH GCC CONFIG
-
- # NOTE: This will need to be updated if the NDK changes the names or moves
- # the location of its prebuilt toolchains.
- #
- GCC=
- HOST_OS=$(get_ndk_host_system)
- HOST_ARCH=$(get_ndk_host_arch)
- CONFIG=$(get_arch_gnu_config $ARCH)
- GCC=$(get_ndk_toolchain_prebuilt \
- "$NDK_DIR" "$ARCH" "$HOST_OS-$HOST_ARCH/bin/$CONFIG-gcc")
- if [ -z "$GCC" -a "$HOST_ARCH" = "x86_64" ]; then
- GCC=$(get_ndk_toolchain_prebuilt \
- "$NDK_DIR" "$ARCH" "$HOST_OS-x86/bin/$CONFIG-gcc")
- fi
- if [ ! -f "$GCC" -a "$ARCH" = "x86" ]; then
- # Special case, the x86 toolchain used to be incorrectly
- # named i686-android-linux-gcc!
- GCC=$(get_ndk_toolchain_prebuilt \
- "$NDK_DIR" "$ARCH" "$HOST_OS-x86/bin/i686-android-linux-gcc")
- fi
- if [ -z "$GCC" ]; then
- panic "Cannot find Android NDK toolchain for '$ARCH' architecture. \
-Please verify your NDK installation!"
- fi
- echo "${GCC%%gcc}"
-}
-
-# $1: NDK install path
-# $2: target architecture.
-get_ndk_gdbserver () {
- local NDK_DIR="$1"
- local ARCH=$2
- local BINARY
-
- # The location has moved after NDK r8
- BINARY=$NDK_DIR/prebuilt/android-$ARCH/gdbserver/gdbserver
- if [ ! -f "$BINARY" ]; then
- BINARY=$(get_ndk_toolchain_prebuilt "$NDK_DIR" "$ARCH" gdbserver)
- fi
- echo "$BINARY"
-}
-
-# Check/probe the path to the Android toolchain installation. Always
-# use the NDK versions of gdb and gdbserver. They must match to avoid
-# issues when both binaries do not speak the same wire protocol.
-#
-if [ -z "$TOOLCHAIN" ]; then
- ANDROID_TOOLCHAIN=$(get_ndk_toolchain_fullprefix \
- "$ANDROID_NDK_ROOT" "$TARGET_ARCH")
- ANDROID_TOOLCHAIN=$(dirname "$ANDROID_TOOLCHAIN")
- log "Auto-config: --toolchain=$ANDROID_TOOLCHAIN"
-else
- # Be flexible, allow one to specify either the install path or the bin
- # sub-directory in --toolchain:
- #
- if [ -d "$TOOLCHAIN/bin" ]; then
- TOOLCHAIN=$TOOLCHAIN/bin
- fi
- ANDROID_TOOLCHAIN=$TOOLCHAIN
-fi
-
-# Cosmetic: Remove trailing directory separator.
-ANDROID_TOOLCHAIN=${ANDROID_TOOLCHAIN%/}
-
-# Find host GDB client binary
-if [ -z "$GDB" ]; then
- GDB=$(which $ANDROID_TOOLCHAIN/*-$GDBEXEPOSTFIX 2>/dev/null | head -1)
- if [ -z "$GDB" ]; then
- panic "Can't find Android gdb client in your path, check your \
---toolchain or --gdb path."
- fi
- log "Host gdb client: $GDB"
-fi
-
-# Find gdbserver binary, we will later push it to /data/local/tmp
-# This ensures that both gdbserver and $GDB talk the same binary protocol,
-# otherwise weird problems will appear.
-#
-if [ -z "$GDBSERVER" ]; then
- GDBSERVER=$(get_ndk_gdbserver "$ANDROID_NDK_ROOT" "$TARGET_ARCH")
- if [ -z "$GDBSERVER" ]; then
- panic "Can't find NDK gdbserver binary. use --gdbserver to specify \
-valid one!"
- fi
- log "Auto-config: --gdbserver=$GDBSERVER"
-fi
-
-# A unique ID for this script's session. This needs to be the same in all
-# sub-shell commands we're going to launch, so take the PID of the launcher
-# process.
-TMP_ID=$$
-
-# Temporary directory, will get cleaned up on exit.
-TMPDIR=/tmp/$USER-adb-gdb-tmp-$TMP_ID
-mkdir -p "$TMPDIR" && rm -rf "$TMPDIR"/*
-
-GDBSERVER_PIDFILE="$TMPDIR"/gdbserver-$TMP_ID.pid
-
-# If --force is specified, try to kill any gdbserver process started by the
-# same user on the device. Normally, these are killed automatically by the
-# script on exit, but there are a few corner cases where this would still
-# be needed.
-if [ "$FORCE" ]; then
- GDBSERVER_PIDS=$(adb_shell ps | awk '$9 ~ /gdbserver/ { print $2; }')
- for GDB_PID in $GDBSERVER_PIDS; do
- log "Killing previous gdbserver (PID=$GDB_PID)"
- adb_shell kill -9 $GDB_PID
- done
-fi
-
-if [ "$START" ]; then
- log "Starting $PROGRAM_NAME on device."
- adb_shell am start -n $PACKAGE_NAME/$ACTIVITY 2>/dev/null
- adb_shell ps | grep -q $PACKAGE_NAME
- fail_panic "Could not start $PROGRAM_NAME on device. Are you sure the \
-package is installed?"
-fi
-
-# Return the timestamp of a given time, as number of seconds since epoch.
-# $1: file path
-# Out: file timestamp
-get_file_timestamp () {
- stat -c %Y "$1" 2>/dev/null
-}
-
-# Detect the build type and symbol directory. This is done by finding
-# the most recent sub-directory containing debug shared libraries under
-# $CHROMIUM_SRC/$CHROMIUM_OUT_DIR/
-#
-# $1: $BUILDTYPE value, can be empty
-# Out: nothing, but this sets SYMBOL_DIR
-#
-detect_symbol_dir () {
- local SUBDIRS SUBDIR LIST DIR DIR_LIBS TSTAMP
- # Note: Ninja places debug libraries under out/$BUILDTYPE/lib/, while
- # Make places then under out/$BUILDTYPE/lib.target.
- if [ "$1" ]; then
- SUBDIRS="$1/lib $1/lib.target"
- else
- SUBDIRS="Release/lib Debug/lib Release/lib.target Debug/lib.target"
- fi
- LIST=$TMPDIR/scan-subdirs-$$.txt
- printf "" > "$LIST"
- for SUBDIR in $SUBDIRS; do
- DIR=$CHROMIUM_SRC/$CHROMIUM_OUT_DIR/$SUBDIR
- if [ -d "$DIR" ]; then
- # Ignore build directories that don't contain symbol versions
- # of the shared libraries.
- DIR_LIBS=$(ls "$DIR"/lib*.so 2>/dev/null)
- if [ -z "$DIR_LIBS" ]; then
- echo "No shared libs: $DIR"
- continue
- fi
- TSTAMP=$(get_file_timestamp "$DIR")
- printf "%s %s\n" "$TSTAMP" "$SUBDIR" >> "$LIST"
- fi
- done
- SUBDIR=$(cat $LIST | sort -r | head -1 | cut -d" " -f2)
- rm -f "$LIST"
-
- if [ -z "$SUBDIR" ]; then
- if [ -z "$1" ]; then
- panic "Could not find any build directory under \
-$CHROMIUM_SRC/$CHROMIUM_OUT_DIR. Please build the program first!"
- else
- panic "Could not find any $1 directory under \
-$CHROMIUM_SRC/$CHROMIUM_OUT_DIR. Check your build type!"
- fi
- fi
-
- SYMBOL_DIR=$CHROMIUM_SRC/$CHROMIUM_OUT_DIR/$SUBDIR
- log "Auto-config: --symbol-dir=$SYMBOL_DIR"
-}
-
-if [ -z "$SYMBOL_DIR" ]; then
- detect_symbol_dir "$BUILDTYPE"
-fi
-
-# Allow several concurrent debugging sessions
-TARGET_GDBSERVER=/data/data/$PACKAGE_NAME/gdbserver-adb-gdb-$TMP_ID
-TMP_TARGET_GDBSERVER=/data/local/tmp/gdbserver-adb-gdb-$TMP_ID
-
-# Return the build fingerprint contained in a build.prop file.
-# $1: path to build.prop file
-get_build_fingerprint_from () {
- cat "$1" | grep -e '^ro.build.fingerprint=' | cut -d= -f2
-}
-
-
-ORG_PULL_LIBS_DIR=$PULL_LIBS_DIR
-PULL_LIBS_DIR=${PULL_LIBS_DIR:-$DEFAULT_PULL_LIBS_DIR}
-
-HOST_FINGERPRINT=
-DEVICE_FINGERPRINT=$(adb_shell getprop ro.build.fingerprint)
-log "Device build fingerprint: $DEVICE_FINGERPRINT"
-
-# If --pull-libs-dir is not specified, and this is a platform build, look
-# if we can use the symbolic libraries under $ANDROID_PRODUCT_OUT/symbols/
-# directly, if the build fingerprint matches the device.
-if [ -z "$ORG_PULL_LIBS_DIR" -a \
- "$ANDROID_PRODUCT_OUT" -a \
- -f "$ANDROID_PRODUCT_OUT/system/build.prop" ]; then
- ANDROID_FINGERPRINT=$(get_build_fingerprint_from \
- "$ANDROID_PRODUCT_OUT"/system/build.prop)
- log "Android build fingerprint: $ANDROID_FINGERPRINT"
- if [ "$ANDROID_FINGERPRINT" = "$DEVICE_FINGERPRINT" ]; then
- log "Perfect match!"
- PULL_LIBS_DIR=$ANDROID_PRODUCT_OUT/symbols
- HOST_FINGERPRINT=$ANDROID_FINGERPRINT
- if [ "$PULL_LIBS" ]; then
- log "Ignoring --pull-libs since the device and platform build \
-fingerprints match."
- NO_PULL_LIBS=true
- fi
- fi
-fi
-
-# If neither --pull-libs an --no-pull-libs were specified, check the build
-# fingerprints of the device, and the cached system libraries on the host.
-#
-if [ -z "$NO_PULL_LIBS" -a -z "$PULL_LIBS" ]; then
- if [ ! -f "$PULL_LIBS_DIR/build.prop" ]; then
- log "Auto-config: --pull-libs (no cached libraries)"
- PULL_LIBS=true
- else
- HOST_FINGERPRINT=$(get_build_fingerprint_from "$PULL_LIBS_DIR/build.prop")
- log "Host build fingerprint: $HOST_FINGERPRINT"
- if [ "$HOST_FINGERPRINT" == "$DEVICE_FINGERPRINT" ]; then
- log "Auto-config: --no-pull-libs (fingerprint match)"
- NO_PULL_LIBS=true
- else
- log "Auto-config: --pull-libs (fingerprint mismatch)"
- PULL_LIBS=true
- fi
- fi
-fi
-
-# Extract the system libraries from the device if necessary.
-if [ "$PULL_LIBS" -a -z "$NO_PULL_LIBS" ]; then
- echo "Extracting system libraries into: $PULL_LIBS_DIR"
-fi
-
-mkdir -p "$PULL_LIBS_DIR"
-fail_panic "Can't create --libs-dir directory: $PULL_LIBS_DIR"
-
-# If requested, work for M-x gdb. The gdb indirections make it
-# difficult to pass --annotate=3 to the gdb binary itself.
-GDB_ARGS=
-if [ "$ANNOTATE" ]; then
- GDB_ARGS=$GDB_ARGS" --annotate=$ANNOTATE"
-fi
-
-# Get the PID from the first argument or else find the PID of the
-# browser process.
-if [ -z "$PID" ]; then
- PROCESSNAME=$PACKAGE_NAME
- if [ "$SANDBOXED_INDEX" ]; then
- PROCESSNAME=$PROCESSNAME:sandboxed_process$SANDBOXED_INDEX
- elif [ "$SANDBOXED" ]; then
- PROCESSNAME=$PROCESSNAME:sandboxed_process
- PID=$(adb_shell ps | \
- awk '$9 ~ /^'$PROCESSNAME'/ { print $2; }' | head -1)
- elif [ "$PRIVILEGED_INDEX" ]; then
- PROCESSNAME=$PROCESSNAME:privileged_process$PRIVILEGED_INDEX
- elif [ "$PRIVILEGED" ]; then
- PROCESSNAME=$PROCESSNAME:privileged_process
- PID=$(adb_shell ps | \
- awk '$9 ~ /^'$PROCESSNAME'/ { print $2; }' | head -1)
- fi
- if [ -z "$PID" ]; then
- PID=$(adb_shell ps | \
- awk '$9 == "'$PROCESSNAME'" { print $2; }' | head -1)
- fi
- if [ -z "$PID" ]; then
- if [ "$START" ]; then
- panic "Can't find application process PID, did it crash?"
- else
- panic "Can't find application process PID, are you sure it is \
-running? Try using --start."
- fi
- fi
- log "Found process PID: $PID"
-elif [ "$SANDBOXED" ]; then
- echo "WARNING: --sandboxed option ignored due to use of --pid."
-elif [ "$PRIVILEGED" ]; then
- echo "WARNING: --privileged option ignored due to use of --pid."
-fi
-
-# Determine if 'adb shell' runs as root or not.
-# If so, we can launch gdbserver directly, otherwise, we have to
-# use run-as $PACKAGE_NAME ..., which requires the package to be debuggable.
-#
-if [ "$SU_PREFIX" ]; then
- # Need to check that this works properly.
- SU_PREFIX_TEST_LOG=$TMPDIR/su-prefix.log
- adb_shell $SU_PREFIX \"echo "foo"\" > $SU_PREFIX_TEST_LOG 2>&1
- if [ $? != 0 -o "$(cat $SU_PREFIX_TEST_LOG)" != "foo" ]; then
- echo "ERROR: Cannot use '$SU_PREFIX' as a valid su prefix:"
- echo "$ adb shell $SU_PREFIX \"echo foo\""
- cat $SU_PREFIX_TEST_LOG
- exit 1
- fi
- COMMAND_PREFIX="$SU_PREFIX \""
- COMMAND_SUFFIX="\""
-else
- SHELL_UID=$(adb shell cat /proc/self/status | \
- awk '$1 == "Uid:" { print $2; }')
- log "Shell UID: $SHELL_UID"
- if [ "$SHELL_UID" != 0 -o -n "$NO_ROOT" ]; then
- COMMAND_PREFIX="run-as $PACKAGE_NAME"
- COMMAND_SUFFIX=
- else
- COMMAND_PREFIX=
- COMMAND_SUFFIX=
- fi
-fi
-log "Command prefix: '$COMMAND_PREFIX'"
-log "Command suffix: '$COMMAND_SUFFIX'"
-
-# Pull device's system libraries that are mapped by our process.
-# Pulling all system libraries is too long, so determine which ones
-# we need by looking at /proc/$PID/maps instead
-if [ "$PULL_LIBS" -a -z "$NO_PULL_LIBS" ]; then
- echo "Extracting system libraries into: $PULL_LIBS_DIR"
- rm -f $PULL_LIBS_DIR/build.prop
- MAPPINGS=$(adb_shell $COMMAND_PREFIX cat /proc/$PID/maps $COMMAND_SUFFIX)
- if [ $? != 0 ]; then
- echo "ERROR: Could not list process's memory mappings."
- if [ "$SU_PREFIX" ]; then
- panic "Are you sure your --su-prefix is correct?"
- else
- panic "Use --su-prefix if the application is not debuggable."
- fi
- fi
- SYSTEM_LIBS=$(echo "$MAPPINGS" | \
- awk '$6 ~ /\/system\/.*\.so$/ { print $6; }' | sort -u)
- for SYSLIB in /system/bin/linker $SYSTEM_LIBS; do
- echo "Pulling from device: $SYSLIB"
- DST_FILE=$PULL_LIBS_DIR$SYSLIB
- DST_DIR=$(dirname "$DST_FILE")
- mkdir -p "$DST_DIR" && adb pull $SYSLIB "$DST_FILE" 2>/dev/null
- fail_panic "Could not pull $SYSLIB from device !?"
- done
- echo "Pulling device build.prop"
- adb pull /system/build.prop $PULL_LIBS_DIR/build.prop
- fail_panic "Could not pull device build.prop !?"
-fi
-
-# Find all the sub-directories of $PULL_LIBS_DIR, up to depth 4
-# so we can add them to solib-search-path later.
-SOLIB_DIRS=$(find $PULL_LIBS_DIR -mindepth 1 -maxdepth 4 -type d | \
- grep -v "^$" | tr '\n' ':')
-
-# This is a re-implementation of gdbclient, where we use compatible
-# versions of gdbserver and $GDBNAME to ensure that everything works
-# properly.
-#
-
-# Push gdbserver to the device
-log "Pushing gdbserver $GDBSERVER to $TARGET_GDBSERVER"
-adb push $GDBSERVER $TMP_TARGET_GDBSERVER &>/dev/null
-adb shell $COMMAND_PREFIX cp $TMP_TARGET_GDBSERVER $TARGET_GDBSERVER
-adb shell rm $TMP_TARGET_GDBSERVER
-fail_panic "Could not copy gdbserver to the device!"
-
-if [ -z "$PORT" ]; then
- PORT=5039
-fi
-HOST_PORT=$PORT
-TARGET_PORT=$PORT
-
-# Select correct app_process for architecture.
-case $TARGET_ARCH in
- arm|x86|mips) GDBEXEC=app_process;;
- arm64|x86_64) GDBEXEC=app_process64;;
- *) fail_panic "Unknown app_process for architecture!";;
-esac
-
-# Detect AddressSanitizer setup on the device. In that case app_process is a
-# script, and the real executable is app_process.real.
-GDBEXEC_ASAN=app_process.real
-adb_shell ls /system/bin/$GDBEXEC_ASAN
-if [ $? == 0 ]; then
- GDBEXEC=$GDBEXEC_ASAN
-fi
-
-# Pull the app_process binary from the device.
-log "Pulling $GDBEXEC from device"
-adb pull /system/bin/$GDBEXEC "$TMPDIR"/$GDBEXEC &>/dev/null
-fail_panic "Could not retrieve $GDBEXEC from the device!"
-
-# Setup network redirection
-log "Setting network redirection (host:$HOST_PORT -> device:$TARGET_PORT)"
-adb forward tcp:$HOST_PORT tcp:$TARGET_PORT
-fail_panic "Could not setup network redirection from \
-host:localhost:$HOST_PORT to device:localhost:$TARGET_PORT!"
-
-# Start gdbserver in the background
-# Note that using run-as requires the package to be debuggable.
-#
-# If not, this will fail horribly. The alternative is to run the
-# program as root, which requires of course root privileges.
-# Maybe we should add a --root option to enable this?
-#
-log "Starting gdbserver in the background:"
-GDBSERVER_LOG=$TMPDIR/gdbserver-$TMP_ID.log
-log "adb shell $COMMAND_PREFIX $TARGET_GDBSERVER :$TARGET_PORT \
---attach $PID $COMMAND_SUFFIX"
-("$ADB" shell $COMMAND_PREFIX $TARGET_GDBSERVER :$TARGET_PORT \
- --attach $PID $COMMAND_SUFFIX > $GDBSERVER_LOG 2>&1) &
-GDBSERVER_PID=$!
-echo "$GDBSERVER_PID" > $GDBSERVER_PIDFILE
-log "background job pid: $GDBSERVER_PID"
-
-# Check that it is still running after a few seconds. If not, this means we
-# could not properly attach to it
-sleep 2
-log "Job control: $(jobs -l)"
-STATE=$(jobs -l | awk '$2 == "'$GDBSERVER_PID'" { print $3; }')
-if [ "$STATE" != "Running" ]; then
- echo "ERROR: GDBServer could not attach to PID $PID!"
- if [ $(adb_shell su -c getenforce) != "Permissive" ]; then
- echo "Device mode is Enforcing. Changing Device mode to Permissive "
- $(adb_shell su -c setenforce 0)
- if [ $(adb_shell su -c getenforce) != "Permissive" ]; then
- echo "ERROR: Failed to Change Device mode to Permissive"
- echo "Failure log (use --verbose for more information):"
- cat $GDBSERVER_LOG
- exit 1
- fi
- else
- echo "Failure log (use --verbose for more information):"
- cat $GDBSERVER_LOG
- exit 1
- fi
-fi
-
-# Generate a file containing useful GDB initialization commands
-readonly COMMANDS=$TMPDIR/gdb.init
-log "Generating GDB initialization commands file: $COMMANDS"
-echo -n "" > $COMMANDS
-echo "set print pretty 1" >> $COMMANDS
-echo "python" >> $COMMANDS
-echo "import sys" >> $COMMANDS
-echo "sys.path.insert(0, '$CHROMIUM_SRC/tools/gdb/')" >> $COMMANDS
-echo "try:" >> $COMMANDS
-echo " import gdb_chrome" >> $COMMANDS
-echo "finally:" >> $COMMANDS
-echo " sys.path.pop(0)" >> $COMMANDS
-echo "end" >> $COMMANDS
-echo "file $TMPDIR/$GDBEXEC" >> $COMMANDS
-echo "directory $CHROMIUM_SRC" >> $COMMANDS
-echo "set solib-absolute-prefix $PULL_LIBS_DIR" >> $COMMANDS
-echo "set solib-search-path $SOLIB_DIRS:$PULL_LIBS_DIR:$SYMBOL_DIR" \
- >> $COMMANDS
-echo "echo Attaching and reading symbols, this may take a while.." \
- >> $COMMANDS
-echo "target remote :$HOST_PORT" >> $COMMANDS
-
-if [ "$GDBINIT" ]; then
- cat "$GDBINIT" >> $COMMANDS
-fi
-
-if [ "$VERBOSE" -gt 0 ]; then
- echo "### START $COMMANDS"
- cat $COMMANDS
- echo "### END $COMMANDS"
-fi
-
-log "Launching gdb client: $GDB $GDB_ARGS -x $COMMANDS"
-$GDB $GDB_ARGS -x $COMMANDS &&
-rm -f "$GDBSERVER_PIDFILE"
diff --git a/build/android/adb_gdb_android_webview_shell b/build/android/adb_gdb_android_webview_shell
deleted file mode 100755
index f685fda..0000000
--- a/build/android/adb_gdb_android_webview_shell
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-#
-# Attach to or start a ContentShell process and debug it.
-# See --help for details.
-#
-PROGDIR=$(dirname "$0")
-export ADB_GDB_PROGNAME=$(basename "$0")
-export ADB_GDB_ACTIVITY=.AwShellActivity
-"$PROGDIR"/adb_gdb \
- --program-name=AwShellApplication \
- --package-name=org.chromium.android_webview.shell \
- "$@"
diff --git a/build/android/adb_gdb_chrome_public b/build/android/adb_gdb_chrome_public
deleted file mode 100755
index 4366c83..0000000
--- a/build/android/adb_gdb_chrome_public
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-#
-# Attach to or start a ChromePublic process and debug it.
-# See --help for details.
-#
-PROGDIR=$(dirname "$0")
-export ADB_GDB_PROGNAME=$(basename "$0")
-export ADB_GDB_ACTIVITY=com.google.android.apps.chrome.Main
-"$PROGDIR"/adb_gdb \
- --program-name=ChromePublic \
- --package-name=org.chromium.chrome \
- "$@"
diff --git a/build/android/adb_gdb_chrome_shell b/build/android/adb_gdb_chrome_shell
deleted file mode 100755
index e5c8a30..0000000
--- a/build/android/adb_gdb_chrome_shell
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-#
-# Attach to or start a ChromeShell process and debug it.
-# See --help for details.
-#
-PROGDIR=$(dirname "$0")
-export ADB_GDB_PROGNAME=$(basename "$0")
-export ADB_GDB_ACTIVITY=.ChromeShellActivity
-"$PROGDIR"/adb_gdb \
- --program-name=ChromeShell \
- --package-name=org.chromium.chrome.shell \
- "$@"
diff --git a/build/android/adb_gdb_content_shell b/build/android/adb_gdb_content_shell
deleted file mode 100755
index 18e1a61..0000000
--- a/build/android/adb_gdb_content_shell
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-#
-# Attach to or start a ContentShell process and debug it.
-# See --help for details.
-#
-PROGDIR=$(dirname "$0")
-export ADB_GDB_PROGNAME=$(basename "$0")
-export ADB_GDB_ACTIVITY=.ContentShellActivity
-"$PROGDIR"/adb_gdb \
- --program-name=ContentShell \
- --package-name=org.chromium.content_shell_apk \
- "$@"
diff --git a/build/android/adb_gdb_cronet_sample b/build/android/adb_gdb_cronet_sample
deleted file mode 100755
index 8d0c864..0000000
--- a/build/android/adb_gdb_cronet_sample
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-#
-# Attach to or start a ContentShell process and debug it.
-# See --help for details.
-#
-PROGDIR=$(dirname "$0")
-export ADB_GDB_PROGNAME=$(basename "$0")
-export ADB_GDB_ACTIVITY=.CronetSampleActivity
-"$PROGDIR"/adb_gdb \
- --program-name=CronetSample \
- --package-name=org.chromium.cronet_sample_apk \
- "$@"
diff --git a/build/android/adb_gdb_mojo_shell b/build/android/adb_gdb_mojo_shell
deleted file mode 100755
index ba91149..0000000
--- a/build/android/adb_gdb_mojo_shell
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-#
-# Attach to or start a ContentShell process and debug it.
-# See --help for details.
-#
-PROGDIR=$(dirname "$0")
-export ADB_GDB_PROGNAME=$(basename "$0")
-export ADB_GDB_ACTIVITY=.MojoShellActivity
-"$PROGDIR"/adb_gdb \
- --program-name=MojoShell \
- --package-name=org.chromium.mojo_shell_apk \
- "$@"
diff --git a/build/android/adb_install_apk.py b/build/android/adb_install_apk.py
deleted file mode 100755
index 50faea7..0000000
--- a/build/android/adb_install_apk.py
+++ /dev/null
@@ -1,114 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Utility script to install APKs from the command line quickly."""
-
-import argparse
-import glob
-import logging
-import os
-import sys
-
-from pylib import constants
-from pylib.device import device_blacklist
-from pylib.device import device_errors
-from pylib.device import device_utils
-from pylib.utils import apk_helper
-from pylib.utils import run_tests_helper
-
-
-def main():
- parser = argparse.ArgumentParser()
-
- apk_group = parser.add_mutually_exclusive_group(required=True)
- apk_group.add_argument('--apk', dest='apk_name',
- help='DEPRECATED The name of the apk containing the'
- ' application (with the .apk extension).')
- apk_group.add_argument('apk_path', nargs='?',
- help='The path to the APK to install.')
-
- # TODO(jbudorick): Remove once no clients pass --apk_package
- parser.add_argument('--apk_package', help='DEPRECATED unused')
- parser.add_argument('--split',
- action='append',
- dest='splits',
- help='A glob matching the apk splits. '
- 'Can be specified multiple times.')
- parser.add_argument('--keep_data',
- action='store_true',
- default=False,
- help='Keep the package data when installing '
- 'the application.')
- parser.add_argument('--debug', action='store_const', const='Debug',
- dest='build_type',
- default=os.environ.get('BUILDTYPE', 'Debug'),
- help='If set, run test suites under out/Debug. '
- 'Default is env var BUILDTYPE or Debug')
- parser.add_argument('--release', action='store_const', const='Release',
- dest='build_type',
- help='If set, run test suites under out/Release. '
- 'Default is env var BUILDTYPE or Debug.')
- parser.add_argument('-d', '--device', dest='device',
- help='Target device for apk to install on.')
- parser.add_argument('-v', '--verbose', action='count',
- help='Enable verbose logging.')
-
- args = parser.parse_args()
-
- run_tests_helper.SetLogLevel(args.verbose)
- constants.SetBuildType(args.build_type)
-
- apk = args.apk_path or args.apk_name
- if not apk.endswith('.apk'):
- apk += '.apk'
- if not os.path.exists(apk):
- apk = os.path.join(constants.GetOutDirectory(), 'apks', apk)
- if not os.path.exists(apk):
- parser.error('%s not found.' % apk)
-
- if args.splits:
- splits = []
- base_apk_package = apk_helper.ApkHelper(apk).GetPackageName()
- for split_glob in args.splits:
- apks = [f for f in glob.glob(split_glob) if f.endswith('.apk')]
- if not apks:
- logging.warning('No apks matched for %s.' % split_glob)
- for f in apks:
- helper = apk_helper.ApkHelper(f)
- if (helper.GetPackageName() == base_apk_package
- and helper.GetSplitName()):
- splits.append(f)
-
- devices = device_utils.DeviceUtils.HealthyDevices()
-
- if args.device:
- devices = [d for d in devices if d == args.device]
- if not devices:
- raise device_errors.DeviceUnreachableError(args.device)
- elif not devices:
- raise device_errors.NoDevicesError()
-
- def blacklisting_install(device):
- try:
- if args.splits:
- device.InstallSplitApk(apk, splits, reinstall=args.keep_data)
- else:
- device.Install(apk, reinstall=args.keep_data)
- except device_errors.CommandFailedError:
- logging.exception('Failed to install %s', args.apk_name)
- device_blacklist.ExtendBlacklist([str(device)])
- logging.warning('Blacklisting %s', str(device))
- except device_errors.CommandTimeoutError:
- logging.exception('Timed out while installing %s', args.apk_name)
- device_blacklist.ExtendBlacklist([str(device)])
- logging.warning('Blacklisting %s', str(device))
-
- device_utils.DeviceUtils.parallel(devices).pMap(blacklisting_install)
-
-
-if __name__ == '__main__':
- sys.exit(main())
-
diff --git a/build/android/adb_kill_android_webview_shell b/build/android/adb_kill_android_webview_shell
deleted file mode 100755
index 5f287f0..0000000
--- a/build/android/adb_kill_android_webview_shell
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-#
-# Kill a running android webview shell.
-#
-# Assumes you have sourced the build/android/envsetup.sh script.
-
-SHELL_PID_LINES=$(adb shell ps | grep ' org.chromium.android_webview.shell')
-VAL=$(echo "$SHELL_PID_LINES" | wc -l)
-if [ $VAL -lt 1 ] ; then
- echo "Not running android webview shell."
-else
- SHELL_PID=$(echo $SHELL_PID_LINES | awk '{print $2}')
- if [ "$SHELL_PID" != "" ] ; then
- set -x
- adb shell kill $SHELL_PID
- set -
- else
- echo "Android webview shell does not appear to be running."
- fi
-fi
diff --git a/build/android/adb_kill_chrome_public b/build/android/adb_kill_chrome_public
deleted file mode 100755
index 5b539a0..0000000
--- a/build/android/adb_kill_chrome_public
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-#
-# Kill a running instance of ChromePublic.
-#
-# Assumes you have sourced the build/android/envsetup.sh script.
-
-SHELL_PID_LINES=$(adb shell ps | grep -w 'org.chromium.chrome')
-VAL=$(echo "$SHELL_PID_LINES" | wc -l)
-if [ $VAL -lt 1 ] ; then
- echo "Not running ChromePublic."
-else
- SHELL_PID=$(echo $SHELL_PID_LINES | awk '{print $2}')
- if [ "$SHELL_PID" != "" ] ; then
- set -x
- adb shell kill $SHELL_PID
- set -
- else
- echo "ChromePublic does not appear to be running."
- fi
-fi
diff --git a/build/android/adb_kill_chrome_shell b/build/android/adb_kill_chrome_shell
deleted file mode 100755
index 2b63c9a..0000000
--- a/build/android/adb_kill_chrome_shell
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-#
-# Kill a running chrome shell.
-#
-# Assumes you have sourced the build/android/envsetup.sh script.
-
-SHELL_PID_LINES=$(adb shell ps | grep ' org.chromium.chrome.shell')
-VAL=$(echo "$SHELL_PID_LINES" | wc -l)
-if [ $VAL -lt 1 ] ; then
- echo "Not running Chrome shell."
-else
- SHELL_PID=$(echo $SHELL_PID_LINES | awk '{print $2}')
- if [ "$SHELL_PID" != "" ] ; then
- set -x
- adb shell kill $SHELL_PID
- set -
- else
- echo "Chrome shell does not appear to be running."
- fi
-fi
diff --git a/build/android/adb_kill_content_shell b/build/android/adb_kill_content_shell
deleted file mode 100755
index e379dd4..0000000
--- a/build/android/adb_kill_content_shell
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-#
-# Kill a running content shell.
-#
-# Assumes you have sourced the build/android/envsetup.sh script.
-
-SHELL_PID_LINES=$(adb shell ps | grep ' org.chromium.content_shell_apk')
-VAL=$(echo "$SHELL_PID_LINES" | wc -l)
-if [ $VAL -lt 1 ] ; then
- echo "Not running Content shell."
-else
- SHELL_PID=$(echo $SHELL_PID_LINES | awk '{print $2}')
- if [ "$SHELL_PID" != "" ] ; then
- set -x
- adb shell kill $SHELL_PID
- set -
- else
- echo "Content shell does not appear to be running."
- fi
-fi
diff --git a/build/android/adb_logcat_monitor.py b/build/android/adb_logcat_monitor.py
deleted file mode 100755
index d3cc67d..0000000
--- a/build/android/adb_logcat_monitor.py
+++ /dev/null
@@ -1,156 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Saves logcats from all connected devices.
-
-Usage: adb_logcat_monitor.py <base_dir> [<adb_binary_path>]
-
-This script will repeatedly poll adb for new devices and save logcats
-inside the <base_dir> directory, which it attempts to create. The
-script will run until killed by an external signal. To test, run the
-script in a shell and <Ctrl>-C it after a while. It should be
-resilient across phone disconnects and reconnects and start the logcat
-early enough to not miss anything.
-"""
-
-import logging
-import os
-import re
-import shutil
-import signal
-import subprocess
-import sys
-import time
-
-# Map from device_id -> (process, logcat_num)
-devices = {}
-
-
-class TimeoutException(Exception):
- """Exception used to signal a timeout."""
- pass
-
-
-class SigtermError(Exception):
- """Exception used to catch a sigterm."""
- pass
-
-
-def StartLogcatIfNecessary(device_id, adb_cmd, base_dir):
- """Spawns a adb logcat process if one is not currently running."""
- process, logcat_num = devices[device_id]
- if process:
- if process.poll() is None:
- # Logcat process is still happily running
- return
- else:
- logging.info('Logcat for device %s has died', device_id)
- error_filter = re.compile('- waiting for device -')
- for line in process.stderr:
- if not error_filter.match(line):
- logging.error(device_id + ': ' + line)
-
- logging.info('Starting logcat %d for device %s', logcat_num,
- device_id)
- logcat_filename = 'logcat_%s_%03d' % (device_id, logcat_num)
- logcat_file = open(os.path.join(base_dir, logcat_filename), 'w')
- process = subprocess.Popen([adb_cmd, '-s', device_id,
- 'logcat', '-v', 'threadtime'],
- stdout=logcat_file,
- stderr=subprocess.PIPE)
- devices[device_id] = (process, logcat_num + 1)
-
-
-def GetAttachedDevices(adb_cmd):
- """Gets the device list from adb.
-
- We use an alarm in this function to avoid deadlocking from an external
- dependency.
-
- Args:
- adb_cmd: binary to run adb
-
- Returns:
- list of devices or an empty list on timeout
- """
- signal.alarm(2)
- try:
- out, err = subprocess.Popen([adb_cmd, 'devices'],
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE).communicate()
- if err:
- logging.warning('adb device error %s', err.strip())
- return re.findall('^(\\S+)\tdevice$', out, re.MULTILINE)
- except TimeoutException:
- logging.warning('"adb devices" command timed out')
- return []
- except (IOError, OSError):
- logging.exception('Exception from "adb devices"')
- return []
- finally:
- signal.alarm(0)
-
-
-def main(base_dir, adb_cmd='adb'):
- """Monitor adb forever. Expects a SIGINT (Ctrl-C) to kill."""
- # We create the directory to ensure 'run once' semantics
- if os.path.exists(base_dir):
- print 'adb_logcat_monitor: %s already exists? Cleaning' % base_dir
- shutil.rmtree(base_dir, ignore_errors=True)
-
- os.makedirs(base_dir)
- logging.basicConfig(filename=os.path.join(base_dir, 'eventlog'),
- level=logging.INFO,
- format='%(asctime)-2s %(levelname)-8s %(message)s')
-
- # Set up the alarm for calling 'adb devices'. This is to ensure
- # our script doesn't get stuck waiting for a process response
- def TimeoutHandler(_signum, _unused_frame):
- raise TimeoutException()
- signal.signal(signal.SIGALRM, TimeoutHandler)
-
- # Handle SIGTERMs to ensure clean shutdown
- def SigtermHandler(_signum, _unused_frame):
- raise SigtermError()
- signal.signal(signal.SIGTERM, SigtermHandler)
-
- logging.info('Started with pid %d', os.getpid())
- pid_file_path = os.path.join(base_dir, 'LOGCAT_MONITOR_PID')
-
- try:
- with open(pid_file_path, 'w') as f:
- f.write(str(os.getpid()))
- while True:
- for device_id in GetAttachedDevices(adb_cmd):
- if not device_id in devices:
- subprocess.call([adb_cmd, '-s', device_id, 'logcat', '-c'])
- devices[device_id] = (None, 0)
-
- for device in devices:
- # This will spawn logcat watchers for any device ever detected
- StartLogcatIfNecessary(device, adb_cmd, base_dir)
-
- time.sleep(5)
- except SigtermError:
- logging.info('Received SIGTERM, shutting down')
- except: # pylint: disable=bare-except
- logging.exception('Unexpected exception in main.')
- finally:
- for process, _ in devices.itervalues():
- if process:
- try:
- process.terminate()
- except OSError:
- pass
- os.remove(pid_file_path)
-
-
-if __name__ == '__main__':
- if 2 <= len(sys.argv) <= 3:
- print 'adb_logcat_monitor: Initializing'
- sys.exit(main(*sys.argv[1:3]))
-
- print 'Usage: %s <base_dir> [<adb_binary_path>]' % sys.argv[0]
diff --git a/build/android/adb_logcat_printer.py b/build/android/adb_logcat_printer.py
deleted file mode 100755
index 55176ab..0000000
--- a/build/android/adb_logcat_printer.py
+++ /dev/null
@@ -1,213 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Shutdown adb_logcat_monitor and print accumulated logs.
-
-To test, call './adb_logcat_printer.py <base_dir>' where
-<base_dir> contains 'adb logcat -v threadtime' files named as
-logcat_<deviceID>_<sequenceNum>
-
-The script will print the files to out, and will combine multiple
-logcats from a single device if there is overlap.
-
-Additionally, if a <base_dir>/LOGCAT_MONITOR_PID exists, the script
-will attempt to terminate the contained PID by sending a SIGINT and
-monitoring for the deletion of the aforementioned file.
-"""
-# pylint: disable=W0702
-
-import cStringIO
-import logging
-import optparse
-import os
-import re
-import signal
-import sys
-import time
-
-
-# Set this to debug for more verbose output
-LOG_LEVEL = logging.INFO
-
-
-def CombineLogFiles(list_of_lists, logger):
- """Splices together multiple logcats from the same device.
-
- Args:
- list_of_lists: list of pairs (filename, list of timestamped lines)
- logger: handler to log events
-
- Returns:
- list of lines with duplicates removed
- """
- cur_device_log = ['']
- for cur_file, cur_file_lines in list_of_lists:
- # Ignore files with just the logcat header
- if len(cur_file_lines) < 2:
- continue
- common_index = 0
- # Skip this step if list just has empty string
- if len(cur_device_log) > 1:
- try:
- line = cur_device_log[-1]
- # Used to make sure we only splice on a timestamped line
- if re.match(r'^\d{2}-\d{2} \d{2}:\d{2}:\d{2}.\d{3} ', line):
- common_index = cur_file_lines.index(line)
- else:
- logger.warning('splice error - no timestamp in "%s"?', line.strip())
- except ValueError:
- # The last line was valid but wasn't found in the next file
- cur_device_log += ['***** POSSIBLE INCOMPLETE LOGCAT *****']
- logger.info('Unable to splice %s. Incomplete logcat?', cur_file)
-
- cur_device_log += ['*'*30 + ' %s' % cur_file]
- cur_device_log.extend(cur_file_lines[common_index:])
-
- return cur_device_log
-
-
-def FindLogFiles(base_dir):
- """Search a directory for logcat files.
-
- Args:
- base_dir: directory to search
-
- Returns:
- Mapping of device_id to a sorted list of file paths for a given device
- """
- logcat_filter = re.compile(r'^logcat_(\S+)_(\d+)$')
- # list of tuples (<device_id>, <seq num>, <full file path>)
- filtered_list = []
- for cur_file in os.listdir(base_dir):
- matcher = logcat_filter.match(cur_file)
- if matcher:
- filtered_list += [(matcher.group(1), int(matcher.group(2)),
- os.path.join(base_dir, cur_file))]
- filtered_list.sort()
- file_map = {}
- for device_id, _, cur_file in filtered_list:
- if device_id not in file_map:
- file_map[device_id] = []
-
- file_map[device_id] += [cur_file]
- return file_map
-
-
-def GetDeviceLogs(log_filenames, logger):
- """Read log files, combine and format.
-
- Args:
- log_filenames: mapping of device_id to sorted list of file paths
- logger: logger handle for logging events
-
- Returns:
- list of formatted device logs, one for each device.
- """
- device_logs = []
-
- for device, device_files in log_filenames.iteritems():
- logger.debug('%s: %s', device, str(device_files))
- device_file_lines = []
- for cur_file in device_files:
- with open(cur_file) as f:
- device_file_lines += [(cur_file, f.read().splitlines())]
- combined_lines = CombineLogFiles(device_file_lines, logger)
- # Prepend each line with a short unique ID so it's easy to see
- # when the device changes. We don't use the start of the device
- # ID because it can be the same among devices. Example lines:
- # AB324: foo
- # AB324: blah
- device_logs += [('\n' + device[-5:] + ': ').join(combined_lines)]
- return device_logs
-
-
-def ShutdownLogcatMonitor(base_dir, logger):
- """Attempts to shutdown adb_logcat_monitor and blocks while waiting."""
- try:
- monitor_pid_path = os.path.join(base_dir, 'LOGCAT_MONITOR_PID')
- with open(monitor_pid_path) as f:
- monitor_pid = int(f.readline())
-
- logger.info('Sending SIGTERM to %d', monitor_pid)
- os.kill(monitor_pid, signal.SIGTERM)
- i = 0
- while True:
- time.sleep(.2)
- if not os.path.exists(monitor_pid_path):
- return
- if not os.path.exists('/proc/%d' % monitor_pid):
- logger.warning('Monitor (pid %d) terminated uncleanly?', monitor_pid)
- return
- logger.info('Waiting for logcat process to terminate.')
- i += 1
- if i >= 10:
- logger.warning('Monitor pid did not terminate. Continuing anyway.')
- return
-
- except (ValueError, IOError, OSError):
- logger.exception('Error signaling logcat monitor - continuing')
-
-
-def main(argv):
- parser = optparse.OptionParser(usage='Usage: %prog [options] <log dir>')
- parser.add_option('--output-path',
- help='Output file path (if unspecified, prints to stdout)')
- options, args = parser.parse_args(argv)
- if len(args) != 1:
- parser.error('Wrong number of unparsed args')
- base_dir = args[0]
- if options.output_path:
- output_file = open(options.output_path, 'w')
- else:
- output_file = sys.stdout
-
- log_stringio = cStringIO.StringIO()
- logger = logging.getLogger('LogcatPrinter')
- logger.setLevel(LOG_LEVEL)
- sh = logging.StreamHandler(log_stringio)
- sh.setFormatter(logging.Formatter('%(asctime)-2s %(levelname)-8s'
- ' %(message)s'))
- logger.addHandler(sh)
-
- try:
- # Wait at least 5 seconds after base_dir is created before printing.
- #
- # The idea is that 'adb logcat > file' output consists of 2 phases:
- # 1 Dump all the saved logs to the file
- # 2 Stream log messages as they are generated
- #
- # We want to give enough time for phase 1 to complete. There's no
- # good method to tell how long to wait, but it usually only takes a
- # second. On most bots, this code path won't occur at all, since
- # adb_logcat_monitor.py command will have spawned more than 5 seconds
- # prior to called this shell script.
- try:
- sleep_time = 5 - (time.time() - os.path.getctime(base_dir))
- except OSError:
- sleep_time = 5
- if sleep_time > 0:
- logger.warning('Monitor just started? Sleeping %.1fs', sleep_time)
- time.sleep(sleep_time)
-
- assert os.path.exists(base_dir), '%s does not exist' % base_dir
- ShutdownLogcatMonitor(base_dir, logger)
- separator = '\n' + '*' * 80 + '\n\n'
- for log in GetDeviceLogs(FindLogFiles(base_dir), logger):
- output_file.write(log)
- output_file.write(separator)
- with open(os.path.join(base_dir, 'eventlog')) as f:
- output_file.write('\nLogcat Monitor Event Log\n')
- output_file.write(f.read())
- except:
- logger.exception('Unexpected exception')
-
- logger.info('Done.')
- sh.flush()
- output_file.write('\nLogcat Printer Event Log\n')
- output_file.write(log_stringio.getvalue())
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv[1:]))
diff --git a/build/android/adb_profile_chrome b/build/android/adb_profile_chrome
deleted file mode 100755
index 21f6faf..0000000
--- a/build/android/adb_profile_chrome
+++ /dev/null
@@ -1,8 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-#
-# Start / stop profiling in chrome.
-exec $(dirname $0)/../../tools/profile_chrome.py $@
diff --git a/build/android/adb_reverse_forwarder.py b/build/android/adb_reverse_forwarder.py
deleted file mode 100755
index 3ce5359..0000000
--- a/build/android/adb_reverse_forwarder.py
+++ /dev/null
@@ -1,80 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (c) 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Command line tool for forwarding ports from a device to the host.
-
-Allows an Android device to connect to services running on the host machine,
-i.e., "adb forward" in reverse. Requires |host_forwarder| and |device_forwarder|
-to be built.
-"""
-
-import logging
-import optparse
-import sys
-import time
-
-from pylib import constants
-from pylib import forwarder
-from pylib.device import adb_wrapper
-from pylib.device import device_errors
-from pylib.device import device_utils
-from pylib.utils import run_tests_helper
-
-
-def main(argv):
- parser = optparse.OptionParser(usage='Usage: %prog [options] device_port '
- 'host_port [device_port_2 host_port_2] ...',
- description=__doc__)
- parser.add_option('-v',
- '--verbose',
- dest='verbose_count',
- default=0,
- action='count',
- help='Verbose level (multiple times for more)')
- parser.add_option('--device',
- help='Serial number of device we should use.')
- parser.add_option('--debug', action='store_const', const='Debug',
- dest='build_type', default='Release',
- help='Use Debug build of host tools instead of Release.')
-
- options, args = parser.parse_args(argv)
- run_tests_helper.SetLogLevel(options.verbose_count)
-
- if len(args) < 2 or not len(args) % 2:
- parser.error('Need even number of port pairs')
- sys.exit(1)
-
- try:
- port_pairs = map(int, args[1:])
- port_pairs = zip(port_pairs[::2], port_pairs[1::2])
- except ValueError:
- parser.error('Bad port number')
- sys.exit(1)
-
- devices = device_utils.DeviceUtils.HealthyDevices()
-
- if options.device:
- device = next((d for d in devices if d == options.device), None)
- if not device:
- raise device_errors.DeviceUnreachableError(options.device)
- elif devices:
- device = devices[0]
- logging.info('No device specified. Defaulting to %s', devices[0])
- else:
- raise device_errors.NoDevicesError()
-
- constants.SetBuildType(options.build_type)
- try:
- forwarder.Forwarder.Map(port_pairs, device)
- while True:
- time.sleep(60)
- except KeyboardInterrupt:
- sys.exit(0)
- finally:
- forwarder.Forwarder.UnmapAllDevicePorts(device)
-
-if __name__ == '__main__':
- main(sys.argv)
diff --git a/build/android/adb_run_android_webview_shell b/build/android/adb_run_android_webview_shell
deleted file mode 100755
index 1014a73..0000000
--- a/build/android/adb_run_android_webview_shell
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-optional_url=$1
-
-adb shell am start \
- -a android.intent.action.VIEW \
- -n org.chromium.android_webview.shell/.AwShellActivity \
- ${optional_url:+-d "$optional_url"}
diff --git a/build/android/adb_run_chrome_public b/build/android/adb_run_chrome_public
deleted file mode 100755
index bf15071..0000000
--- a/build/android/adb_run_chrome_public
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-optional_url=$1
-
-adb shell am start \
- -a android.intent.action.VIEW \
- -n org.chromium.chrome/com.google.android.apps.chrome.Main \
- ${optional_url:+-d "$optional_url"}
diff --git a/build/android/adb_run_chrome_shell b/build/android/adb_run_chrome_shell
deleted file mode 100755
index 79c4c32..0000000
--- a/build/android/adb_run_chrome_shell
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-optional_url=$1
-
-adb shell am start \
- -a android.intent.action.VIEW \
- -n org.chromium.chrome.shell/.ChromeShellActivity \
- ${optional_url:+-d "$optional_url"}
diff --git a/build/android/adb_run_content_shell b/build/android/adb_run_content_shell
deleted file mode 100755
index 3f01f3b..0000000
--- a/build/android/adb_run_content_shell
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/bash
-#
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-optional_url=$1
-
-adb shell am start \
- -a android.intent.action.VIEW \
- -n org.chromium.content_shell_apk/.ContentShellActivity \
- ${optional_url:+-d "$optional_url"}
diff --git a/build/android/adb_run_mojo_shell b/build/android/adb_run_mojo_shell
deleted file mode 100755
index b585e4a..0000000
--- a/build/android/adb_run_mojo_shell
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/bin/bash
-#
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-optional_url=$1
-parameters=$2
-
-adb logcat -c
-adb shell am start -S \
- -a android.intent.action.VIEW \
- -n org.chromium.mojo_shell_apk/.MojoShellActivity \
- ${parameters:+--esa parameters "$parameters"} \
- ${optional_url:+-d "$optional_url"}
-adb logcat -s MojoShellApplication MojoShellActivity chromium
diff --git a/build/android/android_no_jni_exports.lst b/build/android/android_no_jni_exports.lst
deleted file mode 100644
index ffc6cf7..0000000
--- a/build/android/android_no_jni_exports.lst
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This script makes all JNI exported symbols local, to prevent the JVM from
-# being able to find them, enforcing use of manual JNI function registration.
-# This is used for all Android binaries by default, unless they explicitly state
-# that they want JNI exported symbols to remain visible, as we need to ensure
-# the manual registration path is correct to maintain compatibility with the
-# crazy linker.
-# Check ld version script manual:
-# https://sourceware.org/binutils/docs-2.24/ld/VERSION.html#VERSION
-
-{
- local:
- Java_*;
-};
diff --git a/build/android/ant/BUILD.gn b/build/android/ant/BUILD.gn
deleted file mode 100644
index a30fb54..0000000
--- a/build/android/ant/BUILD.gn
+++ /dev/null
@@ -1,13 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-copy("keystore") {
- sources = [
- "chromium-debug.keystore",
- ]
-
- outputs = [
- "$root_out_dir/chromium-debug.keystore",
- ]
-}
diff --git a/build/android/ant/apk-package.xml b/build/android/ant/apk-package.xml
deleted file mode 100644
index e8b76f7..0000000
--- a/build/android/ant/apk-package.xml
+++ /dev/null
@@ -1,96 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Copyright (C) 2005-2008 The Android Open Source Project
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
--->
-
-<project default="-package">
- <property name="verbose" value="false" />
- <property name="out.dir" location="${OUT_DIR}" />
- <property name="out.absolute.dir" location="${out.dir}" />
-
- <property name="sdk.dir" location="${ANDROID_SDK_ROOT}"/>
- <property name="emma.device.jar" location="${EMMA_DEVICE_JAR}" />
-
- <condition property="emma.enabled" value="true" else="false">
- <equals arg1="${EMMA_INSTRUMENT}" arg2="1"/>
- </condition>
-
- <!-- jar file from where the tasks are loaded -->
- <path id="android.antlibs">
- <pathelement path="${sdk.dir}/tools/lib/ant-tasks.jar" />
- </path>
-
- <!-- Custom tasks -->
- <taskdef resource="anttasks.properties" classpathref="android.antlibs" />
-
- <condition property="build.target" value="release" else="debug">
- <equals arg1="${CONFIGURATION_NAME}" arg2="Release" />
- </condition>
- <condition property="build.is.packaging.debug" value="true" else="false">
- <equals arg1="${build.target}" arg2="debug" />
- </condition>
-
- <!-- Disables automatic signing. -->
- <property name="build.is.signing.debug" value="false"/>
-
- <!-- SDK tools assume that out.packaged.file is signed and name it "...-unaligned" -->
- <property name="out.packaged.file" value="${UNSIGNED_APK_PATH}" />
-
- <property name="native.libs.absolute.dir" location="${NATIVE_LIBS_DIR}" />
-
- <!-- Intermediate files -->
- <property name="resource.package.file.name" value="${RESOURCE_PACKAGED_APK_NAME}" />
-
- <property name="intermediate.dex.file" location="${DEX_FILE_PATH}" />
-
- <!-- Macro that enables passing a variable list of external jar files
- to ApkBuilder. -->
- <macrodef name="package-helper">
- <element name="extra-jars" optional="yes" />
- <sequential>
- <apkbuilder
- outfolder="${out.absolute.dir}"
- resourcefile="${resource.package.file.name}"
- apkfilepath="${out.packaged.file}"
- debugpackaging="${build.is.packaging.debug}"
- debugsigning="${build.is.signing.debug}"
- verbose="${verbose}"
- hascode="${HAS_CODE}"
- previousBuildType="/"
- buildType="${build.is.packaging.debug}/${build.is.signing.debug}">
- <dex path="${intermediate.dex.file}"/>
- <nativefolder path="${native.libs.absolute.dir}" />
- <extra-jars/>
- </apkbuilder>
- </sequential>
- </macrodef>
-
-
- <!-- Packages the application. -->
- <target name="-package">
- <if condition="${emma.enabled}">
- <then>
- <package-helper>
- <extra-jars>
- <jarfile path="${emma.device.jar}" />
- </extra-jars>
- </package-helper>
- </then>
- <else>
- <package-helper />
- </else>
- </if>
- </target>
-</project>
diff --git a/build/android/ant/chromium-debug.keystore b/build/android/ant/chromium-debug.keystore
deleted file mode 100644
index 67eb0aa..0000000
--- a/build/android/ant/chromium-debug.keystore
+++ /dev/null
Binary files differ
diff --git a/build/android/ant/empty/res/.keep b/build/android/ant/empty/res/.keep
deleted file mode 100644
index 1fd038b..0000000
--- a/build/android/ant/empty/res/.keep
+++ /dev/null
@@ -1,2 +0,0 @@
-# This empty res folder can be passed to aapt while building Java libraries or
-# APKs that don't have any resources.
diff --git a/build/android/apkbuilder_action.gypi b/build/android/apkbuilder_action.gypi
deleted file mode 100644
index 27807d8..0000000
--- a/build/android/apkbuilder_action.gypi
+++ /dev/null
@@ -1,79 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is a helper to java_apk.gypi. It should be used to create an
-# action that runs ApkBuilder via ANT.
-#
-# Required variables:
-# apk_name - File name (minus path & extension) of the output apk.
-# apk_path - Path to output apk.
-# package_input_paths - Late-evaluated list of resource zips.
-# native_libs_dir - Path to lib/ directory to use. Set to an empty directory
-# if no native libs are needed.
-# Optional variables:
-# has_code - Whether to include classes.dex in the apk.
-# dex_path - Path to classes.dex. Used only when has_code=1.
-# extra_inputs - List of extra action inputs.
-{
- 'variables': {
- 'variables': {
- 'has_code%': 1,
- },
- 'conditions': [
- ['has_code == 0', {
- 'has_code_str': 'false',
- }, {
- 'has_code_str': 'true',
- }],
- ],
- 'has_code%': '<(has_code)',
- 'extra_inputs%': [],
- # Write the inputs list to a file, so that its mtime is updated when
- # the list of inputs changes.
- 'inputs_list_file': '>|(apk_package.<(_target_name).<(apk_name).gypcmd >@(package_input_paths))',
- 'resource_packaged_apk_name': '<(apk_name)-resources.ap_',
- 'resource_packaged_apk_path': '<(intermediate_dir)/<(resource_packaged_apk_name)',
- },
- 'action_name': 'apkbuilder_<(apk_name)',
- 'message': 'Packaging <(apk_name)',
- 'inputs': [
- '<(DEPTH)/build/android/ant/apk-package.xml',
- '<(DEPTH)/build/android/gyp/util/build_utils.py',
- '<(DEPTH)/build/android/gyp/ant.py',
- '<(resource_packaged_apk_path)',
- '<@(extra_inputs)',
- '>@(package_input_paths)',
- '>(inputs_list_file)',
- ],
- 'outputs': [
- '<(apk_path)',
- ],
- 'conditions': [
- ['has_code == 1', {
- 'inputs': ['<(dex_path)'],
- 'action': [
- '-DDEX_FILE_PATH=<(dex_path)',
- ]
- }],
- ],
- 'action': [
- 'python', '<(DEPTH)/build/android/gyp/ant.py',
- '--',
- '-quiet',
- '-DHAS_CODE=<(has_code_str)',
- '-DANDROID_SDK_ROOT=<(android_sdk_root)',
- '-DANDROID_SDK_TOOLS=<(android_sdk_tools)',
- '-DRESOURCE_PACKAGED_APK_NAME=<(resource_packaged_apk_name)',
- '-DNATIVE_LIBS_DIR=<(native_libs_dir)',
- '-DAPK_NAME=<(apk_name)',
- '-DCONFIGURATION_NAME=<(CONFIGURATION_NAME)',
- '-DOUT_DIR=<(intermediate_dir)',
- '-DUNSIGNED_APK_PATH=<(apk_path)',
- '-DEMMA_INSTRUMENT=<(emma_instrument)',
- '-DEMMA_DEVICE_JAR=<(emma_device_jar)',
- '-Dbasedir=.',
- '-buildfile',
- '<(DEPTH)/build/android/ant/apk-package.xml',
- ]
-}
diff --git a/build/android/asan_symbolize.py b/build/android/asan_symbolize.py
deleted file mode 100755
index 10087a6..0000000
--- a/build/android/asan_symbolize.py
+++ /dev/null
@@ -1,103 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-
-import collections
-import optparse
-import os
-import re
-import sys
-
-from pylib import constants
-
-# Uses symbol.py from third_party/android_platform, not python's.
-sys.path.insert(0,
- os.path.join(constants.DIR_SOURCE_ROOT,
- 'third_party/android_platform/development/scripts'))
-import symbol
-
-
-_RE_ASAN = re.compile(r'(.*?)(#\S*?) (\S*?) \((.*?)\+(.*?)\)')
-
-def _ParseAsanLogLine(line):
- m = re.match(_RE_ASAN, line)
- if not m:
- return None
- return {
- 'prefix': m.group(1),
- 'library': m.group(4),
- 'pos': m.group(2),
- 'rel_address': '%08x' % int(m.group(5), 16),
- }
-
-
-def _FindASanLibraries():
- asan_lib_dir = os.path.join(constants.DIR_SOURCE_ROOT,
- 'third_party', 'llvm-build',
- 'Release+Asserts', 'lib')
- asan_libs = []
- for src_dir, _, files in os.walk(asan_lib_dir):
- asan_libs += [os.path.relpath(os.path.join(src_dir, f))
- for f in files
- if f.endswith('.so')]
- return asan_libs
-
-
-def _TranslateLibPath(library, asan_libs):
- for asan_lib in asan_libs:
- if os.path.basename(library) == os.path.basename(asan_lib):
- return '/' + asan_lib
- return symbol.TranslateLibPath(library)
-
-
-def _Symbolize(asan_input):
- asan_libs = _FindASanLibraries()
- libraries = collections.defaultdict(list)
- asan_lines = []
- for asan_log_line in [a.rstrip() for a in asan_input]:
- m = _ParseAsanLogLine(asan_log_line)
- if m:
- libraries[m['library']].append(m)
- asan_lines.append({'raw_log': asan_log_line, 'parsed': m})
-
- all_symbols = collections.defaultdict(dict)
- for library, items in libraries.iteritems():
- libname = _TranslateLibPath(library, asan_libs)
- lib_relative_addrs = set([i['rel_address'] for i in items])
- info_dict = symbol.SymbolInformationForSet(libname,
- lib_relative_addrs,
- True)
- if info_dict:
- all_symbols[library]['symbols'] = info_dict
-
- for asan_log_line in asan_lines:
- m = asan_log_line['parsed']
- if not m:
- print asan_log_line['raw_log']
- continue
- if (m['library'] in all_symbols and
- m['rel_address'] in all_symbols[m['library']]['symbols']):
- s = all_symbols[m['library']]['symbols'][m['rel_address']][0]
- print '%s%s %s %s' % (m['prefix'], m['pos'], s[0], s[1])
- else:
- print asan_log_line['raw_log']
-
-
-def main():
- parser = optparse.OptionParser()
- parser.add_option('-l', '--logcat',
- help='File containing adb logcat output with ASan stacks. '
- 'Use stdin if not specified.')
- options, _ = parser.parse_args()
- if options.logcat:
- asan_input = file(options.logcat, 'r')
- else:
- asan_input = sys.stdin
- _Symbolize(asan_input.readlines())
-
-
-if __name__ == "__main__":
- sys.exit(main())
diff --git a/build/android/avd.py b/build/android/avd.py
deleted file mode 100755
index c45544f..0000000
--- a/build/android/avd.py
+++ /dev/null
@@ -1,96 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Launches Android Virtual Devices with a set configuration for testing Chrome.
-
-The script will launch a specified number of Android Virtual Devices (AVD's).
-"""
-
-
-import install_emulator_deps
-import logging
-import optparse
-import os
-import re
-import sys
-
-from pylib import cmd_helper
-from pylib import constants
-from pylib.utils import emulator
-
-
-def main(argv):
- # ANDROID_SDK_ROOT needs to be set to the location of the SDK used to launch
- # the emulator to find the system images upon launch.
- emulator_sdk = os.path.join(constants.EMULATOR_SDK_ROOT, 'sdk')
- os.environ['ANDROID_SDK_ROOT'] = emulator_sdk
-
- opt_parser = optparse.OptionParser(description='AVD script.')
- opt_parser.add_option('--name', help='Optinaly, name of existing AVD to '
- 'launch. If not specified, new AVD\'s will be created')
- opt_parser.add_option('-n', '--num', dest='emulator_count',
- help='Number of emulators to launch (default is 1).',
- type='int', default='1')
- opt_parser.add_option('--abi', default='x86',
- help='Platform of emulators to launch (x86 default).')
- opt_parser.add_option('--api-level', dest='api_level',
- help='API level for the image, e.g. 19 for Android 4.4',
- type='int', default=constants.ANDROID_SDK_VERSION)
-
- options, _ = opt_parser.parse_args(argv[1:])
-
- logging.basicConfig(level=logging.INFO,
- format='# %(asctime)-15s: %(message)s')
- logging.root.setLevel(logging.INFO)
-
- # Check if KVM is enabled for x86 AVD's and check for x86 system images.
- # TODO(andrewhayden) Since we can fix all of these with install_emulator_deps
- # why don't we just run it?
- if options.abi == 'x86':
- if not install_emulator_deps.CheckKVM():
- logging.critical('ERROR: KVM must be enabled in BIOS, and installed. '
- 'Enable KVM in BIOS and run install_emulator_deps.py')
- return 1
- elif not install_emulator_deps.CheckX86Image(options.api_level):
- logging.critical('ERROR: System image for x86 AVD not installed. Run '
- 'install_emulator_deps.py')
- return 1
-
- if not install_emulator_deps.CheckSDK():
- logging.critical('ERROR: Emulator SDK not installed. Run '
- 'install_emulator_deps.py.')
- return 1
-
- # If AVD is specified, check that the SDK has the required target. If not,
- # check that the SDK has the desired target for the temporary AVD's.
- api_level = options.api_level
- if options.name:
- android = os.path.join(constants.EMULATOR_SDK_ROOT, 'sdk', 'tools',
- 'android')
- avds_output = cmd_helper.GetCmdOutput([android, 'list', 'avd'])
- names = re.findall(r'Name: (\w+)', avds_output)
- api_levels = re.findall(r'API level (\d+)', avds_output)
- try:
- avd_index = names.index(options.name)
- except ValueError:
- logging.critical('ERROR: Specified AVD %s does not exist.' % options.name)
- return 1
- api_level = int(api_levels[avd_index])
-
- if not install_emulator_deps.CheckSDKPlatform(api_level):
- logging.critical('ERROR: Emulator SDK missing required target for API %d. '
- 'Run install_emulator_deps.py.')
- return 1
-
- if options.name:
- emulator.LaunchEmulator(options.name, options.abi)
- else:
- emulator.LaunchTempEmulators(options.emulator_count, options.abi,
- options.api_level, True)
-
-
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv))
diff --git a/build/android/bb_run_sharded_steps.py b/build/android/bb_run_sharded_steps.py
deleted file mode 100755
index 6aeba5b..0000000
--- a/build/android/bb_run_sharded_steps.py
+++ /dev/null
@@ -1,41 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""DEPRECATED!
-TODO(bulach): remove me once all other repositories reference
-'test_runner.py perf' directly.
-"""
-
-import optparse
-import sys
-
-from pylib import cmd_helper
-
-
-def main(argv):
- parser = optparse.OptionParser()
- parser.add_option('-s', '--steps',
- help='A JSON file containing all the steps to be '
- 'sharded.')
- parser.add_option('--flaky_steps',
- help='A JSON file containing steps that are flaky and '
- 'will have its exit code ignored.')
- parser.add_option('-p', '--print_results',
- help='Only prints the results for the previously '
- 'executed step, do not run it again.')
- options, _ = parser.parse_args(argv)
- if options.print_results:
- return cmd_helper.RunCmd(['build/android/test_runner.py', 'perf',
- '--print-step', options.print_results])
- flaky_options = []
- if options.flaky_steps:
- flaky_options = ['--flaky-steps', options.flaky_steps]
- return cmd_helper.RunCmd(['build/android/test_runner.py', 'perf', '-v',
- '--steps', options.steps] + flaky_options)
-
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv))
diff --git a/build/android/buildbot/OWNERS b/build/android/buildbot/OWNERS
deleted file mode 100644
index f289720..0000000
--- a/build/android/buildbot/OWNERS
+++ /dev/null
@@ -1,6 +0,0 @@
-set noparent
-
-cmp@chromium.org
-jbudorick@chromium.org
-navabi@chromium.org
-
diff --git a/build/android/buildbot/bb_annotations.py b/build/android/buildbot/bb_annotations.py
deleted file mode 100644
index 059d673..0000000
--- a/build/android/buildbot/bb_annotations.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Helper functions to print buildbot messages."""
-
-def PrintLink(label, url):
- """Adds a link with name |label| linking to |url| to current buildbot step.
-
- Args:
- label: A string with the name of the label.
- url: A string of the URL.
- """
- print '@@@STEP_LINK@%s@%s@@@' % (label, url)
-
-
-def PrintMsg(msg):
- """Appends |msg| to the current buildbot step text.
-
- Args:
- msg: String to be appended.
- """
- print '@@@STEP_TEXT@%s@@@' % msg
-
-
-def PrintSummaryText(msg):
- """Appends |msg| to main build summary. Visible from waterfall.
-
- Args:
- msg: String to be appended.
- """
- print '@@@STEP_SUMMARY_TEXT@%s@@@' % msg
-
-
-def PrintError():
- """Marks the current step as failed."""
- print '@@@STEP_FAILURE@@@'
-
-
-def PrintWarning():
- """Marks the current step with a warning."""
- print '@@@STEP_WARNINGS@@@'
-
-
-def PrintNamedStep(step):
- print '@@@BUILD_STEP %s@@@' % step
diff --git a/build/android/buildbot/bb_device_status_check.py b/build/android/buildbot/bb_device_status_check.py
deleted file mode 100755
index 917c51e..0000000
--- a/build/android/buildbot/bb_device_status_check.py
+++ /dev/null
@@ -1,404 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""A class to keep track of devices across builds and report state."""
-import json
-import logging
-import optparse
-import os
-import psutil
-import re
-import signal
-import smtplib
-import subprocess
-import sys
-import time
-import urllib
-
-import bb_annotations
-import bb_utils
-
-sys.path.append(os.path.join(os.path.dirname(__file__),
- os.pardir, os.pardir, 'util', 'lib',
- 'common'))
-import perf_tests_results_helper # pylint: disable=F0401
-
-sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
-from pylib import constants
-from pylib.cmd_helper import GetCmdOutput
-from pylib.device import adb_wrapper
-from pylib.device import battery_utils
-from pylib.device import device_blacklist
-from pylib.device import device_errors
-from pylib.device import device_list
-from pylib.device import device_utils
-from pylib.utils import run_tests_helper
-
-_RE_DEVICE_ID = re.compile('Device ID = (\d+)')
-
-def DeviceInfo(device, options):
- """Gathers info on a device via various adb calls.
-
- Args:
- device: A DeviceUtils instance for the device to construct info about.
-
- Returns:
- Tuple of device type, build id, report as a string, error messages, and
- boolean indicating whether or not device can be used for testing.
- """
- battery = battery_utils.BatteryUtils(device)
-
- build_product = ''
- build_id = ''
- battery_level = 100
- errors = []
- dev_good = True
- json_data = {}
-
- try:
- build_product = device.build_product
- build_id = device.build_id
-
- json_data = {
- 'serial': device.adb.GetDeviceSerial(),
- 'type': build_product,
- 'build': build_id,
- 'build_detail': device.GetProp('ro.build.fingerprint'),
- 'battery': {},
- 'imei_slice': 'Unknown',
- 'wifi_ip': device.GetProp('dhcp.wlan0.ipaddress'),
- }
-
- battery_info = {}
- try:
- battery_info = battery.GetBatteryInfo(timeout=5)
- battery_level = int(battery_info.get('level', battery_level))
- json_data['battery'] = battery_info
- except device_errors.CommandFailedError:
- logging.exception('Failed to get battery information for %s', str(device))
-
- try:
- for l in device.RunShellCommand(['dumpsys', 'iphonesubinfo'],
- check_return=True, timeout=5):
- m = _RE_DEVICE_ID.match(l)
- if m:
- json_data['imei_slice'] = m.group(1)[-6:]
- except device_errors.CommandFailedError:
- logging.exception('Failed to get IMEI slice for %s', str(device))
-
- if battery_level < 15:
- errors += ['Device critically low in battery.']
- dev_good = False
- if not battery.GetCharging():
- battery.SetCharging(True)
- if not options.no_provisioning_check:
- setup_wizard_disabled = (
- device.GetProp('ro.setupwizard.mode') == 'DISABLED')
- if not setup_wizard_disabled and device.build_type != 'user':
- errors += ['Setup wizard not disabled. Was it provisioned correctly?']
- if (device.product_name == 'mantaray' and
- battery_info.get('AC powered', None) != 'true'):
- errors += ['Mantaray device not connected to AC power.']
- except device_errors.CommandFailedError:
- logging.exception('Failure while getting device status.')
- dev_good = False
- except device_errors.CommandTimeoutError:
- logging.exception('Timeout while getting device status.')
- dev_good = False
-
- return (build_product, build_id, battery_level, errors, dev_good, json_data)
-
-
-def CheckForMissingDevices(options, devices):
- """Uses file of previous online devices to detect broken phones.
-
- Args:
- options: out_dir parameter of options argument is used as the base
- directory to load and update the cache file.
- devices: A list of DeviceUtils instance for the currently visible and
- online attached devices.
- """
- out_dir = os.path.abspath(options.out_dir)
- device_serials = set(d.adb.GetDeviceSerial() for d in devices)
-
- # last_devices denotes all known devices prior to this run
- last_devices_path = os.path.join(out_dir, device_list.LAST_DEVICES_FILENAME)
- last_missing_devices_path = os.path.join(out_dir,
- device_list.LAST_MISSING_DEVICES_FILENAME)
- try:
- last_devices = device_list.GetPersistentDeviceList(last_devices_path)
- except IOError:
- # Ignore error, file might not exist
- last_devices = []
-
- try:
- last_missing_devices = device_list.GetPersistentDeviceList(
- last_missing_devices_path)
- except IOError:
- last_missing_devices = []
-
- missing_devs = list(set(last_devices) - device_serials)
- new_missing_devs = list(set(missing_devs) - set(last_missing_devices))
-
- if new_missing_devs and os.environ.get('BUILDBOT_SLAVENAME'):
- logging.info('new_missing_devs %s' % new_missing_devs)
- devices_missing_msg = '%d devices not detected.' % len(missing_devs)
- bb_annotations.PrintSummaryText(devices_missing_msg)
-
- from_address = 'chrome-bot@chromium.org'
- to_addresses = ['chrome-labs-tech-ticket@google.com',
- 'chrome-android-device-alert@google.com']
- cc_addresses = ['chrome-android-device-alert@google.com']
- subject = 'Devices offline on %s, %s, %s' % (
- os.environ.get('BUILDBOT_SLAVENAME'),
- os.environ.get('BUILDBOT_BUILDERNAME'),
- os.environ.get('BUILDBOT_BUILDNUMBER'))
- msg = ('Please reboot the following devices:\n%s' %
- '\n'.join(map(str, new_missing_devs)))
- SendEmail(from_address, to_addresses, cc_addresses, subject, msg)
-
- all_known_devices = list(device_serials | set(last_devices))
- device_list.WritePersistentDeviceList(last_devices_path, all_known_devices)
- device_list.WritePersistentDeviceList(last_missing_devices_path, missing_devs)
-
- if not all_known_devices:
- # This can happen if for some reason the .last_devices file is not
- # present or if it was empty.
- return ['No online devices. Have any devices been plugged in?']
- if missing_devs:
- devices_missing_msg = '%d devices not detected.' % len(missing_devs)
- bb_annotations.PrintSummaryText(devices_missing_msg)
- return ['Current online devices: %s' % ', '.join(d for d in device_serials),
- '%s are no longer visible. Were they removed?' % missing_devs]
- else:
- new_devs = device_serials - set(last_devices)
- if new_devs and os.path.exists(last_devices_path):
- bb_annotations.PrintWarning()
- bb_annotations.PrintSummaryText(
- '%d new devices detected' % len(new_devs))
- logging.info('New devices detected:')
- for d in new_devs:
- logging.info(' %s', d)
-
-
-def SendEmail(from_address, to_addresses, cc_addresses, subject, msg):
- msg_body = '\r\n'.join(['From: %s' % from_address,
- 'To: %s' % ', '.join(to_addresses),
- 'CC: %s' % ', '.join(cc_addresses),
- 'Subject: %s' % subject, '', msg])
- try:
- server = smtplib.SMTP('localhost')
- server.sendmail(from_address, to_addresses, msg_body)
- server.quit()
- except Exception:
- logging.exception('Failed to send alert email.')
-
-
-def RestartUsb():
- if not os.path.isfile('/usr/bin/restart_usb'):
- logging.error('Could not restart usb. ''/usr/bin/restart_usb not '
- 'installed on host (see BUG=305769).')
- return False
-
- lsusb_proc = bb_utils.SpawnCmd(['lsusb'], stdout=subprocess.PIPE)
- lsusb_output, _ = lsusb_proc.communicate()
- if lsusb_proc.returncode:
- logging.error('Could not get list of USB ports (i.e. lsusb).')
- return lsusb_proc.returncode
-
- usb_devices = [re.findall(r'Bus (\d\d\d) Device (\d\d\d)', lsusb_line)[0]
- for lsusb_line in lsusb_output.strip().split('\n')]
-
- all_restarted = True
- # Walk USB devices from leaves up (i.e reverse sorted) restarting the
- # connection. If a parent node (e.g. usb hub) is restarted before the
- # devices connected to it, the (bus, dev) for the hub can change, making the
- # output we have wrong. This way we restart the devices before the hub.
- for (bus, dev) in reversed(sorted(usb_devices)):
- # Can not restart root usb connections
- if dev != '001':
- return_code = bb_utils.RunCmd(['/usr/bin/restart_usb', bus, dev])
- if return_code:
- logging.error('Error restarting USB device /dev/bus/usb/%s/%s',
- bus, dev)
- all_restarted = False
- else:
- logging.info('Restarted USB device /dev/bus/usb/%s/%s', bus, dev)
-
- return all_restarted
-
-
-def KillAllAdb():
- def GetAllAdb():
- for p in psutil.process_iter():
- try:
- if 'adb' in p.name:
- yield p
- except (psutil.NoSuchProcess, psutil.AccessDenied):
- pass
-
- for sig in [signal.SIGTERM, signal.SIGQUIT, signal.SIGKILL]:
- for p in GetAllAdb():
- try:
- logging.info('kill %d %d (%s [%s])', sig, p.pid, p.name,
- ' '.join(p.cmdline))
- p.send_signal(sig)
- except (psutil.NoSuchProcess, psutil.AccessDenied):
- pass
- for p in GetAllAdb():
- try:
- logging.error('Unable to kill %d (%s [%s])', p.pid, p.name,
- ' '.join(p.cmdline))
- except (psutil.NoSuchProcess, psutil.AccessDenied):
- pass
-
-
-def main():
- parser = optparse.OptionParser()
- parser.add_option('', '--out-dir',
- help='Directory where the device path is stored',
- default=os.path.join(constants.DIR_SOURCE_ROOT, 'out'))
- parser.add_option('--no-provisioning-check', action='store_true',
- help='Will not check if devices are provisioned properly.')
- parser.add_option('--device-status-dashboard', action='store_true',
- help='Output device status data for dashboard.')
- parser.add_option('--restart-usb', action='store_true',
- help='Restart USB ports before running device check.')
- parser.add_option('--json-output',
- help='Output JSON information into a specified file.')
- parser.add_option('-v', '--verbose', action='count', default=1,
- help='Log more information.')
-
- options, args = parser.parse_args()
- if args:
- parser.error('Unknown options %s' % args)
-
- run_tests_helper.SetLogLevel(options.verbose)
-
- # Remove the last build's "bad devices" before checking device statuses.
- device_blacklist.ResetBlacklist()
-
- try:
- expected_devices = device_list.GetPersistentDeviceList(
- os.path.join(options.out_dir, device_list.LAST_DEVICES_FILENAME))
- except IOError:
- expected_devices = []
- devices = device_utils.DeviceUtils.HealthyDevices()
- device_serials = [d.adb.GetDeviceSerial() for d in devices]
- # Only restart usb if devices are missing.
- if set(expected_devices) != set(device_serials):
- logging.warning('expected_devices: %s', expected_devices)
- logging.warning('devices: %s', device_serials)
- KillAllAdb()
- retries = 5
- usb_restarted = True
- if options.restart_usb:
- if not RestartUsb():
- usb_restarted = False
- bb_annotations.PrintWarning()
- logging.error('USB reset stage failed, '
- 'wait for any device to come back.')
- while retries:
- logging.info('retry adb devices...')
- time.sleep(1)
- devices = device_utils.DeviceUtils.HealthyDevices()
- device_serials = [d.adb.GetDeviceSerial() for d in devices]
- if set(expected_devices) == set(device_serials):
- # All devices are online, keep going.
- break
- if not usb_restarted and devices:
- # The USB wasn't restarted, but there's at least one device online.
- # No point in trying to wait for all devices.
- break
- retries -= 1
-
- types, builds, batteries, errors, devices_ok, json_data = (
- [], [], [], [], [], [])
- if devices:
- types, builds, batteries, errors, devices_ok, json_data = (
- zip(*[DeviceInfo(dev, options) for dev in devices]))
-
- # Write device info to file for buildbot info display.
- if os.path.exists('/home/chrome-bot'):
- with open('/home/chrome-bot/.adb_device_info', 'w') as f:
- for device in json_data:
- try:
- f.write('%s %s %s %.1fC %s%%\n' % (device['serial'], device['type'],
- device['build'], float(device['battery']['temperature']) / 10,
- device['battery']['level']))
- except Exception:
- pass
-
- err_msg = CheckForMissingDevices(options, devices) or []
-
- unique_types = list(set(types))
- unique_builds = list(set(builds))
-
- bb_annotations.PrintMsg('Online devices: %d. Device types %s, builds %s'
- % (len(devices), unique_types, unique_builds))
-
- for j in json_data:
- logging.info('Device %s (%s)', j.get('serial'), j.get('type'))
- logging.info(' Build: %s (%s)', j.get('build'), j.get('build_detail'))
- logging.info(' Current Battery Service state:')
- for k, v in j.get('battery', {}).iteritems():
- logging.info(' %s: %s', k, v)
- logging.info(' IMEI slice: %s', j.get('imei_slice'))
- logging.info(' WiFi IP: %s', j.get('wifi_ip'))
-
-
- for dev, dev_errors in zip(devices, errors):
- if dev_errors:
- err_msg += ['%s errors:' % str(dev)]
- err_msg += [' %s' % error for error in dev_errors]
-
- if err_msg:
- bb_annotations.PrintWarning()
- for e in err_msg:
- logging.error(e)
- from_address = 'buildbot@chromium.org'
- to_addresses = ['chromium-android-device-alerts@google.com']
- bot_name = os.environ.get('BUILDBOT_BUILDERNAME')
- slave_name = os.environ.get('BUILDBOT_SLAVENAME')
- subject = 'Device status check errors on %s, %s.' % (slave_name, bot_name)
- SendEmail(from_address, to_addresses, [], subject, '\n'.join(err_msg))
-
- if options.device_status_dashboard:
- offline_devices = [
- device_utils.DeviceUtils(a)
- for a in adb_wrapper.AdbWrapper.Devices(is_ready=False)
- if a.GetState() == 'offline']
-
- perf_tests_results_helper.PrintPerfResult('BotDevices', 'OnlineDevices',
- [len(devices)], 'devices')
- perf_tests_results_helper.PrintPerfResult('BotDevices', 'OfflineDevices',
- [len(offline_devices)], 'devices',
- 'unimportant')
- for dev, battery in zip(devices, batteries):
- perf_tests_results_helper.PrintPerfResult('DeviceBattery', str(dev),
- [battery], '%',
- 'unimportant')
-
- if options.json_output:
- with open(options.json_output, 'wb') as f:
- f.write(json.dumps(json_data, indent=4))
-
- num_failed_devs = 0
- for device_ok, device in zip(devices_ok, devices):
- if not device_ok:
- logging.warning('Blacklisting %s', str(device))
- device_blacklist.ExtendBlacklist([str(device)])
- num_failed_devs += 1
-
- if num_failed_devs == len(devices):
- return 2
-
- if not devices:
- return 1
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/build/android/buildbot/bb_device_steps.py b/build/android/buildbot/bb_device_steps.py
deleted file mode 100755
index 8ad42b9..0000000
--- a/build/android/buildbot/bb_device_steps.py
+++ /dev/null
@@ -1,796 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import collections
-import glob
-import hashlib
-import json
-import os
-import random
-import re
-import shutil
-import sys
-
-import bb_utils
-import bb_annotations
-
-sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
-import provision_devices
-from pylib import constants
-from pylib.device import device_utils
-from pylib.gtest import gtest_config
-
-CHROME_SRC_DIR = bb_utils.CHROME_SRC
-DIR_BUILD_ROOT = os.path.dirname(CHROME_SRC_DIR)
-CHROME_OUT_DIR = bb_utils.CHROME_OUT_DIR
-BLINK_SCRIPTS_DIR = 'third_party/WebKit/Tools/Scripts'
-
-SLAVE_SCRIPTS_DIR = os.path.join(bb_utils.BB_BUILD_DIR, 'scripts', 'slave')
-LOGCAT_DIR = os.path.join(bb_utils.CHROME_OUT_DIR, 'logcat')
-GS_URL = 'https://storage.googleapis.com'
-GS_AUTH_URL = 'https://storage.cloud.google.com'
-
-# Describes an instrumation test suite:
-# test: Name of test we're running.
-# apk: apk to be installed.
-# apk_package: package for the apk to be installed.
-# test_apk: apk to run tests on.
-# test_data: data folder in format destination:source.
-# host_driven_root: The host-driven test root directory.
-# annotation: Annotation of the tests to include.
-# exclude_annotation: The annotation of the tests to exclude.
-I_TEST = collections.namedtuple('InstrumentationTest', [
- 'name', 'apk', 'apk_package', 'test_apk', 'test_data', 'isolate_file_path',
- 'host_driven_root', 'annotation', 'exclude_annotation', 'extra_flags'])
-
-
-def SrcPath(*path):
- return os.path.join(CHROME_SRC_DIR, *path)
-
-
-def I(name, apk, apk_package, test_apk, test_data, isolate_file_path=None,
- host_driven_root=None, annotation=None, exclude_annotation=None,
- extra_flags=None):
- return I_TEST(name, apk, apk_package, test_apk, test_data, isolate_file_path,
- host_driven_root, annotation, exclude_annotation, extra_flags)
-
-INSTRUMENTATION_TESTS = dict((suite.name, suite) for suite in [
- I('ContentShell',
- 'ContentShell.apk',
- 'org.chromium.content_shell_apk',
- 'ContentShellTest',
- 'content:content/test/data/android/device_files',
- isolate_file_path='content/content_shell_test_apk.isolate'),
- I('ChromeShell',
- 'ChromeShell.apk',
- 'org.chromium.chrome.shell',
- 'ChromeShellTest',
- 'chrome:chrome/test/data/android/device_files',
- isolate_file_path='chrome/chrome_shell_test_apk.isolate',
- host_driven_root=constants.CHROME_SHELL_HOST_DRIVEN_DIR),
- I('AndroidWebView',
- 'AndroidWebView.apk',
- 'org.chromium.android_webview.shell',
- 'AndroidWebViewTest',
- 'webview:android_webview/test/data/device_files',
- isolate_file_path='android_webview/android_webview_test_apk.isolate'),
- I('ChromeSyncShell',
- 'ChromeSyncShell.apk',
- 'org.chromium.chrome.browser.sync',
- 'ChromeSyncShellTest',
- None),
- ])
-
-InstallablePackage = collections.namedtuple('InstallablePackage', [
- 'name', 'apk', 'apk_package'])
-
-INSTALLABLE_PACKAGES = dict((package.name, package) for package in (
- [InstallablePackage(i.name, i.apk, i.apk_package)
- for i in INSTRUMENTATION_TESTS.itervalues()] +
- [InstallablePackage('ChromeDriverWebViewShell',
- 'ChromeDriverWebViewShell.apk',
- 'org.chromium.chromedriver_webview_shell')]))
-
-VALID_TESTS = set([
- 'base_junit_tests',
- 'chromedriver',
- 'chrome_proxy',
- 'components_browsertests',
- 'gfx_unittests',
- 'gl_unittests',
- 'gpu',
- 'python_unittests',
- 'telemetry_unittests',
- 'telemetry_perf_unittests',
- 'ui',
- 'unit',
- 'webkit',
- 'webkit_layout'
-])
-
-RunCmd = bb_utils.RunCmd
-
-
-def _GetRevision(options):
- """Get the SVN revision number.
-
- Args:
- options: options object.
-
- Returns:
- The revision number.
- """
- revision = options.build_properties.get('got_revision')
- if not revision:
- revision = options.build_properties.get('revision', 'testing')
- return revision
-
-
-def _RunTest(options, cmd, suite):
- """Run test command with runtest.py.
-
- Args:
- options: options object.
- cmd: the command to run.
- suite: test name.
- """
- property_args = bb_utils.EncodeProperties(options)
- args = [os.path.join(SLAVE_SCRIPTS_DIR, 'runtest.py')] + property_args
- args += ['--test-platform', 'android']
- if options.factory_properties.get('generate_gtest_json'):
- args.append('--generate-json-file')
- args += ['-o', 'gtest-results/%s' % suite,
- '--annotate', 'gtest',
- '--build-number', str(options.build_properties.get('buildnumber',
- '')),
- '--builder-name', options.build_properties.get('buildername', '')]
- if options.target == 'Release':
- args += ['--target', 'Release']
- else:
- args += ['--target', 'Debug']
- if options.flakiness_server:
- args += ['--flakiness-dashboard-server=%s' %
- options.flakiness_server]
- args += cmd
- RunCmd(args, cwd=DIR_BUILD_ROOT)
-
-
-def RunTestSuites(options, suites, suites_options=None):
- """Manages an invocation of test_runner.py for gtests.
-
- Args:
- options: options object.
- suites: List of suite names to run.
- suites_options: Command line options dictionary for particular suites.
- For example,
- {'content_browsertests', ['--num_retries=1', '--release']}
- will add the options only to content_browsertests.
- """
-
- if not suites_options:
- suites_options = {}
-
- args = ['--verbose']
- if options.target == 'Release':
- args.append('--release')
- if options.asan:
- args.append('--tool=asan')
- if options.gtest_filter:
- args.append('--gtest-filter=%s' % options.gtest_filter)
-
- for suite in suites:
- bb_annotations.PrintNamedStep(suite)
- cmd = [suite] + args
- cmd += suites_options.get(suite, [])
- if suite == 'content_browsertests' or suite == 'components_browsertests':
- cmd.append('--num_retries=1')
- _RunTest(options, cmd, suite)
-
-
-def RunJunitSuite(suite):
- bb_annotations.PrintNamedStep(suite)
- RunCmd(['build/android/test_runner.py', 'junit', '-s', suite])
-
-
-def RunChromeDriverTests(options):
- """Run all the steps for running chromedriver tests."""
- bb_annotations.PrintNamedStep('chromedriver_annotation')
- RunCmd(['chrome/test/chromedriver/run_buildbot_steps.py',
- '--android-packages=%s,%s,%s,%s' %
- ('chrome_shell',
- 'chrome_stable',
- 'chrome_beta',
- 'chromedriver_webview_shell'),
- '--revision=%s' % _GetRevision(options),
- '--update-log'])
-
-def RunChromeProxyTests(options):
- """Run the chrome_proxy tests.
-
- Args:
- options: options object.
- """
- InstallApk(options, INSTRUMENTATION_TESTS['ChromeShell'], False)
- args = ['--browser', 'android-chrome-shell']
- devices = device_utils.DeviceUtils.HealthyDevices()
- if devices:
- args = args + ['--device', devices[0].adb.GetDeviceSerial()]
- bb_annotations.PrintNamedStep('chrome_proxy')
- RunCmd(['tools/chrome_proxy/run_tests'] + args)
-
-
-def RunTelemetryTests(options, step_name, run_tests_path):
- """Runs either telemetry_perf_unittests or telemetry_unittests.
-
- Args:
- options: options object.
- step_name: either 'telemetry_unittests' or 'telemetry_perf_unittests'
- run_tests_path: path to run_tests script (tools/perf/run_tests for
- perf_unittests and tools/telemetry/run_tests for
- telemetry_unittests)
- """
- InstallApk(options, INSTRUMENTATION_TESTS['ChromeShell'], False)
- args = ['--browser', 'android-chrome-shell']
- devices = device_utils.DeviceUtils.HealthyDevices()
- if devices:
- args = args + ['--device', 'android']
- bb_annotations.PrintNamedStep(step_name)
- RunCmd([run_tests_path] + args)
-
-
-def InstallApk(options, test, print_step=False):
- """Install an apk to all phones.
-
- Args:
- options: options object
- test: An I_TEST namedtuple
- print_step: Print a buildbot step
- """
- if print_step:
- bb_annotations.PrintNamedStep('install_%s' % test.name.lower())
-
- args = ['--apk_package', test.apk_package]
- if options.target == 'Release':
- args.append('--release')
- args.append(test.apk)
-
- RunCmd(['build/android/adb_install_apk.py'] + args, halt_on_failure=True)
-
-
-def RunInstrumentationSuite(options, test, flunk_on_failure=True,
- python_only=False, official_build=False):
- """Manages an invocation of test_runner.py for instrumentation tests.
-
- Args:
- options: options object
- test: An I_TEST namedtuple
- flunk_on_failure: Flunk the step if tests fail.
- Python: Run only host driven Python tests.
- official_build: Run official-build tests.
- """
- bb_annotations.PrintNamedStep('%s_instrumentation_tests' % test.name.lower())
-
- if test.apk:
- InstallApk(options, test)
- args = ['--test-apk', test.test_apk, '--verbose']
- if test.test_data:
- args.extend(['--test_data', test.test_data])
- if options.target == 'Release':
- args.append('--release')
- if options.asan:
- args.append('--tool=asan')
- if options.flakiness_server:
- args.append('--flakiness-dashboard-server=%s' %
- options.flakiness_server)
- if options.coverage_bucket:
- args.append('--coverage-dir=%s' % options.coverage_dir)
- if test.isolate_file_path:
- args.append('--isolate-file-path=%s' % test.isolate_file_path)
- if test.host_driven_root:
- args.append('--host-driven-root=%s' % test.host_driven_root)
- if test.annotation:
- args.extend(['-A', test.annotation])
- if test.exclude_annotation:
- args.extend(['-E', test.exclude_annotation])
- if test.extra_flags:
- args.extend(test.extra_flags)
- if python_only:
- args.append('-p')
- if official_build:
- # The option needs to be assigned 'True' as it does not have an action
- # associated with it.
- args.append('--official-build')
-
- RunCmd(['build/android/test_runner.py', 'instrumentation'] + args,
- flunk_on_failure=flunk_on_failure)
-
-
-def RunWebkitLint():
- """Lint WebKit's TestExpectation files."""
- bb_annotations.PrintNamedStep('webkit_lint')
- RunCmd([SrcPath(os.path.join(BLINK_SCRIPTS_DIR, 'lint-test-expectations'))])
-
-
-def RunWebkitLayoutTests(options):
- """Run layout tests on an actual device."""
- bb_annotations.PrintNamedStep('webkit_tests')
- cmd_args = [
- '--no-show-results',
- '--no-new-test-results',
- '--full-results-html',
- '--clobber-old-results',
- '--exit-after-n-failures', '5000',
- '--exit-after-n-crashes-or-timeouts', '100',
- '--debug-rwt-logging',
- '--results-directory', '../layout-test-results',
- '--target', options.target,
- '--builder-name', options.build_properties.get('buildername', ''),
- '--build-number', str(options.build_properties.get('buildnumber', '')),
- '--master-name', 'ChromiumWebkit', # TODO: Get this from the cfg.
- '--build-name', options.build_properties.get('buildername', ''),
- '--platform=android']
-
- for flag in 'test_results_server', 'driver_name', 'additional_driver_flag':
- if flag in options.factory_properties:
- cmd_args.extend(['--%s' % flag.replace('_', '-'),
- options.factory_properties.get(flag)])
-
- for f in options.factory_properties.get('additional_expectations', []):
- cmd_args.extend(
- ['--additional-expectations=%s' % os.path.join(CHROME_SRC_DIR, *f)])
-
- # TODO(dpranke): Remove this block after
- # https://codereview.chromium.org/12927002/ lands.
- for f in options.factory_properties.get('additional_expectations_files', []):
- cmd_args.extend(
- ['--additional-expectations=%s' % os.path.join(CHROME_SRC_DIR, *f)])
-
- exit_code = RunCmd(
- [SrcPath(os.path.join(BLINK_SCRIPTS_DIR, 'run-webkit-tests'))] + cmd_args)
- if exit_code == 255: # test_run_results.UNEXPECTED_ERROR_EXIT_STATUS
- bb_annotations.PrintMsg('?? (crashed or hung)')
- elif exit_code == 254: # test_run_results.NO_DEVICES_EXIT_STATUS
- bb_annotations.PrintMsg('?? (no devices found)')
- elif exit_code == 253: # test_run_results.NO_TESTS_EXIT_STATUS
- bb_annotations.PrintMsg('?? (no tests found)')
- else:
- full_results_path = os.path.join('..', 'layout-test-results',
- 'full_results.json')
- if os.path.exists(full_results_path):
- full_results = json.load(open(full_results_path))
- unexpected_passes, unexpected_failures, unexpected_flakes = (
- _ParseLayoutTestResults(full_results))
- if unexpected_failures:
- _PrintDashboardLink('failed', unexpected_failures.keys(),
- max_tests=25)
- elif unexpected_passes:
- _PrintDashboardLink('unexpected passes', unexpected_passes.keys(),
- max_tests=10)
- if unexpected_flakes:
- _PrintDashboardLink('unexpected flakes', unexpected_flakes.keys(),
- max_tests=10)
-
- if exit_code == 0 and (unexpected_passes or unexpected_flakes):
- # If exit_code != 0, RunCmd() will have already printed an error.
- bb_annotations.PrintWarning()
- else:
- bb_annotations.PrintError()
- bb_annotations.PrintMsg('?? (results missing)')
-
- if options.factory_properties.get('archive_webkit_results', False):
- bb_annotations.PrintNamedStep('archive_webkit_results')
- base = 'https://storage.googleapis.com/chromium-layout-test-archives'
- builder_name = options.build_properties.get('buildername', '')
- build_number = str(options.build_properties.get('buildnumber', ''))
- results_link = '%s/%s/%s/layout-test-results/results.html' % (
- base, EscapeBuilderName(builder_name), build_number)
- bb_annotations.PrintLink('results', results_link)
- bb_annotations.PrintLink('(zip)', '%s/%s/%s/layout-test-results.zip' % (
- base, EscapeBuilderName(builder_name), build_number))
- gs_bucket = 'gs://chromium-layout-test-archives'
- RunCmd([os.path.join(SLAVE_SCRIPTS_DIR, 'chromium',
- 'archive_layout_test_results.py'),
- '--results-dir', '../../layout-test-results',
- '--build-number', build_number,
- '--builder-name', builder_name,
- '--gs-bucket', gs_bucket],
- cwd=DIR_BUILD_ROOT)
-
-
-def _ParseLayoutTestResults(results):
- """Extract the failures from the test run."""
- # Cloned from third_party/WebKit/Tools/Scripts/print-json-test-results
- tests = _ConvertTrieToFlatPaths(results['tests'])
- failures = {}
- flakes = {}
- passes = {}
- for (test, result) in tests.iteritems():
- if result.get('is_unexpected'):
- actual_results = result['actual'].split()
- expected_results = result['expected'].split()
- if len(actual_results) > 1:
- # We report the first failure type back, even if the second
- # was more severe.
- if actual_results[1] in expected_results:
- flakes[test] = actual_results[0]
- else:
- failures[test] = actual_results[0]
- elif actual_results[0] == 'PASS':
- passes[test] = result
- else:
- failures[test] = actual_results[0]
-
- return (passes, failures, flakes)
-
-
-def _ConvertTrieToFlatPaths(trie, prefix=None):
- """Flatten the trie of failures into a list."""
- # Cloned from third_party/WebKit/Tools/Scripts/print-json-test-results
- result = {}
- for name, data in trie.iteritems():
- if prefix:
- name = prefix + '/' + name
-
- if len(data) and 'actual' not in data and 'expected' not in data:
- result.update(_ConvertTrieToFlatPaths(data, name))
- else:
- result[name] = data
-
- return result
-
-
-def _PrintDashboardLink(link_text, tests, max_tests):
- """Add a link to the flakiness dashboard in the step annotations."""
- if len(tests) > max_tests:
- test_list_text = ' '.join(tests[:max_tests]) + ' and more'
- else:
- test_list_text = ' '.join(tests)
-
- dashboard_base = ('http://test-results.appspot.com'
- '/dashboards/flakiness_dashboard.html#'
- 'master=ChromiumWebkit&tests=')
-
- bb_annotations.PrintLink('%d %s: %s' %
- (len(tests), link_text, test_list_text),
- dashboard_base + ','.join(tests))
-
-
-def EscapeBuilderName(builder_name):
- return re.sub('[ ()]', '_', builder_name)
-
-
-def SpawnLogcatMonitor():
- shutil.rmtree(LOGCAT_DIR, ignore_errors=True)
- bb_utils.SpawnCmd([
- os.path.join(CHROME_SRC_DIR, 'build', 'android', 'adb_logcat_monitor.py'),
- LOGCAT_DIR])
-
- # Wait for logcat_monitor to pull existing logcat
- RunCmd(['sleep', '5'])
-
-
-def ProvisionDevices(options):
- bb_annotations.PrintNamedStep('provision_devices')
-
- if not bb_utils.TESTING:
- # Restart adb to work around bugs, sleep to wait for usb discovery.
- device_utils.RestartServer()
- RunCmd(['sleep', '1'])
- provision_cmd = ['build/android/provision_devices.py', '-t', options.target]
- if options.auto_reconnect:
- provision_cmd.append('--auto-reconnect')
- if options.skip_wipe:
- provision_cmd.append('--skip-wipe')
- if options.disable_location:
- provision_cmd.append('--disable-location')
- RunCmd(provision_cmd, halt_on_failure=True)
-
-
-def DeviceStatusCheck(options):
- bb_annotations.PrintNamedStep('device_status_check')
- cmd = ['build/android/buildbot/bb_device_status_check.py']
- if options.restart_usb:
- cmd.append('--restart-usb')
- RunCmd(cmd, halt_on_failure=True)
-
-
-def GetDeviceSetupStepCmds():
- return [
- ('device_status_check', DeviceStatusCheck),
- ('provision_devices', ProvisionDevices),
- ]
-
-
-def RunUnitTests(options):
- suites = gtest_config.STABLE_TEST_SUITES
- if options.asan:
- suites = [s for s in suites
- if s not in gtest_config.ASAN_EXCLUDED_TEST_SUITES]
- RunTestSuites(options, suites)
-
-
-def RunTelemetryUnitTests(options):
- RunTelemetryTests(options, 'telemetry_unittests', 'tools/telemetry/run_tests')
-
-
-def RunTelemetryPerfUnitTests(options):
- RunTelemetryTests(options, 'telemetry_perf_unittests', 'tools/perf/run_tests')
-
-
-def RunInstrumentationTests(options):
- for test in INSTRUMENTATION_TESTS.itervalues():
- RunInstrumentationSuite(options, test)
-
-
-def RunWebkitTests(options):
- RunTestSuites(options, ['webkit_unit_tests', 'blink_heap_unittests'])
- RunWebkitLint()
-
-
-def RunGPUTests(options):
- revision = _GetRevision(options)
- builder_name = options.build_properties.get('buildername', 'noname')
-
- bb_annotations.PrintNamedStep('pixel_tests')
- RunCmd(['content/test/gpu/run_gpu_test.py',
- 'pixel', '-v',
- '--browser',
- 'android-content-shell',
- '--build-revision',
- str(revision),
- '--upload-refimg-to-cloud-storage',
- '--refimg-cloud-storage-bucket',
- 'chromium-gpu-archive/reference-images',
- '--os-type',
- 'android',
- '--test-machine-name',
- EscapeBuilderName(builder_name)])
-
- bb_annotations.PrintNamedStep('webgl_conformance_tests')
- RunCmd(['content/test/gpu/run_gpu_test.py', '-v',
- '--browser=android-content-shell', 'webgl_conformance',
- '--webgl-conformance-version=1.0.1'])
-
- bb_annotations.PrintNamedStep('android_webview_webgl_conformance_tests')
- RunCmd(['content/test/gpu/run_gpu_test.py', '-v',
- '--browser=android-webview-shell', 'webgl_conformance',
- '--webgl-conformance-version=1.0.1'])
-
- bb_annotations.PrintNamedStep('gpu_rasterization_tests')
- RunCmd(['content/test/gpu/run_gpu_test.py',
- 'gpu_rasterization', '-v',
- '--browser',
- 'android-content-shell',
- '--build-revision',
- str(revision),
- '--test-machine-name',
- EscapeBuilderName(builder_name)])
-
-
-def RunPythonUnitTests(_options):
- for suite in constants.PYTHON_UNIT_TEST_SUITES:
- bb_annotations.PrintNamedStep(suite)
- RunCmd(['build/android/test_runner.py', 'python', '-s', suite])
-
-
-def GetTestStepCmds():
- return [
- ('base_junit_tests',
- lambda _options: RunJunitSuite('base_junit_tests')),
- ('chromedriver', RunChromeDriverTests),
- ('chrome_proxy', RunChromeProxyTests),
- ('components_browsertests',
- lambda options: RunTestSuites(options, ['components_browsertests'])),
- ('gfx_unittests',
- lambda options: RunTestSuites(options, ['gfx_unittests'])),
- ('gl_unittests',
- lambda options: RunTestSuites(options, ['gl_unittests'])),
- ('gpu', RunGPUTests),
- ('python_unittests', RunPythonUnitTests),
- ('telemetry_unittests', RunTelemetryUnitTests),
- ('telemetry_perf_unittests', RunTelemetryPerfUnitTests),
- ('ui', RunInstrumentationTests),
- ('unit', RunUnitTests),
- ('webkit', RunWebkitTests),
- ('webkit_layout', RunWebkitLayoutTests),
- ]
-
-
-def MakeGSPath(options, gs_base_dir):
- revision = _GetRevision(options)
- bot_id = options.build_properties.get('buildername', 'testing')
- randhash = hashlib.sha1(str(random.random())).hexdigest()
- gs_path = '%s/%s/%s/%s' % (gs_base_dir, bot_id, revision, randhash)
- # remove double slashes, happens with blank revisions and confuses gsutil
- gs_path = re.sub('/+', '/', gs_path)
- return gs_path
-
-def UploadHTML(options, gs_base_dir, dir_to_upload, link_text,
- link_rel_path='index.html', gs_url=GS_URL):
- """Uploads directory at |dir_to_upload| to Google Storage and output a link.
-
- Args:
- options: Command line options.
- gs_base_dir: The Google Storage base directory (e.g.
- 'chromium-code-coverage/java')
- dir_to_upload: Absolute path to the directory to be uploaded.
- link_text: Link text to be displayed on the step.
- link_rel_path: Link path relative to |dir_to_upload|.
- gs_url: Google storage URL.
- """
- gs_path = MakeGSPath(options, gs_base_dir)
- RunCmd([bb_utils.GSUTIL_PATH, 'cp', '-R', dir_to_upload, 'gs://%s' % gs_path])
- bb_annotations.PrintLink(link_text,
- '%s/%s/%s' % (gs_url, gs_path, link_rel_path))
-
-
-def GenerateJavaCoverageReport(options):
- """Generates an HTML coverage report using EMMA and uploads it."""
- bb_annotations.PrintNamedStep('java_coverage_report')
-
- coverage_html = os.path.join(options.coverage_dir, 'coverage_html')
- RunCmd(['build/android/generate_emma_html.py',
- '--coverage-dir', options.coverage_dir,
- '--metadata-dir', os.path.join(CHROME_OUT_DIR, options.target),
- '--cleanup',
- '--output', os.path.join(coverage_html, 'index.html')])
- return coverage_html
-
-
-def LogcatDump(options):
- # Print logcat, kill logcat monitor
- bb_annotations.PrintNamedStep('logcat_dump')
- logcat_file = os.path.join(CHROME_OUT_DIR, options.target, 'full_log.txt')
- RunCmd([SrcPath('build', 'android', 'adb_logcat_printer.py'),
- '--output-path', logcat_file, LOGCAT_DIR])
- gs_path = MakeGSPath(options, 'chromium-android/logcat_dumps')
- RunCmd([bb_utils.GSUTIL_PATH, 'cp', '-z', 'txt', logcat_file,
- 'gs://%s' % gs_path])
- bb_annotations.PrintLink('logcat dump', '%s/%s' % (GS_AUTH_URL, gs_path))
-
-
-def RunStackToolSteps(options):
- """Run stack tool steps.
-
- Stack tool is run for logcat dump, optionally for ASAN.
- """
- bb_annotations.PrintNamedStep('Run stack tool with logcat dump')
- logcat_file = os.path.join(CHROME_OUT_DIR, options.target, 'full_log.txt')
- RunCmd([os.path.join(CHROME_SRC_DIR, 'third_party', 'android_platform',
- 'development', 'scripts', 'stack'),
- '--more-info', logcat_file])
- if options.asan_symbolize:
- bb_annotations.PrintNamedStep('Run stack tool for ASAN')
- RunCmd([
- os.path.join(CHROME_SRC_DIR, 'build', 'android', 'asan_symbolize.py'),
- '-l', logcat_file])
-
-
-def GenerateTestReport(options):
- bb_annotations.PrintNamedStep('test_report')
- for report in glob.glob(
- os.path.join(CHROME_OUT_DIR, options.target, 'test_logs', '*.log')):
- RunCmd(['cat', report])
- os.remove(report)
-
-
-def MainTestWrapper(options):
- try:
- # Spawn logcat monitor
- SpawnLogcatMonitor()
-
- # Run all device setup steps
- for _, cmd in GetDeviceSetupStepCmds():
- cmd(options)
-
- if options.install:
- for i in options.install:
- install_obj = INSTALLABLE_PACKAGES[i]
- InstallApk(options, install_obj, print_step=True)
-
- if options.test_filter:
- bb_utils.RunSteps(options.test_filter, GetTestStepCmds(), options)
-
- if options.coverage_bucket:
- coverage_html = GenerateJavaCoverageReport(options)
- UploadHTML(options, '%s/java' % options.coverage_bucket, coverage_html,
- 'Coverage Report')
- shutil.rmtree(coverage_html, ignore_errors=True)
-
- if options.experimental:
- RunTestSuites(options, gtest_config.EXPERIMENTAL_TEST_SUITES)
-
- finally:
- # Run all post test steps
- LogcatDump(options)
- if not options.disable_stack_tool:
- RunStackToolSteps(options)
- GenerateTestReport(options)
- # KillHostHeartbeat() has logic to check if heartbeat process is running,
- # and kills only if it finds the process is running on the host.
- provision_devices.KillHostHeartbeat()
- if options.cleanup:
- shutil.rmtree(os.path.join(CHROME_OUT_DIR, options.target),
- ignore_errors=True)
-
-
-def GetDeviceStepsOptParser():
- parser = bb_utils.GetParser()
- parser.add_option('--experimental', action='store_true',
- help='Run experiemental tests')
- parser.add_option('-f', '--test-filter', metavar='<filter>', default=[],
- action='append',
- help=('Run a test suite. Test suites: "%s"' %
- '", "'.join(VALID_TESTS)))
- parser.add_option('--gtest-filter',
- help='Filter for running a subset of tests of a gtest test')
- parser.add_option('--asan', action='store_true', help='Run tests with asan.')
- parser.add_option('--install', metavar='<apk name>', action="append",
- help='Install an apk by name')
- parser.add_option('--no-reboot', action='store_true',
- help='Do not reboot devices during provisioning.')
- parser.add_option('--coverage-bucket',
- help=('Bucket name to store coverage results. Coverage is '
- 'only run if this is set.'))
- parser.add_option('--restart-usb', action='store_true',
- help='Restart usb ports before device status check.')
- parser.add_option(
- '--flakiness-server',
- help=('The flakiness dashboard server to which the results should be '
- 'uploaded.'))
- parser.add_option(
- '--auto-reconnect', action='store_true',
- help='Push script to device which restarts adbd on disconnections.')
- parser.add_option('--skip-wipe', action='store_true',
- help='Do not wipe devices during provisioning.')
- parser.add_option('--disable-location', action='store_true',
- help='Disable location settings.')
- parser.add_option(
- '--logcat-dump-output',
- help='The logcat dump output will be "tee"-ed into this file')
- # During processing perf bisects, a seperate working directory created under
- # which builds are produced. Therefore we should look for relevent output
- # file under this directory.(/b/build/slave/<slave_name>/build/bisect/src/out)
- parser.add_option(
- '--chrome-output-dir',
- help='Chrome output directory to be used while bisecting.')
-
- parser.add_option('--disable-stack-tool', action='store_true',
- help='Do not run stack tool.')
- parser.add_option('--asan-symbolize', action='store_true',
- help='Run stack tool for ASAN')
- parser.add_option('--cleanup', action='store_true',
- help='Delete out/<target> directory at the end of the run.')
- return parser
-
-
-def main(argv):
- parser = GetDeviceStepsOptParser()
- options, args = parser.parse_args(argv[1:])
-
- if args:
- return sys.exit('Unused args %s' % args)
-
- unknown_tests = set(options.test_filter) - VALID_TESTS
- if unknown_tests:
- return sys.exit('Unknown tests %s' % list(unknown_tests))
-
- setattr(options, 'target', options.factory_properties.get('target', 'Debug'))
-
- if options.chrome_output_dir:
- global CHROME_OUT_DIR
- global LOGCAT_DIR
- CHROME_OUT_DIR = options.chrome_output_dir
- LOGCAT_DIR = os.path.join(CHROME_OUT_DIR, 'logcat')
-
- if options.coverage_bucket:
- setattr(options, 'coverage_dir',
- os.path.join(CHROME_OUT_DIR, options.target, 'coverage'))
-
- MainTestWrapper(options)
-
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv))
diff --git a/build/android/buildbot/bb_host_steps.py b/build/android/buildbot/bb_host_steps.py
deleted file mode 100755
index 1e927fb..0000000
--- a/build/android/buildbot/bb_host_steps.py
+++ /dev/null
@@ -1,133 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import json
-import sys
-
-import bb_utils
-import bb_annotations
-
-sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
-from pylib import constants
-
-
-SLAVE_SCRIPTS_DIR = os.path.join(bb_utils.BB_BUILD_DIR, 'scripts', 'slave')
-VALID_HOST_TESTS = set(['check_webview_licenses'])
-
-DIR_BUILD_ROOT = os.path.dirname(constants.DIR_SOURCE_ROOT)
-
-# Short hand for RunCmd which is used extensively in this file.
-RunCmd = bb_utils.RunCmd
-
-
-def SrcPath(*path):
- return os.path.join(constants.DIR_SOURCE_ROOT, *path)
-
-
-def CheckWebViewLicenses(_):
- bb_annotations.PrintNamedStep('check_licenses')
- RunCmd([SrcPath('android_webview', 'tools', 'webview_licenses.py'), 'scan'],
- warning_code=1)
-
-
-def RunHooks(build_type):
- RunCmd([SrcPath('build', 'landmines.py')])
- build_path = SrcPath('out', build_type)
- landmine_path = os.path.join(build_path, '.landmines_triggered')
- clobber_env = os.environ.get('BUILDBOT_CLOBBER')
- if clobber_env or os.path.isfile(landmine_path):
- bb_annotations.PrintNamedStep('Clobber')
- if not clobber_env:
- print 'Clobbering due to triggered landmines:'
- with open(landmine_path) as f:
- print f.read()
- RunCmd(['rm', '-rf', build_path])
-
- bb_annotations.PrintNamedStep('runhooks')
- RunCmd(['gclient', 'runhooks'], halt_on_failure=True)
-
-
-def Compile(options):
- RunHooks(options.target)
- cmd = [os.path.join(SLAVE_SCRIPTS_DIR, 'compile.py'),
- '--build-tool=ninja',
- '--compiler=goma',
- '--target=%s' % options.target,
- '--goma-dir=%s' % bb_utils.GOMA_DIR]
- bb_annotations.PrintNamedStep('compile')
- if options.build_targets:
- build_targets = options.build_targets.split(',')
- cmd += ['--build-args', ' '.join(build_targets)]
- RunCmd(cmd, halt_on_failure=True, cwd=DIR_BUILD_ROOT)
-
-
-def ZipBuild(options):
- bb_annotations.PrintNamedStep('zip_build')
- RunCmd([
- os.path.join(SLAVE_SCRIPTS_DIR, 'zip_build.py'),
- '--src-dir', constants.DIR_SOURCE_ROOT,
- '--exclude-files', 'lib.target,gen,android_webview,jingle_unittests']
- + bb_utils.EncodeProperties(options), cwd=DIR_BUILD_ROOT)
-
-
-def ExtractBuild(options):
- bb_annotations.PrintNamedStep('extract_build')
- RunCmd([os.path.join(SLAVE_SCRIPTS_DIR, 'extract_build.py')]
- + bb_utils.EncodeProperties(options), cwd=DIR_BUILD_ROOT)
-
-
-def BisectPerfRegression(options):
- args = []
- if options.extra_src:
- args = ['--extra_src', options.extra_src]
- RunCmd([SrcPath('tools', 'prepare-bisect-perf-regression.py'),
- '-w', os.path.join(constants.DIR_SOURCE_ROOT, os.pardir)])
- RunCmd([SrcPath('tools', 'run-bisect-perf-regression.py'),
- '-w', os.path.join(constants.DIR_SOURCE_ROOT, os.pardir),
- '--build-properties=%s' % json.dumps(options.build_properties)] +
- args)
-
-
-def GetHostStepCmds():
- return [
- ('compile', Compile),
- ('extract_build', ExtractBuild),
- ('check_webview_licenses', CheckWebViewLicenses),
- ('bisect_perf_regression', BisectPerfRegression),
- ('zip_build', ZipBuild)
- ]
-
-
-def GetHostStepsOptParser():
- parser = bb_utils.GetParser()
- parser.add_option('--steps', help='Comma separated list of host tests.')
- parser.add_option('--build-targets', default='',
- help='Comma separated list of build targets.')
- parser.add_option('--experimental', action='store_true',
- help='Indicate whether to compile experimental targets.')
- parser.add_option('--extra_src', default='',
- help='Path to extra source file. If this is supplied, '
- 'bisect script will use it to override default behavior.')
-
- return parser
-
-
-def main(argv):
- parser = GetHostStepsOptParser()
- options, args = parser.parse_args(argv[1:])
- if args:
- return sys.exit('Unused args %s' % args)
-
- setattr(options, 'target', options.factory_properties.get('target', 'Debug'))
- setattr(options, 'extra_src',
- options.factory_properties.get('extra_src', ''))
-
- if options.steps:
- bb_utils.RunSteps(options.steps.split(','), GetHostStepCmds(), options)
-
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv))
diff --git a/build/android/buildbot/bb_run_bot.py b/build/android/buildbot/bb_run_bot.py
deleted file mode 100755
index 0c8a977..0000000
--- a/build/android/buildbot/bb_run_bot.py
+++ /dev/null
@@ -1,320 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (c) 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import collections
-import copy
-import json
-import os
-import pipes
-import re
-import subprocess
-import sys
-
-import bb_utils
-
-sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
-from pylib import constants
-
-
-CHROMIUM_COVERAGE_BUCKET = 'chromium-code-coverage'
-
-_BotConfig = collections.namedtuple(
- 'BotConfig', ['bot_id', 'host_obj', 'test_obj'])
-
-HostConfig = collections.namedtuple(
- 'HostConfig',
- ['script', 'host_steps', 'extra_args', 'extra_gyp_defines', 'target_arch'])
-
-TestConfig = collections.namedtuple('Tests', ['script', 'tests', 'extra_args'])
-
-
-def BotConfig(bot_id, host_object, test_object=None):
- return _BotConfig(bot_id, host_object, test_object)
-
-
-def DictDiff(d1, d2):
- diff = []
- for key in sorted(set(d1.keys() + d2.keys())):
- if key in d1 and d1[key] != d2.get(key):
- diff.append('- %s=%s' % (key, pipes.quote(d1[key])))
- if key in d2 and d2[key] != d1.get(key):
- diff.append('+ %s=%s' % (key, pipes.quote(d2[key])))
- return '\n'.join(diff)
-
-
-def GetEnvironment(host_obj, testing, extra_env_vars=None):
- init_env = dict(os.environ)
- init_env['GYP_GENERATORS'] = 'ninja'
- if extra_env_vars:
- init_env.update(extra_env_vars)
- envsetup_cmd = '. build/android/envsetup.sh'
- if testing:
- # Skip envsetup to avoid presubmit dependence on android deps.
- print 'Testing mode - skipping "%s"' % envsetup_cmd
- envsetup_cmd = ':'
- else:
- print 'Running %s' % envsetup_cmd
- proc = subprocess.Popen(['bash', '-exc',
- envsetup_cmd + ' >&2; python build/android/buildbot/env_to_json.py'],
- stdout=subprocess.PIPE, stderr=subprocess.PIPE,
- cwd=bb_utils.CHROME_SRC, env=init_env)
- json_env, envsetup_output = proc.communicate()
- if proc.returncode != 0:
- print >> sys.stderr, 'FATAL Failure in envsetup.'
- print >> sys.stderr, envsetup_output
- sys.exit(1)
- env = json.loads(json_env)
- env['GYP_DEFINES'] = env.get('GYP_DEFINES', '') + \
- ' OS=android fastbuild=1 use_goma=1 gomadir=%s' % bb_utils.GOMA_DIR
- if host_obj.target_arch:
- env['GYP_DEFINES'] += ' target_arch=%s' % host_obj.target_arch
- extra_gyp = host_obj.extra_gyp_defines
- if extra_gyp:
- env['GYP_DEFINES'] += ' %s' % extra_gyp
- if re.search('(asan|clang)=1', extra_gyp):
- env.pop('CXX_target', None)
-
- # Bots checkout chrome in /b/build/slave/<name>/build/src
- build_internal_android = os.path.abspath(os.path.join(
- bb_utils.CHROME_SRC, '..', '..', '..', '..', '..', 'build_internal',
- 'scripts', 'slave', 'android'))
- if os.path.exists(build_internal_android):
- env['PATH'] = os.pathsep.join([build_internal_android, env['PATH']])
- return env
-
-
-def GetCommands(options, bot_config):
- """Get a formatted list of commands.
-
- Args:
- options: Options object.
- bot_config: A BotConfig named tuple.
- host_step_script: Host step script.
- device_step_script: Device step script.
- Returns:
- list of Command objects.
- """
- property_args = bb_utils.EncodeProperties(options)
- commands = [[bot_config.host_obj.script,
- '--steps=%s' % ','.join(bot_config.host_obj.host_steps)] +
- property_args + (bot_config.host_obj.extra_args or [])]
-
- test_obj = bot_config.test_obj
- if test_obj:
- run_test_cmd = [test_obj.script] + property_args
- for test in test_obj.tests:
- run_test_cmd.extend(['-f', test])
- if test_obj.extra_args:
- run_test_cmd.extend(test_obj.extra_args)
- commands.append(run_test_cmd)
- return commands
-
-
-def GetBotStepMap():
- compile_step = ['compile']
- chrome_proxy_tests = ['chrome_proxy']
- python_unittests = ['python_unittests']
- std_host_tests = ['check_webview_licenses']
- std_build_steps = ['compile', 'zip_build']
- std_test_steps = ['extract_build']
- std_tests = ['ui', 'unit']
- telemetry_tests = ['telemetry_perf_unittests']
- telemetry_tests_user_build = ['telemetry_unittests',
- 'telemetry_perf_unittests']
- trial_tests = [
- 'base_junit_tests',
- 'components_browsertests',
- 'gfx_unittests',
- 'gl_unittests',
- ]
- flakiness_server = (
- '--flakiness-server=%s' % constants.UPSTREAM_FLAKINESS_SERVER)
- experimental = ['--experimental']
- bisect_chrome_output_dir = os.path.abspath(
- os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, os.pardir,
- os.pardir, 'bisect', 'src', 'out'))
- B = BotConfig
- H = (lambda steps, extra_args=None, extra_gyp=None, target_arch=None:
- HostConfig('build/android/buildbot/bb_host_steps.py', steps, extra_args,
- extra_gyp, target_arch))
- T = (lambda tests, extra_args=None:
- TestConfig('build/android/buildbot/bb_device_steps.py', tests,
- extra_args))
-
- bot_configs = [
- # Main builders
- B('main-builder-dbg', H(std_build_steps + std_host_tests)),
- B('main-builder-rel', H(std_build_steps)),
- B('main-clang-builder',
- H(compile_step, extra_gyp='clang=1 component=shared_library')),
- B('main-clobber', H(compile_step)),
- B('main-tests-rel', H(std_test_steps),
- T(std_tests + telemetry_tests + chrome_proxy_tests,
- ['--cleanup', flakiness_server])),
- B('main-tests', H(std_test_steps),
- T(std_tests, ['--cleanup', flakiness_server])),
-
- # Other waterfalls
- B('asan-builder-tests', H(compile_step,
- extra_gyp='asan=1 component=shared_library'),
- T(std_tests, ['--asan', '--asan-symbolize'])),
- B('blink-try-builder', H(compile_step)),
- B('chromedriver-fyi-tests-dbg', H(std_test_steps),
- T(['chromedriver'],
- ['--install=ChromeShell', '--install=ChromeDriverWebViewShell',
- '--skip-wipe', '--disable-location', '--cleanup'])),
- B('fyi-x86-builder-dbg',
- H(compile_step + std_host_tests, experimental, target_arch='ia32')),
- B('fyi-builder-dbg',
- H(std_build_steps + std_host_tests, experimental,
- extra_gyp='emma_coverage=1')),
- B('x86-builder-dbg',
- H(compile_step + std_host_tests, target_arch='ia32')),
- B('fyi-builder-rel', H(std_build_steps, experimental)),
- B('fyi-tests', H(std_test_steps),
- T(std_tests + python_unittests,
- ['--experimental', flakiness_server,
- '--coverage-bucket', CHROMIUM_COVERAGE_BUCKET,
- '--cleanup'])),
- B('user-build-fyi-tests-dbg', H(std_test_steps),
- T(sorted(telemetry_tests_user_build + trial_tests))),
- B('fyi-component-builder-tests-dbg',
- H(compile_step, extra_gyp='component=shared_library'),
- T(std_tests, ['--experimental', flakiness_server])),
- B('gpu-builder-tests-dbg',
- H(compile_step),
- T(['gpu'], ['--install=ContentShell'])),
- # Pass empty T([]) so that logcat monitor and device status check are run.
- B('perf-bisect-builder-tests-dbg',
- H(['bisect_perf_regression']),
- T([], ['--chrome-output-dir', bisect_chrome_output_dir])),
- B('perf-tests-rel', H(std_test_steps),
- T([], ['--install=ChromeShell', '--cleanup'])),
- B('webkit-latest-webkit-tests', H(std_test_steps),
- T(['webkit_layout', 'webkit'], ['--cleanup', '--auto-reconnect'])),
- B('webkit-latest-contentshell', H(compile_step),
- T(['webkit_layout'], ['--auto-reconnect'])),
- B('builder-unit-tests', H(compile_step), T(['unit'])),
-
- # Generic builder config (for substring match).
- B('builder', H(std_build_steps)),
- ]
-
- bot_map = dict((config.bot_id, config) for config in bot_configs)
-
- # These bots have identical configuration to ones defined earlier.
- copy_map = [
- ('lkgr-clobber', 'main-clobber'),
- ('try-builder-dbg', 'main-builder-dbg'),
- ('try-builder-rel', 'main-builder-rel'),
- ('try-clang-builder', 'main-clang-builder'),
- ('try-fyi-builder-dbg', 'fyi-builder-dbg'),
- ('try-x86-builder-dbg', 'x86-builder-dbg'),
- ('try-tests-rel', 'main-tests-rel'),
- ('try-tests', 'main-tests'),
- ('try-fyi-tests', 'fyi-tests'),
- ('webkit-latest-tests', 'main-tests'),
- ]
- for to_id, from_id in copy_map:
- assert to_id not in bot_map
- # pylint: disable=W0212
- bot_map[to_id] = copy.deepcopy(bot_map[from_id])._replace(bot_id=to_id)
-
- # Trybots do not upload to flakiness dashboard. They should be otherwise
- # identical in configuration to their trunk building counterparts.
- test_obj = bot_map[to_id].test_obj
- if to_id.startswith('try') and test_obj:
- extra_args = test_obj.extra_args
- if extra_args and flakiness_server in extra_args:
- extra_args.remove(flakiness_server)
- return bot_map
-
-
-# Return an object from the map, looking first for an exact id match.
-# If this fails, look for an id which is a substring of the specified id.
-# Choose the longest of all substring matches.
-# pylint: disable=W0622
-def GetBestMatch(id_map, id):
- config = id_map.get(id)
- if not config:
- substring_matches = [x for x in id_map.iterkeys() if x in id]
- if substring_matches:
- max_id = max(substring_matches, key=len)
- print 'Using config from id="%s" (substring match).' % max_id
- config = id_map[max_id]
- return config
-
-
-def GetRunBotOptParser():
- parser = bb_utils.GetParser()
- parser.add_option('--bot-id', help='Specify bot id directly.')
- parser.add_option('--testing', action='store_true',
- help='For testing: print, but do not run commands')
-
- return parser
-
-
-def GetBotConfig(options, bot_step_map):
- bot_id = options.bot_id or options.factory_properties.get('android_bot_id')
- if not bot_id:
- print (sys.stderr,
- 'A bot id must be specified through option or factory_props.')
- return
-
- bot_config = GetBestMatch(bot_step_map, bot_id)
- if not bot_config:
- print 'Error: config for id="%s" cannot be inferred.' % bot_id
- return bot_config
-
-
-def RunBotCommands(options, commands, env):
- print 'Environment changes:'
- print DictDiff(dict(os.environ), env)
-
- for command in commands:
- print bb_utils.CommandToString(command)
- sys.stdout.flush()
- if options.testing:
- env['BUILDBOT_TESTING'] = '1'
- return_code = subprocess.call(command, cwd=bb_utils.CHROME_SRC, env=env)
- if return_code != 0:
- return return_code
-
-
-def main(argv):
- proc = subprocess.Popen(
- ['/bin/hostname', '-f'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
- hostname_stdout, hostname_stderr = proc.communicate()
- if proc.returncode == 0:
- print 'Running on: ' + hostname_stdout
- else:
- print >> sys.stderr, 'WARNING: failed to run hostname'
- print >> sys.stderr, hostname_stdout
- print >> sys.stderr, hostname_stderr
- sys.exit(1)
-
- parser = GetRunBotOptParser()
- options, args = parser.parse_args(argv[1:])
- if args:
- parser.error('Unused args: %s' % args)
-
- bot_config = GetBotConfig(options, GetBotStepMap())
- if not bot_config:
- sys.exit(1)
-
- print 'Using config:', bot_config
-
- commands = GetCommands(options, bot_config)
- for command in commands:
- print 'Will run: ', bb_utils.CommandToString(command)
- print
-
- env = GetEnvironment(bot_config.host_obj, options.testing)
- return RunBotCommands(options, commands, env)
-
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv))
diff --git a/build/android/buildbot/bb_utils.py b/build/android/buildbot/bb_utils.py
deleted file mode 100644
index 3c16cc2..0000000
--- a/build/android/buildbot/bb_utils.py
+++ /dev/null
@@ -1,100 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import json
-import optparse
-import os
-import pipes
-import subprocess
-import sys
-
-import bb_annotations
-
-sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
-from pylib import constants
-
-
-TESTING = 'BUILDBOT_TESTING' in os.environ
-
-BB_BUILD_DIR = os.path.abspath(
- os.path.join(os.path.dirname(__file__), os.pardir, os.pardir, os.pardir,
- os.pardir, os.pardir, os.pardir, os.pardir))
-
-CHROME_SRC = os.path.abspath(
- os.path.join(os.path.dirname(__file__), '..', '..', '..'))
-
-# TODO: Figure out how to merge this with pylib.cmd_helper.OutDirectory().
-CHROME_OUT_DIR = os.path.join(CHROME_SRC, 'out')
-
-GOMA_DIR = os.environ.get('GOMA_DIR', os.path.join(BB_BUILD_DIR, 'goma'))
-
-GSUTIL_PATH = os.path.join(BB_BUILD_DIR, 'third_party', 'gsutil', 'gsutil')
-
-def CommandToString(command):
- """Returns quoted command that can be run in bash shell."""
- return ' '.join(map(pipes.quote, command))
-
-
-def SpawnCmd(command, stdout=None, cwd=CHROME_SRC):
- """Spawn a process without waiting for termination."""
- print '>', CommandToString(command)
- sys.stdout.flush()
- if TESTING:
- class MockPopen(object):
- @staticmethod
- def wait():
- return 0
- @staticmethod
- def communicate():
- return '', ''
- return MockPopen()
- return subprocess.Popen(command, cwd=cwd, stdout=stdout)
-
-
-def RunCmd(command, flunk_on_failure=True, halt_on_failure=False,
- warning_code=constants.WARNING_EXIT_CODE, stdout=None,
- cwd=CHROME_SRC):
- """Run a command relative to the chrome source root."""
- code = SpawnCmd(command, stdout, cwd).wait()
- print '<', CommandToString(command)
- if code != 0:
- print 'ERROR: process exited with code %d' % code
- if code != warning_code and flunk_on_failure:
- bb_annotations.PrintError()
- else:
- bb_annotations.PrintWarning()
- # Allow steps to have both halting (i.e. 1) and non-halting exit codes.
- if code != warning_code and halt_on_failure:
- print 'FATAL %d != %d' % (code, warning_code)
- sys.exit(1)
- return code
-
-
-def GetParser():
- def ConvertJson(option, _, value, parser):
- setattr(parser.values, option.dest, json.loads(value))
- parser = optparse.OptionParser()
- parser.add_option('--build-properties', action='callback',
- callback=ConvertJson, type='string', default={},
- help='build properties in JSON format')
- parser.add_option('--factory-properties', action='callback',
- callback=ConvertJson, type='string', default={},
- help='factory properties in JSON format')
- return parser
-
-
-def EncodeProperties(options):
- return ['--factory-properties=%s' % json.dumps(options.factory_properties),
- '--build-properties=%s' % json.dumps(options.build_properties)]
-
-
-def RunSteps(steps, step_cmds, options):
- unknown_steps = set(steps) - set(step for step, _ in step_cmds)
- if unknown_steps:
- print >> sys.stderr, 'FATAL: Unknown steps %s' % list(unknown_steps)
- sys.exit(1)
-
- for step, cmd in step_cmds:
- if step in steps:
- cmd(options)
diff --git a/build/android/buildbot/env_to_json.py b/build/android/buildbot/env_to_json.py
deleted file mode 100755
index f9a7a44..0000000
--- a/build/android/buildbot/env_to_json.py
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/usr/bin/python
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# Encode current environment into json.
-
-import json
-import os
-
-print json.dumps(dict(os.environ))
diff --git a/build/android/buildbot/tests/bb_run_bot_test.py b/build/android/buildbot/tests/bb_run_bot_test.py
deleted file mode 100755
index 810c60d..0000000
--- a/build/android/buildbot/tests/bb_run_bot_test.py
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import subprocess
-import sys
-
-BUILDBOT_DIR = os.path.join(os.path.dirname(__file__), '..')
-sys.path.append(BUILDBOT_DIR)
-import bb_run_bot
-
-def RunBotProcesses(bot_process_map):
- code = 0
- for bot, proc in bot_process_map:
- _, err = proc.communicate()
- code |= proc.returncode
- if proc.returncode != 0:
- print 'Error running the bot script with id="%s"' % bot, err
-
- return code
-
-
-def main():
- procs = [
- (bot, subprocess.Popen(
- [os.path.join(BUILDBOT_DIR, 'bb_run_bot.py'), '--bot-id', bot,
- '--testing'], stdout=subprocess.PIPE, stderr=subprocess.PIPE))
- for bot in bb_run_bot.GetBotStepMap()]
- return RunBotProcesses(procs)
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/build/android/chrome_with_libs.gyp b/build/android/chrome_with_libs.gyp
deleted file mode 100644
index 690be88..0000000
--- a/build/android/chrome_with_libs.gyp
+++ /dev/null
@@ -1,82 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to add more loadable libs into Chrome_apk.
-#
-# This is useful when building Chrome_apk with some loadable modules which are
-# not included in Chrome_apk.
-# As an example, when building Chrome_apk with
-# libpeer_target_type=loadable_module,
-# the libpeerconnection.so is not included in Chrome_apk. To add the missing
-# lib, follow the steps below:
-# - Run gyp:
-# GYP_DEFINES="$GYP_DEFINES libpeer_target_type=loadable_module" CHROMIUM_GYP_FILE="build/android/chrome_with_libs.gyp" build/gyp_chromium
-# - Build chrome_with_libs:
-# ninja (or make) chrome_with_libs
-#
-# This tool also allows replacing the loadable module with a new one via the
-# following steps:
-# - Build Chrome_apk with the gyp define:
-# GYP_DEFINES="$GYP_DEFINES libpeer_target_type=loadable_module" build/gyp_chromium
-# ninja (or make) Chrome_apk
-# - Replace libpeerconnection.so with a new one:
-# cp the_new_one path/to/libpeerconnection.so
-# - Run gyp:
-# GYP_DEFINES="$GYP_DEFINES libpeer_target_type=loadable_module" CHROMIUM_GYP_FILE="build/android/chrome_with_libs.gyp" build/gyp_chromium
-# - Build chrome_with_libs:
-# ninja (or make) chrome_with_libs
-{
- 'targets': [
- {
- # An "All" target is required for a top-level gyp-file.
- 'target_name': 'All',
- 'type': 'none',
- 'dependencies': [
- 'chrome_with_libs',
- ],
- },
- {
- 'target_name': 'chrome_with_libs',
- 'type': 'none',
- 'variables': {
- 'intermediate_dir': '<(PRODUCT_DIR)/prebuilt_libs/',
- 'chrome_unsigned_path': '<(PRODUCT_DIR)/chrome_apk/Chrome-unsigned.apk',
- 'chrome_with_libs_unsigned': '<(intermediate_dir)/Chrome-with-libs-unsigned.apk',
- 'chrome_with_libs_final': '<(PRODUCT_DIR)/apks/Chrome-with-libs.apk',
- },
- 'dependencies': [
- '<(DEPTH)/clank/native/framework/clank.gyp:chrome_apk'
- ],
- 'copies': [
- {
- 'destination': '<(intermediate_dir)/lib/<(android_app_abi)',
- 'files': [
- '<(PRODUCT_DIR)/libpeerconnection.so',
- ],
- },
- ],
- 'actions': [
- {
- 'action_name': 'put_libs_in_chrome',
- 'variables': {
- 'inputs': [
- '<(intermediate_dir)/lib/<(android_app_abi)/libpeerconnection.so',
- ],
- 'input_apk_path': '<(chrome_unsigned_path)',
- 'output_apk_path': '<(chrome_with_libs_unsigned)',
- 'libraries_top_dir%': '<(intermediate_dir)',
- },
- 'includes': [ 'create_standalone_apk_action.gypi' ],
- },
- {
- 'action_name': 'finalize_chrome_with_libs',
- 'variables': {
- 'input_apk_path': '<(chrome_with_libs_unsigned)',
- 'output_apk_path': '<(chrome_with_libs_final)',
- },
- 'includes': [ 'finalize_apk_action.gypi'],
- },
- ],
- }],
-}
diff --git a/build/android/create_standalone_apk_action.gypi b/build/android/create_standalone_apk_action.gypi
deleted file mode 100644
index d17af7c..0000000
--- a/build/android/create_standalone_apk_action.gypi
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included into an action to provide an action that
-# combines a directory of shared libraries and an incomplete APK into a
-# standalone APK.
-#
-# To use this, create a gyp action with the following form:
-# {
-# 'action_name': 'some descriptive action name',
-# 'variables': {
-# 'inputs': [ 'input_path1', 'input_path2' ],
-# 'input_apk_path': '<(unsigned_apk_path)',
-# 'output_apk_path': '<(unsigned_standalone_apk_path)',
-# 'libraries_top_dir': '<(libraries_top_dir)',
-# },
-# 'includes': [ 'relative/path/to/create_standalone_apk_action.gypi' ],
-# },
-
-{
- 'message': 'Creating standalone APK: <(output_apk_path)',
- 'variables': {
- 'inputs': [],
- },
- 'inputs': [
- '<(DEPTH)/build/android/gyp/util/build_utils.py',
- '<(DEPTH)/build/android/gyp/create_standalone_apk.py',
- '<(input_apk_path)',
- '>@(inputs)',
- ],
- 'outputs': [
- '<(output_apk_path)',
- ],
- 'action': [
- 'python', '<(DEPTH)/build/android/gyp/create_standalone_apk.py',
- '--libraries-top-dir=<(libraries_top_dir)',
- '--input-apk-path=<(input_apk_path)',
- '--output-apk-path=<(output_apk_path)',
- ],
-}
diff --git a/build/android/developer_recommended_flags.gypi b/build/android/developer_recommended_flags.gypi
deleted file mode 100644
index 79c201de..0000000
--- a/build/android/developer_recommended_flags.gypi
+++ /dev/null
@@ -1,61 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This is the set of recommended gyp variable settings for Chrome for Android development.
-#
-# These can be used by copying this file to $CHROME_SRC/chrome/supplement.gypi.
-#
-# Even better, create chrome/supplement.gypi containing the following:
-# {
-# 'includes': [ '../build/android/developer_recommended_flags.gypi' ]
-# }
-# and you'll get new settings automatically.
-# When using this method, you can override individual settings by setting them unconditionally (with
-# no %) in chrome/supplement.gypi.
-# I.e. to disable gyp_managed_install but use everything else:
-# {
-# 'variables': {
-# 'gyp_managed_install': 0,
-# },
-# 'includes': [ '../build/android/developer_recommended_flags.gypi' ]
-# }
-
-{
- 'variables': {
- 'variables': {
- # Set component to 'shared_library' to enable the component build. This builds native code as
- # many small shared libraries instead of one monolithic library. This slightly reduces the time
- # required for incremental builds.
- 'component%': 'shared_library',
- },
- 'component%': '<(component)',
-
- # When gyp_managed_install is set to 1, building an APK will install that APK on the connected
- # device(/emulator). To install on multiple devices (or onto a new device), build the APK once
- # with each device attached. This greatly reduces the time required for incremental builds.
- #
- # This comes with some caveats:
- # Only works with a single device connected (it will print a warning if
- # zero or multiple devices are attached).
- # Device must be flashed with a user-debug unsigned Android build.
- # Some actions are always run (i.e. ninja will never say "no work to do").
- 'gyp_managed_install%': 1,
-
- # With gyp_managed_install, we do not necessarily need a standalone APK.
- # When create_standalone_apk is set to 1, we will build a standalone APK
- # anyway. For even faster builds, you can set create_standalone_apk to 0.
- 'create_standalone_apk%': 1,
-
- # Set clang to 1 to use the clang compiler. Clang has much (much, much) better warning/error
- # messages than gcc.
- # TODO(cjhopman): Enable this when http://crbug.com/156420 is addressed. Until then, users can
- # set clang to 1, but Android stack traces will sometimes be incomplete.
- #'clang%': 1,
-
- # Set fastbuild to 1 to build with less debugging information. This can greatly decrease linking
- # time. The downside is that stack traces will be missing useful information (like line
- # numbers).
- #'fastbuild%': 1,
- },
-}
diff --git a/build/android/dex_action.gypi b/build/android/dex_action.gypi
deleted file mode 100644
index 56d386f..0000000
--- a/build/android/dex_action.gypi
+++ /dev/null
@@ -1,60 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included into an action to provide a rule that dexes
-# compiled java files. If proguard_enabled == "true" and CONFIGURATION_NAME ==
-# "Release", then it will dex the proguard_enabled_input_path instead of the
-# normal dex_input_paths/dex_generated_input_paths.
-#
-# To use this, create a gyp target with the following form:
-# {
-# 'action_name': 'some name for the action'
-# 'actions': [
-# 'variables': {
-# 'dex_input_paths': [ 'files to dex (when proguard is not used) and add to input paths' ],
-# 'dex_generated_input_dirs': [ 'dirs that contain generated files to dex' ],
-#
-# # For targets that use proguard:
-# 'proguard_enabled': 'true',
-# 'proguard_enabled_input_path': 'path to dex when using proguard',
-# },
-# 'includes': [ 'relative/path/to/dex_action.gypi' ],
-# ],
-# },
-#
-
-{
- 'message': 'Creating dex file: <(output_path)',
- 'variables': {
- 'dex_input_paths': [],
- 'dex_generated_input_dirs': [],
- 'proguard_enabled%': 'false',
- 'proguard_enabled_input_path%': '',
- 'dex_no_locals%': 0,
- 'dex_additional_options': [],
- },
- 'inputs': [
- '<(DEPTH)/build/android/gyp/util/build_utils.py',
- '<(DEPTH)/build/android/gyp/util/md5_check.py',
- '<(DEPTH)/build/android/gyp/dex.py',
- '>@(dex_input_paths)',
- ],
- 'outputs': [
- '<(output_path)',
- '<(output_path).inputs',
- ],
- 'action': [
- 'python', '<(DEPTH)/build/android/gyp/dex.py',
- '--dex-path=<(output_path)',
- '--android-sdk-tools=<(android_sdk_tools)',
- '--output-directory=<(PRODUCT_DIR)',
- '--configuration-name=<(CONFIGURATION_NAME)',
- '--proguard-enabled=>(proguard_enabled)',
- '--proguard-enabled-input-path=<(proguard_enabled_input_path)',
- '--no-locals=>(dex_no_locals)',
- '>@(dex_additional_options)',
- '>@(dex_input_paths)',
- '>@(dex_generated_input_dirs)',
- ]
-}
diff --git a/build/android/disable_lto.gypi b/build/android/disable_lto.gypi
deleted file mode 100644
index e379cfd..0000000
--- a/build/android/disable_lto.gypi
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (c) 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included to disable LTO on a target.
-
-{
- 'target_conditions': [
- ['_toolset=="target"', {
- 'conditions': [
- ['OS=="android" and (use_lto==1 or use_lto_o2==1)', {
- 'cflags!': [
- '-flto',
- '-ffat-lto-objects',
- ],
- }],
- ],
- }],
- ],
-}
diff --git a/build/android/empty/src/.keep b/build/android/empty/src/.keep
deleted file mode 100644
index 0f710b6..0000000
--- a/build/android/empty/src/.keep
+++ /dev/null
@@ -1,6 +0,0 @@
-This is a file that needs to live here until http://crbug.com/158155 has
-been fixed.
-
-The ant build system requires that a src folder is always present, and for
-some of our targets that is not the case. Giving it an empty src-folder works
-nicely though.
diff --git a/build/android/empty_proguard.flags b/build/android/empty_proguard.flags
deleted file mode 100644
index 53484fe..0000000
--- a/build/android/empty_proguard.flags
+++ /dev/null
@@ -1 +0,0 @@
-# Used for apk targets that do not need proguard. See build/java_apk.gypi.
diff --git a/build/android/enable_asserts.py b/build/android/enable_asserts.py
deleted file mode 100755
index 8fb7dca..0000000
--- a/build/android/enable_asserts.py
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Enables dalvik vm asserts in the android device."""
-
-import argparse
-import sys
-
-from pylib.device import device_utils
-
-
-def main():
- parser = argparse.ArgumentParser()
-
- set_asserts_group = parser.add_mutually_exclusive_group(required=True)
- set_asserts_group.add_argument(
- '--enable_asserts', dest='set_asserts', action='store_true',
- help='Sets the dalvik.vm.enableassertions property to "all"')
- set_asserts_group.add_argument(
- '--disable_asserts', dest='set_asserts', action='store_false',
- help='Removes the dalvik.vm.enableassertions property')
-
- args = parser.parse_args()
-
- # TODO(jbudorick): Accept optional serial number and run only for the
- # specified device when present.
- devices = device_utils.DeviceUtils.parallel()
-
- def set_java_asserts_and_restart(device):
- if device.SetJavaAsserts(args.set_asserts):
- device.RunShellCommand('stop')
- device.RunShellCommand('start')
-
- devices.pMap(set_java_asserts_and_restart)
- return 0
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/build/android/envsetup.sh b/build/android/envsetup.sh
deleted file mode 100755
index 0545330..0000000
--- a/build/android/envsetup.sh
+++ /dev/null
@@ -1,62 +0,0 @@
-#!/bin/bash
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# Sets up environment for building Chromium on Android.
-
-# Make sure we're being sourced (possibly by another script). Check for bash
-# since zsh sets $0 when sourcing.
-if [[ -n "$BASH_VERSION" && "${BASH_SOURCE:-$0}" == "$0" ]]; then
- echo "ERROR: envsetup must be sourced."
- exit 1
-fi
-
-# This only exists to set local variables. Don't call this manually.
-android_envsetup_main() {
- local SCRIPT_PATH="$1"
- local SCRIPT_DIR="$(dirname "$SCRIPT_PATH")"
-
- local CURRENT_DIR="$(readlink -f "${SCRIPT_DIR}/../../")"
- if [[ -z "${CHROME_SRC}" ]]; then
- # If $CHROME_SRC was not set, assume current directory is CHROME_SRC.
- local CHROME_SRC="${CURRENT_DIR}"
- fi
-
- if [[ "${CURRENT_DIR/"${CHROME_SRC}"/}" == "${CURRENT_DIR}" ]]; then
- # If current directory is not in $CHROME_SRC, it might be set for other
- # source tree. If $CHROME_SRC was set correctly and we are in the correct
- # directory, "${CURRENT_DIR/"${CHROME_SRC}"/}" will be "".
- # Otherwise, it will equal to "${CURRENT_DIR}"
- echo "Warning: Current directory is out of CHROME_SRC, it may not be \
- the one you want."
- echo "${CHROME_SRC}"
- fi
-
- # Allow the caller to override a few environment variables. If any of them is
- # unset, we default to a sane value that's known to work. This allows for
- # experimentation with a custom SDK.
- if [[ -z "${ANDROID_SDK_ROOT}" || ! -d "${ANDROID_SDK_ROOT}" ]]; then
- local ANDROID_SDK_ROOT="${CHROME_SRC}/third_party/android_tools/sdk/"
- fi
-
- # Add Android SDK tools to system path.
- export PATH=$PATH:${ANDROID_SDK_ROOT}/platform-tools
-
- # Add Android utility tools to the system path.
- export PATH=$PATH:${ANDROID_SDK_ROOT}/tools/
-
- # Add Chromium Android development scripts to system path.
- # Must be after CHROME_SRC is set.
- export PATH=$PATH:${CHROME_SRC}/build/android
-
- export ENVSETUP_GYP_CHROME_SRC=${CHROME_SRC} # TODO(thakis): Remove.
-}
-# In zsh, $0 is the name of the file being sourced.
-android_envsetup_main "${BASH_SOURCE:-$0}"
-unset -f android_envsetup_main
-
-android_gyp() {
- echo "Please call build/gyp_chromium instead. android_gyp is going away."
- "${ENVSETUP_GYP_CHROME_SRC}/build/gyp_chromium" --depth="${ENVSETUP_GYP_CHROME_SRC}" --check "$@"
-}
diff --git a/build/android/finalize_apk_action.gypi b/build/android/finalize_apk_action.gypi
deleted file mode 100644
index 644f9e8..0000000
--- a/build/android/finalize_apk_action.gypi
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included into an action to provide an action that
-# signs and zipaligns an APK.
-#
-# To use this, create a gyp action with the following form:
-# {
-# 'action_name': 'some descriptive action name',
-# 'variables': {
-# 'input_apk_path': 'relative/path/to/input.apk',
-# 'output_apk_path': 'relative/path/to/output.apk',
-# },
-# 'includes': [ '../../build/android/finalize_apk_action.gypi' ],
-# },
-#
-
-{
- 'message': 'Signing/aligning <(_target_name) APK: <(input_apk_path)',
- 'variables': {
- 'keystore_path%': '<(DEPTH)/build/android/ant/chromium-debug.keystore',
- 'keystore_name%': 'chromiumdebugkey',
- 'keystore_password%': 'chromium',
- 'zipalign_path%': '<(android_sdk_tools)/zipalign',
- 'rezip_apk_jar_path%': '<(PRODUCT_DIR)/lib.java/rezip_apk.jar',
- 'load_library_from_zip%': 0,
- },
- 'inputs': [
- '<(DEPTH)/build/android/gyp/finalize_apk.py',
- '<(DEPTH)/build/android/gyp/util/build_utils.py',
- '<(keystore_path)',
- '<(input_apk_path)',
- ],
- 'outputs': [
- '<(output_apk_path)',
- ],
- 'action': [
- 'python', '<(DEPTH)/build/android/gyp/finalize_apk.py',
- '--zipalign-path=<(zipalign_path)',
- '--unsigned-apk-path=<(input_apk_path)',
- '--final-apk-path=<(output_apk_path)',
- '--key-path=<(keystore_path)',
- '--key-name=<(keystore_name)',
- '--key-passwd=<(keystore_password)',
- '--load-library-from-zip=<(load_library_from_zip)',
- '--rezip-apk-jar-path=<(rezip_apk_jar_path)',
- ],
-}
diff --git a/build/android/finalize_splits_action.gypi b/build/android/finalize_splits_action.gypi
deleted file mode 100644
index daa7f83..0000000
--- a/build/android/finalize_splits_action.gypi
+++ /dev/null
@@ -1,76 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included into an action to provide an action that
-# signs and zipaligns split APKs.
-#
-# Required variables:
-# apk_name - Base name of the apk.
-# Optional variables:
-# density_splits - Whether to process density splits
-# language_splits - Whether to language splits
-
-{
- 'variables': {
- 'keystore_path%': '<(DEPTH)/build/android/ant/chromium-debug.keystore',
- 'keystore_name%': 'chromiumdebugkey',
- 'keystore_password%': 'chromium',
- 'zipalign_path%': '<(android_sdk_tools)/zipalign',
- 'density_splits%': 0,
- 'language_splits%': [],
- 'resource_packaged_apk_name': '<(apk_name)-resources.ap_',
- 'resource_packaged_apk_path': '<(intermediate_dir)/<(resource_packaged_apk_name)',
- 'base_output_path': '<(PRODUCT_DIR)/apks/<(apk_name)',
- },
- 'inputs': [
- '<(DEPTH)/build/android/gyp/finalize_splits.py',
- '<(DEPTH)/build/android/gyp/finalize_apk.py',
- '<(DEPTH)/build/android/gyp/util/build_utils.py',
- '<(keystore_path)',
- ],
- 'action': [
- 'python', '<(DEPTH)/build/android/gyp/finalize_splits.py',
- '--resource-packaged-apk-path=<(resource_packaged_apk_path)',
- '--base-output-path=<(base_output_path)',
- '--zipalign-path=<(zipalign_path)',
- '--key-path=<(keystore_path)',
- '--key-name=<(keystore_name)',
- '--key-passwd=<(keystore_password)',
- ],
- 'conditions': [
- ['density_splits == 1', {
- 'message': 'Signing/aligning <(_target_name) density splits',
- 'inputs': [
- '<(resource_packaged_apk_path)_hdpi',
- '<(resource_packaged_apk_path)_xhdpi',
- '<(resource_packaged_apk_path)_xxhdpi',
- '<(resource_packaged_apk_path)_xxxhdpi',
- '<(resource_packaged_apk_path)_tvdpi',
- ],
- 'outputs': [
- '<(base_output_path)-density-hdpi.apk',
- '<(base_output_path)-density-xhdpi.apk',
- '<(base_output_path)-density-xxhdpi.apk',
- '<(base_output_path)-density-xxxhdpi.apk',
- '<(base_output_path)-density-tvdpi.apk',
- ],
- 'action': [
- '--densities=hdpi,xhdpi,xxhdpi,xxxhdpi,tvdpi',
- ],
- }],
- ['language_splits != []', {
- 'message': 'Signing/aligning <(_target_name) language splits',
- 'inputs': [
- "<!@(python <(DEPTH)/build/apply_locales.py '<(resource_packaged_apk_path)_ZZLOCALE' <(language_splits))",
- ],
- 'outputs': [
- "<!@(python <(DEPTH)/build/apply_locales.py '<(base_output_path)-lang-ZZLOCALE.apk' <(language_splits))",
- ],
- 'action': [
- '--languages=<(language_splits)',
- ],
- }],
- ],
-}
-
diff --git a/build/android/findbugs_action.gypi b/build/android/findbugs_action.gypi
deleted file mode 100644
index e3b3d36..0000000
--- a/build/android/findbugs_action.gypi
+++ /dev/null
@@ -1,22 +0,0 @@
-
-{
- 'action_name': 'findbugs_<(_target_name)',
- 'message': 'Running findbugs on <(_target_name)',
- 'variables': {
- },
- 'inputs': [
- '<(DEPTH)/build/android/findbugs_diff.py',
- '<(DEPTH)/build/android/findbugs_filter/findbugs_exclude.xml',
- '<(DEPTH)/build/android/pylib/utils/findbugs.py',
- '<(findbugs_target_jar_path)',
- ],
- 'outputs': [
- '<(stamp_path)',
- ],
- 'action': [
- 'python', '<(DEPTH)/build/android/findbugs_diff.py',
- '--auxclasspath-gyp', '>(auxclasspath)',
- '--stamp', '<(stamp_path)',
- '<(findbugs_target_jar_path)',
- ],
-}
diff --git a/build/android/findbugs_diff.py b/build/android/findbugs_diff.py
deleted file mode 100755
index f55e462..0000000
--- a/build/android/findbugs_diff.py
+++ /dev/null
@@ -1,110 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Runs findbugs, and returns an error code if there are new warnings.
-
-Other options
- --only-analyze used to only analyze the class you are interested.
- --relase-build analyze the classes in out/Release directory.
- --findbugs-args used to passin other findbugs's options.
-
-Run
- $CHROMIUM_SRC/third_party/findbugs/bin/findbugs -textui for details.
-
-"""
-
-import argparse
-import os
-import sys
-
-from pylib import constants
-from pylib.utils import findbugs
-
-_DEFAULT_BASE_DIR = os.path.join(
- constants.DIR_SOURCE_ROOT, 'build', 'android', 'findbugs_filter')
-
-sys.path.append(
- os.path.join(constants.DIR_SOURCE_ROOT, 'build', 'android', 'gyp'))
-from util import build_utils
-
-
-def main():
- parser = argparse.ArgumentParser()
-
- parser.add_argument(
- '-a', '--auxclasspath', default=None, dest='auxclasspath',
- help='Set aux classpath for analysis.')
- parser.add_argument(
- '--auxclasspath-gyp', dest='auxclasspath_gyp',
- help='A gyp list containing the aux classpath for analysis')
- parser.add_argument(
- '-o', '--only-analyze', default=None,
- dest='only_analyze', help='Only analyze the given classes and packages.')
- parser.add_argument(
- '-e', '--exclude', default=None, dest='exclude',
- help='Exclude bugs matching given filter.')
- parser.add_argument(
- '-l', '--release-build', action='store_true', dest='release_build',
- help='Analyze release build instead of debug.')
- parser.add_argument(
- '-f', '--findbug-args', default=None, dest='findbug_args',
- help='Additional findbug arguments.')
- parser.add_argument(
- '-b', '--base-dir', default=_DEFAULT_BASE_DIR,
- dest='base_dir', help='Base directory for configuration file.')
- parser.add_argument(
- '--output-file', dest='output_file',
- help='Path to save the output to.')
- parser.add_argument(
- '--stamp', help='Path to touch on success.')
- parser.add_argument(
- '--depfile', help='Path to the depfile. This must be specified as the '
- "action's first output.")
-
- parser.add_argument(
- 'jar_paths', metavar='JAR_PATH', nargs='+',
- help='JAR file to analyze')
-
- args = parser.parse_args(build_utils.ExpandFileArgs(sys.argv[1:]))
- if args.auxclasspath:
- args.auxclasspath = args.auxclasspath.split(':')
- elif args.auxclasspath_gyp:
- args.auxclasspath = build_utils.ParseGypList(args.auxclasspath_gyp)
-
- if args.base_dir:
- if not args.exclude:
- args.exclude = os.path.join(args.base_dir, 'findbugs_exclude.xml')
-
- findbugs_command, findbugs_warnings = findbugs.Run(
- args.exclude, args.only_analyze, args.auxclasspath,
- args.output_file, args.findbug_args, args.jar_paths)
-
- if findbugs_warnings:
- print
- print '*' * 80
- print 'FindBugs run via:'
- print findbugs_command
- print
- print 'FindBugs reported the following issues:'
- for warning in sorted(findbugs_warnings):
- print str(warning)
- print '*' * 80
- print
- else:
- if args.depfile:
- build_utils.WriteDepfile(
- args.depfile,
- build_utils.GetPythonDependencies() + args.auxclasspath
- + args.jar_paths)
- if args.stamp:
- build_utils.Touch(args.stamp)
-
- return len(findbugs_warnings)
-
-
-if __name__ == '__main__':
- sys.exit(main())
-
diff --git a/build/android/findbugs_filter/findbugs_exclude.xml b/build/android/findbugs_filter/findbugs_exclude.xml
deleted file mode 100644
index dbff9d9..0000000
--- a/build/android/findbugs_filter/findbugs_exclude.xml
+++ /dev/null
@@ -1,23 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Copyright (c) 2012 The Chromium Authors. All rights reserved.
- Use of this source code is governed by a BSD-style license that can be
- found in the LICENSE file.
--->
-
-<!--
-Documentation: http://findbugs.sourceforge.net/manual/filter.html
-In particular, ~ at the start of a string means it's a regex.
--->
-<FindBugsFilter>
- <!-- Skip the generated resource classes (including nested classes). -->
- <Match>
- <Class name="~.*\.R(\$\w+)?" />
- </Match>
- <Match>
- <Class name="~org\.chromium\..*\.Manifest(\$\w+)?" />
- </Match>
- <Bug pattern="DM_STRING_CTOR" />
- <!-- Ignore "reliance on default String encoding" warnings, as we're not multi-platform -->
- <Bug pattern="DM_DEFAULT_ENCODING" />
-</FindBugsFilter>
diff --git a/build/android/generate_emma_html.py b/build/android/generate_emma_html.py
deleted file mode 100755
index 93b0b0e..0000000
--- a/build/android/generate_emma_html.py
+++ /dev/null
@@ -1,90 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Aggregates EMMA coverage files to produce html output."""
-
-import fnmatch
-import json
-import optparse
-import os
-import sys
-
-from pylib import cmd_helper
-from pylib import constants
-
-
-def _GetFilesWithExt(root_dir, ext):
- """Gets all files with a given extension.
-
- Args:
- root_dir: Directory in which to search for files.
- ext: Extension to look for (including dot)
-
- Returns:
- A list of absolute paths to files that match.
- """
- files = []
- for root, _, filenames in os.walk(root_dir):
- basenames = fnmatch.filter(filenames, '*.' + ext)
- files.extend([os.path.join(root, basename)
- for basename in basenames])
-
- return files
-
-
-def main():
- option_parser = optparse.OptionParser()
- option_parser.add_option('--output', help='HTML output filename.')
- option_parser.add_option('--coverage-dir', default=None,
- help=('Root of the directory in which to search for '
- 'coverage data (.ec) files.'))
- option_parser.add_option('--metadata-dir', default=None,
- help=('Root of the directory in which to search for '
- 'coverage metadata (.em) files.'))
- option_parser.add_option('--cleanup', action='store_true',
- help=('If set, removes coverage files generated at '
- 'runtime.'))
- options, _ = option_parser.parse_args()
-
- if not (options.coverage_dir and options.metadata_dir and options.output):
- option_parser.error('One or more mandatory options are missing.')
-
- coverage_files = _GetFilesWithExt(options.coverage_dir, 'ec')
- metadata_files = _GetFilesWithExt(options.metadata_dir, 'em')
- print 'Found coverage files: %s' % str(coverage_files)
- print 'Found metadata files: %s' % str(metadata_files)
-
- sources = []
- for f in metadata_files:
- sources_file = os.path.splitext(f)[0] + '_sources.txt'
- with open(sources_file, 'r') as sf:
- sources.extend(json.load(sf))
- sources = [os.path.join(constants.DIR_SOURCE_ROOT, s) for s in sources]
- print 'Sources: %s' % sources
-
- input_args = []
- for f in coverage_files + metadata_files:
- input_args.append('-in')
- input_args.append(f)
-
- output_args = ['-Dreport.html.out.file', options.output]
- source_args = ['-sp', ','.join(sources)]
-
- exit_code = cmd_helper.RunCmd(
- ['java', '-cp',
- os.path.join(constants.ANDROID_SDK_ROOT, 'tools', 'lib', 'emma.jar'),
- 'emma', 'report', '-r', 'html']
- + input_args + output_args + source_args)
-
- if options.cleanup:
- for f in coverage_files:
- os.remove(f)
-
- return exit_code
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/build/android/gn/zip.py b/build/android/gn/zip.py
deleted file mode 100755
index 5050ea0..0000000
--- a/build/android/gn/zip.py
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Archives a set of files.
-"""
-
-import ast
-import optparse
-import os
-import sys
-import zipfile
-
-sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, 'gyp'))
-from util import build_utils
-
-def DoZip(inputs, output, base_dir):
- with zipfile.ZipFile(output, 'w') as outfile:
- for f in inputs:
- outfile.write(f, os.path.relpath(f, base_dir))
-
-def main():
- parser = optparse.OptionParser()
- build_utils.AddDepfileOption(parser)
-
- parser.add_option('--inputs', help='List of files to archive.')
- parser.add_option('--output', help='Path to output archive.')
- parser.add_option('--base-dir',
- help='If provided, the paths in the archive will be '
- 'relative to this directory', default='.')
-
- options, _ = parser.parse_args()
-
- inputs = ast.literal_eval(options.inputs)
- output = options.output
- base_dir = options.base_dir
-
- DoZip(inputs, output, base_dir)
-
- if options.depfile:
- build_utils.WriteDepfile(
- options.depfile,
- build_utils.GetPythonDependencies())
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/build/android/gyp/aidl.py b/build/android/gyp/aidl.py
deleted file mode 100755
index d5aa546..0000000
--- a/build/android/gyp/aidl.py
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Invokes Android's aidl
-"""
-
-import optparse
-import os
-import sys
-
-from util import build_utils
-
-
-def main(argv):
- option_parser = optparse.OptionParser()
- build_utils.AddDepfileOption(option_parser)
- option_parser.add_option('--aidl-path', help='Path to the aidl binary.')
- option_parser.add_option('--imports', help='Files to import.')
- option_parser.add_option('--includes',
- help='Directories to add as import search paths.')
- option_parser.add_option('--srcjar', help='Path for srcjar output.')
- options, args = option_parser.parse_args(argv[1:])
-
- with build_utils.TempDir() as temp_dir:
- for f in args:
- classname = os.path.splitext(os.path.basename(f))[0]
- output = os.path.join(temp_dir, classname + '.java')
- aidl_cmd = [options.aidl_path]
- aidl_cmd += [
- '-p' + s for s in build_utils.ParseGypList(options.imports)
- ]
- if options.includes is not None:
- aidl_cmd += [
- '-I' + s for s in build_utils.ParseGypList(options.includes)
- ]
- aidl_cmd += [
- f,
- output
- ]
- build_utils.CheckOutput(aidl_cmd)
-
- build_utils.ZipDir(options.srcjar, temp_dir)
-
- if options.depfile:
- build_utils.WriteDepfile(
- options.depfile,
- build_utils.GetPythonDependencies())
-
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv))
diff --git a/build/android/gyp/ant.py b/build/android/gyp/ant.py
deleted file mode 100755
index 5394b9e..0000000
--- a/build/android/gyp/ant.py
+++ /dev/null
@@ -1,65 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""An Ant wrapper that suppresses useless Ant output.
-
-Ant build scripts output "BUILD SUCCESSFUL" and build timing at the end of
-every build. In the Android build, this just adds a lot of useless noise to the
-build output. This script forwards its arguments to ant, and prints Ant's
-output up until the BUILD SUCCESSFUL line.
-
-Also, when a command fails, this script will re-run that ant command with the
-'-verbose' argument so that the failure is easier to debug.
-"""
-
-import optparse
-import sys
-import traceback
-
-from util import build_utils
-
-
-def main(argv):
- option_parser = optparse.OptionParser()
- build_utils.AddDepfileOption(option_parser)
- options, args = option_parser.parse_args(argv[1:])
-
- try:
- stdout = build_utils.CheckOutput(['ant'] + args)
- except build_utils.CalledProcessError:
- # It is very difficult to diagnose ant failures without the '-verbose'
- # argument. So, when an ant command fails, re-run it with '-verbose' so that
- # the cause of the failure is easier to identify.
- verbose_args = ['-verbose'] + [a for a in args if a != '-quiet']
- try:
- stdout = build_utils.CheckOutput(['ant'] + verbose_args)
- except build_utils.CalledProcessError:
- traceback.print_exc()
- sys.exit(1)
-
- # If this did sys.exit(1), building again would succeed (which would be
- # awkward). Instead, just print a big warning.
- build_utils.PrintBigWarning(
- 'This is unexpected. `ant ' + ' '.join(args) + '` failed.' +
- 'But, running `ant ' + ' '.join(verbose_args) + '` passed.')
-
- stdout = stdout.strip().split('\n')
- for line in stdout:
- if line.strip() == 'BUILD SUCCESSFUL':
- break
- print line
-
- if options.depfile:
- assert '-buildfile' in args
- ant_buildfile = args[args.index('-buildfile') + 1]
-
- build_utils.WriteDepfile(
- options.depfile,
- [ant_buildfile] + build_utils.GetPythonDependencies())
-
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv))
diff --git a/build/android/gyp/apk_install.py b/build/android/gyp/apk_install.py
deleted file mode 100755
index a512e50..0000000
--- a/build/android/gyp/apk_install.py
+++ /dev/null
@@ -1,118 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Installs an APK.
-
-"""
-
-import optparse
-import os
-import re
-import sys
-
-from util import build_device
-from util import build_utils
-from util import md5_check
-
-BUILD_ANDROID_DIR = os.path.join(os.path.dirname(__file__), '..')
-sys.path.append(BUILD_ANDROID_DIR)
-
-from pylib import constants
-from pylib.utils import apk_helper
-
-
-def GetNewMetadata(device, apk_package):
- """Gets the metadata on the device for the apk_package apk."""
- output = device.RunShellCommand('ls -l /data/app/')
- # Matches lines like:
- # -rw-r--r-- system system 7376582 2013-04-19 16:34 \
- # org.chromium.chrome.shell.apk
- # -rw-r--r-- system system 7376582 2013-04-19 16:34 \
- # org.chromium.chrome.shell-1.apk
- apk_matcher = lambda s: re.match('.*%s(-[0-9]*)?(.apk)?$' % apk_package, s)
- matches = filter(apk_matcher, output)
- return matches[0] if matches else None
-
-def HasInstallMetadataChanged(device, apk_package, metadata_path):
- """Checks if the metadata on the device for apk_package has changed."""
- if not os.path.exists(metadata_path):
- return True
-
- with open(metadata_path, 'r') as expected_file:
- return expected_file.read() != device.GetInstallMetadata(apk_package)
-
-
-def RecordInstallMetadata(device, apk_package, metadata_path):
- """Records the metadata from the device for apk_package."""
- metadata = GetNewMetadata(device, apk_package)
- if not metadata:
- raise Exception('APK install failed unexpectedly.')
-
- with open(metadata_path, 'w') as outfile:
- outfile.write(metadata)
-
-
-def main():
- parser = optparse.OptionParser()
- parser.add_option('--apk-path',
- help='Path to .apk to install.')
- parser.add_option('--split-apk-path',
- help='Path to .apk splits (can specify multiple times, causes '
- '--install-multiple to be used.',
- action='append')
- parser.add_option('--android-sdk-tools',
- help='Path to the Android SDK build tools folder. ' +
- 'Required when using --split-apk-path.')
- parser.add_option('--install-record',
- help='Path to install record (touched only when APK is installed).')
- parser.add_option('--build-device-configuration',
- help='Path to build device configuration.')
- parser.add_option('--stamp',
- help='Path to touch on success.')
- parser.add_option('--configuration-name',
- help='The build CONFIGURATION_NAME')
- options, _ = parser.parse_args()
-
- device = build_device.GetBuildDeviceFromPath(
- options.build_device_configuration)
- if not device:
- return
-
- constants.SetBuildType(options.configuration_name)
-
- serial_number = device.GetSerialNumber()
- apk_package = apk_helper.GetPackageName(options.apk_path)
-
- metadata_path = '%s.%s.device.time.stamp' % (options.apk_path, serial_number)
-
- # If the APK on the device does not match the one that was last installed by
- # the build, then the APK has to be installed (regardless of the md5 record).
- force_install = HasInstallMetadataChanged(device, apk_package, metadata_path)
-
-
- def Install():
- if options.split_apk_path:
- device.InstallSplitApk(options.apk_path, options.split_apk_path)
- else:
- device.Install(options.apk_path, reinstall=True)
-
- RecordInstallMetadata(device, apk_package, metadata_path)
- build_utils.Touch(options.install_record)
-
-
- record_path = '%s.%s.md5.stamp' % (options.apk_path, serial_number)
- md5_check.CallAndRecordIfStale(
- Install,
- record_path=record_path,
- input_paths=[options.apk_path],
- force=force_install)
-
- if options.stamp:
- build_utils.Touch(options.stamp)
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/build/android/gyp/apk_obfuscate.py b/build/android/gyp/apk_obfuscate.py
deleted file mode 100755
index b075758..0000000
--- a/build/android/gyp/apk_obfuscate.py
+++ /dev/null
@@ -1,147 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Generates the obfuscated jar and test jar for an apk.
-
-If proguard is not enabled or 'Release' is not in the configuration name,
-obfuscation will be a no-op.
-"""
-
-import optparse
-import os
-import sys
-
-from util import build_utils
-from util import proguard_util
-
-
-def ParseArgs(argv):
- parser = optparse.OptionParser()
- parser.add_option('--android-sdk', help='path to the Android SDK folder')
- parser.add_option('--android-sdk-tools',
- help='path to the Android SDK build tools folder')
- parser.add_option('--android-sdk-jar',
- help='path to Android SDK\'s android.jar')
- parser.add_option('--proguard-jar-path',
- help='Path to proguard.jar in the sdk')
- parser.add_option('--input-jars-paths',
- help='Path to jars to include in obfuscated jar')
-
- parser.add_option('--proguard-configs',
- help='Paths to proguard config files')
-
- parser.add_option('--configuration-name',
- help='Gyp configuration name (i.e. Debug, Release)')
- parser.add_option('--proguard-enabled', action='store_true',
- help='Set if proguard is enabled for this target.')
-
- parser.add_option('--obfuscated-jar-path',
- help='Output path for obfuscated jar.')
-
- parser.add_option('--testapp', action='store_true',
- help='Set this if building an instrumentation test apk')
- parser.add_option('--tested-apk-obfuscated-jar-path',
- help='Path to obfusctated jar of the tested apk')
- parser.add_option('--test-jar-path',
- help='Output path for jar containing all the test apk\'s '
- 'code.')
-
- parser.add_option('--stamp', help='File to touch on success')
-
- (options, args) = parser.parse_args(argv)
-
- if args:
- parser.error('No positional arguments should be given. ' + str(args))
-
- # Check that required options have been provided.
- required_options = (
- 'android_sdk',
- 'android_sdk_tools',
- 'android_sdk_jar',
- 'proguard_jar_path',
- 'input_jars_paths',
- 'configuration_name',
- 'obfuscated_jar_path',
- )
-
- if options.testapp:
- required_options += (
- 'test_jar_path',
- )
-
- build_utils.CheckOptions(options, parser, required=required_options)
- return options, args
-
-
-def DoProguard(options):
- proguard = proguard_util.ProguardCmdBuilder(options.proguard_jar_path)
- proguard.outjar(options.obfuscated_jar_path)
-
- library_classpath = [options.android_sdk_jar]
- input_jars = build_utils.ParseGypList(options.input_jars_paths)
-
- exclude_paths = []
- configs = build_utils.ParseGypList(options.proguard_configs)
- if options.tested_apk_obfuscated_jar_path:
- # configs should only contain the process_resources.py generated config.
- assert len(configs) == 1, (
- 'test apks should not have custom proguard configs: ' + str(configs))
- tested_jar_info = build_utils.ReadJson(
- options.tested_apk_obfuscated_jar_path + '.info')
- exclude_paths = tested_jar_info['inputs']
- configs = tested_jar_info['configs']
-
- proguard.is_test(True)
- proguard.mapping(options.tested_apk_obfuscated_jar_path + '.mapping')
- library_classpath.append(options.tested_apk_obfuscated_jar_path)
-
- proguard.libraryjars(library_classpath)
- proguard_injars = [p for p in input_jars if p not in exclude_paths]
- proguard.injars(proguard_injars)
- proguard.configs(configs)
-
- proguard.CheckOutput()
-
- this_info = {
- 'inputs': proguard_injars,
- 'configs': configs
- }
-
- build_utils.WriteJson(
- this_info, options.obfuscated_jar_path + '.info')
-
-
-def main(argv):
- options, _ = ParseArgs(argv)
-
- input_jars = build_utils.ParseGypList(options.input_jars_paths)
-
- if options.testapp:
- dependency_class_filters = [
- '*R.class', '*R$*.class', '*Manifest.class', '*BuildConfig.class']
- build_utils.MergeZips(
- options.test_jar_path, input_jars, dependency_class_filters)
-
- if options.configuration_name == 'Release' and options.proguard_enabled:
- DoProguard(options)
- else:
- output_files = [
- options.obfuscated_jar_path,
- options.obfuscated_jar_path + '.info',
- options.obfuscated_jar_path + '.dump',
- options.obfuscated_jar_path + '.seeds',
- options.obfuscated_jar_path + '.usage',
- options.obfuscated_jar_path + '.mapping']
- for f in output_files:
- if os.path.exists(f):
- os.remove(f)
- build_utils.Touch(f)
-
- if options.stamp:
- build_utils.Touch(options.stamp)
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv[1:]))
diff --git a/build/android/gyp/copy_ex.py b/build/android/gyp/copy_ex.py
deleted file mode 100755
index a474e77..0000000
--- a/build/android/gyp/copy_ex.py
+++ /dev/null
@@ -1,77 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Copies files to a directory."""
-
-import optparse
-import os
-import shutil
-import sys
-
-from util import build_utils
-
-
-def _get_all_files(base):
- """Returns a list of all the files in |base|. Each entry is relative to the
- last path entry of |base|."""
- result = []
- dirname = os.path.dirname(base)
- for root, _, files in os.walk(base):
- result.extend([os.path.join(root[len(dirname):], f) for f in files])
- return result
-
-
-def main(args):
- args = build_utils.ExpandFileArgs(args)
-
- parser = optparse.OptionParser()
- build_utils.AddDepfileOption(parser)
-
- parser.add_option('--dest', help='Directory to copy files to.')
- parser.add_option('--files', action='append',
- help='List of files to copy.')
- parser.add_option('--clear', action='store_true',
- help='If set, the destination directory will be deleted '
- 'before copying files to it. This is highly recommended to '
- 'ensure that no stale files are left in the directory.')
- parser.add_option('--stamp', help='Path to touch on success.')
-
- options, _ = parser.parse_args(args)
-
- if options.clear:
- build_utils.DeleteDirectory(options.dest)
- build_utils.MakeDirectory(options.dest)
-
- files = []
- for file_arg in options.files:
- files += build_utils.ParseGypList(file_arg)
-
- deps = []
-
- for f in files:
- if os.path.isdir(f):
- if not options.clear:
- print ('To avoid stale files you must use --clear when copying '
- 'directories')
- sys.exit(-1)
- shutil.copytree(f, os.path.join(options.dest, os.path.basename(f)))
- deps.extend(_get_all_files(f))
- else:
- shutil.copy(f, options.dest)
- deps.append(f)
-
- if options.depfile:
- build_utils.WriteDepfile(
- options.depfile,
- deps + build_utils.GetPythonDependencies())
-
- if options.stamp:
- build_utils.Touch(options.stamp)
-
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv[1:]))
-
diff --git a/build/android/gyp/create_device_library_links.py b/build/android/gyp/create_device_library_links.py
deleted file mode 100755
index 3e630b6..0000000
--- a/build/android/gyp/create_device_library_links.py
+++ /dev/null
@@ -1,114 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Creates symlinks to native libraries for an APK.
-
-The native libraries should have previously been pushed to the device (in
-options.target_dir). This script then creates links in an apk's lib/ folder to
-those native libraries.
-"""
-
-import optparse
-import os
-import sys
-
-from util import build_device
-from util import build_utils
-
-BUILD_ANDROID_DIR = os.path.join(os.path.dirname(__file__), '..')
-sys.path.append(BUILD_ANDROID_DIR)
-
-from pylib import constants
-from pylib.utils import apk_helper
-
-def RunShellCommand(device, cmd):
- output = device.RunShellCommand(cmd)
-
- if output:
- raise Exception(
- 'Unexpected output running command: ' + cmd + '\n' +
- '\n'.join(output))
-
-
-def CreateSymlinkScript(options):
- libraries = build_utils.ParseGypList(options.libraries)
-
- link_cmd = (
- 'rm $APK_LIBRARIES_DIR/%(lib_basename)s > /dev/null 2>&1 \n'
- 'ln -s $STRIPPED_LIBRARIES_DIR/%(lib_basename)s '
- '$APK_LIBRARIES_DIR/%(lib_basename)s \n'
- )
-
- script = '#!/bin/sh \n'
-
- for lib in libraries:
- script += link_cmd % { 'lib_basename': lib }
-
- with open(options.script_host_path, 'w') as scriptfile:
- scriptfile.write(script)
-
-
-def TriggerSymlinkScript(options):
- device = build_device.GetBuildDeviceFromPath(
- options.build_device_configuration)
- if not device:
- return
-
- apk_package = apk_helper.GetPackageName(options.apk)
- apk_libraries_dir = '/data/data/%s/lib' % apk_package
-
- device_dir = os.path.dirname(options.script_device_path)
- mkdir_cmd = ('if [ ! -e %(dir)s ]; then mkdir -p %(dir)s; fi ' %
- { 'dir': device_dir })
- RunShellCommand(device, mkdir_cmd)
- device.PushChangedFiles([(options.script_host_path,
- options.script_device_path)])
-
- trigger_cmd = (
- 'APK_LIBRARIES_DIR=%(apk_libraries_dir)s; '
- 'STRIPPED_LIBRARIES_DIR=%(target_dir)s; '
- '. %(script_device_path)s'
- ) % {
- 'apk_libraries_dir': apk_libraries_dir,
- 'target_dir': options.target_dir,
- 'script_device_path': options.script_device_path
- }
- RunShellCommand(device, trigger_cmd)
-
-
-def main(args):
- args = build_utils.ExpandFileArgs(args)
- parser = optparse.OptionParser()
- parser.add_option('--apk', help='Path to the apk.')
- parser.add_option('--script-host-path',
- help='Path on the host for the symlink script.')
- parser.add_option('--script-device-path',
- help='Path on the device to push the created symlink script.')
- parser.add_option('--libraries',
- help='List of native libraries.')
- parser.add_option('--target-dir',
- help='Device directory that contains the target libraries for symlinks.')
- parser.add_option('--stamp', help='Path to touch on success.')
- parser.add_option('--build-device-configuration',
- help='Path to build device configuration.')
- parser.add_option('--configuration-name',
- help='The build CONFIGURATION_NAME')
- options, _ = parser.parse_args(args)
-
- required_options = ['apk', 'libraries', 'script_host_path',
- 'script_device_path', 'target_dir', 'configuration_name']
- build_utils.CheckOptions(options, parser, required=required_options)
- constants.SetBuildType(options.configuration_name)
-
- CreateSymlinkScript(options)
- TriggerSymlinkScript(options)
-
- if options.stamp:
- build_utils.Touch(options.stamp)
-
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv[1:]))
diff --git a/build/android/gyp/create_dist_jar.py b/build/android/gyp/create_dist_jar.py
deleted file mode 100755
index 0d31c5d..0000000
--- a/build/android/gyp/create_dist_jar.py
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Merges a list of jars into a single jar."""
-
-import optparse
-import sys
-
-from util import build_utils
-
-def main(args):
- args = build_utils.ExpandFileArgs(args)
- parser = optparse.OptionParser()
- build_utils.AddDepfileOption(parser)
- parser.add_option('--output', help='Path to output jar.')
- parser.add_option('--inputs', action='append', help='List of jar inputs.')
- options, _ = parser.parse_args(args)
- build_utils.CheckOptions(options, parser, ['output', 'inputs'])
-
- input_jars = []
- for inputs_arg in options.inputs:
- input_jars.extend(build_utils.ParseGypList(inputs_arg))
-
- build_utils.MergeZips(options.output, input_jars)
-
- if options.depfile:
- build_utils.WriteDepfile(
- options.depfile,
- input_jars + build_utils.GetPythonDependencies())
-
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv[1:]))
diff --git a/build/android/gyp/create_flutter_jar.py b/build/android/gyp/create_flutter_jar.py
deleted file mode 100644
index c30bae2..0000000
--- a/build/android/gyp/create_flutter_jar.py
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2016 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Create a JAR incorporating all the components required to build a Flutter application"""
-
-import optparse
-import os
-import sys
-import zipfile
-
-from util import build_utils
-
-def main(args):
- args = build_utils.ExpandFileArgs(args)
- parser = optparse.OptionParser()
- build_utils.AddDepfileOption(parser)
- parser.add_option('--output', help='Path to output jar.')
- parser.add_option('--dist_jar', help='Flutter shell Java code jar.')
- parser.add_option('--native_lib', action='append', help='Native code library.')
- parser.add_option('--android_abi', help='Native code ABI.')
- parser.add_option('--asset_dir', help='Path to assets.')
- options, _ = parser.parse_args(args)
- build_utils.CheckOptions(options, parser, [
- 'output', 'dist_jar', 'native_lib', 'android_abi', 'asset_dir'
- ])
-
- input_deps = []
-
- with zipfile.ZipFile(options.output, 'w', zipfile.ZIP_DEFLATED) as out_zip:
- input_deps.append(options.dist_jar)
- with zipfile.ZipFile(options.dist_jar, 'r') as dist_zip:
- for dist_file in dist_zip.infolist():
- if dist_file.filename.endswith('.class'):
- out_zip.writestr(dist_file.filename, dist_zip.read(dist_file.filename))
-
- for native_lib in options.native_lib:
- input_deps.append(native_lib)
- out_zip.write(native_lib,
- 'lib/%s/%s' % (options.android_abi, os.path.basename(native_lib)))
-
- for asset_file in os.listdir(options.asset_dir):
- input_deps.append(asset_file)
- out_zip.write(os.path.join(options.asset_dir, asset_file),
- 'assets/%s' % asset_file)
-
- if options.depfile:
- build_utils.WriteDepfile(
- options.depfile,
- input_deps + build_utils.GetPythonDependencies())
-
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv[1:]))
diff --git a/build/android/gyp/create_java_binary_script.py b/build/android/gyp/create_java_binary_script.py
deleted file mode 100755
index 5de43f2..0000000
--- a/build/android/gyp/create_java_binary_script.py
+++ /dev/null
@@ -1,77 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Creates a simple script to run a java "binary".
-
-This creates a script that sets up the java command line for running a java
-jar. This includes correctly setting the classpath and the main class.
-"""
-
-import optparse
-import os
-import sys
-
-from util import build_utils
-
-# The java command must be executed in the current directory because there may
-# be user-supplied paths in the args. The script receives the classpath relative
-# to the directory that the script is written in and then, when run, must
-# recalculate the paths relative to the current directory.
-script_template = """\
-#!/usr/bin/env python
-#
-# This file was generated by build/android/gyp/create_java_binary_script.py
-
-import os
-import sys
-
-self_dir = os.path.dirname(__file__)
-classpath = [{classpath}]
-if os.getcwd() != self_dir:
- offset = os.path.relpath(self_dir, os.getcwd())
- classpath = [os.path.join(offset, p) for p in classpath]
-java_args = [
- "java",
- "-classpath", ":".join(classpath),
- "-enableassertions",
- \"{main_class}\"] + sys.argv[1:]
-os.execvp("java", java_args)
-"""
-
-def main(argv):
- argv = build_utils.ExpandFileArgs(argv)
- parser = optparse.OptionParser()
- build_utils.AddDepfileOption(parser)
- parser.add_option('--output', help='Output path for executable script.')
- parser.add_option('--jar-path', help='Path to the main jar.')
- parser.add_option('--main-class',
- help='Name of the java class with the "main" entry point.')
- parser.add_option('--classpath', action='append',
- help='Classpath for running the jar.')
- options, _ = parser.parse_args(argv)
-
- classpath = [options.jar_path]
- for cp_arg in options.classpath:
- classpath += build_utils.ParseGypList(cp_arg)
-
- run_dir = os.path.dirname(options.output)
- classpath = [os.path.relpath(p, run_dir) for p in classpath]
-
- with open(options.output, 'w') as script:
- script.write(script_template.format(
- classpath=('"%s"' % '", "'.join(classpath)),
- main_class=options.main_class))
-
- os.chmod(options.output, 0750)
-
- if options.depfile:
- build_utils.WriteDepfile(
- options.depfile,
- build_utils.GetPythonDependencies())
-
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv[1:]))
diff --git a/build/android/gyp/create_placeholder_files.py b/build/android/gyp/create_placeholder_files.py
deleted file mode 100755
index 103e1df..0000000
--- a/build/android/gyp/create_placeholder_files.py
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Create placeholder files.
-"""
-
-import optparse
-import os
-import sys
-
-from util import build_utils
-
-def main():
- parser = optparse.OptionParser()
- parser.add_option(
- '--dest-lib-dir',
- help='Destination directory to have placeholder files.')
- parser.add_option(
- '--stamp',
- help='Path to touch on success')
-
- options, args = parser.parse_args()
-
- for name in args:
- target_path = os.path.join(options.dest_lib_dir, name)
- build_utils.Touch(target_path)
-
- if options.stamp:
- build_utils.Touch(options.stamp)
-
-if __name__ == '__main__':
- sys.exit(main())
-
diff --git a/build/android/gyp/create_standalone_apk.py b/build/android/gyp/create_standalone_apk.py
deleted file mode 100755
index c560599..0000000
--- a/build/android/gyp/create_standalone_apk.py
+++ /dev/null
@@ -1,60 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Combines stripped libraries and incomplete APK into single standalone APK.
-
-"""
-
-import optparse
-import os
-import shutil
-import sys
-import tempfile
-
-from util import build_utils
-from util import md5_check
-
-def CreateStandaloneApk(options):
- def DoZip():
- with tempfile.NamedTemporaryFile(suffix='.zip') as intermediate_file:
- intermediate_path = intermediate_file.name
- shutil.copy(options.input_apk_path, intermediate_path)
- apk_path_abs = os.path.abspath(intermediate_path)
- build_utils.CheckOutput(
- ['zip', '-r', '-1', apk_path_abs, 'lib'],
- cwd=options.libraries_top_dir)
- shutil.copy(intermediate_path, options.output_apk_path)
-
- input_paths = [options.input_apk_path, options.libraries_top_dir]
- record_path = '%s.standalone.stamp' % options.input_apk_path
- md5_check.CallAndRecordIfStale(
- DoZip,
- record_path=record_path,
- input_paths=input_paths)
-
-
-def main():
- parser = optparse.OptionParser()
- parser.add_option('--libraries-top-dir',
- help='Top directory that contains libraries '
- '(i.e. library paths are like '
- 'libraries_top_dir/lib/android_app_abi/foo.so).')
- parser.add_option('--input-apk-path', help='Path to incomplete APK.')
- parser.add_option('--output-apk-path', help='Path for standalone APK.')
- parser.add_option('--stamp', help='Path to touch on success.')
- options, _ = parser.parse_args()
-
- required_options = ['libraries_top_dir', 'input_apk_path', 'output_apk_path']
- build_utils.CheckOptions(options, parser, required=required_options)
-
- CreateStandaloneApk(options)
-
- if options.stamp:
- build_utils.Touch(options.stamp)
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/build/android/gyp/create_test_runner_script.py b/build/android/gyp/create_test_runner_script.py
deleted file mode 100755
index 247bf20..0000000
--- a/build/android/gyp/create_test_runner_script.py
+++ /dev/null
@@ -1,96 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Creates a script to run an android test using build/android/test_runner.py.
-"""
-
-import argparse
-import os
-import sys
-
-from util import build_utils
-
-SCRIPT_TEMPLATE = """\
-#!/usr/bin/env python
-#
-# This file was generated by build/android/gyp/create_test_runner_script.py
-
-import logging
-import os
-import sys
-
-def main():
- script_directory = os.path.dirname(__file__)
-
- def ResolvePath(path):
- \"\"\"Returns an absolute filepath given a path relative to this script.
- \"\"\"
- return os.path.abspath(os.path.join(script_directory, path))
-
- test_runner_path = ResolvePath('{test_runner_path}')
- test_runner_args = {test_runner_args}
- test_runner_path_args = {test_runner_path_args}
- for arg, path in test_runner_path_args.iteritems():
- test_runner_args.extend([arg, ResolvePath(path)])
-
- test_runner_cmd = ' '.join(
- [test_runner_path] + test_runner_args + sys.argv[1:])
- logging.critical(test_runner_cmd)
- os.system(test_runner_cmd)
-
-if __name__ == '__main__':
- sys.exit(main())
-"""
-
-def main():
- parser = argparse.ArgumentParser()
- parser.add_argument('--script-output-path',
- help='Output path for executable script.')
- parser.add_argument('--depfile',
- help='Path to the depfile. This must be specified as '
- "the action's first output.")
- # We need to intercept any test runner path arguments and make all
- # of the paths relative to the output script directory.
- group = parser.add_argument_group('Test runner path arguments.')
- group.add_argument('--output-directory')
- group.add_argument('--isolate-file-path')
- group.add_argument('--support-apk')
- args, test_runner_args = parser.parse_known_args()
-
- def RelativizePathToScript(path):
- """Returns the path relative to the output script directory."""
- return os.path.relpath(path, os.path.dirname(args.script_output_path))
-
- test_runner_path = os.path.join(
- os.path.dirname(__file__), os.path.pardir, 'test_runner.py')
- test_runner_path = RelativizePathToScript(test_runner_path)
-
- test_runner_path_args = {}
- if args.output_directory:
- test_runner_path_args['--output-directory'] = RelativizePathToScript(
- args.output_directory)
- if args.isolate_file_path:
- test_runner_path_args['--isolate-file-path'] = RelativizePathToScript(
- args.isolate_file_path)
- if args.support_apk:
- test_runner_path_args['--support-apk'] = RelativizePathToScript(
- args.support_apk)
-
- with open(args.script_output_path, 'w') as script:
- script.write(SCRIPT_TEMPLATE.format(
- test_runner_path=str(test_runner_path),
- test_runner_args=str(test_runner_args),
- test_runner_path_args=str(test_runner_path_args)))
-
- os.chmod(args.script_output_path, 0750)
-
- if args.depfile:
- build_utils.WriteDepfile(
- args.depfile,
- build_utils.GetPythonDependencies())
-
-if __name__ == '__main__':
- sys.exit(main())
\ No newline at end of file
diff --git a/build/android/gyp/dex.py b/build/android/gyp/dex.py
deleted file mode 100755
index c26d23a..0000000
--- a/build/android/gyp/dex.py
+++ /dev/null
@@ -1,89 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import optparse
-import os
-import sys
-
-from util import build_utils
-from util import md5_check
-
-
-def DoDex(options, paths):
- dx_binary = os.path.join(options.android_sdk_tools, 'dx')
- # See http://crbug.com/272064 for context on --force-jumbo.
- dex_cmd = [dx_binary, '--dex', '--force-jumbo', '--output', options.dex_path]
- if options.no_locals != '0':
- dex_cmd.append('--no-locals')
-
- dex_cmd += paths
-
- record_path = '%s.md5.stamp' % options.dex_path
- md5_check.CallAndRecordIfStale(
- lambda: build_utils.CheckOutput(dex_cmd, print_stderr=False),
- record_path=record_path,
- input_paths=paths,
- input_strings=dex_cmd,
- force=not os.path.exists(options.dex_path))
- build_utils.WriteJson(
- [os.path.relpath(p, options.output_directory) for p in paths],
- options.dex_path + '.inputs')
-
-
-def main():
- args = build_utils.ExpandFileArgs(sys.argv[1:])
-
- parser = optparse.OptionParser()
- build_utils.AddDepfileOption(parser)
-
- parser.add_option('--android-sdk-tools',
- help='Android sdk build tools directory.')
- parser.add_option('--output-directory',
- default=os.getcwd(),
- help='Path to the output build directory.')
- parser.add_option('--dex-path', help='Dex output path.')
- parser.add_option('--configuration-name',
- help='The build CONFIGURATION_NAME.')
- parser.add_option('--proguard-enabled',
- help='"true" if proguard is enabled.')
- parser.add_option('--proguard-enabled-input-path',
- help=('Path to dex in Release mode when proguard '
- 'is enabled.'))
- parser.add_option('--no-locals',
- help='Exclude locals list from the dex file.')
- parser.add_option('--inputs', help='A list of additional input paths.')
- parser.add_option('--excluded-paths',
- help='A list of paths to exclude from the dex file.')
-
- options, paths = parser.parse_args(args)
-
- required_options = ('android_sdk_tools',)
- build_utils.CheckOptions(options, parser, required=required_options)
-
- if (options.proguard_enabled == 'true'
- and options.configuration_name == 'Release'):
- paths = [options.proguard_enabled_input_path]
-
- if options.inputs:
- paths += build_utils.ParseGypList(options.inputs)
-
- if options.excluded_paths:
- # Excluded paths are relative to the output directory.
- exclude_paths = build_utils.ParseGypList(options.excluded_paths)
- paths = [p for p in paths if not
- os.path.relpath(p, options.output_directory) in exclude_paths]
-
- DoDex(options, paths)
-
- if options.depfile:
- build_utils.WriteDepfile(
- options.depfile,
- paths + build_utils.GetPythonDependencies())
-
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/build/android/gyp/emma_instr.py b/build/android/gyp/emma_instr.py
deleted file mode 100755
index 6f3555a..0000000
--- a/build/android/gyp/emma_instr.py
+++ /dev/null
@@ -1,207 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Instruments classes and jar files.
-
-This script corresponds to the 'emma_instr' action in the java build process.
-Depending on whether emma_instrument is set, the 'emma_instr' action will either
-call one of the instrument commands, or the copy command.
-
-Possible commands are:
-- instrument_jar: Accepts a jar and instruments it using emma.jar.
-- instrument_classes: Accepts a directory containing java classes and
- instruments it using emma.jar.
-- copy: Called when EMMA coverage is not enabled. This allows us to make
- this a required step without necessarily instrumenting on every build.
- Also removes any stale coverage files.
-"""
-
-import collections
-import json
-import os
-import shutil
-import sys
-import tempfile
-
-sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir))
-from pylib.utils import command_option_parser
-
-from util import build_utils
-
-
-def _AddCommonOptions(option_parser):
- """Adds common options to |option_parser|."""
- option_parser.add_option('--input-path',
- help=('Path to input file(s). Either the classes '
- 'directory, or the path to a jar.'))
- option_parser.add_option('--output-path',
- help=('Path to output final file(s) to. Either the '
- 'final classes directory, or the directory in '
- 'which to place the instrumented/copied jar.'))
- option_parser.add_option('--stamp', help='Path to touch when done.')
- option_parser.add_option('--coverage-file',
- help='File to create with coverage metadata.')
- option_parser.add_option('--sources-file',
- help='File to create with the list of sources.')
-
-
-def _AddInstrumentOptions(option_parser):
- """Adds options related to instrumentation to |option_parser|."""
- _AddCommonOptions(option_parser)
- option_parser.add_option('--sources',
- help='Space separated list of sources.')
- option_parser.add_option('--src-root',
- help='Root of the src repository.')
- option_parser.add_option('--emma-jar',
- help='Path to emma.jar.')
- option_parser.add_option(
- '--filter-string', default='',
- help=('Filter string consisting of a list of inclusion/exclusion '
- 'patterns separated with whitespace and/or comma.'))
-
-
-def _RunCopyCommand(_command, options, _, option_parser):
- """Copies the jar from input to output locations.
-
- Also removes any old coverage/sources file.
-
- Args:
- command: String indicating the command that was received to trigger
- this function.
- options: optparse options dictionary.
- args: List of extra args from optparse.
- option_parser: optparse.OptionParser object.
-
- Returns:
- An exit code.
- """
- if not (options.input_path and options.output_path and
- options.coverage_file and options.sources_file):
- option_parser.error('All arguments are required.')
-
- coverage_file = os.path.join(os.path.dirname(options.output_path),
- options.coverage_file)
- sources_file = os.path.join(os.path.dirname(options.output_path),
- options.sources_file)
- if os.path.exists(coverage_file):
- os.remove(coverage_file)
- if os.path.exists(sources_file):
- os.remove(sources_file)
-
- if os.path.isdir(options.input_path):
- shutil.rmtree(options.output_path, ignore_errors=True)
- shutil.copytree(options.input_path, options.output_path)
- else:
- shutil.copy(options.input_path, options.output_path)
-
- if options.stamp:
- build_utils.Touch(options.stamp)
-
-
-def _CreateSourcesFile(sources_string, sources_file, src_root):
- """Adds all normalized source directories to |sources_file|.
-
- Args:
- sources_string: String generated from gyp containing the list of sources.
- sources_file: File into which to write the JSON list of sources.
- src_root: Root which sources added to the file should be relative to.
-
- Returns:
- An exit code.
- """
- src_root = os.path.abspath(src_root)
- sources = build_utils.ParseGypList(sources_string)
- relative_sources = []
- for s in sources:
- abs_source = os.path.abspath(s)
- if abs_source[:len(src_root)] != src_root:
- print ('Error: found source directory not under repository root: %s %s'
- % (abs_source, src_root))
- return 1
- rel_source = os.path.relpath(abs_source, src_root)
-
- relative_sources.append(rel_source)
-
- with open(sources_file, 'w') as f:
- json.dump(relative_sources, f)
-
-
-def _RunInstrumentCommand(command, options, _, option_parser):
- """Instruments the classes/jar files using EMMA.
-
- Args:
- command: 'instrument_jar' or 'instrument_classes'. This distinguishes
- whether we copy the output from the created lib/ directory, or classes/
- directory.
- options: optparse options dictionary.
- args: List of extra args from optparse.
- option_parser: optparse.OptionParser object.
-
- Returns:
- An exit code.
- """
- if not (options.input_path and options.output_path and
- options.coverage_file and options.sources_file and options.sources and
- options.src_root and options.emma_jar):
- option_parser.error('All arguments are required.')
-
- coverage_file = os.path.join(os.path.dirname(options.output_path),
- options.coverage_file)
- sources_file = os.path.join(os.path.dirname(options.output_path),
- options.sources_file)
- if os.path.exists(coverage_file):
- os.remove(coverage_file)
- temp_dir = tempfile.mkdtemp()
- try:
- cmd = ['java', '-cp', options.emma_jar,
- 'emma', 'instr',
- '-ip', options.input_path,
- '-ix', options.filter_string,
- '-d', temp_dir,
- '-out', coverage_file,
- '-m', 'fullcopy']
- build_utils.CheckOutput(cmd)
-
- if command == 'instrument_jar':
- for jar in os.listdir(os.path.join(temp_dir, 'lib')):
- shutil.copy(os.path.join(temp_dir, 'lib', jar),
- options.output_path)
- else: # 'instrument_classes'
- if os.path.isdir(options.output_path):
- shutil.rmtree(options.output_path, ignore_errors=True)
- shutil.copytree(os.path.join(temp_dir, 'classes'),
- options.output_path)
- finally:
- shutil.rmtree(temp_dir)
-
- _CreateSourcesFile(options.sources, sources_file, options.src_root)
-
- if options.stamp:
- build_utils.Touch(options.stamp)
-
- return 0
-
-
-CommandFunctionTuple = collections.namedtuple(
- 'CommandFunctionTuple', ['add_options_func', 'run_command_func'])
-VALID_COMMANDS = {
- 'copy': CommandFunctionTuple(_AddCommonOptions,
- _RunCopyCommand),
- 'instrument_jar': CommandFunctionTuple(_AddInstrumentOptions,
- _RunInstrumentCommand),
- 'instrument_classes': CommandFunctionTuple(_AddInstrumentOptions,
- _RunInstrumentCommand),
-}
-
-
-def main():
- option_parser = command_option_parser.CommandOptionParser(
- commands_dict=VALID_COMMANDS)
- command_option_parser.ParseAndExecute(option_parser)
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/build/android/gyp/finalize_apk.py b/build/android/gyp/finalize_apk.py
deleted file mode 100755
index 0a80035..0000000
--- a/build/android/gyp/finalize_apk.py
+++ /dev/null
@@ -1,132 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-"""Signs and zipaligns APK.
-
-"""
-
-import optparse
-import shutil
-import sys
-import tempfile
-
-from util import build_utils
-
-def RenameInflateAndAddPageAlignment(
- rezip_apk_jar_path, in_zip_file, out_zip_file):
- rezip_apk_cmd = [
- 'java',
- '-classpath',
- rezip_apk_jar_path,
- 'RezipApk',
- 'renamealign',
- in_zip_file,
- out_zip_file,
- ]
- build_utils.CheckOutput(rezip_apk_cmd)
-
-
-def ReorderAndAlignApk(rezip_apk_jar_path, in_zip_file, out_zip_file):
- rezip_apk_cmd = [
- 'java',
- '-classpath',
- rezip_apk_jar_path,
- 'RezipApk',
- 'reorder',
- in_zip_file,
- out_zip_file,
- ]
- build_utils.CheckOutput(rezip_apk_cmd)
-
-
-def JarSigner(key_path, key_name, key_passwd, unsigned_path, signed_path):
- shutil.copy(unsigned_path, signed_path)
- sign_cmd = [
- 'jarsigner',
- '-sigalg', 'MD5withRSA',
- '-digestalg', 'SHA1',
- '-keystore', key_path,
- '-storepass', key_passwd,
- signed_path,
- key_name,
- ]
- build_utils.CheckOutput(sign_cmd)
-
-
-def AlignApk(zipalign_path, unaligned_path, final_path):
- align_cmd = [
- zipalign_path,
- '-f', '4', # 4 bytes
- unaligned_path,
- final_path,
- ]
- build_utils.CheckOutput(align_cmd)
-
-
-def main():
- parser = optparse.OptionParser()
- build_utils.AddDepfileOption(parser)
-
- parser.add_option('--rezip-apk-jar-path',
- help='Path to the RezipApk jar file.')
- parser.add_option('--zipalign-path', help='Path to the zipalign tool.')
- parser.add_option('--unsigned-apk-path', help='Path to input unsigned APK.')
- parser.add_option('--final-apk-path',
- help='Path to output signed and aligned APK.')
- parser.add_option('--key-path', help='Path to keystore for signing.')
- parser.add_option('--key-passwd', help='Keystore password')
- parser.add_option('--key-name', help='Keystore name')
- parser.add_option('--stamp', help='Path to touch on success.')
- parser.add_option('--load-library-from-zip', type='int',
- help='If non-zero, build the APK such that the library can be loaded ' +
- 'directly from the zip file using the crazy linker. The library ' +
- 'will be renamed, uncompressed and page aligned.')
-
- options, _ = parser.parse_args()
-
- FinalizeApk(options)
-
- if options.depfile:
- build_utils.WriteDepfile(
- options.depfile, build_utils.GetPythonDependencies())
-
- if options.stamp:
- build_utils.Touch(options.stamp)
-
-
-def FinalizeApk(options):
- with tempfile.NamedTemporaryFile() as signed_apk_path_tmp, \
- tempfile.NamedTemporaryFile() as apk_to_sign_tmp:
-
- if options.load_library_from_zip:
- # We alter the name of the library so that the Android Package Manager
- # does not extract it into a separate file. This must be done before
- # signing, as the filename is part of the signed manifest. At the same
- # time we uncompress the library, which is necessary so that it can be
- # loaded directly from the APK.
- # Move the library to a page boundary by adding a page alignment file.
- apk_to_sign = apk_to_sign_tmp.name
- RenameInflateAndAddPageAlignment(
- options.rezip_apk_jar_path, options.unsigned_apk_path, apk_to_sign)
- else:
- apk_to_sign = options.unsigned_apk_path
-
- signed_apk_path = signed_apk_path_tmp.name
- JarSigner(options.key_path, options.key_name, options.key_passwd,
- apk_to_sign, signed_apk_path)
-
- if options.load_library_from_zip:
- # Reorder the contents of the APK. This re-establishes the canonical
- # order which means the library will be back at its page aligned location.
- # This step also aligns uncompressed items to 4 bytes.
- ReorderAndAlignApk(
- options.rezip_apk_jar_path, signed_apk_path, options.final_apk_path)
- else:
- # Align uncompressed items to 4 bytes
- AlignApk(options.zipalign_path, signed_apk_path, options.final_apk_path)
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/build/android/gyp/finalize_splits.py b/build/android/gyp/finalize_splits.py
deleted file mode 100755
index a6796bb..0000000
--- a/build/android/gyp/finalize_splits.py
+++ /dev/null
@@ -1,52 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-"""Signs and zipaligns split APKs.
-
-This script is require only by GYP (not GN).
-"""
-
-import optparse
-import sys
-
-import finalize_apk
-from util import build_utils
-
-def main():
- parser = optparse.OptionParser()
- parser.add_option('--zipalign-path', help='Path to the zipalign tool.')
- parser.add_option('--resource-packaged-apk-path',
- help='Base path to input .ap_s.')
- parser.add_option('--base-output-path',
- help='Path to output .apk, minus extension.')
- parser.add_option('--key-path', help='Path to keystore for signing.')
- parser.add_option('--key-passwd', help='Keystore password')
- parser.add_option('--key-name', help='Keystore name')
- parser.add_option('--densities',
- help='Comma separated list of densities finalize.')
- parser.add_option('--languages',
- help='GYP list of language splits to finalize.')
-
- options, _ = parser.parse_args()
- options.load_library_from_zip = 0
-
- if options.densities:
- for density in options.densities.split(','):
- options.unsigned_apk_path = ("%s_%s" %
- (options.resource_packaged_apk_path, density))
- options.final_apk_path = ("%s-density-%s.apk" %
- (options.base_output_path, density))
- finalize_apk.FinalizeApk(options)
-
- if options.languages:
- for lang in build_utils.ParseGypList(options.languages):
- options.unsigned_apk_path = ("%s_%s" %
- (options.resource_packaged_apk_path, lang))
- options.final_apk_path = ("%s-lang-%s.apk" %
- (options.base_output_path, lang))
- finalize_apk.FinalizeApk(options)
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/build/android/gyp/find.py b/build/android/gyp/find.py
deleted file mode 100755
index a9f1d49..0000000
--- a/build/android/gyp/find.py
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Finds files in directories.
-"""
-
-import fnmatch
-import optparse
-import os
-import sys
-
-
-def main(argv):
- parser = optparse.OptionParser()
- parser.add_option('--pattern', default='*', help='File pattern to match.')
- options, directories = parser.parse_args(argv)
-
- for d in directories:
- if not os.path.exists(d):
- print >> sys.stderr, '%s does not exist' % d
- return 1
- for root, _, filenames in os.walk(d):
- for f in fnmatch.filter(filenames, options.pattern):
- print os.path.join(root, f)
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv[1:]))
diff --git a/build/android/gyp/find_sun_tools_jar.py b/build/android/gyp/find_sun_tools_jar.py
deleted file mode 100755
index 2f15a15..0000000
--- a/build/android/gyp/find_sun_tools_jar.py
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""This finds the java distribution's tools.jar and copies it somewhere.
-"""
-
-import argparse
-import os
-import re
-import shutil
-import sys
-
-from util import build_utils
-
-RT_JAR_FINDER = re.compile(r'\[Opened (.*)/jre/lib/rt.jar\]')
-
-def main():
- parser = argparse.ArgumentParser(description='Find Sun Tools Jar')
- parser.add_argument('--depfile',
- help='Path to depfile. This must be specified as the '
- 'action\'s first output.')
- parser.add_argument('--output', required=True)
- args = parser.parse_args()
-
- sun_tools_jar_path = FindSunToolsJarPath()
-
- if sun_tools_jar_path is None:
- raise Exception("Couldn\'t find tools.jar")
-
- # Using copyfile instead of copy() because copy() calls copymode()
- # We don't want the locked mode because we may copy over this file again
- shutil.copyfile(sun_tools_jar_path, args.output)
-
- if args.depfile:
- build_utils.WriteDepfile(
- args.depfile,
- [sun_tools_jar_path] + build_utils.GetPythonDependencies())
-
-
-def FindSunToolsJarPath():
- # This works with at least openjdk 1.6, 1.7 and sun java 1.6, 1.7
- stdout = build_utils.CheckOutput(
- ["java", "-verbose", "-version"], print_stderr=False)
- for ln in stdout.splitlines():
- match = RT_JAR_FINDER.match(ln)
- if match:
- return os.path.join(match.group(1), 'lib', 'tools.jar')
-
- return None
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/build/android/gyp/gcc_preprocess.py b/build/android/gyp/gcc_preprocess.py
deleted file mode 100755
index 03becf9..0000000
--- a/build/android/gyp/gcc_preprocess.py
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import optparse
-import os
-import sys
-
-from util import build_utils
-
-def DoGcc(options):
- build_utils.MakeDirectory(os.path.dirname(options.output))
-
- gcc_cmd = [ 'gcc' ] # invoke host gcc.
- if options.defines:
- gcc_cmd.extend(sum(map(lambda w: ['-D', w], options.defines), []))
- gcc_cmd.extend([
- '-E', # stop after preprocessing.
- '-D', 'ANDROID', # Specify ANDROID define for pre-processor.
- '-x', 'c-header', # treat sources as C header files
- '-P', # disable line markers, i.e. '#line 309'
- '-I', options.include_path,
- '-o', options.output,
- options.template
- ])
-
- build_utils.CheckOutput(gcc_cmd)
-
-
-def main(args):
- args = build_utils.ExpandFileArgs(args)
-
- parser = optparse.OptionParser()
- build_utils.AddDepfileOption(parser)
-
- parser.add_option('--include-path', help='Include path for gcc.')
- parser.add_option('--template', help='Path to template.')
- parser.add_option('--output', help='Path for generated file.')
- parser.add_option('--stamp', help='Path to touch on success.')
- parser.add_option('--defines', help='Pre-defines macros', action='append')
-
- options, _ = parser.parse_args(args)
-
- DoGcc(options)
-
- if options.depfile:
- build_utils.WriteDepfile(
- options.depfile,
- build_utils.GetPythonDependencies())
-
- if options.stamp:
- build_utils.Touch(options.stamp)
-
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv[1:]))
diff --git a/build/android/gyp/generate_split_manifest.py b/build/android/gyp/generate_split_manifest.py
deleted file mode 100755
index 9cb3bca..0000000
--- a/build/android/gyp/generate_split_manifest.py
+++ /dev/null
@@ -1,97 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-"""Creates an AndroidManifest.xml for an APK split.
-
-Given the manifest file for the main APK, generates an AndroidManifest.xml with
-the value required for a Split APK (package, versionCode, etc).
-"""
-
-import optparse
-import xml.etree.ElementTree
-
-from util import build_utils
-
-MANIFEST_TEMPLATE = """<?xml version="1.0" encoding="utf-8"?>
-<manifest
- xmlns:android="http://schemas.android.com/apk/res/android"
- package="%(package)s"
- split="%(split)s">
- <uses-sdk android:minSdkVersion="21" />
- <application android:hasCode="%(has_code)s">
- </application>
-</manifest>
-"""
-
-def ParseArgs():
- """Parses command line options.
-
- Returns:
- An options object as from optparse.OptionsParser.parse_args()
- """
- parser = optparse.OptionParser()
- build_utils.AddDepfileOption(parser)
- parser.add_option('--main-manifest', help='The main manifest of the app')
- parser.add_option('--out-manifest', help='The output manifest')
- parser.add_option('--split', help='The name of the split')
- parser.add_option(
- '--has-code',
- action='store_true',
- default=False,
- help='Whether the split will contain a .dex file')
-
- (options, args) = parser.parse_args()
-
- if args:
- parser.error('No positional arguments should be given.')
-
- # Check that required options have been provided.
- required_options = ('main_manifest', 'out_manifest', 'split')
- build_utils.CheckOptions(options, parser, required=required_options)
-
- return options
-
-
-def Build(main_manifest, split, has_code):
- """Builds a split manifest based on the manifest of the main APK.
-
- Args:
- main_manifest: the XML manifest of the main APK as a string
- split: the name of the split as a string
- has_code: whether this split APK will contain .dex files
-
- Returns:
- The XML split manifest as a string
- """
-
- doc = xml.etree.ElementTree.fromstring(main_manifest)
- package = doc.get('package')
-
- return MANIFEST_TEMPLATE % {
- 'package': package,
- 'split': split.replace('-', '_'),
- 'has_code': str(has_code).lower()
- }
-
-
-def main():
- options = ParseArgs()
- main_manifest = file(options.main_manifest).read()
- split_manifest = Build(
- main_manifest,
- options.split,
- options.has_code)
-
- with file(options.out_manifest, 'w') as f:
- f.write(split_manifest)
-
- if options.depfile:
- build_utils.WriteDepfile(
- options.depfile,
- [options.main_manifest] + build_utils.GetPythonDependencies())
-
-
-if __name__ == '__main__':
- main()
diff --git a/build/android/gyp/generate_v14_compatible_resources.py b/build/android/gyp/generate_v14_compatible_resources.py
deleted file mode 100755
index 9c8ff3b..0000000
--- a/build/android/gyp/generate_v14_compatible_resources.py
+++ /dev/null
@@ -1,319 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Convert Android xml resources to API 14 compatible.
-
-There are two reasons that we cannot just use API 17 attributes,
-so we are generating another set of resources by this script.
-
-1. paddingStart attribute can cause a crash on Galaxy Tab 2.
-2. There is a bug that paddingStart does not override paddingLeft on
- JB-MR1. This is fixed on JB-MR2. b/8654490
-
-Therefore, this resource generation script can be removed when
-we drop the support for JB-MR1.
-
-Please refer to http://crbug.com/235118 for the details.
-"""
-
-import optparse
-import os
-import re
-import shutil
-import sys
-import xml.dom.minidom as minidom
-
-from util import build_utils
-
-# Note that we are assuming 'android:' is an alias of
-# the namespace 'http://schemas.android.com/apk/res/android'.
-
-GRAVITY_ATTRIBUTES = ('android:gravity', 'android:layout_gravity')
-
-# Almost all the attributes that has "Start" or "End" in
-# its name should be mapped.
-ATTRIBUTES_TO_MAP = {'paddingStart' : 'paddingLeft',
- 'drawableStart' : 'drawableLeft',
- 'layout_alignStart' : 'layout_alignLeft',
- 'layout_marginStart' : 'layout_marginLeft',
- 'layout_alignParentStart' : 'layout_alignParentLeft',
- 'layout_toStartOf' : 'layout_toLeftOf',
- 'paddingEnd' : 'paddingRight',
- 'drawableEnd' : 'drawableRight',
- 'layout_alignEnd' : 'layout_alignRight',
- 'layout_marginEnd' : 'layout_marginRight',
- 'layout_alignParentEnd' : 'layout_alignParentRight',
- 'layout_toEndOf' : 'layout_toRightOf'}
-
-ATTRIBUTES_TO_MAP = dict(['android:' + k, 'android:' + v] for k, v
- in ATTRIBUTES_TO_MAP.iteritems())
-
-ATTRIBUTES_TO_MAP_REVERSED = dict([v, k] for k, v
- in ATTRIBUTES_TO_MAP.iteritems())
-
-
-def IterateXmlElements(node):
- """minidom helper function that iterates all the element nodes.
- Iteration order is pre-order depth-first."""
- if node.nodeType == node.ELEMENT_NODE:
- yield node
- for child_node in node.childNodes:
- for child_node_element in IterateXmlElements(child_node):
- yield child_node_element
-
-
-def ParseAndReportErrors(filename):
- try:
- return minidom.parse(filename)
- except Exception:
- import traceback
- traceback.print_exc()
- sys.stderr.write('Failed to parse XML file: %s\n' % filename)
- sys.exit(1)
-
-
-def AssertNotDeprecatedAttribute(name, value, filename):
- """Raises an exception if the given attribute is deprecated."""
- msg = None
- if name in ATTRIBUTES_TO_MAP_REVERSED:
- msg = '{0} should use {1} instead of {2}'.format(filename,
- ATTRIBUTES_TO_MAP_REVERSED[name], name)
- elif name in GRAVITY_ATTRIBUTES and ('left' in value or 'right' in value):
- msg = '{0} should use start/end instead of left/right for {1}'.format(
- filename, name)
-
- if msg:
- msg += ('\nFor background, see: http://android-developers.blogspot.com/'
- '2013/03/native-rtl-support-in-android-42.html\n'
- 'If you have a legitimate need for this attribute, discuss with '
- 'kkimlabs@chromium.org or newt@chromium.org')
- raise Exception(msg)
-
-
-def WriteDomToFile(dom, filename):
- """Write the given dom to filename."""
- build_utils.MakeDirectory(os.path.dirname(filename))
- with open(filename, 'w') as f:
- dom.writexml(f, '', ' ', '\n', encoding='utf-8')
-
-
-def HasStyleResource(dom):
- """Return True if the dom is a style resource, False otherwise."""
- root_node = IterateXmlElements(dom).next()
- return bool(root_node.nodeName == 'resources' and
- list(root_node.getElementsByTagName('style')))
-
-
-def ErrorIfStyleResourceExistsInDir(input_dir):
- """If a style resource is in input_dir, raises an exception."""
- for input_filename in build_utils.FindInDirectory(input_dir, '*.xml'):
- dom = ParseAndReportErrors(input_filename)
- if HasStyleResource(dom):
- raise Exception('error: style file ' + input_filename +
- ' should be under ' + input_dir +
- '-v17 directory. Please refer to '
- 'http://crbug.com/243952 for the details.')
-
-
-def GenerateV14LayoutResourceDom(dom, filename, assert_not_deprecated=True):
- """Convert layout resource to API 14 compatible layout resource.
-
- Args:
- dom: Parsed minidom object to be modified.
- filename: Filename that the DOM was parsed from.
- assert_not_deprecated: Whether deprecated attributes (e.g. paddingLeft) will
- cause an exception to be thrown.
-
- Returns:
- True if dom is modified, False otherwise.
- """
- is_modified = False
-
- # Iterate all the elements' attributes to find attributes to convert.
- for element in IterateXmlElements(dom):
- for name, value in list(element.attributes.items()):
- # Convert any API 17 Start/End attributes to Left/Right attributes.
- # For example, from paddingStart="10dp" to paddingLeft="10dp"
- # Note: gravity attributes are not necessary to convert because
- # start/end values are backward-compatible. Explained at
- # https://plus.sandbox.google.com/+RomanNurik/posts/huuJd8iVVXY?e=Showroom
- if name in ATTRIBUTES_TO_MAP:
- element.setAttribute(ATTRIBUTES_TO_MAP[name], value)
- del element.attributes[name]
- is_modified = True
- elif assert_not_deprecated:
- AssertNotDeprecatedAttribute(name, value, filename)
-
- return is_modified
-
-
-def GenerateV14StyleResourceDom(dom, filename, assert_not_deprecated=True):
- """Convert style resource to API 14 compatible style resource.
-
- Args:
- dom: Parsed minidom object to be modified.
- filename: Filename that the DOM was parsed from.
- assert_not_deprecated: Whether deprecated attributes (e.g. paddingLeft) will
- cause an exception to be thrown.
-
- Returns:
- True if dom is modified, False otherwise.
- """
- is_modified = False
-
- for style_element in dom.getElementsByTagName('style'):
- for item_element in style_element.getElementsByTagName('item'):
- name = item_element.attributes['name'].value
- value = item_element.childNodes[0].nodeValue
- if name in ATTRIBUTES_TO_MAP:
- item_element.attributes['name'].value = ATTRIBUTES_TO_MAP[name]
- is_modified = True
- elif assert_not_deprecated:
- AssertNotDeprecatedAttribute(name, value, filename)
-
- return is_modified
-
-
-def GenerateV14LayoutResource(input_filename, output_v14_filename,
- output_v17_filename):
- """Convert API 17 layout resource to API 14 compatible layout resource.
-
- It's mostly a simple replacement, s/Start/Left s/End/Right,
- on the attribute names.
- If the generated resource is identical to the original resource,
- don't do anything. If not, write the generated resource to
- output_v14_filename, and copy the original resource to output_v17_filename.
- """
- dom = ParseAndReportErrors(input_filename)
- is_modified = GenerateV14LayoutResourceDom(dom, input_filename)
-
- if is_modified:
- # Write the generated resource.
- WriteDomToFile(dom, output_v14_filename)
-
- # Copy the original resource.
- build_utils.MakeDirectory(os.path.dirname(output_v17_filename))
- shutil.copy2(input_filename, output_v17_filename)
-
-
-def GenerateV14StyleResource(input_filename, output_v14_filename):
- """Convert API 17 style resources to API 14 compatible style resource.
-
- Write the generated style resource to output_v14_filename.
- It's mostly a simple replacement, s/Start/Left s/End/Right,
- on the attribute names.
- """
- dom = ParseAndReportErrors(input_filename)
- GenerateV14StyleResourceDom(dom, input_filename)
-
- # Write the generated resource.
- WriteDomToFile(dom, output_v14_filename)
-
-
-def GenerateV14LayoutResourcesInDir(input_dir, output_v14_dir, output_v17_dir):
- """Convert layout resources to API 14 compatible resources in input_dir."""
- for input_filename in build_utils.FindInDirectory(input_dir, '*.xml'):
- rel_filename = os.path.relpath(input_filename, input_dir)
- output_v14_filename = os.path.join(output_v14_dir, rel_filename)
- output_v17_filename = os.path.join(output_v17_dir, rel_filename)
- GenerateV14LayoutResource(input_filename, output_v14_filename,
- output_v17_filename)
-
-
-def GenerateV14StyleResourcesInDir(input_dir, output_v14_dir):
- """Convert style resources to API 14 compatible resources in input_dir."""
- for input_filename in build_utils.FindInDirectory(input_dir, '*.xml'):
- rel_filename = os.path.relpath(input_filename, input_dir)
- output_v14_filename = os.path.join(output_v14_dir, rel_filename)
- GenerateV14StyleResource(input_filename, output_v14_filename)
-
-
-def ParseArgs():
- """Parses command line options.
-
- Returns:
- An options object as from optparse.OptionsParser.parse_args()
- """
- parser = optparse.OptionParser()
- parser.add_option('--res-dir',
- help='directory containing resources '
- 'used to generate v14 compatible resources')
- parser.add_option('--res-v14-compatibility-dir',
- help='output directory into which '
- 'v14 compatible resources will be generated')
- parser.add_option('--stamp', help='File to touch on success')
-
- options, args = parser.parse_args()
-
- if args:
- parser.error('No positional arguments should be given.')
-
- # Check that required options have been provided.
- required_options = ('res_dir', 'res_v14_compatibility_dir')
- build_utils.CheckOptions(options, parser, required=required_options)
- return options
-
-def GenerateV14Resources(res_dir, res_v14_dir):
- for name in os.listdir(res_dir):
- if not os.path.isdir(os.path.join(res_dir, name)):
- continue
-
- dir_pieces = name.split('-')
- resource_type = dir_pieces[0]
- qualifiers = dir_pieces[1:]
-
- api_level_qualifier_index = -1
- api_level_qualifier = ''
- for index, qualifier in enumerate(qualifiers):
- if re.match('v[0-9]+$', qualifier):
- api_level_qualifier_index = index
- api_level_qualifier = qualifier
- break
-
- # Android pre-v17 API doesn't support RTL. Skip.
- if 'ldrtl' in qualifiers:
- continue
-
- input_dir = os.path.abspath(os.path.join(res_dir, name))
-
- # We also need to copy the original v17 resource to *-v17 directory
- # because the generated v14 resource will hide the original resource.
- output_v14_dir = os.path.join(res_v14_dir, name)
- output_v17_dir = os.path.join(res_v14_dir, name + '-v17')
-
- # We only convert layout resources under layout*/, xml*/,
- # and style resources under values*/.
- if resource_type in ('layout', 'xml'):
- if not api_level_qualifier:
- GenerateV14LayoutResourcesInDir(input_dir, output_v14_dir,
- output_v17_dir)
- elif resource_type == 'values':
- if api_level_qualifier == 'v17':
- output_qualifiers = qualifiers[:]
- del output_qualifiers[api_level_qualifier_index]
- output_v14_dir = os.path.join(res_v14_dir,
- '-'.join([resource_type] +
- output_qualifiers))
- GenerateV14StyleResourcesInDir(input_dir, output_v14_dir)
- elif not api_level_qualifier:
- ErrorIfStyleResourceExistsInDir(input_dir)
-
-def main():
- options = ParseArgs()
-
- res_v14_dir = options.res_v14_compatibility_dir
-
- build_utils.DeleteDirectory(res_v14_dir)
- build_utils.MakeDirectory(res_v14_dir)
-
- GenerateV14Resources(options.res_dir, res_v14_dir)
-
- if options.stamp:
- build_utils.Touch(options.stamp)
-
-if __name__ == '__main__':
- sys.exit(main())
-
diff --git a/build/android/gyp/get_device_configuration.py b/build/android/gyp/get_device_configuration.py
deleted file mode 100755
index 390eb2f..0000000
--- a/build/android/gyp/get_device_configuration.py
+++ /dev/null
@@ -1,67 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Gets and writes the configurations of the attached devices.
-
-This configuration is used by later build steps to determine which devices to
-install to and what needs to be installed to those devices.
-"""
-
-import optparse
-import sys
-
-from util import build_utils
-from util import build_device
-
-
-def main(argv):
- parser = optparse.OptionParser()
- parser.add_option('--stamp', action='store')
- parser.add_option('--output', action='store')
- options, _ = parser.parse_args(argv)
-
- devices = build_device.GetAttachedDevices()
-
- device_configurations = []
- for d in devices:
- configuration, is_online, has_root = (
- build_device.GetConfigurationForDevice(d))
-
- if not is_online:
- build_utils.PrintBigWarning(
- '%s is not online. Skipping managed install for this device. '
- 'Try rebooting the device to fix this warning.' % d)
- continue
-
- if not has_root:
- build_utils.PrintBigWarning(
- '"adb root" failed on device: %s\n'
- 'Skipping managed install for this device.'
- % configuration['description'])
- continue
-
- device_configurations.append(configuration)
-
- if len(device_configurations) == 0:
- build_utils.PrintBigWarning(
- 'No valid devices attached. Skipping managed install steps.')
- elif len(devices) > 1:
- # Note that this checks len(devices) and not len(device_configurations).
- # This way, any time there are multiple devices attached it is
- # explicitly stated which device we will install things to even if all but
- # one device were rejected for other reasons (e.g. two devices attached,
- # one w/o root).
- build_utils.PrintBigWarning(
- 'Multiple devices attached. '
- 'Installing to the preferred device: '
- '%(id)s (%(description)s)' % (device_configurations[0]))
-
-
- build_device.WriteConfigurations(device_configurations, options.output)
-
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv))
diff --git a/build/android/gyp/insert_chromium_version.py b/build/android/gyp/insert_chromium_version.py
deleted file mode 100755
index 171f9d4..0000000
--- a/build/android/gyp/insert_chromium_version.py
+++ /dev/null
@@ -1,66 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Insert a version string into a library as a section '.chromium.version'.
-"""
-
-import optparse
-import os
-import sys
-import tempfile
-
-from util import build_utils
-
-def InsertChromiumVersion(android_objcopy,
- library_path,
- version_string):
- # Remove existing .chromium.version section from .so
- objcopy_command = [android_objcopy,
- '--remove-section=.chromium.version',
- library_path]
- build_utils.CheckOutput(objcopy_command)
-
- # Add a .chromium.version section.
- with tempfile.NamedTemporaryFile() as stream:
- stream.write(version_string)
- stream.flush()
- objcopy_command = [android_objcopy,
- '--add-section', '.chromium.version=%s' % stream.name,
- library_path]
- build_utils.CheckOutput(objcopy_command)
-
-def main(args):
- args = build_utils.ExpandFileArgs(args)
- parser = optparse.OptionParser()
-
- parser.add_option('--android-objcopy',
- help='Path to the toolchain\'s objcopy binary')
- parser.add_option('--stripped-libraries-dir',
- help='Directory of native libraries')
- parser.add_option('--libraries',
- help='List of libraries')
- parser.add_option('--version-string',
- help='Version string to be inserted')
- parser.add_option('--stamp', help='Path to touch on success')
-
- options, _ = parser.parse_args(args)
- libraries = build_utils.ParseGypList(options.libraries)
-
- for library in libraries:
- library_path = os.path.join(options.stripped_libraries_dir, library)
-
- InsertChromiumVersion(options.android_objcopy,
- library_path,
- options.version_string)
-
- if options.stamp:
- build_utils.Touch(options.stamp)
-
- return 0
-
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv[1:]))
diff --git a/build/android/gyp/jar.py b/build/android/gyp/jar.py
deleted file mode 100755
index 48abf5e..0000000
--- a/build/android/gyp/jar.py
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import fnmatch
-import optparse
-import os
-import sys
-
-from util import build_utils
-from util import md5_check
-
-
-def Jar(class_files, classes_dir, jar_path, manifest_file=None):
- jar_path = os.path.abspath(jar_path)
-
- # The paths of the files in the jar will be the same as they are passed in to
- # the command. Because of this, the command should be run in
- # options.classes_dir so the .class file paths in the jar are correct.
- jar_cwd = classes_dir
- class_files_rel = [os.path.relpath(f, jar_cwd) for f in class_files]
- jar_cmd = ['jar', 'cf0', jar_path]
- if manifest_file:
- jar_cmd[1] += 'm'
- jar_cmd.append(os.path.abspath(manifest_file))
- jar_cmd.extend(class_files_rel)
-
- with build_utils.TempDir() as temp_dir:
- empty_file = os.path.join(temp_dir, '.empty')
- build_utils.Touch(empty_file)
- jar_cmd.append(os.path.relpath(empty_file, jar_cwd))
- record_path = '%s.md5.stamp' % jar_path
- md5_check.CallAndRecordIfStale(
- lambda: build_utils.CheckOutput(jar_cmd, cwd=jar_cwd),
- record_path=record_path,
- input_paths=class_files,
- input_strings=jar_cmd,
- force=not os.path.exists(jar_path),
- )
-
- build_utils.Touch(jar_path, fail_if_missing=True)
-
-
-def JarDirectory(classes_dir, excluded_classes, jar_path, manifest_file=None):
- class_files = build_utils.FindInDirectory(classes_dir, '*.class')
- for exclude in excluded_classes:
- class_files = filter(
- lambda f: not fnmatch.fnmatch(f, exclude), class_files)
-
- Jar(class_files, classes_dir, jar_path, manifest_file=manifest_file)
-
-
-def main():
- parser = optparse.OptionParser()
- parser.add_option('--classes-dir', help='Directory containing .class files.')
- parser.add_option('--jar-path', help='Jar output path.')
- parser.add_option('--excluded-classes',
- help='List of .class file patterns to exclude from the jar.')
- parser.add_option('--stamp', help='Path to touch on success.')
-
- options, _ = parser.parse_args()
-
- if options.excluded_classes:
- excluded_classes = build_utils.ParseGypList(options.excluded_classes)
- else:
- excluded_classes = []
- JarDirectory(options.classes_dir,
- excluded_classes,
- options.jar_path)
-
- if options.stamp:
- build_utils.Touch(options.stamp)
-
-
-if __name__ == '__main__':
- sys.exit(main())
-
diff --git a/build/android/gyp/jar_toc.py b/build/android/gyp/jar_toc.py
deleted file mode 100755
index 00d97d2..0000000
--- a/build/android/gyp/jar_toc.py
+++ /dev/null
@@ -1,127 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Creates a TOC file from a Java jar.
-
-The TOC file contains the non-package API of the jar. This includes all
-public/protected/package classes/functions/members and the values of static
-final variables (members with package access are kept because in some cases we
-have multiple libraries with the same package, particularly test+non-test). Some
-other information (major/minor javac version) is also included.
-
-This TOC file then can be used to determine if a dependent library should be
-rebuilt when this jar changes. I.e. any change to the jar that would require a
-rebuild, will have a corresponding change in the TOC file.
-"""
-
-import optparse
-import os
-import re
-import sys
-import zipfile
-
-from util import build_utils
-from util import md5_check
-
-
-def GetClassesInZipFile(zip_file):
- classes = []
- files = zip_file.namelist()
- for f in files:
- if f.endswith('.class'):
- # f is of the form org/chromium/base/Class$Inner.class
- classes.append(f.replace('/', '.')[:-6])
- return classes
-
-
-def CallJavap(classpath, classes):
- javap_cmd = [
- 'javap',
- '-package', # Show public/protected/package.
- # -verbose is required to get constant values (which can be inlined in
- # dependents).
- '-verbose',
- '-J-XX:NewSize=4m',
- '-classpath', classpath
- ] + classes
- return build_utils.CheckOutput(javap_cmd)
-
-
-def ExtractToc(disassembled_classes):
- # javap output is structured by indent (2-space) levels.
- good_patterns = [
- '^[^ ]', # This includes all class/function/member signatures.
- '^ SourceFile:',
- '^ minor version:',
- '^ major version:',
- '^ Constant value:',
- ]
- bad_patterns = [
- '^const #', # Matches the constant pool (i.e. literals used in the class).
- ]
-
- def JavapFilter(line):
- return (re.match('|'.join(good_patterns), line) and
- not re.match('|'.join(bad_patterns), line))
- toc = filter(JavapFilter, disassembled_classes.split('\n'))
-
- return '\n'.join(toc)
-
-
-def UpdateToc(jar_path, toc_path):
- classes = GetClassesInZipFile(zipfile.ZipFile(jar_path))
- toc = []
-
- limit = 1000 # Split into multiple calls to stay under command size limit
- for i in xrange(0, len(classes), limit):
- javap_output = CallJavap(classpath=jar_path, classes=classes[i:i+limit])
- toc.append(ExtractToc(javap_output))
-
- with open(toc_path, 'w') as tocfile:
- tocfile.write(''.join(toc))
-
-
-def DoJarToc(options):
- jar_path = options.jar_path
- toc_path = options.toc_path
- record_path = '%s.md5.stamp' % toc_path
- md5_check.CallAndRecordIfStale(
- lambda: UpdateToc(jar_path, toc_path),
- record_path=record_path,
- input_paths=[jar_path],
- force=not os.path.exists(toc_path),
- )
- build_utils.Touch(toc_path, fail_if_missing=True)
-
-
-def main():
- parser = optparse.OptionParser()
- build_utils.AddDepfileOption(parser)
-
- parser.add_option('--jar-path', help='Input .jar path.')
- parser.add_option('--toc-path', help='Output .jar.TOC path.')
- parser.add_option('--stamp', help='Path to touch on success.')
-
- options, _ = parser.parse_args()
-
- if options.depfile:
- build_utils.WriteDepfile(
- options.depfile,
- build_utils.GetPythonDependencies())
-
- DoJarToc(options)
-
- if options.depfile:
- build_utils.WriteDepfile(
- options.depfile,
- build_utils.GetPythonDependencies())
-
- if options.stamp:
- build_utils.Touch(options.stamp)
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/build/android/gyp/java_cpp_enum.py b/build/android/gyp/java_cpp_enum.py
deleted file mode 100755
index c2f1764..0000000
--- a/build/android/gyp/java_cpp_enum.py
+++ /dev/null
@@ -1,340 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import collections
-import re
-import optparse
-import os
-from string import Template
-import sys
-
-from util import build_utils
-
-# List of C++ types that are compatible with the Java code generated by this
-# script.
-#
-# This script can parse .idl files however, at present it ignores special
-# rules such as [cpp_enum_prefix_override="ax_attr"].
-ENUM_FIXED_TYPE_WHITELIST = ['char', 'unsigned char',
- 'short', 'unsigned short',
- 'int', 'int8_t', 'int16_t', 'int32_t', 'uint8_t', 'uint16_t']
-
-class EnumDefinition(object):
- def __init__(self, original_enum_name=None, class_name_override=None,
- enum_package=None, entries=None, fixed_type=None):
- self.original_enum_name = original_enum_name
- self.class_name_override = class_name_override
- self.enum_package = enum_package
- self.entries = collections.OrderedDict(entries or [])
- self.prefix_to_strip = None
- self.fixed_type = fixed_type
-
- def AppendEntry(self, key, value):
- if key in self.entries:
- raise Exception('Multiple definitions of key %s found.' % key)
- self.entries[key] = value
-
- @property
- def class_name(self):
- return self.class_name_override or self.original_enum_name
-
- def Finalize(self):
- self._Validate()
- self._AssignEntryIndices()
- self._StripPrefix()
-
- def _Validate(self):
- assert self.class_name
- assert self.enum_package
- assert self.entries
- if self.fixed_type and self.fixed_type not in ENUM_FIXED_TYPE_WHITELIST:
- raise Exception('Fixed type %s for enum %s not whitelisted.' %
- (self.fixed_type, self.class_name))
-
- def _AssignEntryIndices(self):
- # Enums, if given no value, are given the value of the previous enum + 1.
- if not all(self.entries.values()):
- prev_enum_value = -1
- for key, value in self.entries.iteritems():
- if not value:
- self.entries[key] = prev_enum_value + 1
- elif value in self.entries:
- self.entries[key] = self.entries[value]
- else:
- try:
- self.entries[key] = int(value)
- except ValueError:
- raise Exception('Could not interpret integer from enum value "%s" '
- 'for key %s.' % (value, key))
- prev_enum_value = self.entries[key]
-
-
- def _StripPrefix(self):
- prefix_to_strip = self.prefix_to_strip
- if not prefix_to_strip:
- prefix_to_strip = self.original_enum_name
- prefix_to_strip = re.sub('(?!^)([A-Z]+)', r'_\1', prefix_to_strip).upper()
- prefix_to_strip += '_'
- if not all([w.startswith(prefix_to_strip) for w in self.entries.keys()]):
- prefix_to_strip = ''
-
- entries = collections.OrderedDict()
- for (k, v) in self.entries.iteritems():
- stripped_key = k.replace(prefix_to_strip, '', 1)
- if isinstance(v, basestring):
- stripped_value = v.replace(prefix_to_strip, '', 1)
- else:
- stripped_value = v
- entries[stripped_key] = stripped_value
-
- self.entries = entries
-
-class DirectiveSet(object):
- class_name_override_key = 'CLASS_NAME_OVERRIDE'
- enum_package_key = 'ENUM_PACKAGE'
- prefix_to_strip_key = 'PREFIX_TO_STRIP'
-
- known_keys = [class_name_override_key, enum_package_key, prefix_to_strip_key]
-
- def __init__(self):
- self._directives = {}
-
- def Update(self, key, value):
- if key not in DirectiveSet.known_keys:
- raise Exception("Unknown directive: " + key)
- self._directives[key] = value
-
- @property
- def empty(self):
- return len(self._directives) == 0
-
- def UpdateDefinition(self, definition):
- definition.class_name_override = self._directives.get(
- DirectiveSet.class_name_override_key, '')
- definition.enum_package = self._directives.get(
- DirectiveSet.enum_package_key)
- definition.prefix_to_strip = self._directives.get(
- DirectiveSet.prefix_to_strip_key)
-
-
-class HeaderParser(object):
- single_line_comment_re = re.compile(r'\s*//')
- multi_line_comment_start_re = re.compile(r'\s*/\*')
- enum_line_re = re.compile(r'^\s*(\w+)(\s*\=\s*([^,\n]+))?,?')
- enum_end_re = re.compile(r'^\s*}\s*;\.*$')
- generator_directive_re = re.compile(
- r'^\s*//\s+GENERATED_JAVA_(\w+)\s*:\s*([\.\w]+)$')
- multi_line_generator_directive_start_re = re.compile(
- r'^\s*//\s+GENERATED_JAVA_(\w+)\s*:\s*\(([\.\w]*)$')
- multi_line_directive_continuation_re = re.compile(
- r'^\s*//\s+([\.\w]+)$')
- multi_line_directive_end_re = re.compile(
- r'^\s*//\s+([\.\w]*)\)$')
-
- optional_class_or_struct_re = r'(class|struct)?'
- enum_name_re = r'(\w+)'
- optional_fixed_type_re = r'(\:\s*(\w+\s*\w+?))?'
- enum_start_re = re.compile(r'^\s*(?:\[cpp.*\])?\s*enum\s+' +
- optional_class_or_struct_re + '\s*' + enum_name_re + '\s*' +
- optional_fixed_type_re + '\s*{\s*$')
-
- def __init__(self, lines, path=None):
- self._lines = lines
- self._path = path
- self._enum_definitions = []
- self._in_enum = False
- self._current_definition = None
- self._generator_directives = DirectiveSet()
- self._multi_line_generator_directive = None
-
- def _ApplyGeneratorDirectives(self):
- self._generator_directives.UpdateDefinition(self._current_definition)
- self._generator_directives = DirectiveSet()
-
- def ParseDefinitions(self):
- for line in self._lines:
- self._ParseLine(line)
- return self._enum_definitions
-
- def _ParseLine(self, line):
- if self._multi_line_generator_directive:
- self._ParseMultiLineDirectiveLine(line)
- elif not self._in_enum:
- self._ParseRegularLine(line)
- else:
- self._ParseEnumLine(line)
-
- def _ParseEnumLine(self, line):
- if HeaderParser.single_line_comment_re.match(line):
- return
- if HeaderParser.multi_line_comment_start_re.match(line):
- raise Exception('Multi-line comments in enums are not supported in ' +
- self._path)
- enum_end = HeaderParser.enum_end_re.match(line)
- enum_entry = HeaderParser.enum_line_re.match(line)
- if enum_end:
- self._ApplyGeneratorDirectives()
- self._current_definition.Finalize()
- self._enum_definitions.append(self._current_definition)
- self._in_enum = False
- elif enum_entry:
- enum_key = enum_entry.groups()[0]
- enum_value = enum_entry.groups()[2]
- self._current_definition.AppendEntry(enum_key, enum_value)
-
- def _ParseMultiLineDirectiveLine(self, line):
- multi_line_directive_continuation = (
- HeaderParser.multi_line_directive_continuation_re.match(line))
- multi_line_directive_end = (
- HeaderParser.multi_line_directive_end_re.match(line))
-
- if multi_line_directive_continuation:
- value_cont = multi_line_directive_continuation.groups()[0]
- self._multi_line_generator_directive[1].append(value_cont)
- elif multi_line_directive_end:
- directive_name = self._multi_line_generator_directive[0]
- directive_value = "".join(self._multi_line_generator_directive[1])
- directive_value += multi_line_directive_end.groups()[0]
- self._multi_line_generator_directive = None
- self._generator_directives.Update(directive_name, directive_value)
- else:
- raise Exception('Malformed multi-line directive declaration in ' +
- self._path)
-
- def _ParseRegularLine(self, line):
- enum_start = HeaderParser.enum_start_re.match(line)
- generator_directive = HeaderParser.generator_directive_re.match(line)
- multi_line_generator_directive_start = (
- HeaderParser.multi_line_generator_directive_start_re.match(line))
-
- if generator_directive:
- directive_name = generator_directive.groups()[0]
- directive_value = generator_directive.groups()[1]
- self._generator_directives.Update(directive_name, directive_value)
- elif multi_line_generator_directive_start:
- directive_name = multi_line_generator_directive_start.groups()[0]
- directive_value = multi_line_generator_directive_start.groups()[1]
- self._multi_line_generator_directive = (directive_name, [directive_value])
- elif enum_start:
- if self._generator_directives.empty:
- return
- self._current_definition = EnumDefinition(
- original_enum_name=enum_start.groups()[1],
- fixed_type=enum_start.groups()[3])
- self._in_enum = True
-
-def GetScriptName():
- script_components = os.path.abspath(sys.argv[0]).split(os.path.sep)
- build_index = script_components.index('build')
- return os.sep.join(script_components[build_index:])
-
-
-def DoGenerate(output_dir, source_paths, print_output_only=False):
- output_paths = []
- for source_path in source_paths:
- enum_definitions = DoParseHeaderFile(source_path)
- if not enum_definitions:
- raise Exception('No enums found in %s\n'
- 'Did you forget prefixing enums with '
- '"// GENERATED_JAVA_ENUM_PACKAGE: foo"?' %
- source_path)
- for enum_definition in enum_definitions:
- package_path = enum_definition.enum_package.replace('.', os.path.sep)
- file_name = enum_definition.class_name + '.java'
- output_path = os.path.join(output_dir, package_path, file_name)
- output_paths.append(output_path)
- if not print_output_only:
- build_utils.MakeDirectory(os.path.dirname(output_path))
- DoWriteOutput(source_path, output_path, enum_definition)
- return output_paths
-
-
-def DoParseHeaderFile(path):
- with open(path) as f:
- return HeaderParser(f.readlines(), path).ParseDefinitions()
-
-
-def GenerateOutput(source_path, enum_definition):
- template = Template("""
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file is autogenerated by
-// ${SCRIPT_NAME}
-// From
-// ${SOURCE_PATH}
-
-package ${PACKAGE};
-
-public class ${CLASS_NAME} {
-${ENUM_ENTRIES}
-}
-""")
-
- enum_template = Template(' public static final int ${NAME} = ${VALUE};')
- enum_entries_string = []
- for enum_name, enum_value in enum_definition.entries.iteritems():
- values = {
- 'NAME': enum_name,
- 'VALUE': enum_value,
- }
- enum_entries_string.append(enum_template.substitute(values))
- enum_entries_string = '\n'.join(enum_entries_string)
-
- values = {
- 'CLASS_NAME': enum_definition.class_name,
- 'ENUM_ENTRIES': enum_entries_string,
- 'PACKAGE': enum_definition.enum_package,
- 'SCRIPT_NAME': GetScriptName(),
- 'SOURCE_PATH': source_path,
- }
- return template.substitute(values)
-
-
-def DoWriteOutput(source_path, output_path, enum_definition):
- with open(output_path, 'w') as out_file:
- out_file.write(GenerateOutput(source_path, enum_definition))
-
-def AssertFilesList(output_paths, assert_files_list):
- actual = set(output_paths)
- expected = set(assert_files_list)
- if not actual == expected:
- need_to_add = list(actual - expected)
- need_to_remove = list(expected - actual)
- raise Exception('Output files list does not match expectations. Please '
- 'add %s and remove %s.' % (need_to_add, need_to_remove))
-
-def DoMain(argv):
- usage = 'usage: %prog [options] output_dir input_file(s)...'
- parser = optparse.OptionParser(usage=usage)
-
- parser.add_option('--assert_file', action="append", default=[],
- dest="assert_files_list", help='Assert that the given '
- 'file is an output. There can be multiple occurrences of '
- 'this flag.')
- parser.add_option('--print_output_only', help='Only print output paths.',
- action='store_true')
- parser.add_option('--verbose', help='Print more information.',
- action='store_true')
-
- options, args = parser.parse_args(argv)
- if len(args) < 2:
- parser.error('Need to specify output directory and at least one input file')
- output_paths = DoGenerate(args[0], args[1:],
- print_output_only=options.print_output_only)
-
- if options.assert_files_list:
- AssertFilesList(output_paths, options.assert_files_list)
-
- if options.verbose:
- print 'Output paths:'
- print '\n'.join(output_paths)
-
- return ' '.join(output_paths)
-
-if __name__ == '__main__':
- DoMain(sys.argv[1:])
diff --git a/build/android/gyp/java_cpp_enum_tests.py b/build/android/gyp/java_cpp_enum_tests.py
deleted file mode 100755
index 44f9766..0000000
--- a/build/android/gyp/java_cpp_enum_tests.py
+++ /dev/null
@@ -1,436 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Tests for enum_preprocess.py.
-
-This test suite containss various tests for the C++ -> Java enum generator.
-"""
-
-import collections
-import optparse
-import os
-import sys
-import unittest
-
-import java_cpp_enum
-from java_cpp_enum import EnumDefinition, GenerateOutput, GetScriptName
-from java_cpp_enum import HeaderParser
-
-sys.path.append(os.path.join(os.path.dirname(__file__), "gyp"))
-from util import build_utils
-
-class TestPreprocess(unittest.TestCase):
- def testOutput(self):
- definition = EnumDefinition(original_enum_name='ClassName',
- enum_package='some.package',
- entries=[('E1', 1), ('E2', '2 << 2')])
- output = GenerateOutput('path/to/file', definition)
- expected = """
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file is autogenerated by
-// %s
-// From
-// path/to/file
-
-package some.package;
-
-public class ClassName {
- public static final int E1 = 1;
- public static final int E2 = 2 << 2;
-}
-"""
- self.assertEqual(expected % GetScriptName(), output)
-
- def testParseSimpleEnum(self):
- test_data = """
- // GENERATED_JAVA_ENUM_PACKAGE: test.namespace
- enum EnumName {
- VALUE_ZERO,
- VALUE_ONE,
- };
- """.split('\n')
- definitions = HeaderParser(test_data).ParseDefinitions()
- self.assertEqual(1, len(definitions))
- definition = definitions[0]
- self.assertEqual('EnumName', definition.class_name)
- self.assertEqual('test.namespace', definition.enum_package)
- self.assertEqual(collections.OrderedDict([('VALUE_ZERO', 0),
- ('VALUE_ONE', 1)]),
- definition.entries)
-
- def testParseBitShifts(self):
- test_data = """
- // GENERATED_JAVA_ENUM_PACKAGE: test.namespace
- enum EnumName {
- VALUE_ZERO = 1 << 0,
- VALUE_ONE = 1 << 1,
- };
- """.split('\n')
- definitions = HeaderParser(test_data).ParseDefinitions()
- self.assertEqual(1, len(definitions))
- definition = definitions[0]
- self.assertEqual('EnumName', definition.class_name)
- self.assertEqual('test.namespace', definition.enum_package)
- self.assertEqual(collections.OrderedDict([('VALUE_ZERO', '1 << 0'),
- ('VALUE_ONE', '1 << 1')]),
- definition.entries)
-
- def testParseClassNameOverride(self):
- test_data = """
- // GENERATED_JAVA_ENUM_PACKAGE: test.namespace
- // GENERATED_JAVA_CLASS_NAME_OVERRIDE: OverrideName
- enum EnumName {
- FOO
- };
-
- // GENERATED_JAVA_ENUM_PACKAGE: test.namespace
- // GENERATED_JAVA_CLASS_NAME_OVERRIDE: OtherOverride
- enum PrefixTest {
- PREFIX_TEST_A,
- PREFIX_TEST_B,
- };
- """.split('\n')
- definitions = HeaderParser(test_data).ParseDefinitions()
- self.assertEqual(2, len(definitions))
- definition = definitions[0]
- self.assertEqual('OverrideName', definition.class_name)
-
- definition = definitions[1]
- self.assertEqual('OtherOverride', definition.class_name)
- self.assertEqual(collections.OrderedDict([('A', 0),
- ('B', 1)]),
- definition.entries)
-
- def testParseTwoEnums(self):
- test_data = """
- // GENERATED_JAVA_ENUM_PACKAGE: test.namespace
- enum EnumOne {
- ENUM_ONE_A = 1,
- // Comment there
- ENUM_ONE_B = A,
- };
-
- enum EnumIgnore {
- C, D, E
- };
-
- // GENERATED_JAVA_ENUM_PACKAGE: other.package
- // GENERATED_JAVA_PREFIX_TO_STRIP: P_
- enum EnumTwo {
- P_A,
- P_B
- };
- """.split('\n')
- definitions = HeaderParser(test_data).ParseDefinitions()
- self.assertEqual(2, len(definitions))
- definition = definitions[0]
- self.assertEqual('EnumOne', definition.class_name)
- self.assertEqual('test.namespace', definition.enum_package)
- self.assertEqual(collections.OrderedDict([('A', '1'),
- ('B', 'A')]),
- definition.entries)
-
- definition = definitions[1]
- self.assertEqual('EnumTwo', definition.class_name)
- self.assertEqual('other.package', definition.enum_package)
- self.assertEqual(collections.OrderedDict([('A', 0),
- ('B', 1)]),
- definition.entries)
-
- def testParseThrowsOnUnknownDirective(self):
- test_data = """
- // GENERATED_JAVA_UNKNOWN: Value
- enum EnumName {
- VALUE_ONE,
- };
- """.split('\n')
- with self.assertRaises(Exception):
- HeaderParser(test_data).ParseDefinitions()
-
- def testParseReturnsEmptyListWithoutDirectives(self):
- test_data = """
- enum EnumName {
- VALUE_ONE,
- };
- """.split('\n')
- self.assertEqual([], HeaderParser(test_data).ParseDefinitions())
-
- def testParseEnumClass(self):
- test_data = """
- // GENERATED_JAVA_ENUM_PACKAGE: test.namespace
- enum class Foo {
- FOO_A,
- };
- """.split('\n')
- definitions = HeaderParser(test_data).ParseDefinitions()
- self.assertEqual(1, len(definitions))
- definition = definitions[0]
- self.assertEqual('Foo', definition.class_name)
- self.assertEqual('test.namespace', definition.enum_package)
- self.assertEqual(collections.OrderedDict([('A', 0)]),
- definition.entries)
-
- def testParseEnumStruct(self):
- test_data = """
- // GENERATED_JAVA_ENUM_PACKAGE: test.namespace
- enum struct Foo {
- FOO_A,
- };
- """.split('\n')
- definitions = HeaderParser(test_data).ParseDefinitions()
- self.assertEqual(1, len(definitions))
- definition = definitions[0]
- self.assertEqual('Foo', definition.class_name)
- self.assertEqual('test.namespace', definition.enum_package)
- self.assertEqual(collections.OrderedDict([('A', 0)]),
- definition.entries)
-
- def testParseFixedTypeEnum(self):
- test_data = """
- // GENERATED_JAVA_ENUM_PACKAGE: test.namespace
- enum Foo : int {
- FOO_A,
- };
- """.split('\n')
- definitions = HeaderParser(test_data).ParseDefinitions()
- self.assertEqual(1, len(definitions))
- definition = definitions[0]
- self.assertEqual('Foo', definition.class_name)
- self.assertEqual('test.namespace', definition.enum_package)
- self.assertEqual('int', definition.fixed_type)
- self.assertEqual(collections.OrderedDict([('A', 0)]),
- definition.entries)
-
- def testParseFixedTypeEnumClass(self):
- test_data = """
- // GENERATED_JAVA_ENUM_PACKAGE: test.namespace
- enum class Foo: unsigned short {
- FOO_A,
- };
- """.split('\n')
- definitions = HeaderParser(test_data).ParseDefinitions()
- self.assertEqual(1, len(definitions))
- definition = definitions[0]
- self.assertEqual('Foo', definition.class_name)
- self.assertEqual('test.namespace', definition.enum_package)
- self.assertEqual('unsigned short', definition.fixed_type)
- self.assertEqual(collections.OrderedDict([('A', 0)]),
- definition.entries)
-
- def testParseUnknownFixedTypeRaises(self):
- test_data = """
- // GENERATED_JAVA_ENUM_PACKAGE: test.namespace
- enum class Foo: foo_type {
- FOO_A,
- };
- """.split('\n')
- with self.assertRaises(Exception):
- HeaderParser(test_data).ParseDefinitions()
-
- def testParseSimpleMultiLineDirective(self):
- test_data = """
- // GENERATED_JAVA_ENUM_PACKAGE: (
- // test.namespace)
- // GENERATED_JAVA_CLASS_NAME_OVERRIDE: Bar
- enum Foo {
- FOO_A,
- };
- """.split('\n')
- definitions = HeaderParser(test_data).ParseDefinitions()
- self.assertEqual('test.namespace', definitions[0].enum_package)
- self.assertEqual('Bar', definitions[0].class_name)
-
- def testParseMultiLineDirective(self):
- test_data = """
- // GENERATED_JAVA_ENUM_PACKAGE: (te
- // st.name
- // space)
- enum Foo {
- FOO_A,
- };
- """.split('\n')
- definitions = HeaderParser(test_data).ParseDefinitions()
- self.assertEqual('test.namespace', definitions[0].enum_package)
-
- def testParseMultiLineDirectiveWithOtherDirective(self):
- test_data = """
- // GENERATED_JAVA_ENUM_PACKAGE: (
- // test.namespace)
- // GENERATED_JAVA_CLASS_NAME_OVERRIDE: (
- // Ba
- // r
- // )
- enum Foo {
- FOO_A,
- };
- """.split('\n')
- definitions = HeaderParser(test_data).ParseDefinitions()
- self.assertEqual('test.namespace', definitions[0].enum_package)
- self.assertEqual('Bar', definitions[0].class_name)
-
- def testParseMalformedMultiLineDirectiveWithOtherDirective(self):
- test_data = """
- // GENERATED_JAVA_ENUM_PACKAGE: (
- // test.name
- // space
- // GENERATED_JAVA_CLASS_NAME_OVERRIDE: Bar
- enum Foo {
- FOO_A,
- };
- """.split('\n')
- with self.assertRaises(Exception):
- HeaderParser(test_data).ParseDefinitions()
-
- def testParseMalformedMultiLineDirective(self):
- test_data = """
- // GENERATED_JAVA_ENUM_PACKAGE: (
- // test.name
- // space
- enum Foo {
- FOO_A,
- };
- """.split('\n')
- with self.assertRaises(Exception):
- HeaderParser(test_data).ParseDefinitions()
-
- def testParseMalformedMultiLineDirectiveShort(self):
- test_data = """
- // GENERATED_JAVA_ENUM_PACKAGE: (
- enum Foo {
- FOO_A,
- };
- """.split('\n')
- with self.assertRaises(Exception):
- HeaderParser(test_data).ParseDefinitions()
-
- def testEnumValueAssignmentNoneDefined(self):
- definition = EnumDefinition(original_enum_name='c', enum_package='p')
- definition.AppendEntry('A', None)
- definition.AppendEntry('B', None)
- definition.AppendEntry('C', None)
- definition.Finalize()
- self.assertEqual(collections.OrderedDict([('A', 0),
- ('B', 1),
- ('C', 2)]),
- definition.entries)
-
- def testEnumValueAssignmentAllDefined(self):
- definition = EnumDefinition(original_enum_name='c', enum_package='p')
- definition.AppendEntry('A', '1')
- definition.AppendEntry('B', '2')
- definition.AppendEntry('C', '3')
- definition.Finalize()
- self.assertEqual(collections.OrderedDict([('A', '1'),
- ('B', '2'),
- ('C', '3')]),
- definition.entries)
-
- def testEnumValueAssignmentReferences(self):
- definition = EnumDefinition(original_enum_name='c', enum_package='p')
- definition.AppendEntry('A', None)
- definition.AppendEntry('B', 'A')
- definition.AppendEntry('C', None)
- definition.AppendEntry('D', 'C')
- definition.Finalize()
- self.assertEqual(collections.OrderedDict([('A', 0),
- ('B', 0),
- ('C', 1),
- ('D', 1)]),
- definition.entries)
-
- def testEnumValueAssignmentSet(self):
- definition = EnumDefinition(original_enum_name='c', enum_package='p')
- definition.AppendEntry('A', None)
- definition.AppendEntry('B', '2')
- definition.AppendEntry('C', None)
- definition.Finalize()
- self.assertEqual(collections.OrderedDict([('A', 0),
- ('B', 2),
- ('C', 3)]),
- definition.entries)
-
- def testEnumValueAssignmentSetReferences(self):
- definition = EnumDefinition(original_enum_name='c', enum_package='p')
- definition.AppendEntry('A', None)
- definition.AppendEntry('B', 'A')
- definition.AppendEntry('C', 'B')
- definition.AppendEntry('D', None)
- definition.Finalize()
- self.assertEqual(collections.OrderedDict([('A', 0),
- ('B', 0),
- ('C', 0),
- ('D', 1)]),
- definition.entries)
-
- def testEnumValueAssignmentRaises(self):
- definition = EnumDefinition(original_enum_name='c', enum_package='p')
- definition.AppendEntry('A', None)
- definition.AppendEntry('B', 'foo')
- definition.AppendEntry('C', None)
- with self.assertRaises(Exception):
- definition.Finalize()
-
- def testExplicitPrefixStripping(self):
- definition = EnumDefinition(original_enum_name='c', enum_package='p')
- definition.AppendEntry('P_A', None)
- definition.AppendEntry('B', None)
- definition.AppendEntry('P_C', None)
- definition.AppendEntry('P_LAST', 'P_C')
- definition.prefix_to_strip = 'P_'
- definition.Finalize()
- self.assertEqual(collections.OrderedDict([('A', 0),
- ('B', 1),
- ('C', 2),
- ('LAST', 2)]),
- definition.entries)
-
- def testImplicitPrefixStripping(self):
- definition = EnumDefinition(original_enum_name='ClassName',
- enum_package='p')
- definition.AppendEntry('CLASS_NAME_A', None)
- definition.AppendEntry('CLASS_NAME_B', None)
- definition.AppendEntry('CLASS_NAME_C', None)
- definition.AppendEntry('CLASS_NAME_LAST', 'CLASS_NAME_C')
- definition.Finalize()
- self.assertEqual(collections.OrderedDict([('A', 0),
- ('B', 1),
- ('C', 2),
- ('LAST', 2)]),
- definition.entries)
-
- def testImplicitPrefixStrippingRequiresAllConstantsToBePrefixed(self):
- definition = EnumDefinition(original_enum_name='Name',
- enum_package='p')
- definition.AppendEntry('A', None)
- definition.AppendEntry('B', None)
- definition.AppendEntry('NAME_LAST', None)
- definition.Finalize()
- self.assertEqual(['A', 'B', 'NAME_LAST'], definition.entries.keys())
-
- def testGenerateThrowsOnEmptyInput(self):
- with self.assertRaises(Exception):
- original_do_parse = java_cpp_enum.DoParseHeaderFile
- try:
- java_cpp_enum.DoParseHeaderFile = lambda _: []
- java_cpp_enum.DoGenerate('dir', ['file'])
- finally:
- java_cpp_enum.DoParseHeaderFile = original_do_parse
-
-def main(argv):
- parser = optparse.OptionParser()
- parser.add_option("--stamp", help="File to touch on success.")
- options, _ = parser.parse_args(argv)
-
- suite = unittest.TestLoader().loadTestsFromTestCase(TestPreprocess)
- unittest.TextTestRunner(verbosity=0).run(suite)
-
- if options.stamp:
- build_utils.Touch(options.stamp)
-
-if __name__ == '__main__':
- main(sys.argv[1:])
diff --git a/build/android/gyp/javac.py b/build/android/gyp/javac.py
deleted file mode 100755
index dafe5df..0000000
--- a/build/android/gyp/javac.py
+++ /dev/null
@@ -1,321 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import fnmatch
-import optparse
-import os
-import shutil
-import re
-import sys
-import textwrap
-
-from util import build_utils
-from util import md5_check
-
-import jar
-
-sys.path.append(build_utils.COLORAMA_ROOT)
-import colorama
-
-
-def ColorJavacOutput(output):
- fileline_prefix = r'(?P<fileline>(?P<file>[-.\w/\\]+.java):(?P<line>[0-9]+):)'
- warning_re = re.compile(
- fileline_prefix + r'(?P<full_message> warning: (?P<message>.*))$')
- error_re = re.compile(
- fileline_prefix + r'(?P<full_message> (?P<message>.*))$')
- marker_re = re.compile(r'\s*(?P<marker>\^)\s*$')
-
- warning_color = ['full_message', colorama.Fore.YELLOW + colorama.Style.DIM]
- error_color = ['full_message', colorama.Fore.MAGENTA + colorama.Style.BRIGHT]
- marker_color = ['marker', colorama.Fore.BLUE + colorama.Style.BRIGHT]
-
- def Colorize(line, regex, color):
- match = regex.match(line)
- start = match.start(color[0])
- end = match.end(color[0])
- return (line[:start]
- + color[1] + line[start:end]
- + colorama.Fore.RESET + colorama.Style.RESET_ALL
- + line[end:])
-
- def ApplyColor(line):
- if warning_re.match(line):
- line = Colorize(line, warning_re, warning_color)
- elif error_re.match(line):
- line = Colorize(line, error_re, error_color)
- elif marker_re.match(line):
- line = Colorize(line, marker_re, marker_color)
- return line
-
- return '\n'.join(map(ApplyColor, output.split('\n')))
-
-
-ERRORPRONE_OPTIONS = [
- '-Xepdisable:'
- # Something in chrome_private_java makes this check crash.
- 'com.google.errorprone.bugpatterns.ClassCanBeStatic,'
- # These crash on lots of targets.
- 'com.google.errorprone.bugpatterns.WrongParameterPackage,'
- 'com.google.errorprone.bugpatterns.GuiceOverridesGuiceInjectableMethod,'
- 'com.google.errorprone.bugpatterns.GuiceOverridesJavaxInjectableMethod,'
- 'com.google.errorprone.bugpatterns.ElementsCountedInLoop'
-]
-
-def DoJavac(
- bootclasspath, classpath, classes_dir, chromium_code,
- use_errorprone_path, java_files):
- """Runs javac.
-
- Builds |java_files| with the provided |classpath| and puts the generated
- .class files into |classes_dir|. If |chromium_code| is true, extra lint
- checking will be enabled.
- """
-
- jar_inputs = []
- for path in classpath:
- if os.path.exists(path + '.TOC'):
- jar_inputs.append(path + '.TOC')
- else:
- jar_inputs.append(path)
-
- javac_args = [
- '-g',
- # Chromium only allows UTF8 source files. Being explicit avoids
- # javac pulling a default encoding from the user's environment.
- '-encoding', 'UTF-8',
- '-classpath', ':'.join(classpath),
- '-d', classes_dir]
-
- if bootclasspath:
- javac_args.extend([
- '-bootclasspath', ':'.join(bootclasspath),
- '-source', '1.7',
- '-target', '1.7',
- ])
-
- if chromium_code:
- # TODO(aurimas): re-enable '-Xlint:deprecation' checks once they are fixed.
- javac_args.extend(['-Xlint:unchecked'])
- else:
- # XDignore.symbol.file makes javac compile against rt.jar instead of
- # ct.sym. This means that using a java internal package/class will not
- # trigger a compile warning or error.
- javac_args.extend(['-XDignore.symbol.file'])
-
- if use_errorprone_path:
- javac_cmd = [use_errorprone_path] + ERRORPRONE_OPTIONS
- else:
- javac_cmd = ['javac']
-
- javac_cmd = javac_cmd + javac_args + java_files
-
- def Compile():
- build_utils.CheckOutput(
- javac_cmd,
- print_stdout=chromium_code,
- stderr_filter=ColorJavacOutput)
-
- record_path = os.path.join(classes_dir, 'javac.md5.stamp')
- md5_check.CallAndRecordIfStale(
- Compile,
- record_path=record_path,
- input_paths=java_files + jar_inputs,
- input_strings=javac_cmd)
-
-
-_MAX_MANIFEST_LINE_LEN = 72
-
-
-def CreateManifest(manifest_path, classpath, main_class=None,
- manifest_entries=None):
- """Creates a manifest file with the given parameters.
-
- This generates a manifest file that compiles with the spec found at
- http://docs.oracle.com/javase/7/docs/technotes/guides/jar/jar.html#JAR_Manifest
-
- Args:
- manifest_path: The path to the manifest file that should be created.
- classpath: The JAR files that should be listed on the manifest file's
- classpath.
- main_class: If present, the class containing the main() function.
- manifest_entries: If present, a list of (key, value) pairs to add to
- the manifest.
-
- """
- output = ['Manifest-Version: 1.0']
- if main_class:
- output.append('Main-Class: %s' % main_class)
- if manifest_entries:
- for k, v in manifest_entries:
- output.append('%s: %s' % (k, v))
- if classpath:
- sanitized_paths = []
- for path in classpath:
- sanitized_paths.append(os.path.basename(path.strip('"')))
- output.append('Class-Path: %s' % ' '.join(sanitized_paths))
- output.append('Created-By: ')
- output.append('')
-
- wrapper = textwrap.TextWrapper(break_long_words=True,
- drop_whitespace=False,
- subsequent_indent=' ',
- width=_MAX_MANIFEST_LINE_LEN - 2)
- output = '\r\n'.join(w for l in output for w in wrapper.wrap(l))
-
- with open(manifest_path, 'w') as f:
- f.write(output)
-
-
-def main(argv):
- colorama.init()
-
- argv = build_utils.ExpandFileArgs(argv)
-
- parser = optparse.OptionParser()
- build_utils.AddDepfileOption(parser)
-
- parser.add_option(
- '--src-gendirs',
- help='Directories containing generated java files.')
- parser.add_option(
- '--java-srcjars',
- action='append',
- default=[],
- help='List of srcjars to include in compilation.')
- parser.add_option(
- '--bootclasspath',
- action='append',
- default=[],
- help='Boot classpath for javac. If this is specified multiple times, '
- 'they will all be appended to construct the classpath.')
- parser.add_option(
- '--classpath',
- action='append',
- help='Classpath for javac. If this is specified multiple times, they '
- 'will all be appended to construct the classpath.')
- parser.add_option(
- '--javac-includes',
- help='A list of file patterns. If provided, only java files that match'
- 'one of the patterns will be compiled.')
- parser.add_option(
- '--jar-excluded-classes',
- default='',
- help='List of .class file patterns to exclude from the jar.')
-
- parser.add_option(
- '--chromium-code',
- type='int',
- help='Whether code being compiled should be built with stricter '
- 'warnings for chromium code.')
-
- parser.add_option(
- '--use-errorprone-path',
- help='Use the Errorprone compiler at this path.')
-
- parser.add_option(
- '--classes-dir',
- help='Directory for compiled .class files.')
- parser.add_option('--jar-path', help='Jar output path.')
- parser.add_option(
- '--main-class',
- help='The class containing the main method.')
- parser.add_option(
- '--manifest-entry',
- action='append',
- help='Key:value pairs to add to the .jar manifest.')
-
- parser.add_option('--stamp', help='Path to touch on success.')
-
- options, args = parser.parse_args(argv)
-
- if options.main_class and not options.jar_path:
- parser.error('--main-class requires --jar-path')
-
- bootclasspath = []
- for arg in options.bootclasspath:
- bootclasspath += build_utils.ParseGypList(arg)
-
- classpath = []
- for arg in options.classpath:
- classpath += build_utils.ParseGypList(arg)
-
- java_srcjars = []
- for arg in options.java_srcjars:
- java_srcjars += build_utils.ParseGypList(arg)
-
- java_files = args
- if options.src_gendirs:
- src_gendirs = build_utils.ParseGypList(options.src_gendirs)
- java_files += build_utils.FindInDirectories(src_gendirs, '*.java')
-
- input_files = bootclasspath + classpath + java_srcjars + java_files
- with build_utils.TempDir() as temp_dir:
- classes_dir = os.path.join(temp_dir, 'classes')
- os.makedirs(classes_dir)
- if java_srcjars:
- java_dir = os.path.join(temp_dir, 'java')
- os.makedirs(java_dir)
- for srcjar in java_srcjars:
- build_utils.ExtractAll(srcjar, path=java_dir, pattern='*.java')
- java_files += build_utils.FindInDirectory(java_dir, '*.java')
-
- if options.javac_includes:
- javac_includes = build_utils.ParseGypList(options.javac_includes)
- filtered_java_files = []
- for f in java_files:
- for include in javac_includes:
- if fnmatch.fnmatch(f, include):
- filtered_java_files.append(f)
- break
- java_files = filtered_java_files
-
- if len(java_files) != 0:
- DoJavac(
- bootclasspath,
- classpath,
- classes_dir,
- options.chromium_code,
- options.use_errorprone_path,
- java_files)
-
- if options.jar_path:
- if options.main_class or options.manifest_entry:
- if options.manifest_entry:
- entries = map(lambda e: e.split(":"), options.manifest_entry)
- else:
- entries = []
- manifest_file = os.path.join(temp_dir, 'manifest')
- CreateManifest(manifest_file, classpath, options.main_class, entries)
- else:
- manifest_file = None
- jar.JarDirectory(classes_dir,
- build_utils.ParseGypList(options.jar_excluded_classes),
- options.jar_path,
- manifest_file=manifest_file)
-
- if options.classes_dir:
- # Delete the old classes directory. This ensures that all .class files in
- # the output are actually from the input .java files. For example, if a
- # .java file is deleted or an inner class is removed, the classes
- # directory should not contain the corresponding old .class file after
- # running this action.
- build_utils.DeleteDirectory(options.classes_dir)
- shutil.copytree(classes_dir, options.classes_dir)
-
- if options.depfile:
- build_utils.WriteDepfile(
- options.depfile,
- input_files + build_utils.GetPythonDependencies())
-
- if options.stamp:
- build_utils.Touch(options.stamp)
-
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv[1:]))
-
-
diff --git a/build/android/gyp/jinja_template.py b/build/android/gyp/jinja_template.py
deleted file mode 100755
index e7c9a34..0000000
--- a/build/android/gyp/jinja_template.py
+++ /dev/null
@@ -1,121 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Renders one or more template files using the Jinja template engine."""
-
-import codecs
-import optparse
-import os
-import sys
-
-from util import build_utils
-
-# Import jinja2 from third_party/jinja2
-sys.path.append(os.path.join(os.path.dirname(__file__), '../../../third_party'))
-import jinja2 # pylint: disable=F0401
-
-
-class RecordingFileSystemLoader(jinja2.FileSystemLoader):
- '''A FileSystemLoader that stores a list of loaded templates.'''
- def __init__(self, searchpath):
- jinja2.FileSystemLoader.__init__(self, searchpath)
- self.loaded_templates = set()
-
- def get_source(self, environment, template):
- contents, filename, uptodate = jinja2.FileSystemLoader.get_source(
- self, environment, template)
- self.loaded_templates.add(os.path.relpath(filename))
- return contents, filename, uptodate
-
- def get_loaded_templates(self):
- return list(self.loaded_templates)
-
-
-def ProcessFile(env, input_filename, loader_base_dir, output_filename,
- variables):
- input_rel_path = os.path.relpath(input_filename, loader_base_dir)
- template = env.get_template(input_rel_path)
- output = template.render(variables)
- with codecs.open(output_filename, 'w', 'utf-8') as output_file:
- output_file.write(output)
-
-
-def ProcessFiles(env, input_filenames, loader_base_dir, inputs_base_dir,
- outputs_zip, variables):
- with build_utils.TempDir() as temp_dir:
- for input_filename in input_filenames:
- relpath = os.path.relpath(os.path.abspath(input_filename),
- os.path.abspath(inputs_base_dir))
- if relpath.startswith(os.pardir):
- raise Exception('input file %s is not contained in inputs base dir %s'
- % (input_filename, inputs_base_dir))
-
- output_filename = os.path.join(temp_dir, relpath)
- parent_dir = os.path.dirname(output_filename)
- build_utils.MakeDirectory(parent_dir)
- ProcessFile(env, input_filename, loader_base_dir, output_filename,
- variables)
-
- build_utils.ZipDir(outputs_zip, temp_dir)
-
-
-def main():
- parser = optparse.OptionParser()
- build_utils.AddDepfileOption(parser)
- parser.add_option('--inputs', help='The template files to process.')
- parser.add_option('--output', help='The output file to generate. Valid '
- 'only if there is a single input.')
- parser.add_option('--outputs-zip', help='A zip file containing the processed '
- 'templates. Required if there are multiple inputs.')
- parser.add_option('--inputs-base-dir', help='A common ancestor directory of '
- 'the inputs. Each output\'s path in the output zip will '
- 'match the relative path from INPUTS_BASE_DIR to the '
- 'input. Required if --output-zip is given.')
- parser.add_option('--loader-base-dir', help='Base path used by the template '
- 'loader. Must be a common ancestor directory of '
- 'the inputs. Defaults to CHROMIUM_SRC.',
- default=build_utils.CHROMIUM_SRC)
- parser.add_option('--variables', help='Variables to be made available in the '
- 'template processing environment, as a GYP list (e.g. '
- '--variables "channel=beta mstone=39")', default='')
- options, args = parser.parse_args()
-
- build_utils.CheckOptions(options, parser, required=['inputs'])
- inputs = build_utils.ParseGypList(options.inputs)
-
- if (options.output is None) == (options.outputs_zip is None):
- parser.error('Exactly one of --output and --output-zip must be given')
- if options.output and len(inputs) != 1:
- parser.error('--output cannot be used with multiple inputs')
- if options.outputs_zip and not options.inputs_base_dir:
- parser.error('--inputs-base-dir must be given when --output-zip is used')
- if args:
- parser.error('No positional arguments should be given.')
-
- variables = {}
- for v in build_utils.ParseGypList(options.variables):
- if '=' not in v:
- parser.error('--variables argument must contain "=": ' + v)
- name, _, value = v.partition('=')
- variables[name] = value
-
- loader = RecordingFileSystemLoader(options.loader_base_dir)
- env = jinja2.Environment(loader=loader, undefined=jinja2.StrictUndefined,
- line_comment_prefix='##')
- if options.output:
- ProcessFile(env, inputs[0], options.loader_base_dir, options.output,
- variables)
- else:
- ProcessFiles(env, inputs, options.loader_base_dir, options.inputs_base_dir,
- options.outputs_zip, variables)
-
- if options.depfile:
- deps = loader.get_loaded_templates() + build_utils.GetPythonDependencies()
- build_utils.WriteDepfile(options.depfile, deps)
-
-
-if __name__ == '__main__':
- main()
diff --git a/build/android/gyp/lint.py b/build/android/gyp/lint.py
deleted file mode 100755
index 6c4645a..0000000
--- a/build/android/gyp/lint.py
+++ /dev/null
@@ -1,214 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (c) 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Runs Android's lint tool."""
-
-
-import optparse
-import os
-import sys
-from xml.dom import minidom
-
-from util import build_utils
-
-
-_SRC_ROOT = os.path.abspath(os.path.join(os.path.dirname(__file__),
- '..', '..', '..'))
-
-
-def _RunLint(lint_path, config_path, processed_config_path, manifest_path,
- result_path, product_dir, sources, jar_path, resource_dir=None):
-
- def _RelativizePath(path):
- """Returns relative path to top-level src dir.
-
- Args:
- path: A path relative to cwd.
- """
- return os.path.relpath(os.path.abspath(path), _SRC_ROOT)
-
- def _ProcessConfigFile():
- if not build_utils.IsTimeStale(processed_config_path, [config_path]):
- return
-
- with open(config_path, 'rb') as f:
- content = f.read().replace(
- 'PRODUCT_DIR', _RelativizePath(product_dir))
-
- with open(processed_config_path, 'wb') as f:
- f.write(content)
-
- def _ProcessResultFile():
- with open(result_path, 'rb') as f:
- content = f.read().replace(
- _RelativizePath(product_dir), 'PRODUCT_DIR')
-
- with open(result_path, 'wb') as f:
- f.write(content)
-
- def _ParseAndShowResultFile():
- dom = minidom.parse(result_path)
- issues = dom.getElementsByTagName('issue')
- print >> sys.stderr
- for issue in issues:
- issue_id = issue.attributes['id'].value
- message = issue.attributes['message'].value
- location_elem = issue.getElementsByTagName('location')[0]
- path = location_elem.attributes['file'].value
- line = location_elem.getAttribute('line')
- if line:
- error = '%s:%s %s: %s [warning]' % (path, line, message, issue_id)
- else:
- # Issues in class files don't have a line number.
- error = '%s %s: %s [warning]' % (path, message, issue_id)
- print >> sys.stderr, error
- for attr in ['errorLine1', 'errorLine2']:
- error_line = issue.getAttribute(attr)
- if error_line:
- print >> sys.stderr, error_line
- return len(issues)
-
- with build_utils.TempDir() as temp_dir:
- _ProcessConfigFile()
-
- cmd = [
- _RelativizePath(lint_path), '-Werror', '--exitcode', '--showall',
- '--config', _RelativizePath(processed_config_path),
- '--classpath', _RelativizePath(jar_path),
- '--xml', _RelativizePath(result_path),
- ]
- if resource_dir:
- cmd.extend(['--resources', _RelativizePath(resource_dir)])
-
- # There may be multiple source files with the same basename (but in
- # different directories). It is difficult to determine what part of the path
- # corresponds to the java package, and so instead just link the source files
- # into temporary directories (creating a new one whenever there is a name
- # conflict).
- src_dirs = []
- def NewSourceDir():
- new_dir = os.path.join(temp_dir, str(len(src_dirs)))
- os.mkdir(new_dir)
- src_dirs.append(new_dir)
- cmd.extend(['--sources', _RelativizePath(new_dir)])
- return new_dir
-
- def PathInDir(d, src):
- return os.path.join(d, os.path.basename(src))
-
- for src in sources:
- src_dir = None
- for d in src_dirs:
- if not os.path.exists(PathInDir(d, src)):
- src_dir = d
- break
- if not src_dir:
- src_dir = NewSourceDir()
- os.symlink(os.path.abspath(src), PathInDir(src_dir, src))
-
- cmd.append(_RelativizePath(os.path.join(manifest_path, os.pardir)))
-
- if os.path.exists(result_path):
- os.remove(result_path)
-
- try:
- build_utils.CheckOutput(cmd, cwd=_SRC_ROOT)
- except build_utils.CalledProcessError as e:
- # There is a problem with lint usage
- if not os.path.exists(result_path):
- print 'Something is wrong:'
- print e
- return 1
-
- # There are actual lint issues
- else:
- try:
- num_issues = _ParseAndShowResultFile()
- except Exception:
- print 'Lint created unparseable xml file...'
- print 'File contents:'
- with open(result_path) as f:
- print f.read()
- return 1
-
- _ProcessResultFile()
- msg = ('\nLint found %d new issues.\n'
- ' - For full explanation refer to %s\n'
- ' - Wanna suppress these issues?\n'
- ' 1. Read comment in %s\n'
- ' 2. Run "python %s %s"\n' %
- (num_issues,
- _RelativizePath(result_path),
- _RelativizePath(config_path),
- _RelativizePath(os.path.join(_SRC_ROOT, 'build', 'android',
- 'lint', 'suppress.py')),
- _RelativizePath(result_path)))
- print >> sys.stderr, msg
- return 1
-
- return 0
-
-
-def main():
- parser = optparse.OptionParser()
- build_utils.AddDepfileOption(parser)
- parser.add_option('--lint-path', help='Path to lint executable.')
- parser.add_option('--config-path', help='Path to lint suppressions file.')
- parser.add_option('--processed-config-path',
- help='Path to processed lint suppressions file.')
- parser.add_option('--manifest-path', help='Path to AndroidManifest.xml')
- parser.add_option('--result-path', help='Path to XML lint result file.')
- parser.add_option('--product-dir', help='Path to product dir.')
- parser.add_option('--src-dirs', help='Directories containing java files.')
- parser.add_option('--java-files', help='Paths to java files.')
- parser.add_option('--jar-path', help='Jar file containing class files.')
- parser.add_option('--resource-dir', help='Path to resource dir.')
- parser.add_option('--can-fail-build', action='store_true',
- help='If set, script will exit with nonzero exit status'
- ' if lint errors are present')
- parser.add_option('--stamp', help='Path to touch on success.')
- parser.add_option('--enable', action='store_true',
- help='Run lint instead of just touching stamp.')
-
- options, _ = parser.parse_args()
-
- build_utils.CheckOptions(
- options, parser, required=['lint_path', 'config_path',
- 'processed_config_path', 'manifest_path',
- 'result_path', 'product_dir',
- 'jar_path'])
-
- rc = 0
-
- if options.enable:
- sources = []
- if options.src_dirs:
- src_dirs = build_utils.ParseGypList(options.src_dirs)
- sources = build_utils.FindInDirectories(src_dirs, '*.java')
- elif options.java_files:
- sources = build_utils.ParseGypList(options.java_files)
- else:
- print 'One of --src-dirs or --java-files must be specified.'
- return 1
- rc = _RunLint(options.lint_path, options.config_path,
- options.processed_config_path,
- options.manifest_path, options.result_path,
- options.product_dir, sources, options.jar_path,
- options.resource_dir)
-
- if options.depfile:
- build_utils.WriteDepfile(
- options.depfile,
- build_utils.GetPythonDependencies())
-
- if options.stamp and not rc:
- build_utils.Touch(options.stamp)
-
- return rc if options.can_fail_build else 0
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/build/android/gyp/locale_pak_resources.py b/build/android/gyp/locale_pak_resources.py
deleted file mode 100755
index 84c4a37..0000000
--- a/build/android/gyp/locale_pak_resources.py
+++ /dev/null
@@ -1,126 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-"""Creates a resources.zip for locale .pak files.
-
-Places the locale.pak files into appropriate resource configs
-(e.g. en-GB.pak -> res/raw-en/en_gb.lpak). Also generates a locale_paks
-TypedArray so that resource files can be enumerated at runtime.
-"""
-
-import collections
-import optparse
-import os
-import sys
-import zipfile
-
-from util import build_utils
-
-
-# This should stay in sync with:
-# base/android/java/src/org/chromium/base/LocaleUtils.java
-_CHROME_TO_ANDROID_LOCALE_MAP = {
- 'he': 'iw',
- 'id': 'in',
- 'fil': 'tl',
-}
-
-
-def ToResourceFileName(name):
- """Returns the resource-compatible file name for the given file."""
- # Resources file names must consist of [a-z0-9_.].
- # Changes extension to .lpak so that compression can be toggled separately for
- # locale pak files vs other pak files.
- return name.replace('-', '_').replace('.pak', '.lpak').lower()
-
-
-def CreateLocalePaksXml(names):
- """Creates the contents for the locale-paks.xml files."""
- VALUES_FILE_TEMPLATE = '''<?xml version="1.0" encoding="utf-8"?>
-<resources>
- <array name="locale_paks">%s
- </array>
-</resources>
-'''
- VALUES_ITEM_TEMPLATE = '''
- <item>@raw/%s</item>'''
-
- res_names = (os.path.splitext(name)[0] for name in names)
- items = ''.join((VALUES_ITEM_TEMPLATE % name for name in res_names))
- return VALUES_FILE_TEMPLATE % items
-
-
-def ComputeMappings(sources):
- """Computes the mappings of sources -> resources.
-
- Returns a tuple of:
- - mappings: List of (src, dest) paths
- - lang_to_locale_map: Map of language -> list of resource names
- e.g. "en" -> ["en_gb.lpak"]
- """
- lang_to_locale_map = collections.defaultdict(list)
- mappings = []
- for src_path in sources:
- basename = os.path.basename(src_path)
- name = os.path.splitext(basename)[0]
- res_name = ToResourceFileName(basename)
- if name == 'en-US':
- dest_dir = 'raw'
- else:
- # Chrome's uses different region mapping logic from Android, so include
- # all regions for each language.
- android_locale = _CHROME_TO_ANDROID_LOCALE_MAP.get(name, name)
- lang = android_locale[0:2]
- dest_dir = 'raw-' + lang
- lang_to_locale_map[lang].append(res_name)
- mappings.append((src_path, os.path.join(dest_dir, res_name)))
- return mappings, lang_to_locale_map
-
-
-def main():
- parser = optparse.OptionParser()
- build_utils.AddDepfileOption(parser)
- parser.add_option('--locale-paks', help='List of files for res/raw-LOCALE')
- parser.add_option('--resources-zip', help='Path to output resources.zip')
- parser.add_option('--print-languages',
- action='store_true',
- help='Print out the list of languages that cover the given locale paks '
- '(using Android\'s language codes)')
-
- options, _ = parser.parse_args()
- build_utils.CheckOptions(options, parser,
- required=['locale_paks'])
-
- sources = build_utils.ParseGypList(options.locale_paks)
-
- if options.depfile:
- deps = sources + build_utils.GetPythonDependencies()
- build_utils.WriteDepfile(options.depfile, deps)
-
- mappings, lang_to_locale_map = ComputeMappings(sources)
- if options.print_languages:
- print '\n'.join(sorted(lang_to_locale_map))
-
- if options.resources_zip:
- with zipfile.ZipFile(options.resources_zip, 'w', zipfile.ZIP_STORED) as out:
- for mapping in mappings:
- out.write(mapping[0], mapping[1])
-
- # Create TypedArray resources so ResourceExtractor can enumerate files.
- def WriteValuesFile(lang, names):
- dest_dir = 'values'
- if lang:
- dest_dir += '-' + lang
- # Always extract en-US.lpak since it's the fallback.
- xml = CreateLocalePaksXml(names + ['en_us.lpak'])
- out.writestr(os.path.join(dest_dir, 'locale-paks.xml'), xml)
-
- for lang, names in lang_to_locale_map.iteritems():
- WriteValuesFile(lang, names)
- WriteValuesFile(None, [])
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/build/android/gyp/pack_relocations.py b/build/android/gyp/pack_relocations.py
deleted file mode 100755
index 02e4499..0000000
--- a/build/android/gyp/pack_relocations.py
+++ /dev/null
@@ -1,107 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Pack relocations in a library (or copy unchanged).
-
-If --enable-packing and --configuration-name=='Release', invoke the
-relocation_packer tool to pack the .rel.dyn or .rela.dyn section in the given
-library files. This step is inserted after the libraries are stripped.
-
-If --enable-packing is zero, the script copies files verbatim, with no
-attempt to pack relocations.
-
-Any library listed in --exclude-packing-list is also copied verbatim,
-irrespective of any --enable-packing setting. Typically this would be
-'libchromium_android_linker.so'.
-"""
-
-import optparse
-import os
-import shlex
-import shutil
-import sys
-import tempfile
-
-from util import build_utils
-
-def PackLibraryRelocations(android_pack_relocations, library_path, output_path):
- shutil.copy(library_path, output_path)
- pack_command = [android_pack_relocations, output_path]
- build_utils.CheckOutput(pack_command)
-
-
-def CopyLibraryUnchanged(library_path, output_path):
- shutil.copy(library_path, output_path)
-
-
-def main(args):
- args = build_utils.ExpandFileArgs(args)
- parser = optparse.OptionParser()
- build_utils.AddDepfileOption(parser)
- parser.add_option('--clear-dir', action='store_true',
- help='If set, the destination directory will be deleted '
- 'before copying files to it. This is highly recommended to '
- 'ensure that no stale files are left in the directory.')
-
- parser.add_option('--configuration-name',
- default='Release',
- help='Gyp configuration name (i.e. Debug, Release)')
- parser.add_option('--enable-packing',
- choices=['0', '1'],
- help=('Pack relocations if 1 and configuration name is \'Release\','
- ' otherwise plain file copy'))
- parser.add_option('--exclude-packing-list',
- default='',
- help='Names of any libraries explicitly not packed')
- parser.add_option('--android-pack-relocations',
- help='Path to the relocations packer binary')
- parser.add_option('--stripped-libraries-dir',
- help='Directory for stripped libraries')
- parser.add_option('--packed-libraries-dir',
- help='Directory for packed libraries')
- parser.add_option('--libraries', action='append',
- help='List of libraries')
- parser.add_option('--stamp', help='Path to touch on success')
-
- options, _ = parser.parse_args(args)
- enable_packing = (options.enable_packing == '1' and
- options.configuration_name == 'Release')
- exclude_packing_set = set(shlex.split(options.exclude_packing_list))
-
- libraries = []
- for libs_arg in options.libraries:
- libraries += build_utils.ParseGypList(libs_arg)
-
- if options.clear_dir:
- build_utils.DeleteDirectory(options.packed_libraries_dir)
-
- build_utils.MakeDirectory(options.packed_libraries_dir)
-
- for library in libraries:
- library_path = os.path.join(options.stripped_libraries_dir, library)
- output_path = os.path.join(
- options.packed_libraries_dir, os.path.basename(library))
-
- if enable_packing and library not in exclude_packing_set:
- PackLibraryRelocations(options.android_pack_relocations,
- library_path,
- output_path)
- else:
- CopyLibraryUnchanged(library_path, output_path)
-
- if options.depfile:
- build_utils.WriteDepfile(
- options.depfile,
- libraries + build_utils.GetPythonDependencies())
-
- if options.stamp:
- build_utils.Touch(options.stamp)
-
- return 0
-
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv[1:]))
diff --git a/build/android/gyp/package_resources.py b/build/android/gyp/package_resources.py
deleted file mode 100755
index d17d1fe..0000000
--- a/build/android/gyp/package_resources.py
+++ /dev/null
@@ -1,270 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# pylint: disable=C0301
-"""Package resources into an apk.
-
-See https://android.googlesource.com/platform/tools/base/+/master/legacy/ant-tasks/src/main/java/com/android/ant/AaptExecTask.java
-and
-https://android.googlesource.com/platform/sdk/+/master/files/ant/build.xml
-"""
-# pylint: enable=C0301
-
-import optparse
-import os
-import re
-import shutil
-import zipfile
-
-from util import build_utils
-
-
-# List is generated from the chrome_apk.apk_intermediates.ap_ via:
-# unzip -l $FILE_AP_ | cut -c31- | grep res/draw | cut -d'/' -f 2 | sort \
-# | uniq | grep -- -tvdpi- | cut -c10-
-# and then manually sorted.
-# Note that we can't just do a cross-product of dimentions because the filenames
-# become too big and aapt fails to create the files.
-# This leaves all default drawables (mdpi) in the main apk. Android gets upset
-# though if any drawables are missing from the default drawables/ directory.
-DENSITY_SPLITS = {
- 'hdpi': (
- 'hdpi-v4', # Order matters for output file names.
- 'ldrtl-hdpi-v4',
- 'sw600dp-hdpi-v13',
- 'ldrtl-hdpi-v17',
- 'ldrtl-sw600dp-hdpi-v17',
- 'hdpi-v21',
- ),
- 'xhdpi': (
- 'xhdpi-v4',
- 'ldrtl-xhdpi-v4',
- 'sw600dp-xhdpi-v13',
- 'ldrtl-xhdpi-v17',
- 'ldrtl-sw600dp-xhdpi-v17',
- 'xhdpi-v21',
- ),
- 'xxhdpi': (
- 'xxhdpi-v4',
- 'ldrtl-xxhdpi-v4',
- 'sw600dp-xxhdpi-v13',
- 'ldrtl-xxhdpi-v17',
- 'ldrtl-sw600dp-xxhdpi-v17',
- 'xxhdpi-v21',
- ),
- 'xxxhdpi': (
- 'xxxhdpi-v4',
- 'ldrtl-xxxhdpi-v4',
- 'sw600dp-xxxhdpi-v13',
- 'ldrtl-xxxhdpi-v17',
- 'ldrtl-sw600dp-xxxhdpi-v17',
- 'xxxhdpi-v21',
- ),
- 'tvdpi': (
- 'tvdpi-v4',
- 'sw600dp-tvdpi-v13',
- 'ldrtl-sw600dp-tvdpi-v17',
- ),
-}
-
-
-def ParseArgs():
- """Parses command line options.
-
- Returns:
- An options object as from optparse.OptionsParser.parse_args()
- """
- parser = optparse.OptionParser()
- build_utils.AddDepfileOption(parser)
- parser.add_option('--android-sdk', help='path to the Android SDK folder')
- parser.add_option('--aapt-path',
- help='path to the Android aapt tool')
-
- parser.add_option('--configuration-name',
- help='Gyp\'s configuration name (Debug or Release).')
-
- parser.add_option('--android-manifest', help='AndroidManifest.xml path')
- parser.add_option('--version-code', help='Version code for apk.')
- parser.add_option('--version-name', help='Version name for apk.')
- parser.add_option(
- '--shared-resources',
- action='store_true',
- help='Make a resource package that can be loaded by a different'
- 'application at runtime to access the package\'s resources.')
- parser.add_option('--resource-zips',
- help='zip files containing resources to be packaged')
- parser.add_option('--asset-dir',
- help='directories containing assets to be packaged')
- parser.add_option('--no-compress', help='disables compression for the '
- 'given comma separated list of extensions')
- parser.add_option(
- '--create-density-splits',
- action='store_true',
- help='Enables density splits')
- parser.add_option('--language-splits',
- help='GYP list of languages to create splits for')
-
- parser.add_option('--apk-path',
- help='Path to output (partial) apk.')
-
- (options, args) = parser.parse_args()
-
- if args:
- parser.error('No positional arguments should be given.')
-
- # Check that required options have been provided.
- required_options = ('android_sdk', 'aapt_path', 'configuration_name',
- 'android_manifest', 'version_code', 'version_name',
- 'apk_path')
-
- build_utils.CheckOptions(options, parser, required=required_options)
-
- return options
-
-
-def MoveImagesToNonMdpiFolders(res_root):
- """Move images from drawable-*-mdpi-* folders to drawable-* folders.
-
- Why? http://crbug.com/289843
- """
- for src_dir_name in os.listdir(res_root):
- src_components = src_dir_name.split('-')
- if src_components[0] != 'drawable' or 'mdpi' not in src_components:
- continue
- src_dir = os.path.join(res_root, src_dir_name)
- if not os.path.isdir(src_dir):
- continue
- dst_components = [c for c in src_components if c != 'mdpi']
- assert dst_components != src_components
- dst_dir_name = '-'.join(dst_components)
- dst_dir = os.path.join(res_root, dst_dir_name)
- build_utils.MakeDirectory(dst_dir)
- for src_file_name in os.listdir(src_dir):
- if not src_file_name.endswith('.png'):
- continue
- src_file = os.path.join(src_dir, src_file_name)
- dst_file = os.path.join(dst_dir, src_file_name)
- assert not os.path.lexists(dst_file)
- shutil.move(src_file, dst_file)
-
-
-def PackageArgsForExtractedZip(d):
- """Returns the aapt args for an extracted resources zip.
-
- A resources zip either contains the resources for a single target or for
- multiple targets. If it is multiple targets merged into one, the actual
- resource directories will be contained in the subdirectories 0, 1, 2, ...
- """
- subdirs = [os.path.join(d, s) for s in os.listdir(d)]
- subdirs = [s for s in subdirs if os.path.isdir(s)]
- is_multi = '0' in [os.path.basename(s) for s in subdirs]
- if is_multi:
- res_dirs = sorted(subdirs, key=lambda p : int(os.path.basename(p)))
- else:
- res_dirs = [d]
- package_command = []
- for d in res_dirs:
- MoveImagesToNonMdpiFolders(d)
- package_command += ['-S', d]
- return package_command
-
-
-def RenameDensitySplits(apk_path):
- """Renames all density splits to have shorter / predictable names."""
- for density, config in DENSITY_SPLITS.iteritems():
- src_path = '%s_%s' % (apk_path, '_'.join(config))
- dst_path = '%s_%s' % (apk_path, density)
- if src_path != dst_path:
- if os.path.exists(dst_path):
- os.unlink(dst_path)
- os.rename(src_path, dst_path)
-
-
-def CheckForMissedConfigs(apk_path, check_density, languages):
- """Raises an exception if apk_path contains any unexpected configs."""
- triggers = []
- if check_density:
- triggers.extend(re.compile('-%s' % density) for density in DENSITY_SPLITS)
- if languages:
- triggers.extend(re.compile(r'-%s\b' % lang) for lang in languages)
- with zipfile.ZipFile(apk_path) as main_apk_zip:
- for name in main_apk_zip.namelist():
- for trigger in triggers:
- if trigger.search(name) and not 'mipmap-' in name:
- raise Exception(('Found config in main apk that should have been ' +
- 'put into a split: %s\nYou need to update ' +
- 'package_resources.py to include this new ' +
- 'config (trigger=%s)') % (name, trigger.pattern))
-
-
-def main():
- options = ParseArgs()
- android_jar = os.path.join(options.android_sdk, 'android.jar')
- aapt = options.aapt_path
-
- with build_utils.TempDir() as temp_dir:
- package_command = [aapt,
- 'package',
- '--version-code', options.version_code,
- '--version-name', options.version_name,
- '-M', options.android_manifest,
- '--no-crunch',
- '-f',
- '--auto-add-overlay',
- '-I', android_jar,
- '-F', options.apk_path,
- '--ignore-assets', build_utils.AAPT_IGNORE_PATTERN,
- ]
-
- if options.no_compress:
- for ext in options.no_compress.split(','):
- package_command += ['-0', ext]
- if options.shared_resources:
- package_command.append('--shared-lib')
-
- if options.asset_dir and os.path.exists(options.asset_dir):
- package_command += ['-A', options.asset_dir]
-
- if options.resource_zips:
- dep_zips = build_utils.ParseGypList(options.resource_zips)
- for z in dep_zips:
- subdir = os.path.join(temp_dir, os.path.basename(z))
- if os.path.exists(subdir):
- raise Exception('Resource zip name conflict: ' + os.path.basename(z))
- build_utils.ExtractAll(z, path=subdir)
- package_command += PackageArgsForExtractedZip(subdir)
-
- if options.create_density_splits:
- for config in DENSITY_SPLITS.itervalues():
- package_command.extend(('--split', ','.join(config)))
-
- language_splits = None
- if options.language_splits:
- language_splits = build_utils.ParseGypList(options.language_splits)
- for lang in language_splits:
- package_command.extend(('--split', lang))
-
- if 'Debug' in options.configuration_name:
- package_command += ['--debug-mode']
-
- build_utils.CheckOutput(
- package_command, print_stdout=False, print_stderr=False)
-
- if options.create_density_splits or language_splits:
- CheckForMissedConfigs(
- options.apk_path, options.create_density_splits, language_splits)
-
- if options.create_density_splits:
- RenameDensitySplits(options.apk_path)
-
- if options.depfile:
- build_utils.WriteDepfile(
- options.depfile,
- build_utils.GetPythonDependencies())
-
-
-if __name__ == '__main__':
- main()
diff --git a/build/android/gyp/process_resources.py b/build/android/gyp/process_resources.py
deleted file mode 100755
index d227954..0000000
--- a/build/android/gyp/process_resources.py
+++ /dev/null
@@ -1,420 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Process Android resources to generate R.java, and prepare for packaging.
-
-This will crunch images and generate v14 compatible resources
-(see generate_v14_compatible_resources.py).
-"""
-
-import codecs
-import optparse
-import os
-import re
-import shutil
-import sys
-import zipfile
-
-import generate_v14_compatible_resources
-
-from util import build_utils
-
-# Import jinja2 from third_party/jinja2
-sys.path.insert(1,
- os.path.join(os.path.dirname(__file__), '../../../third_party'))
-from jinja2 import Template # pylint: disable=F0401
-
-
-def ParseArgs(args):
- """Parses command line options.
-
- Returns:
- An options object as from optparse.OptionsParser.parse_args()
- """
- parser = optparse.OptionParser()
- build_utils.AddDepfileOption(parser)
-
- parser.add_option('--android-sdk', help='path to the Android SDK folder')
- parser.add_option('--aapt-path',
- help='path to the Android aapt tool')
- parser.add_option('--non-constant-id', action='store_true')
-
- parser.add_option('--android-manifest', help='AndroidManifest.xml path')
- parser.add_option('--custom-package', help='Java package for R.java')
- parser.add_option(
- '--shared-resources',
- action='store_true',
- help='Make a resource package that can be loaded by a different'
- 'application at runtime to access the package\'s resources.')
-
- parser.add_option('--resource-dirs',
- help='Directories containing resources of this target.')
- parser.add_option('--dependencies-res-zips',
- help='Resources from dependents.')
-
- parser.add_option('--resource-zip-out',
- help='Path for output zipped resources.')
-
- parser.add_option('--R-dir',
- help='directory to hold generated R.java.')
- parser.add_option('--srcjar-out',
- help='Path to srcjar to contain generated R.java.')
- parser.add_option('--r-text-out',
- help='Path to store the R.txt file generated by appt.')
-
- parser.add_option('--proguard-file',
- help='Path to proguard.txt generated file')
-
- parser.add_option(
- '--v14-skip',
- action="store_true",
- help='Do not generate nor verify v14 resources')
-
- parser.add_option(
- '--extra-res-packages',
- help='Additional package names to generate R.java files for')
- parser.add_option(
- '--extra-r-text-files',
- help='For each additional package, the R.txt file should contain a '
- 'list of resources to be included in the R.java file in the format '
- 'generated by aapt')
- parser.add_option(
- '--include-all-resources',
- action='store_true',
- help='Include every resource ID in every generated R.java file '
- '(ignoring R.txt).')
-
- parser.add_option(
- '--all-resources-zip-out',
- help='Path for output of all resources. This includes resources in '
- 'dependencies.')
-
- parser.add_option('--stamp', help='File to touch on success')
-
- (options, args) = parser.parse_args(args)
-
- if args:
- parser.error('No positional arguments should be given.')
-
- # Check that required options have been provided.
- required_options = (
- 'android_sdk',
- 'aapt_path',
- 'android_manifest',
- 'dependencies_res_zips',
- 'resource_dirs',
- 'resource_zip_out',
- )
- build_utils.CheckOptions(options, parser, required=required_options)
-
- if (options.R_dir is None) == (options.srcjar_out is None):
- raise Exception('Exactly one of --R-dir or --srcjar-out must be specified.')
-
- return options
-
-
-def CreateExtraRJavaFiles(
- r_dir, extra_packages, extra_r_text_files, shared_resources, include_all):
- if include_all:
- java_files = build_utils.FindInDirectory(r_dir, "R.java")
- if len(java_files) != 1:
- return
- r_java_file = java_files[0]
- r_java_contents = codecs.open(r_java_file, encoding='utf-8').read()
-
- for package in extra_packages:
- package_r_java_dir = os.path.join(r_dir, *package.split('.'))
- build_utils.MakeDirectory(package_r_java_dir)
- package_r_java_path = os.path.join(package_r_java_dir, 'R.java')
- new_r_java = re.sub(r'package [.\w]*;', u'package %s;' % package,
- r_java_contents)
- codecs.open(package_r_java_path, 'w', encoding='utf-8').write(new_r_java)
- else:
- if len(extra_packages) != len(extra_r_text_files):
- raise Exception('Need one R.txt file per extra package')
-
- all_resources = {}
- r_txt_file = os.path.join(r_dir, 'R.txt')
- if not os.path.exists(r_txt_file):
- return
- with open(r_txt_file) as f:
- for line in f:
- m = re.match(r'(int(?:\[\])?) (\w+) (\w+) (.+)$', line)
- if not m:
- raise Exception('Unexpected line in R.txt: %s' % line)
- java_type, resource_type, name, value = m.groups()
- all_resources[(resource_type, name)] = (java_type, value)
-
- for package, r_text_file in zip(extra_packages, extra_r_text_files):
- if os.path.exists(r_text_file):
- package_r_java_dir = os.path.join(r_dir, *package.split('.'))
- build_utils.MakeDirectory(package_r_java_dir)
- package_r_java_path = os.path.join(package_r_java_dir, 'R.java')
- CreateExtraRJavaFile(
- package, package_r_java_path, r_text_file, all_resources,
- shared_resources)
-
-
-def CreateExtraRJavaFile(
- package, r_java_path, r_text_file, all_resources, shared_resources):
- resources = {}
- with open(r_text_file) as f:
- for line in f:
- m = re.match(r'int(?:\[\])? (\w+) (\w+) ', line)
- if not m:
- raise Exception('Unexpected line in R.txt: %s' % line)
- resource_type, name = m.groups()
- java_type, value = all_resources[(resource_type, name)]
- if resource_type not in resources:
- resources[resource_type] = []
- resources[resource_type].append((name, java_type, value))
-
- template = Template("""/* AUTO-GENERATED FILE. DO NOT MODIFY. */
-
-package {{ package }};
-
-public final class R {
- {% for resource_type in resources %}
- public static final class {{ resource_type }} {
- {% for name, java_type, value in resources[resource_type] %}
- {% if shared_resources %}
- public static {{ java_type }} {{ name }} = {{ value }};
- {% else %}
- public static final {{ java_type }} {{ name }} = {{ value }};
- {% endif %}
- {% endfor %}
- }
- {% endfor %}
- {% if shared_resources %}
- public static void onResourcesLoaded(int packageId) {
- {% for resource_type in resources %}
- {% for name, java_type, value in resources[resource_type] %}
- {% if java_type == 'int[]' %}
- for(int i = 0; i < {{ resource_type }}.{{ name }}.length; ++i) {
- {{ resource_type }}.{{ name }}[i] =
- ({{ resource_type }}.{{ name }}[i] & 0x00ffffff)
- | (packageId << 24);
- }
- {% else %}
- {{ resource_type }}.{{ name }} =
- ({{ resource_type }}.{{ name }} & 0x00ffffff)
- | (packageId << 24);
- {% endif %}
- {% endfor %}
- {% endfor %}
- }
- {% endif %}
-}
-""", trim_blocks=True, lstrip_blocks=True)
-
- output = template.render(package=package, resources=resources,
- shared_resources=shared_resources)
- with open(r_java_path, 'w') as f:
- f.write(output)
-
-
-def CrunchDirectory(aapt, input_dir, output_dir):
- """Crunches the images in input_dir and its subdirectories into output_dir.
-
- If an image is already optimized, crunching often increases image size. In
- this case, the crunched image is overwritten with the original image.
- """
- aapt_cmd = [aapt,
- 'crunch',
- '-C', output_dir,
- '-S', input_dir,
- '--ignore-assets', build_utils.AAPT_IGNORE_PATTERN]
- build_utils.CheckOutput(aapt_cmd, stderr_filter=FilterCrunchStderr,
- fail_func=DidCrunchFail)
-
- # Check for images whose size increased during crunching and replace them
- # with their originals (except for 9-patches, which must be crunched).
- for dir_, _, files in os.walk(output_dir):
- for crunched in files:
- if crunched.endswith('.9.png'):
- continue
- if not crunched.endswith('.png'):
- raise Exception('Unexpected file in crunched dir: ' + crunched)
- crunched = os.path.join(dir_, crunched)
- original = os.path.join(input_dir, os.path.relpath(crunched, output_dir))
- original_size = os.path.getsize(original)
- crunched_size = os.path.getsize(crunched)
- if original_size < crunched_size:
- shutil.copyfile(original, crunched)
-
-
-def FilterCrunchStderr(stderr):
- """Filters out lines from aapt crunch's stderr that can safely be ignored."""
- filtered_lines = []
- for line in stderr.splitlines(True):
- # Ignore this libpng warning, which is a known non-error condition.
- # http://crbug.com/364355
- if ('libpng warning: iCCP: Not recognizing known sRGB profile that has '
- + 'been edited' in line):
- continue
- filtered_lines.append(line)
- return ''.join(filtered_lines)
-
-
-def DidCrunchFail(returncode, stderr):
- """Determines whether aapt crunch failed from its return code and output.
-
- Because aapt's return code cannot be trusted, any output to stderr is
- an indication that aapt has failed (http://crbug.com/314885).
- """
- return returncode != 0 or stderr
-
-
-def ZipResources(resource_dirs, zip_path):
- # Python zipfile does not provide a way to replace a file (it just writes
- # another file with the same name). So, first collect all the files to put
- # in the zip (with proper overriding), and then zip them.
- files_to_zip = dict()
- for d in resource_dirs:
- for root, _, files in os.walk(d):
- for f in files:
- archive_path = os.path.join(os.path.relpath(root, d), f)
- path = os.path.join(root, f)
- files_to_zip[archive_path] = path
- with zipfile.ZipFile(zip_path, 'w') as outzip:
- for archive_path, path in files_to_zip.iteritems():
- outzip.write(path, archive_path)
-
-
-def CombineZips(zip_files, output_path):
- # When packaging resources, if the top-level directories in the zip file are
- # of the form 0, 1, ..., then each subdirectory will be passed to aapt as a
- # resources directory. While some resources just clobber others (image files,
- # etc), other resources (particularly .xml files) need to be more
- # intelligently merged. That merging is left up to aapt.
- with zipfile.ZipFile(output_path, 'w') as outzip:
- for i, z in enumerate(zip_files):
- with zipfile.ZipFile(z, 'r') as inzip:
- for name in inzip.namelist():
- new_name = '%d/%s' % (i, name)
- outzip.writestr(new_name, inzip.read(name))
-
-
-def main():
- args = build_utils.ExpandFileArgs(sys.argv[1:])
-
- options = ParseArgs(args)
- android_jar = os.path.join(options.android_sdk, 'android.jar')
- aapt = options.aapt_path
-
- input_files = []
-
- with build_utils.TempDir() as temp_dir:
- deps_dir = os.path.join(temp_dir, 'deps')
- build_utils.MakeDirectory(deps_dir)
- v14_dir = os.path.join(temp_dir, 'v14')
- build_utils.MakeDirectory(v14_dir)
-
- gen_dir = os.path.join(temp_dir, 'gen')
- build_utils.MakeDirectory(gen_dir)
-
- input_resource_dirs = build_utils.ParseGypList(options.resource_dirs)
-
- if not options.v14_skip:
- for resource_dir in input_resource_dirs:
- generate_v14_compatible_resources.GenerateV14Resources(
- resource_dir,
- v14_dir)
-
- dep_zips = build_utils.ParseGypList(options.dependencies_res_zips)
- input_files += dep_zips
- dep_subdirs = []
- for z in dep_zips:
- subdir = os.path.join(deps_dir, os.path.basename(z))
- if os.path.exists(subdir):
- raise Exception('Resource zip name conflict: ' + os.path.basename(z))
- build_utils.ExtractAll(z, path=subdir)
- dep_subdirs.append(subdir)
-
- # Generate R.java. This R.java contains non-final constants and is used only
- # while compiling the library jar (e.g. chromium_content.jar). When building
- # an apk, a new R.java file with the correct resource -> ID mappings will be
- # generated by merging the resources from all libraries and the main apk
- # project.
- package_command = [aapt,
- 'package',
- '-m',
- '-M', options.android_manifest,
- '--auto-add-overlay',
- '-I', android_jar,
- '--output-text-symbols', gen_dir,
- '-J', gen_dir,
- '--ignore-assets', build_utils.AAPT_IGNORE_PATTERN]
-
- for d in input_resource_dirs:
- package_command += ['-S', d]
-
- for d in dep_subdirs:
- package_command += ['-S', d]
-
- if options.non_constant_id:
- package_command.append('--non-constant-id')
- if options.custom_package:
- package_command += ['--custom-package', options.custom_package]
- if options.proguard_file:
- package_command += ['-G', options.proguard_file]
- if options.shared_resources:
- package_command.append('--shared-lib')
- build_utils.CheckOutput(package_command, print_stderr=False)
-
- if options.extra_res_packages:
- CreateExtraRJavaFiles(
- gen_dir,
- build_utils.ParseGypList(options.extra_res_packages),
- build_utils.ParseGypList(options.extra_r_text_files),
- options.shared_resources,
- options.include_all_resources)
-
- # This is the list of directories with resources to put in the final .zip
- # file. The order of these is important so that crunched/v14 resources
- # override the normal ones.
- zip_resource_dirs = input_resource_dirs + [v14_dir]
-
- base_crunch_dir = os.path.join(temp_dir, 'crunch')
-
- # Crunch image resources. This shrinks png files and is necessary for
- # 9-patch images to display correctly. 'aapt crunch' accepts only a single
- # directory at a time and deletes everything in the output directory.
- for idx, input_dir in enumerate(input_resource_dirs):
- crunch_dir = os.path.join(base_crunch_dir, str(idx))
- build_utils.MakeDirectory(crunch_dir)
- zip_resource_dirs.append(crunch_dir)
- CrunchDirectory(aapt, input_dir, crunch_dir)
-
- ZipResources(zip_resource_dirs, options.resource_zip_out)
-
- if options.all_resources_zip_out:
- CombineZips([options.resource_zip_out] + dep_zips,
- options.all_resources_zip_out)
-
- if options.R_dir:
- build_utils.DeleteDirectory(options.R_dir)
- shutil.copytree(gen_dir, options.R_dir)
- else:
- build_utils.ZipDir(options.srcjar_out, gen_dir)
-
- if options.r_text_out:
- r_text_path = os.path.join(gen_dir, 'R.txt')
- if os.path.exists(r_text_path):
- shutil.copyfile(r_text_path, options.r_text_out)
- else:
- open(options.r_text_out, 'w').close()
-
- if options.depfile:
- input_files += build_utils.GetPythonDependencies()
- build_utils.WriteDepfile(options.depfile, input_files)
-
- if options.stamp:
- build_utils.Touch(options.stamp)
-
-
-if __name__ == '__main__':
- main()
diff --git a/build/android/gyp/proguard.py b/build/android/gyp/proguard.py
deleted file mode 100755
index 5127100..0000000
--- a/build/android/gyp/proguard.py
+++ /dev/null
@@ -1,69 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import optparse
-import sys
-
-from util import build_utils
-from util import proguard_util
-
-def DoProguard(options):
- proguard = proguard_util.ProguardCmdBuilder(options.proguard_path)
- proguard.injars(build_utils.ParseGypList(options.input_paths))
- proguard.configs(build_utils.ParseGypList(options.proguard_configs))
- proguard.outjar(options.output_path)
-
- if options.mapping:
- proguard.mapping(options.mapping)
-
- if options.is_test:
- proguard.is_test(True)
-
- classpath = []
- for arg in options.classpath:
- classpath += build_utils.ParseGypList(arg)
- classpath = list(set(classpath))
- proguard.libraryjars(classpath)
-
- proguard.CheckOutput()
-
- return proguard.GetInputs()
-
-
-def main(args):
- args = build_utils.ExpandFileArgs(args)
- parser = optparse.OptionParser()
- build_utils.AddDepfileOption(parser)
- parser.add_option('--proguard-path',
- help='Path to the proguard executable.')
- parser.add_option('--input-paths',
- help='Paths to the .jar files proguard should run on.')
- parser.add_option('--output-path', help='Path to the generated .jar file.')
- parser.add_option('--proguard-configs',
- help='Paths to proguard configuration files.')
- parser.add_option('--mapping', help='Path to proguard mapping to apply.')
- parser.add_option('--is-test', action='store_true',
- help='If true, extra proguard options for instrumentation tests will be '
- 'added.')
- parser.add_option('--classpath', action='append',
- help='Classpath for proguard.')
- parser.add_option('--stamp', help='Path to touch on success.')
-
- options, _ = parser.parse_args(args)
-
- inputs = DoProguard(options)
-
- if options.depfile:
- build_utils.WriteDepfile(
- options.depfile,
- inputs + build_utils.GetPythonDependencies())
-
- if options.stamp:
- build_utils.Touch(options.stamp)
-
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv[1:]))
diff --git a/build/android/gyp/push_libraries.py b/build/android/gyp/push_libraries.py
deleted file mode 100755
index 6b31a2e..0000000
--- a/build/android/gyp/push_libraries.py
+++ /dev/null
@@ -1,80 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Pushes native libraries to a device.
-
-"""
-
-import optparse
-import os
-import sys
-
-BUILD_ANDROID_DIR = os.path.join(os.path.dirname(__file__), os.pardir)
-sys.path.append(BUILD_ANDROID_DIR)
-
-from pylib import constants
-
-from util import build_device
-from util import build_utils
-from util import md5_check
-
-def DoPush(options):
- libraries = build_utils.ParseGypList(options.libraries)
-
- device = build_device.GetBuildDeviceFromPath(
- options.build_device_configuration)
- if not device:
- return
-
- serial_number = device.GetSerialNumber()
- # A list so that it is modifiable in Push below.
- needs_directory = [True]
- for lib in libraries:
- device_path = os.path.join(options.device_dir, lib)
- host_path = os.path.join(options.libraries_dir, lib)
-
- def Push():
- if needs_directory:
- device.RunShellCommand('mkdir -p ' + options.device_dir)
- needs_directory[:] = [] # = False
- device.PushChangedFiles([(host_path, device_path)])
-
- record_path = '%s.%s.push.md5.stamp' % (host_path, serial_number)
- md5_check.CallAndRecordIfStale(
- Push,
- record_path=record_path,
- input_paths=[host_path],
- input_strings=[device_path])
-
-
-def main(args):
- args = build_utils.ExpandFileArgs(args)
- parser = optparse.OptionParser()
- parser.add_option('--libraries-dir',
- help='Directory that contains stripped libraries.')
- parser.add_option('--device-dir',
- help='Device directory to push the libraries to.')
- parser.add_option('--libraries',
- help='List of native libraries.')
- parser.add_option('--stamp', help='Path to touch on success.')
- parser.add_option('--build-device-configuration',
- help='Path to build device configuration.')
- parser.add_option('--configuration-name',
- help='The build CONFIGURATION_NAME')
- options, _ = parser.parse_args(args)
-
- required_options = ['libraries', 'device_dir', 'libraries']
- build_utils.CheckOptions(options, parser, required=required_options)
- constants.SetBuildType(options.configuration_name)
-
- DoPush(options)
-
- if options.stamp:
- build_utils.Touch(options.stamp)
-
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv[1:]))
diff --git a/build/android/gyp/strip_library_for_device.py b/build/android/gyp/strip_library_for_device.py
deleted file mode 100755
index 9e2daae..0000000
--- a/build/android/gyp/strip_library_for_device.py
+++ /dev/null
@@ -1,61 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import optparse
-import os
-import sys
-
-from util import build_utils
-
-
-def StripLibrary(android_strip, android_strip_args, library_path, output_path):
- if build_utils.IsTimeStale(output_path, [library_path]):
- strip_cmd = ([android_strip] +
- android_strip_args +
- ['-o', output_path, library_path])
- build_utils.CheckOutput(strip_cmd)
-
-
-def main(args):
- args = build_utils.ExpandFileArgs(args)
-
- parser = optparse.OptionParser()
- build_utils.AddDepfileOption(parser)
-
- parser.add_option('--android-strip',
- help='Path to the toolchain\'s strip binary')
- parser.add_option('--android-strip-arg', action='append',
- help='Argument to be passed to strip')
- parser.add_option('--libraries-dir',
- help='Directory for un-stripped libraries')
- parser.add_option('--stripped-libraries-dir',
- help='Directory for stripped libraries')
- parser.add_option('--libraries',
- help='List of libraries to strip')
- parser.add_option('--stamp', help='Path to touch on success')
-
- options, _ = parser.parse_args(args)
-
- libraries = build_utils.ParseGypList(options.libraries)
-
- build_utils.MakeDirectory(options.stripped_libraries_dir)
-
- for library in libraries:
- for base_path in options.libraries_dir.split(','):
- library_path = os.path.join(base_path, library)
- if (os.path.exists(library_path)):
- break
- stripped_library_path = os.path.join(
- options.stripped_libraries_dir, library)
- StripLibrary(options.android_strip, options.android_strip_arg, library_path,
- stripped_library_path)
-
- if options.stamp:
- build_utils.Touch(options.stamp)
-
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv[1:]))
diff --git a/build/android/gyp/test/BUILD.gn b/build/android/gyp/test/BUILD.gn
deleted file mode 100644
index 2deac1d..0000000
--- a/build/android/gyp/test/BUILD.gn
+++ /dev/null
@@ -1,13 +0,0 @@
-import("//build/config/android/rules.gni")
-
-java_library("hello_world_java") {
- java_files = [ "java/org/chromium/helloworld/HelloWorldPrinter.java" ]
-}
-
-java_binary("hello_world") {
- deps = [
- ":hello_world_java",
- ]
- java_files = [ "java/org/chromium/helloworld/HelloWorldMain.java" ]
- main_class = "org.chromium.helloworld.HelloWorldMain"
-}
diff --git a/build/android/gyp/test/java/org/chromium/helloworld/HelloWorldMain.java b/build/android/gyp/test/java/org/chromium/helloworld/HelloWorldMain.java
deleted file mode 100644
index 10860d8..0000000
--- a/build/android/gyp/test/java/org/chromium/helloworld/HelloWorldMain.java
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.helloworld;
-
-public class HelloWorldMain {
- public static void main(String[] args) {
- if (args.length > 0) {
- System.exit(Integer.parseInt(args[0]));
- }
- HelloWorldPrinter.print();
- }
-}
-
diff --git a/build/android/gyp/test/java/org/chromium/helloworld/HelloWorldPrinter.java b/build/android/gyp/test/java/org/chromium/helloworld/HelloWorldPrinter.java
deleted file mode 100644
index b09673e..0000000
--- a/build/android/gyp/test/java/org/chromium/helloworld/HelloWorldPrinter.java
+++ /dev/null
@@ -1,12 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.helloworld;
-
-public class HelloWorldPrinter {
- public static void print() {
- System.out.println("Hello, world!");
- }
-}
-
diff --git a/build/android/gyp/touch.py b/build/android/gyp/touch.py
deleted file mode 100755
index 7b4375e..0000000
--- a/build/android/gyp/touch.py
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import sys
-
-from util import build_utils
-
-def main(argv):
- for f in argv[1:]:
- build_utils.Touch(f)
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv))
diff --git a/build/android/gyp/util/__init__.py b/build/android/gyp/util/__init__.py
deleted file mode 100644
index 727e987..0000000
--- a/build/android/gyp/util/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
diff --git a/build/android/gyp/util/build_device.py b/build/android/gyp/util/build_device.py
deleted file mode 100644
index 8ab1112..0000000
--- a/build/android/gyp/util/build_device.py
+++ /dev/null
@@ -1,108 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-""" A simple device interface for build steps.
-
-"""
-
-import logging
-import os
-import re
-import sys
-
-from util import build_utils
-
-BUILD_ANDROID_DIR = os.path.join(os.path.dirname(__file__), '..', '..')
-sys.path.append(BUILD_ANDROID_DIR)
-
-from pylib import android_commands
-from pylib.device import device_errors
-from pylib.device import device_utils
-
-GetAttachedDevices = android_commands.GetAttachedDevices
-
-
-class BuildDevice(object):
- def __init__(self, configuration):
- self.id = configuration['id']
- self.description = configuration['description']
- self.install_metadata = configuration['install_metadata']
- self.device = device_utils.DeviceUtils(self.id)
-
- def RunShellCommand(self, *args, **kwargs):
- return self.device.RunShellCommand(*args, **kwargs)
-
- def PushChangedFiles(self, *args, **kwargs):
- return self.device.PushChangedFiles(*args, **kwargs)
-
- def GetSerialNumber(self):
- return self.id
-
- def Install(self, *args, **kwargs):
- return self.device.Install(*args, **kwargs)
-
- def InstallSplitApk(self, *args, **kwargs):
- return self.device.InstallSplitApk(*args, **kwargs)
-
- def GetInstallMetadata(self, apk_package):
- """Gets the metadata on the device for the apk_package apk."""
- # Matches lines like:
- # -rw-r--r-- system system 7376582 2013-04-19 16:34 \
- # org.chromium.chrome.shell.apk
- # -rw-r--r-- system system 7376582 2013-04-19 16:34 \
- # org.chromium.chrome.shell-1.apk
- apk_matcher = lambda s: re.match('.*%s(-[0-9]*)?.apk$' % apk_package, s)
- matches = filter(apk_matcher, self.install_metadata)
- return matches[0] if matches else None
-
-
-def GetConfigurationForDevice(device_id):
- device = device_utils.DeviceUtils(device_id)
- configuration = None
- has_root = False
- is_online = device.IsOnline()
- if is_online:
- cmd = 'ls -l /data/app; getprop ro.build.description'
- cmd_output = device.RunShellCommand(cmd)
- has_root = not 'Permission denied' in cmd_output[0]
- if not has_root:
- # Disable warning log messages from EnableRoot()
- logging.getLogger().disabled = True
- try:
- device.EnableRoot()
- has_root = True
- except device_errors.CommandFailedError:
- has_root = False
- finally:
- logging.getLogger().disabled = False
- cmd_output = device.RunShellCommand(cmd)
-
- configuration = {
- 'id': device_id,
- 'description': cmd_output[-1],
- 'install_metadata': cmd_output[:-1],
- }
- return configuration, is_online, has_root
-
-
-def WriteConfigurations(configurations, path):
- # Currently we only support installing to the first device.
- build_utils.WriteJson(configurations[:1], path, only_if_changed=True)
-
-
-def ReadConfigurations(path):
- return build_utils.ReadJson(path)
-
-
-def GetBuildDevice(configurations):
- assert len(configurations) == 1
- return BuildDevice(configurations[0])
-
-
-def GetBuildDeviceFromPath(path):
- configurations = ReadConfigurations(path)
- if len(configurations) > 0:
- return GetBuildDevice(ReadConfigurations(path))
- return None
-
diff --git a/build/android/gyp/util/build_utils.py b/build/android/gyp/util/build_utils.py
deleted file mode 100644
index 65b1a64..0000000
--- a/build/android/gyp/util/build_utils.py
+++ /dev/null
@@ -1,376 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import ast
-import contextlib
-import fnmatch
-import json
-import os
-import pipes
-import re
-import shlex
-import shutil
-import subprocess
-import sys
-import tempfile
-import zipfile
-
-
-CHROMIUM_SRC = os.path.normpath(
- os.path.join(os.path.dirname(__file__),
- os.pardir, os.pardir, os.pardir, os.pardir))
-COLORAMA_ROOT = os.path.join(CHROMIUM_SRC,
- 'third_party', 'colorama', 'src')
-# aapt should ignore OWNERS files in addition the default ignore pattern.
-AAPT_IGNORE_PATTERN = ('!OWNERS:!.svn:!.git:!.ds_store:!*.scc:.*:<dir>_*:' +
- '!CVS:!thumbs.db:!picasa.ini:!*~:!*.d.stamp')
-
-
-@contextlib.contextmanager
-def TempDir():
- dirname = tempfile.mkdtemp()
- try:
- yield dirname
- finally:
- shutil.rmtree(dirname)
-
-
-def MakeDirectory(dir_path):
- try:
- os.makedirs(dir_path)
- except OSError:
- pass
-
-
-def DeleteDirectory(dir_path):
- if os.path.exists(dir_path):
- shutil.rmtree(dir_path)
-
-
-def Touch(path, fail_if_missing=False):
- if fail_if_missing and not os.path.exists(path):
- raise Exception(path + ' doesn\'t exist.')
-
- MakeDirectory(os.path.dirname(path))
- with open(path, 'a'):
- os.utime(path, None)
-
-
-def FindInDirectory(directory, filename_filter):
- files = []
- for root, _dirnames, filenames in os.walk(directory):
- matched_files = fnmatch.filter(filenames, filename_filter)
- files.extend((os.path.join(root, f) for f in matched_files))
- return files
-
-
-def FindInDirectories(directories, filename_filter):
- all_files = []
- for directory in directories:
- all_files.extend(FindInDirectory(directory, filename_filter))
- return all_files
-
-
-def ParseGnList(gn_string):
- return ast.literal_eval(gn_string)
-
-
-def ParseGypList(gyp_string):
- # The ninja generator doesn't support $ in strings, so use ## to
- # represent $.
- # TODO(cjhopman): Remove when
- # https://code.google.com/p/gyp/issues/detail?id=327
- # is addressed.
- gyp_string = gyp_string.replace('##', '$')
-
- if gyp_string.startswith('['):
- return ParseGnList(gyp_string)
- return shlex.split(gyp_string)
-
-
-def CheckOptions(options, parser, required=None):
- if not required:
- return
- for option_name in required:
- if getattr(options, option_name) is None:
- parser.error('--%s is required' % option_name.replace('_', '-'))
-
-
-def WriteJson(obj, path, only_if_changed=False):
- old_dump = None
- if os.path.exists(path):
- with open(path, 'r') as oldfile:
- old_dump = oldfile.read()
-
- new_dump = json.dumps(obj, sort_keys=True, indent=2, separators=(',', ': '))
-
- if not only_if_changed or old_dump != new_dump:
- with open(path, 'w') as outfile:
- outfile.write(new_dump)
-
-
-def ReadJson(path):
- with open(path, 'r') as jsonfile:
- return json.load(jsonfile)
-
-
-class CalledProcessError(Exception):
- """This exception is raised when the process run by CheckOutput
- exits with a non-zero exit code."""
-
- def __init__(self, cwd, args, output):
- super(CalledProcessError, self).__init__()
- self.cwd = cwd
- self.args = args
- self.output = output
-
- def __str__(self):
- # A user should be able to simply copy and paste the command that failed
- # into their shell.
- copyable_command = '( cd {}; {} )'.format(os.path.abspath(self.cwd),
- ' '.join(map(pipes.quote, self.args)))
- return 'Command failed: {}\n{}'.format(copyable_command, self.output)
-
-
-# This can be used in most cases like subprocess.check_output(). The output,
-# particularly when the command fails, better highlights the command's failure.
-# If the command fails, raises a build_utils.CalledProcessError.
-def CheckOutput(args, cwd=None,
- print_stdout=False, print_stderr=True,
- stdout_filter=None,
- stderr_filter=None,
- fail_func=lambda returncode, stderr: returncode != 0):
- if not cwd:
- cwd = os.getcwd()
-
- child = subprocess.Popen(args,
- stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=cwd)
- stdout, stderr = child.communicate()
-
- if stdout_filter is not None:
- stdout = stdout_filter(stdout)
-
- if stderr_filter is not None:
- stderr = stderr_filter(stderr)
-
- if fail_func(child.returncode, stderr):
- raise CalledProcessError(cwd, args, stdout + stderr)
-
- if print_stdout:
- sys.stdout.write(stdout)
- if print_stderr:
- sys.stderr.write(stderr)
-
- return stdout
-
-
-def GetModifiedTime(path):
- # For a symlink, the modified time should be the greater of the link's
- # modified time and the modified time of the target.
- return max(os.lstat(path).st_mtime, os.stat(path).st_mtime)
-
-
-def IsTimeStale(output, inputs):
- if not os.path.exists(output):
- return True
-
- output_time = GetModifiedTime(output)
- for i in inputs:
- if GetModifiedTime(i) > output_time:
- return True
- return False
-
-
-def IsDeviceReady():
- device_state = CheckOutput(['adb', 'get-state'])
- return device_state.strip() == 'device'
-
-
-def CheckZipPath(name):
- if os.path.normpath(name) != name:
- raise Exception('Non-canonical zip path: %s' % name)
- if os.path.isabs(name):
- raise Exception('Absolute zip path: %s' % name)
-
-
-def ExtractAll(zip_path, path=None, no_clobber=True, pattern=None):
- if path is None:
- path = os.getcwd()
- elif not os.path.exists(path):
- MakeDirectory(path)
-
- with zipfile.ZipFile(zip_path) as z:
- for name in z.namelist():
- if name.endswith('/'):
- continue
- if pattern is not None:
- if not fnmatch.fnmatch(name, pattern):
- continue
- CheckZipPath(name)
- if no_clobber:
- output_path = os.path.join(path, name)
- if os.path.exists(output_path):
- raise Exception(
- 'Path already exists from zip: %s %s %s'
- % (zip_path, name, output_path))
-
- z.extractall(path=path)
-
-
-def DoZip(inputs, output, base_dir):
- with zipfile.ZipFile(output, 'w') as outfile:
- for f in inputs:
- CheckZipPath(os.path.relpath(f, base_dir))
- outfile.write(f, os.path.relpath(f, base_dir))
-
-
-def ZipDir(output, base_dir):
- with zipfile.ZipFile(output, 'w') as outfile:
- for root, _, files in os.walk(base_dir):
- for f in files:
- path = os.path.join(root, f)
- archive_path = os.path.relpath(path, base_dir)
- CheckZipPath(archive_path)
- outfile.write(path, archive_path)
-
-
-def MergeZips(output, inputs, exclude_patterns=None):
- added_names = set()
- def Allow(name):
- if exclude_patterns is not None:
- for p in exclude_patterns:
- if fnmatch.fnmatch(name, p):
- return False
- return True
-
- with zipfile.ZipFile(output, 'w') as out_zip:
- for in_file in inputs:
- with zipfile.ZipFile(in_file, 'r') as in_zip:
- for name in in_zip.namelist():
- if name not in added_names and Allow(name):
- out_zip.writestr(name, in_zip.read(name))
- added_names.add(name)
-
-
-def PrintWarning(message):
- print 'WARNING: ' + message
-
-
-def PrintBigWarning(message):
- print '***** ' * 8
- PrintWarning(message)
- print '***** ' * 8
-
-
-def GetSortedTransitiveDependencies(top, deps_func):
- """Gets the list of all transitive dependencies in sorted order.
-
- There should be no cycles in the dependency graph.
-
- Args:
- top: a list of the top level nodes
- deps_func: A function that takes a node and returns its direct dependencies.
- Returns:
- A list of all transitive dependencies of nodes in top, in order (a node will
- appear in the list at a higher index than all of its dependencies).
- """
- def Node(dep):
- return (dep, deps_func(dep))
-
- # First: find all deps
- unchecked_deps = list(top)
- all_deps = set(top)
- while unchecked_deps:
- dep = unchecked_deps.pop()
- new_deps = deps_func(dep).difference(all_deps)
- unchecked_deps.extend(new_deps)
- all_deps = all_deps.union(new_deps)
-
- # Then: simple, slow topological sort.
- sorted_deps = []
- unsorted_deps = dict(map(Node, all_deps))
- while unsorted_deps:
- for library, dependencies in unsorted_deps.items():
- if not dependencies.intersection(unsorted_deps.keys()):
- sorted_deps.append(library)
- del unsorted_deps[library]
-
- return sorted_deps
-
-
-def GetPythonDependencies():
- """Gets the paths of imported non-system python modules.
-
- A path is assumed to be a "system" import if it is outside of chromium's
- src/. The paths will be relative to the current directory.
- """
- module_paths = (m.__file__ for m in sys.modules.itervalues()
- if m is not None and hasattr(m, '__file__'))
-
- abs_module_paths = map(os.path.abspath, module_paths)
-
- non_system_module_paths = [
- p for p in abs_module_paths if p.startswith(CHROMIUM_SRC)]
- def ConvertPycToPy(s):
- if s.endswith('.pyc'):
- return s[:-1]
- return s
-
- non_system_module_paths = map(ConvertPycToPy, non_system_module_paths)
- non_system_module_paths = map(os.path.relpath, non_system_module_paths)
- return sorted(set(non_system_module_paths))
-
-
-def AddDepfileOption(parser):
- parser.add_option('--depfile',
- help='Path to depfile. This must be specified as the '
- 'action\'s first output.')
-
-
-def WriteDepfile(path, dependencies):
- with open(path, 'w') as depfile:
- depfile.write(path)
- depfile.write(': ')
- depfile.write(' '.join(dependencies))
- depfile.write('\n')
-
-
-def ExpandFileArgs(args):
- """Replaces file-arg placeholders in args.
-
- These placeholders have the form:
- @FileArg(filename:key1:key2:...:keyn)
-
- The value of such a placeholder is calculated by reading 'filename' as json.
- And then extracting the value at [key1][key2]...[keyn].
-
- Note: This intentionally does not return the list of files that appear in such
- placeholders. An action that uses file-args *must* know the paths of those
- files prior to the parsing of the arguments (typically by explicitly listing
- them in the action's inputs in build files).
- """
- new_args = list(args)
- file_jsons = dict()
- r = re.compile('@FileArg\((.*?)\)')
- for i, arg in enumerate(args):
- match = r.search(arg)
- if not match:
- continue
-
- if match.end() != len(arg):
- raise Exception('Unexpected characters after FileArg: ' + arg)
-
- lookup_path = match.group(1).split(':')
- file_path = lookup_path[0]
- if not file_path in file_jsons:
- file_jsons[file_path] = ReadJson(file_path)
-
- expansion = file_jsons[file_path]
- for k in lookup_path[1:]:
- expansion = expansion[k]
-
- new_args[i] = arg[:match.start()] + str(expansion)
-
- return new_args
-
diff --git a/build/android/gyp/util/md5_check.py b/build/android/gyp/util/md5_check.py
deleted file mode 100644
index 9f365aa..0000000
--- a/build/android/gyp/util/md5_check.py
+++ /dev/null
@@ -1,86 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import hashlib
-import os
-
-
-def CallAndRecordIfStale(
- function, record_path=None, input_paths=None, input_strings=None,
- force=False):
- """Calls function if the md5sum of the input paths/strings has changed.
-
- The md5sum of the inputs is compared with the one stored in record_path. If
- this has changed (or the record doesn't exist), function will be called and
- the new md5sum will be recorded.
-
- If force is True, the function will be called regardless of whether the
- md5sum is out of date.
- """
- if not input_paths:
- input_paths = []
- if not input_strings:
- input_strings = []
- md5_checker = _Md5Checker(
- record_path=record_path,
- input_paths=input_paths,
- input_strings=input_strings)
- if force or md5_checker.IsStale():
- function()
- md5_checker.Write()
-
-
-def _UpdateMd5ForFile(md5, path, block_size=2**16):
- with open(path, 'rb') as infile:
- while True:
- data = infile.read(block_size)
- if not data:
- break
- md5.update(data)
-
-
-def _UpdateMd5ForDirectory(md5, dir_path):
- for root, _, files in os.walk(dir_path):
- for f in files:
- _UpdateMd5ForFile(md5, os.path.join(root, f))
-
-
-def _UpdateMd5ForPath(md5, path):
- if os.path.isdir(path):
- _UpdateMd5ForDirectory(md5, path)
- else:
- _UpdateMd5ForFile(md5, path)
-
-
-class _Md5Checker(object):
- def __init__(self, record_path=None, input_paths=None, input_strings=None):
- if not input_paths:
- input_paths = []
- if not input_strings:
- input_strings = []
-
- assert record_path.endswith('.stamp'), (
- 'record paths must end in \'.stamp\' so that they are easy to find '
- 'and delete')
-
- self.record_path = record_path
-
- md5 = hashlib.md5()
- for i in sorted(input_paths):
- _UpdateMd5ForPath(md5, i)
- for s in input_strings:
- md5.update(s)
- self.new_digest = md5.hexdigest()
-
- self.old_digest = ''
- if os.path.exists(self.record_path):
- with open(self.record_path, 'r') as old_record:
- self.old_digest = old_record.read()
-
- def IsStale(self):
- return self.old_digest != self.new_digest
-
- def Write(self):
- with open(self.record_path, 'w') as new_record:
- new_record.write(self.new_digest)
diff --git a/build/android/gyp/util/md5_check_test.py b/build/android/gyp/util/md5_check_test.py
deleted file mode 100644
index 4f89fc2..0000000
--- a/build/android/gyp/util/md5_check_test.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import tempfile
-import unittest
-
-import md5_check # pylint: disable=W0403
-
-
-class TestMd5Check(unittest.TestCase):
- def setUp(self):
- self.called = False
-
- def testCallAndRecordIfStale(self):
- input_strings = ['string1', 'string2']
- input_file1 = tempfile.NamedTemporaryFile()
- input_file2 = tempfile.NamedTemporaryFile()
- file1_contents = 'input file 1'
- file2_contents = 'input file 2'
- input_file1.write(file1_contents)
- input_file1.flush()
- input_file2.write(file2_contents)
- input_file2.flush()
- input_files = [input_file1.name, input_file2.name]
-
- record_path = tempfile.NamedTemporaryFile(suffix='.stamp')
-
- def CheckCallAndRecord(should_call, message, force=False):
- self.called = False
- def MarkCalled():
- self.called = True
- md5_check.CallAndRecordIfStale(
- MarkCalled,
- record_path=record_path.name,
- input_paths=input_files,
- input_strings=input_strings,
- force=force)
- self.failUnlessEqual(should_call, self.called, message)
-
- CheckCallAndRecord(True, 'should call when record doesn\'t exist')
- CheckCallAndRecord(False, 'should not call when nothing changed')
- CheckCallAndRecord(True, force=True, message='should call when forced')
-
- input_file1.write('some more input')
- input_file1.flush()
- CheckCallAndRecord(True, 'changed input file should trigger call')
-
- input_files = input_files[::-1]
- CheckCallAndRecord(False, 'reordering of inputs shouldn\'t trigger call')
-
- input_files = input_files[:1]
- CheckCallAndRecord(True, 'removing file should trigger call')
-
- input_files.append(input_file2.name)
- CheckCallAndRecord(True, 'added input file should trigger call')
-
- input_strings[0] = input_strings[0] + ' a bit longer'
- CheckCallAndRecord(True, 'changed input string should trigger call')
-
- input_strings = input_strings[::-1]
- CheckCallAndRecord(True, 'reordering of string inputs should trigger call')
-
- input_strings = input_strings[:1]
- CheckCallAndRecord(True, 'removing a string should trigger call')
-
- input_strings.append('a brand new string')
- CheckCallAndRecord(True, 'added input string should trigger call')
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/build/android/gyp/util/proguard_util.py b/build/android/gyp/util/proguard_util.py
deleted file mode 100644
index 901cd9f..0000000
--- a/build/android/gyp/util/proguard_util.py
+++ /dev/null
@@ -1,128 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-from util import build_utils
-
-def FilterProguardOutput(output):
- '''ProGuard outputs boring stuff to stdout (proguard version, jar path, etc)
- as well as interesting stuff (notes, warnings, etc). If stdout is entirely
- boring, this method suppresses the output.
- '''
- ignore_patterns = [
- 'ProGuard, version ',
- 'Reading program jar [',
- 'Reading library jar [',
- 'Preparing output jar [',
- ' Copying resources from program jar [',
- ]
- for line in output.splitlines():
- for pattern in ignore_patterns:
- if line.startswith(pattern):
- break
- else:
- # line doesn't match any of the patterns; it's probably something worth
- # printing out.
- return output
- return ''
-
-
-class ProguardCmdBuilder(object):
- def __init__(self, proguard_jar):
- assert os.path.exists(proguard_jar)
- self._proguard_jar_path = proguard_jar
- self._test = None
- self._mapping = None
- self._libraries = None
- self._injars = None
- self._configs = None
- self._outjar = None
-
- def outjar(self, path):
- assert self._outjar is None
- self._outjar = path
-
- def is_test(self, enable):
- assert self._test is None
- self._test = enable
-
- def mapping(self, path):
- assert self._mapping is None
- assert os.path.exists(path), path
- self._mapping = path
-
- def libraryjars(self, paths):
- assert self._libraries is None
- for p in paths:
- assert os.path.exists(p), p
- self._libraries = paths
-
- def injars(self, paths):
- assert self._injars is None
- for p in paths:
- assert os.path.exists(p), p
- self._injars = paths
-
- def configs(self, paths):
- assert self._configs is None
- for p in paths:
- assert os.path.exists(p), p
- self._configs = paths
-
- def build(self):
- assert self._injars is not None
- assert self._outjar is not None
- assert self._configs is not None
- cmd = [
- 'java', '-jar', self._proguard_jar_path,
- '-forceprocessing',
- ]
- if self._test:
- cmd += [
- '-dontobfuscate',
- '-dontoptimize',
- '-dontshrink',
- '-dontskipnonpubliclibraryclassmembers',
- ]
-
- if self._mapping:
- cmd += [
- '-applymapping', self._mapping,
- ]
-
- if self._libraries:
- cmd += [
- '-libraryjars', ':'.join(self._libraries),
- ]
-
- cmd += [
- '-injars', ':'.join(self._injars)
- ]
-
- for config_file in self._configs:
- cmd += ['-include', config_file]
-
- # The output jar must be specified after inputs.
- cmd += [
- '-outjars', self._outjar,
- '-dump', self._outjar + '.dump',
- '-printseeds', self._outjar + '.seeds',
- '-printusage', self._outjar + '.usage',
- '-printmapping', self._outjar + '.mapping',
- ]
- return cmd
-
- def GetInputs(self):
- inputs = [self._proguard_jar_path] + self._configs + self._injars
- if self._mapping:
- inputs.append(self._mapping)
- if self._libraries:
- inputs += self._libraries
- return inputs
-
-
- def CheckOutput(self):
- build_utils.CheckOutput(self.build(), print_stdout=True,
- stdout_filter=FilterProguardOutput)
-
diff --git a/build/android/gyp/write_build_config.py b/build/android/gyp/write_build_config.py
deleted file mode 100755
index 3773e98..0000000
--- a/build/android/gyp/write_build_config.py
+++ /dev/null
@@ -1,357 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Writes a build_config file.
-
-The build_config file for a target is a json file containing information about
-how to build that target based on the target's dependencies. This includes
-things like: the javac classpath, the list of android resources dependencies,
-etc. It also includes the information needed to create the build_config for
-other targets that depend on that one.
-
-Android build scripts should not refer to the build_config directly, and the
-build specification should instead pass information in using the special
-file-arg syntax (see build_utils.py:ExpandFileArgs). That syntax allows passing
-of values in a json dict in a file and looks like this:
- --python-arg=@FileArg(build_config_path:javac:classpath)
-
-Note: If paths to input files are passed in this way, it is important that:
- 1. inputs/deps of the action ensure that the files are available the first
- time the action runs.
- 2. Either (a) or (b)
- a. inputs/deps ensure that the action runs whenever one of the files changes
- b. the files are added to the action's depfile
-"""
-
-import optparse
-import os
-import sys
-import xml.dom.minidom
-
-from util import build_utils
-
-import write_ordered_libraries
-
-class AndroidManifest(object):
- def __init__(self, path):
- self.path = path
- dom = xml.dom.minidom.parse(path)
- manifests = dom.getElementsByTagName('manifest')
- assert len(manifests) == 1
- self.manifest = manifests[0]
-
- def GetInstrumentation(self):
- instrumentation_els = self.manifest.getElementsByTagName('instrumentation')
- if len(instrumentation_els) == 0:
- return None
- if len(instrumentation_els) != 1:
- raise Exception(
- 'More than one <instrumentation> element found in %s' % self.path)
- return instrumentation_els[0]
-
- def CheckInstrumentation(self, expected_package):
- instr = self.GetInstrumentation()
- if not instr:
- raise Exception('No <instrumentation> elements found in %s' % self.path)
- instrumented_package = instr.getAttributeNS(
- 'http://schemas.android.com/apk/res/android', 'targetPackage')
- if instrumented_package != expected_package:
- raise Exception(
- 'Wrong instrumented package. Expected %s, got %s'
- % (expected_package, instrumented_package))
-
- def GetPackageName(self):
- return self.manifest.getAttribute('package')
-
-
-dep_config_cache = {}
-def GetDepConfig(path):
- if not path in dep_config_cache:
- dep_config_cache[path] = build_utils.ReadJson(path)['deps_info']
- return dep_config_cache[path]
-
-
-def DepsOfType(wanted_type, configs):
- return [c for c in configs if c['type'] == wanted_type]
-
-
-def GetAllDepsConfigsInOrder(deps_config_paths):
- def GetDeps(path):
- return set(GetDepConfig(path)['deps_configs'])
- return build_utils.GetSortedTransitiveDependencies(deps_config_paths, GetDeps)
-
-
-class Deps(object):
- def __init__(self, direct_deps_config_paths):
- self.all_deps_config_paths = GetAllDepsConfigsInOrder(
- direct_deps_config_paths)
- self.direct_deps_configs = [
- GetDepConfig(p) for p in direct_deps_config_paths]
- self.all_deps_configs = [
- GetDepConfig(p) for p in self.all_deps_config_paths]
-
- def All(self, wanted_type=None):
- if type is None:
- return self.all_deps_configs
- return DepsOfType(wanted_type, self.all_deps_configs)
-
- def Direct(self, wanted_type=None):
- if wanted_type is None:
- return self.direct_deps_configs
- return DepsOfType(wanted_type, self.direct_deps_configs)
-
- def AllConfigPaths(self):
- return self.all_deps_config_paths
-
-
-def main(argv):
- parser = optparse.OptionParser()
- build_utils.AddDepfileOption(parser)
- parser.add_option('--build-config', help='Path to build_config output.')
- parser.add_option(
- '--type',
- help='Type of this target (e.g. android_library).')
- parser.add_option(
- '--possible-deps-configs',
- help='List of paths for dependency\'s build_config files. Some '
- 'dependencies may not write build_config files. Missing build_config '
- 'files are handled differently based on the type of this target.')
-
- # android_resources options
- parser.add_option('--srcjar', help='Path to target\'s resources srcjar.')
- parser.add_option('--resources-zip', help='Path to target\'s resources zip.')
- parser.add_option('--r-text', help='Path to target\'s R.txt file.')
- parser.add_option('--package-name',
- help='Java package name for these resources.')
- parser.add_option('--android-manifest', help='Path to android manifest.')
-
- # java library options
- parser.add_option('--jar-path', help='Path to target\'s jar output.')
- parser.add_option('--supports-android', action='store_true',
- help='Whether this library supports running on the Android platform.')
- parser.add_option('--requires-android', action='store_true',
- help='Whether this library requires running on the Android platform.')
- parser.add_option('--bypass-platform-checks', action='store_true',
- help='Bypass checks for support/require Android platform.')
-
- # android library options
- parser.add_option('--dex-path', help='Path to target\'s dex output.')
-
- # native library options
- parser.add_option('--native-libs', help='List of top-level native libs.')
- parser.add_option('--readelf-path', help='Path to toolchain\'s readelf.')
-
- parser.add_option('--tested-apk-config',
- help='Path to the build config of the tested apk (for an instrumentation '
- 'test apk).')
-
- options, args = parser.parse_args(argv)
-
- if args:
- parser.error('No positional arguments should be given.')
-
-
- if not options.type in [
- 'java_library', 'android_resources', 'android_apk', 'deps_dex']:
- raise Exception('Unknown type: <%s>' % options.type)
-
- required_options = ['build_config'] + {
- 'java_library': ['jar_path'],
- 'android_resources': ['resources_zip'],
- 'android_apk': ['jar_path', 'dex_path', 'resources_zip'],
- 'deps_dex': ['dex_path']
- }[options.type]
-
- if options.native_libs:
- required_options.append('readelf_path')
-
- build_utils.CheckOptions(options, parser, required_options)
-
- if options.type == 'java_library':
- if options.supports_android and not options.dex_path:
- raise Exception('java_library that supports Android requires a dex path.')
-
- if options.requires_android and not options.supports_android:
- raise Exception(
- '--supports-android is required when using --requires-android')
-
- possible_deps_config_paths = build_utils.ParseGypList(
- options.possible_deps_configs)
-
- allow_unknown_deps = (options.type == 'android_apk' or
- options.type == 'android_resources')
- unknown_deps = [
- c for c in possible_deps_config_paths if not os.path.exists(c)]
- if unknown_deps and not allow_unknown_deps:
- raise Exception('Unknown deps: ' + str(unknown_deps))
-
- direct_deps_config_paths = [
- c for c in possible_deps_config_paths if not c in unknown_deps]
-
- deps = Deps(direct_deps_config_paths)
- direct_library_deps = deps.Direct('java_library')
- all_library_deps = deps.All('java_library')
-
- direct_resources_deps = deps.Direct('android_resources')
- all_resources_deps = deps.All('android_resources')
- # Resources should be ordered with the highest-level dependency first so that
- # overrides are done correctly.
- all_resources_deps.reverse()
-
- if options.type == 'android_apk' and options.tested_apk_config:
- tested_apk_deps = Deps([options.tested_apk_config])
- tested_apk_resources_deps = tested_apk_deps.All('android_resources')
- all_resources_deps = [
- d for d in all_resources_deps if not d in tested_apk_resources_deps]
-
- # Initialize some common config.
- config = {
- 'deps_info': {
- 'name': os.path.basename(options.build_config),
- 'path': options.build_config,
- 'type': options.type,
- 'deps_configs': direct_deps_config_paths,
- }
- }
- deps_info = config['deps_info']
-
- if options.type == 'java_library' and not options.bypass_platform_checks:
- deps_info['requires_android'] = options.requires_android
- deps_info['supports_android'] = options.supports_android
-
- deps_require_android = (all_resources_deps +
- [d['name'] for d in all_library_deps if d['requires_android']])
- deps_not_support_android = (
- [d['name'] for d in all_library_deps if not d['supports_android']])
-
- if deps_require_android and not options.requires_android:
- raise Exception('Some deps require building for the Android platform: ' +
- str(deps_require_android))
-
- if deps_not_support_android and options.supports_android:
- raise Exception('Not all deps support the Android platform: ' +
- str(deps_not_support_android))
-
- if options.type in ['java_library', 'android_apk']:
- javac_classpath = [c['jar_path'] for c in direct_library_deps]
- java_full_classpath = [c['jar_path'] for c in all_library_deps]
- deps_info['resources_deps'] = [c['path'] for c in all_resources_deps]
- deps_info['jar_path'] = options.jar_path
- if options.type == 'android_apk' or options.supports_android:
- deps_info['dex_path'] = options.dex_path
- config['javac'] = {
- 'classpath': javac_classpath,
- }
- config['java'] = {
- 'full_classpath': java_full_classpath
- }
-
- if options.type == 'java_library':
- # Only resources might have srcjars (normal srcjar targets are listed in
- # srcjar_deps). A resource's srcjar contains the R.java file for those
- # resources, and (like Android's default build system) we allow a library to
- # refer to the resources in any of its dependents.
- config['javac']['srcjars'] = [
- c['srcjar'] for c in direct_resources_deps if 'srcjar' in c]
-
- if options.type == 'android_apk':
- # Apks will get their resources srcjar explicitly passed to the java step.
- config['javac']['srcjars'] = []
-
- if options.type == 'android_resources':
- deps_info['resources_zip'] = options.resources_zip
- if options.srcjar:
- deps_info['srcjar'] = options.srcjar
- if options.android_manifest:
- manifest = AndroidManifest(options.android_manifest)
- deps_info['package_name'] = manifest.GetPackageName()
- if options.package_name:
- deps_info['package_name'] = options.package_name
- if options.r_text:
- deps_info['r_text'] = options.r_text
-
- if options.type == 'android_resources' or options.type == 'android_apk':
- config['resources'] = {}
- config['resources']['dependency_zips'] = [
- c['resources_zip'] for c in all_resources_deps]
- config['resources']['extra_package_names'] = []
- config['resources']['extra_r_text_files'] = []
-
- if options.type == 'android_apk':
- config['resources']['extra_package_names'] = [
- c['package_name'] for c in all_resources_deps if 'package_name' in c]
- config['resources']['extra_r_text_files'] = [
- c['r_text'] for c in all_resources_deps if 'r_text' in c]
-
- if options.type in ['android_apk', 'deps_dex']:
- deps_dex_files = [c['dex_path'] for c in all_library_deps]
-
- # An instrumentation test apk should exclude the dex files that are in the apk
- # under test.
- if options.type == 'android_apk' and options.tested_apk_config:
- tested_apk_deps = Deps([options.tested_apk_config])
- tested_apk_library_deps = tested_apk_deps.All('java_library')
- tested_apk_deps_dex_files = [c['dex_path'] for c in tested_apk_library_deps]
- deps_dex_files = [
- p for p in deps_dex_files if not p in tested_apk_deps_dex_files]
-
- tested_apk_config = GetDepConfig(options.tested_apk_config)
- expected_tested_package = tested_apk_config['package_name']
- AndroidManifest(options.android_manifest).CheckInstrumentation(
- expected_tested_package)
-
- # Dependencies for the final dex file of an apk or a 'deps_dex'.
- if options.type in ['android_apk', 'deps_dex']:
- config['final_dex'] = {}
- dex_config = config['final_dex']
- # TODO(cjhopman): proguard version
- dex_config['dependency_dex_files'] = deps_dex_files
-
- if options.type == 'android_apk':
- config['dist_jar'] = {
- 'dependency_jars': [
- c['jar_path'] for c in all_library_deps
- ]
- }
- manifest = AndroidManifest(options.android_manifest)
- deps_info['package_name'] = manifest.GetPackageName()
- if not options.tested_apk_config and manifest.GetInstrumentation():
- # This must then have instrumentation only for itself.
- manifest.CheckInstrumentation(manifest.GetPackageName())
-
- library_paths = []
- java_libraries_list = []
- if options.native_libs:
- libraries = build_utils.ParseGypList(options.native_libs)
- if libraries:
- libraries_dir = os.path.dirname(libraries[0])
- write_ordered_libraries.SetReadelfPath(options.readelf_path)
- write_ordered_libraries.SetLibraryDirs([libraries_dir])
- all_native_library_deps = (
- write_ordered_libraries.GetSortedTransitiveDependenciesForBinaries(
- libraries))
- # Create a java literal array with the "base" library names:
- # e.g. libfoo.so -> foo
- java_libraries_list = '{%s}' % ','.join(
- ['"%s"' % s[3:-3] for s in all_native_library_deps])
- library_paths = map(
- write_ordered_libraries.FullLibraryPath, all_native_library_deps)
-
- config['native'] = {
- 'libraries': library_paths,
- 'java_libraries_list': java_libraries_list
- }
-
- build_utils.WriteJson(config, options.build_config, only_if_changed=True)
-
- if options.depfile:
- build_utils.WriteDepfile(
- options.depfile,
- deps.AllConfigPaths() + build_utils.GetPythonDependencies())
-
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv[1:]))
diff --git a/build/android/gyp/write_ordered_libraries.py b/build/android/gyp/write_ordered_libraries.py
deleted file mode 100755
index 0fc9a8c..0000000
--- a/build/android/gyp/write_ordered_libraries.py
+++ /dev/null
@@ -1,144 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Writes dependency ordered list of native libraries.
-
-The list excludes any Android system libraries, as those are not bundled with
-the APK.
-
-This list of libraries is used for several steps of building an APK.
-In the component build, the --input-libraries only needs to be the top-level
-library (i.e. libcontent_shell_content_view). This will then use readelf to
-inspect the shared libraries and determine the full list of (non-system)
-libraries that should be included in the APK.
-"""
-
-# TODO(cjhopman): See if we can expose the list of library dependencies from
-# gyp, rather than calculating it ourselves.
-# http://crbug.com/225558
-
-import optparse
-import os
-import re
-import sys
-
-from util import build_utils
-
-_readelf = None
-_library_dirs = None
-
-_library_re = re.compile(
- '.*NEEDED.*Shared library: \[(?P<library_name>.+)\]')
-
-
-def SetReadelfPath(path):
- global _readelf
- _readelf = path
-
-
-def SetLibraryDirs(dirs):
- global _library_dirs
- _library_dirs = dirs
-
-
-def FullLibraryPath(library_name):
- assert _library_dirs is not None
- for directory in _library_dirs:
- path = '%s/%s' % (directory, library_name)
- if os.path.exists(path):
- return path
- return library_name
-
-
-def IsSystemLibrary(library_name):
- # If the library doesn't exist in the libraries directory, assume that it is
- # an Android system library.
- return not os.path.exists(FullLibraryPath(library_name))
-
-
-def CallReadElf(library_or_executable):
- assert _readelf is not None
- readelf_cmd = [_readelf,
- '-d',
- FullLibraryPath(library_or_executable)]
- return build_utils.CheckOutput(readelf_cmd)
-
-
-def GetDependencies(library_or_executable):
- elf = CallReadElf(library_or_executable)
- return set(_library_re.findall(elf))
-
-
-def GetNonSystemDependencies(library_name):
- all_deps = GetDependencies(library_name)
- return set((lib for lib in all_deps if not IsSystemLibrary(lib)))
-
-
-def GetSortedTransitiveDependencies(libraries):
- """Returns all transitive library dependencies in dependency order."""
- return build_utils.GetSortedTransitiveDependencies(
- libraries, GetNonSystemDependencies)
-
-
-def GetSortedTransitiveDependenciesForBinaries(binaries):
- if binaries[0].endswith('.so'):
- libraries = [os.path.basename(lib) for lib in binaries]
- else:
- assert len(binaries) == 1
- all_deps = GetDependencies(binaries[0])
- libraries = [lib for lib in all_deps if not IsSystemLibrary(lib)]
-
- return GetSortedTransitiveDependencies(libraries)
-
-
-def main():
- parser = optparse.OptionParser()
- build_utils.AddDepfileOption(parser)
-
- parser.add_option('--input-libraries',
- help='A list of top-level input libraries.')
- parser.add_option('--libraries-dir',
- help='The directory which contains shared libraries.')
- parser.add_option('--readelf', help='Path to the readelf binary.')
- parser.add_option('--output', help='Path to the generated .json file.')
- parser.add_option('--stamp', help='Path to touch on success.')
-
- options, _ = parser.parse_args()
-
- SetReadelfPath(options.readelf)
- SetLibraryDirs(options.libraries_dir.split(','))
-
- libraries = build_utils.ParseGypList(options.input_libraries)
- if len(libraries):
- libraries = GetSortedTransitiveDependenciesForBinaries(libraries)
-
- # Convert to "base" library names: e.g. libfoo.so -> foo
- java_libraries_list = (
- '{%s}' % ','.join(['"%s"' % s[3:-3] for s in libraries]))
-
- out_json = {
- 'libraries': libraries,
- 'lib_paths': [FullLibraryPath(l) for l in libraries],
- 'java_libraries_list': java_libraries_list
- }
- build_utils.WriteJson(
- out_json,
- options.output,
- only_if_changed=True)
-
- if options.stamp:
- build_utils.Touch(options.stamp)
-
- if options.depfile:
- build_utils.WriteDepfile(
- options.depfile,
- libraries + build_utils.GetPythonDependencies())
-
-
-if __name__ == '__main__':
- sys.exit(main())
-
-
diff --git a/build/android/gyp/zip.py b/build/android/gyp/zip.py
deleted file mode 100755
index 51322df..0000000
--- a/build/android/gyp/zip.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Archives a set of files.
-"""
-
-import optparse
-import sys
-
-from util import build_utils
-
-def main():
- parser = optparse.OptionParser()
- parser.add_option('--input-dir', help='Directory of files to archive.')
- parser.add_option('--output', help='Path to output archive.')
- options, _ = parser.parse_args()
-
- inputs = build_utils.FindInDirectory(options.input_dir, '*')
- build_utils.DoZip(inputs, options.output, options.input_dir)
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/build/android/host_heartbeat.py b/build/android/host_heartbeat.py
deleted file mode 100755
index 6a7cdd1..0000000
--- a/build/android/host_heartbeat.py
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (c) 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Sends a heart beat pulse to the currently online Android devices.
-This heart beat lets the devices know that they are connected to a host.
-"""
-# pylint: disable=W0702
-
-import sys
-import time
-
-from pylib.device import device_utils
-
-PULSE_PERIOD = 20
-
-def main():
- while True:
- try:
- devices = device_utils.DeviceUtils.HealthyDevices()
- for d in devices:
- d.RunShellCommand(['touch', '/sdcard/host_heartbeat'],
- check_return=True)
- except:
- # Keep the heatbeat running bypassing all errors.
- pass
- time.sleep(PULSE_PERIOD)
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/build/android/increase_size_for_speed.gypi b/build/android/increase_size_for_speed.gypi
deleted file mode 100644
index 48d17f5..0000000
--- a/build/android/increase_size_for_speed.gypi
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright (c) 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included to optimize a target for speed
-# rather than for size on Android.
-# This is used in some carefully tailored targets and is not meant
-# to be included everywhere. Before adding the template to another target,
-# please ask in chromium-dev@. See crbug.com/411909
-
-{
- 'configurations': {
- 'Release': {
- 'target_conditions': [
- ['_toolset=="target"', {
- 'conditions': [
- ['OS=="android"', {
- 'cflags!': ['-Os'],
- 'cflags': ['-O2'],
- }],
- # Do not merge -Os and -O2 in LTO.
- # LTO merges all optimization options at link-time. -O2 takes
- # precedence over -Os. Avoid using LTO simultaneously
- # on -Os and -O2 parts for that reason.
- ['OS=="android" and use_lto==1', {
- 'cflags!': [
- '-flto',
- '-ffat-lto-objects',
- ],
- }],
- ['OS=="android" and use_lto_o2==1', {
- 'cflags': [
- '-flto',
- '-ffat-lto-objects',
- ],
- }],
- ],
- }],
- ],
- },
- },
-}
diff --git a/build/android/insert_chromium_version.gypi b/build/android/insert_chromium_version.gypi
deleted file mode 100644
index a6ff908..0000000
--- a/build/android/insert_chromium_version.gypi
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included into an action to provide a rule that
-# inserts a chromium version string into native libraries.
-#
-# To use this, create a gyp target with the following form:
-# {
-# 'action_name': 'insert_chromium_version',
-# 'actions': [
-# 'variables': {
-# 'ordered_libraries_file': 'file generated by write_ordered_libraries'
-# 'stripped_libraries_dir': 'the directory contains native libraries'
-# 'input_paths': 'files to be added to the list of inputs'
-# 'stamp': 'file to touch when the action is complete'
-# 'version_string': 'chromium version string to be inserted'
-# 'includes': [ '../../build/android/insert_chromium_version.gypi' ],
-# ],
-# },
-#
-
-{
- 'message': 'Inserting chromium version string into native libraries',
- 'variables': {
- 'input_paths': [],
- },
- 'inputs': [
- '<(DEPTH)/build/android/gyp/util/build_utils.py',
- '<(DEPTH)/build/android/gyp/insert_chromium_version.py',
- '<(ordered_libraries_file)',
- '>@(input_paths)',
- ],
- 'outputs': [
- '<(stamp)',
- ],
- 'action': [
- 'python', '<(DEPTH)/build/android/gyp/insert_chromium_version.py',
- '--android-objcopy=<(android_objcopy)',
- '--stripped-libraries-dir=<(stripped_libraries_dir)',
- '--libraries=@FileArg(<(ordered_libraries_file):libraries)',
- '--version-string=<(version_string)',
- '--stamp=<(stamp)',
- ],
- 'conditions': [
- ['component == "shared_library"', {
- # Add a fake output to force the build to always re-run this step. This
- # is required because the real inputs are not known at gyp-time and
- # changing base.so may not trigger changes to dependent libraries.
- 'outputs': [ '<(stamp).fake' ]
- }],
- ],
-}
diff --git a/build/android/install_emulator_deps.py b/build/android/install_emulator_deps.py
deleted file mode 100755
index 82d1c75..0000000
--- a/build/android/install_emulator_deps.py
+++ /dev/null
@@ -1,277 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Installs deps for using SDK emulator for testing.
-
-The script will download the SDK and system images, if they are not present, and
-install and enable KVM, if virtualization has been enabled in the BIOS.
-"""
-
-
-import logging
-import optparse
-import os
-import re
-import shutil
-import sys
-
-from pylib import cmd_helper
-from pylib import constants
-from pylib import pexpect
-from pylib.utils import run_tests_helper
-
-# Android API level
-DEFAULT_ANDROID_API_LEVEL = constants.ANDROID_SDK_VERSION
-
-# From the Android Developer's website.
-# Keep this up to date; the user can install older API levels as necessary.
-SDK_BASE_URL = 'http://dl.google.com/android/adt'
-SDK_ZIP = 'adt-bundle-linux-x86_64-20131030.zip'
-
-# pylint: disable=line-too-long
-# Android x86 system image from the Intel website:
-# http://software.intel.com/en-us/articles/intel-eula-x86-android-4-2-jelly-bean-bin
-# These don't exist prior to Android-15.
-# As of 08 Nov 2013, Android-19 is not yet available either.
-X86_IMG_URLS = {
- 15: 'https://software.intel.com/sites/landingpage/android/sysimg_x86-15_r01.zip',
- 16: 'https://software.intel.com/sites/landingpage/android/sysimg_x86-16_r01.zip',
- 17: 'https://software.intel.com/sites/landingpage/android/sysimg_x86-17_r01.zip',
- 18: 'https://software.intel.com/sites/landingpage/android/sysimg_x86-18_r01.zip',
- 19: 'https://software.intel.com/sites/landingpage/android/sysimg_x86-19_r01.zip'}
-#pylint: enable=line-too-long
-
-def CheckSDK():
- """Check if SDK is already installed.
-
- Returns:
- True if the emulator SDK directory (src/android_emulator_sdk/) exists.
- """
- return os.path.exists(constants.EMULATOR_SDK_ROOT)
-
-
-def CheckSDKPlatform(api_level=DEFAULT_ANDROID_API_LEVEL):
- """Check if the "SDK Platform" for the specified API level is installed.
- This is necessary in order for the emulator to run when the target
- is specified.
-
- Args:
- api_level: the Android API level to check; defaults to the latest API.
-
- Returns:
- True if the platform is already installed.
- """
- android_binary = os.path.join(constants.EMULATOR_SDK_ROOT,
- 'sdk', 'tools', 'android')
- pattern = re.compile('id: [0-9]+ or "android-%d"' % api_level)
- try:
- exit_code, stdout = cmd_helper.GetCmdStatusAndOutput(
- [android_binary, 'list'])
- if exit_code != 0:
- raise Exception('\'android list\' command failed')
- for line in stdout.split('\n'):
- if pattern.match(line):
- return True
- return False
- except OSError:
- logging.exception('Unable to execute \'android list\'')
- return False
-
-
-def CheckX86Image(api_level=DEFAULT_ANDROID_API_LEVEL):
- """Check if Android system images have been installed.
-
- Args:
- api_level: the Android API level to check for; defaults to the latest API.
-
- Returns:
- True if sdk/system-images/android-<api_level>/x86 exists inside
- EMULATOR_SDK_ROOT.
- """
- api_target = 'android-%d' % api_level
- return os.path.exists(os.path.join(constants.EMULATOR_SDK_ROOT,
- 'sdk', 'system-images',
- api_target, 'x86'))
-
-
-def CheckKVM():
- """Quickly check whether KVM is enabled.
-
- Returns:
- True iff /dev/kvm exists (Linux only).
- """
- return os.path.exists('/dev/kvm')
-
-
-def RunKvmOk():
- """Run kvm-ok as root to check that KVM is properly enabled after installation
- of the required packages.
-
- Returns:
- True iff KVM is enabled (/dev/kvm exists). On failure, returns False
- but also print detailed information explaining why KVM isn't enabled
- (e.g. CPU doesn't support it, or BIOS disabled it).
- """
- try:
- # Note: kvm-ok is in /usr/sbin, so always use 'sudo' to run it.
- return not cmd_helper.RunCmd(['sudo', 'kvm-ok'])
- except OSError:
- logging.info('kvm-ok not installed')
- return False
-
-
-def GetSDK():
- """Download the SDK and unzip it into EMULATOR_SDK_ROOT."""
- logging.info('Download Android SDK.')
- sdk_url = '%s/%s' % (SDK_BASE_URL, SDK_ZIP)
- try:
- cmd_helper.RunCmd(['curl', '-o', '/tmp/sdk.zip', sdk_url])
- print 'curled unzipping...'
- rc = cmd_helper.RunCmd(['unzip', '-o', '/tmp/sdk.zip', '-d', '/tmp/'])
- if rc:
- raise Exception('ERROR: could not download/unzip Android SDK.')
- # Get the name of the sub-directory that everything will be extracted to.
- dirname, _ = os.path.splitext(SDK_ZIP)
- zip_dir = '/tmp/%s' % dirname
- # Move the extracted directory to EMULATOR_SDK_ROOT
- shutil.move(zip_dir, constants.EMULATOR_SDK_ROOT)
- finally:
- os.unlink('/tmp/sdk.zip')
-
-
-def InstallKVM():
- """Installs KVM packages."""
- rc = cmd_helper.RunCmd(['sudo', 'apt-get', 'install', 'kvm'])
- if rc:
- logging.critical('ERROR: Did not install KVM. Make sure hardware '
- 'virtualization is enabled in BIOS (i.e. Intel VT-x or '
- 'AMD SVM).')
- # TODO(navabi): Use modprobe kvm-amd on AMD processors.
- rc = cmd_helper.RunCmd(['sudo', 'modprobe', 'kvm-intel'])
- if rc:
- logging.critical('ERROR: Did not add KVM module to Linux Kernel. Make sure '
- 'hardware virtualization is enabled in BIOS.')
- # Now check to ensure KVM acceleration can be used.
- if not RunKvmOk():
- logging.critical('ERROR: Can not use KVM acceleration. Make sure hardware '
- 'virtualization is enabled in BIOS (i.e. Intel VT-x or '
- 'AMD SVM).')
-
-
-def GetX86Image(api_level=DEFAULT_ANDROID_API_LEVEL):
- """Download x86 system image from Intel's website.
-
- Args:
- api_level: the Android API level to download for.
- """
- logging.info('Download x86 system image directory into sdk directory.')
- # TODO(andrewhayden): Use python tempfile lib instead
- temp_file = '/tmp/x86_img_android-%d.zip' % api_level
- if api_level not in X86_IMG_URLS:
- raise Exception('ERROR: no URL known for x86 image for android-%s' %
- api_level)
- try:
- cmd_helper.RunCmd(['curl', '-o', temp_file, X86_IMG_URLS[api_level]])
- rc = cmd_helper.RunCmd(['unzip', '-o', temp_file, '-d', '/tmp/'])
- if rc:
- raise Exception('ERROR: Could not download/unzip image zip.')
- api_target = 'android-%d' % api_level
- sys_imgs = os.path.join(constants.EMULATOR_SDK_ROOT, 'sdk',
- 'system-images', api_target, 'x86')
- logging.info('Deploying system image to %s' % sys_imgs)
- shutil.move('/tmp/x86', sys_imgs)
- finally:
- os.unlink(temp_file)
-
-
-def GetSDKPlatform(api_level=DEFAULT_ANDROID_API_LEVEL):
- """Update the SDK to include the platform specified.
-
- Args:
- api_level: the Android API level to download
- """
- android_binary = os.path.join(constants.EMULATOR_SDK_ROOT,
- 'sdk', 'tools', 'android')
- pattern = re.compile(
- r'\s*([0-9]+)- SDK Platform Android [\.,0-9]+, API %d.*' % api_level)
- # Example:
- # 2- SDK Platform Android 4.3, API 18, revision 2
- exit_code, stdout = cmd_helper.GetCmdStatusAndOutput(
- [android_binary, 'list', 'sdk'])
- if exit_code != 0:
- raise Exception('\'android list sdk\' command return %d' % exit_code)
- for line in stdout.split('\n'):
- match = pattern.match(line)
- if match:
- index = match.group(1)
- print 'package %s corresponds to platform level %d' % (index, api_level)
- # update sdk --no-ui --filter $INDEX
- update_command = [android_binary,
- 'update', 'sdk', '--no-ui', '--filter', index]
- update_command_str = ' '.join(update_command)
- logging.info('running update command: %s' % update_command_str)
- update_process = pexpect.spawn(update_command_str)
- # TODO(andrewhayden): Do we need to bug the user about this?
- if update_process.expect('Do you accept the license') != 0:
- raise Exception('License agreement check failed')
- update_process.sendline('y')
- if update_process.expect('Done. 1 package installed.') == 0:
- print 'Successfully installed platform for API level %d' % api_level
- return
- else:
- raise Exception('Failed to install platform update')
- raise Exception('Could not find android-%d update for the SDK!' % api_level)
-
-
-def main(argv):
- opt_parser = optparse.OptionParser(
- description='Install dependencies for running the Android emulator')
- opt_parser.add_option('--api-level', dest='api_level',
- help='The API level (e.g., 19 for Android 4.4) to ensure is available',
- type='int', default=DEFAULT_ANDROID_API_LEVEL)
- opt_parser.add_option('-v', dest='verbose', action='store_true',
- help='enable verbose logging')
- options, _ = opt_parser.parse_args(argv[1:])
-
- # run_tests_helper will set logging to INFO or DEBUG
- # We achieve verbose output by configuring it with 2 (==DEBUG)
- verbosity = 1
- if options.verbose:
- verbosity = 2
- logging.basicConfig(level=logging.INFO,
- format='# %(asctime)-15s: %(message)s')
- run_tests_helper.SetLogLevel(verbose_count=verbosity)
-
- # Calls below will download emulator SDK and/or system images only if needed.
- if CheckSDK():
- logging.info('android_emulator_sdk/ already exists, skipping download.')
- else:
- GetSDK()
-
- # Check target. The target has to be installed in order to run the emulator.
- if CheckSDKPlatform(options.api_level):
- logging.info('SDK platform android-%d already present, skipping.' %
- options.api_level)
- else:
- logging.info('SDK platform android-%d not present, installing.' %
- options.api_level)
- GetSDKPlatform(options.api_level)
-
- # Download the x86 system image only if needed.
- if CheckX86Image(options.api_level):
- logging.info('x86 image for android-%d already present, skipping.' %
- options.api_level)
- else:
- GetX86Image(options.api_level)
-
- # Make sure KVM packages are installed and enabled.
- if CheckKVM():
- logging.info('KVM already installed and enabled.')
- else:
- InstallKVM()
-
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv))
diff --git a/build/android/instr_action.gypi b/build/android/instr_action.gypi
deleted file mode 100644
index fa6d062..0000000
--- a/build/android/instr_action.gypi
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included into an action to provide a rule that
-# instruments either java class files, or jars.
-
-{
- 'variables': {
- 'instr_type%': 'jar',
- 'input_path%': '',
- 'output_path%': '',
- 'stamp_path%': '',
- 'extra_instr_args': [
- '--coverage-file=<(_target_name).em',
- '--sources-file=<(_target_name)_sources.txt',
- ],
- 'emma_jar': '<(android_sdk_root)/tools/lib/emma.jar',
- 'conditions': [
- ['emma_instrument != 0', {
- 'extra_instr_args': [
- '--sources=<(java_in_dir)/src >(additional_src_dirs) >(generated_src_dirs)',
- '--src-root=<(DEPTH)',
- '--emma-jar=<(emma_jar)',
- '--filter-string=<(emma_filter)',
- ],
- 'conditions': [
- ['instr_type == "jar"', {
- 'instr_action': 'instrument_jar',
- }, {
- 'instr_action': 'instrument_classes',
- }]
- ],
- }, {
- 'instr_action': 'copy',
- 'extra_instr_args': [],
- }]
- ]
- },
- 'inputs': [
- '<(DEPTH)/build/android/gyp/emma_instr.py',
- '<(DEPTH)/build/android/gyp/util/build_utils.py',
- '<(DEPTH)/build/android/pylib/utils/command_option_parser.py',
- ],
- 'action': [
- 'python', '<(DEPTH)/build/android/gyp/emma_instr.py',
- '<(instr_action)',
- '--input-path=<(input_path)',
- '--output-path=<(output_path)',
- '--stamp=<(stamp_path)',
- '<@(extra_instr_args)',
- ]
-}
diff --git a/build/android/java_cpp_enum.gypi b/build/android/java_cpp_enum.gypi
deleted file mode 100644
index d4abafa..0000000
--- a/build/android/java_cpp_enum.gypi
+++ /dev/null
@@ -1,64 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included into a target to provide an action
-# to generate Java source files from a C++ header file containing annotated
-# enum definitions using a Python script.
-#
-# To use this, create a gyp target with the following form:
-# {
-# 'target_name': 'bitmap_format_java',
-# 'type': 'none',
-# 'variables': {
-# 'source_file': 'ui/android/bitmap_format.h',
-# },
-# 'includes': [ '../build/android/java_cpp_enum.gypi' ],
-# },
-#
-# Then have the gyp target which compiles the java code depend on the newly
-# created target.
-
-{
- 'variables': {
- # Location where all generated Java sources will be placed.
- 'output_dir': '<(SHARED_INTERMEDIATE_DIR)/enums/<(_target_name)',
- 'generator_path': '<(DEPTH)/build/android/gyp/java_cpp_enum.py',
- 'generator_args': '<(output_dir) <(source_file)',
- },
- 'direct_dependent_settings': {
- 'variables': {
- # Ensure that the output directory is used in the class path
- # when building targets that depend on this one.
- 'generated_src_dirs': [
- '<(output_dir)/',
- ],
- # Ensure that the targets depending on this one are rebuilt if the sources
- # of this one are modified.
- 'additional_input_paths': [
- '<(source_file)',
- ],
- },
- },
- 'actions': [
- {
- 'action_name': 'generate_java_constants',
- 'inputs': [
- '<(DEPTH)/build/android/gyp/util/build_utils.py',
- '<(generator_path)',
- '<(source_file)',
- ],
- 'outputs': [
- # This is the main reason this is an action and not a rule. Gyp doesn't
- # properly expand RULE_INPUT_PATH here and so it's impossible to
- # calculate the list of outputs.
- '<!@pymod_do_main(java_cpp_enum --print_output_only '
- '<@(generator_args))',
- ],
- 'action': [
- 'python', '<(generator_path)', '<@(generator_args)'
- ],
- 'message': 'Generating Java from cpp header <(source_file)',
- },
- ],
-}
diff --git a/build/android/java_cpp_template.gypi b/build/android/java_cpp_template.gypi
deleted file mode 100644
index 3296659..0000000
--- a/build/android/java_cpp_template.gypi
+++ /dev/null
@@ -1,81 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included into a target to provide a rule
-# to generate Java source files from templates that are processed
-# through the host C pre-processor.
-#
-# NOTE: For generating Java conterparts to enums prefer using the java_cpp_enum
-# rule instead.
-#
-# To use this, create a gyp target with the following form:
-# {
-# 'target_name': 'android_net_java_constants',
-# 'type': 'none',
-# 'sources': [
-# 'net/android/NetError.template',
-# ],
-# 'variables': {
-# 'package_name': 'org/chromium/net',
-# 'template_deps': ['base/net_error_list.h'],
-# },
-# 'includes': [ '../build/android/java_cpp_template.gypi' ],
-# },
-#
-# The 'sources' entry should only list template file. The template file
-# itself should use the 'ClassName.template' format, and will generate
-# 'gen/templates/<target-name>/<package-name>/ClassName.java. The files which
-# template dependents on and typically included by the template should be listed
-# in template_deps variables. Any change to them will force a rebuild of
-# the template, and hence of any source that depends on it.
-#
-
-{
- # Location where all generated Java sources will be placed.
- 'variables': {
- 'include_path%': '<(DEPTH)',
- 'output_dir': '<(SHARED_INTERMEDIATE_DIR)/templates/<(_target_name)/<(package_name)',
- },
- 'direct_dependent_settings': {
- 'variables': {
- # Ensure that the output directory is used in the class path
- # when building targets that depend on this one.
- 'generated_src_dirs': [
- '<(output_dir)/',
- ],
- # Ensure dependents are rebuilt when sources for this rule change.
- 'additional_input_paths': [
- '<@(_sources)',
- '<@(template_deps)',
- ],
- },
- },
- # Define a single rule that will be apply to each .template file
- # listed in 'sources'.
- 'rules': [
- {
- 'rule_name': 'generate_java_constants',
- 'extension': 'template',
- # Set template_deps as additional dependencies.
- 'variables': {
- 'output_path': '<(output_dir)/<(RULE_INPUT_ROOT).java',
- },
- 'inputs': [
- '<(DEPTH)/build/android/gyp/util/build_utils.py',
- '<(DEPTH)/build/android/gyp/gcc_preprocess.py',
- '<@(template_deps)'
- ],
- 'outputs': [
- '<(output_path)',
- ],
- 'action': [
- 'python', '<(DEPTH)/build/android/gyp/gcc_preprocess.py',
- '--include-path=<(include_path)',
- '--output=<(output_path)',
- '--template=<(RULE_INPUT_PATH)',
- ],
- 'message': 'Generating Java from cpp template <(RULE_INPUT_PATH)',
- }
- ],
-}
diff --git a/build/android/jinja_template.gypi b/build/android/jinja_template.gypi
deleted file mode 100644
index 9c49360..0000000
--- a/build/android/jinja_template.gypi
+++ /dev/null
@@ -1,85 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included into a target to process one or more
-# Jinja templates.
-#
-# To process a single template file, create a gyp target with the following
-# form:
-# {
-# 'target_name': 'chrome_shell_manifest',
-# 'type': 'none',
-# 'variables': {
-# 'jinja_inputs': ['android/shell/java/AndroidManifest.xml'],
-# 'jinja_output': '<(SHARED_INTERMEDIATE_DIR)/chrome_shell_manifest/AndroidManifest.xml',
-# 'jinja_variables': ['app_name=ChromeShell'],
-# },
-# 'includes': [ '../build/android/jinja_template.gypi' ],
-# },
-#
-# To process multiple template files and package the results into a zip file,
-# create a gyp target with the following form:
-# {
-# 'target_name': 'chrome_template_resources',
-# 'type': 'none',
-# 'variables': {
-# 'jinja_inputs_base_dir': 'android/shell/java/res_template',
-# 'jinja_inputs': [
-# '<(jinja_inputs_base_dir)/xml/searchable.xml',
-# '<(jinja_inputs_base_dir)/xml/syncadapter.xml',
-# ],
-# 'jinja_outputs_zip': '<(PRODUCT_DIR)/res.java/<(_target_name).zip',
-# 'jinja_variables': ['app_name=ChromeShell'],
-# },
-# 'includes': [ '../build/android/jinja_template.gypi' ],
-# },
-#
-
-{
- 'actions': [
- {
- 'action_name': '<(_target_name)_jinja_template',
- 'message': 'processing jinja template',
- 'variables': {
- 'jinja_output%': '',
- 'jinja_outputs_zip%': '',
- 'jinja_inputs_base_dir%': '',
- 'jinja_includes%': [],
- 'jinja_variables%': [],
- 'jinja_args': [],
- },
- 'inputs': [
- '<(DEPTH)/build/android/gyp/util/build_utils.py',
- '<(DEPTH)/build/android/gyp/jinja_template.py',
- '<@(jinja_inputs)',
- '<@(jinja_includes)',
- ],
- 'conditions': [
- ['jinja_output != ""', {
- 'outputs': [ '<(jinja_output)' ],
- 'variables': {
- 'jinja_args': ['--output', '<(jinja_output)'],
- },
- }],
- ['jinja_outputs_zip != ""', {
- 'outputs': [ '<(jinja_outputs_zip)' ],
- 'variables': {
- 'jinja_args': ['--outputs-zip', '<(jinja_outputs_zip)'],
- },
- }],
- ['jinja_inputs_base_dir != ""', {
- 'variables': {
- 'jinja_args': ['--inputs-base-dir', '<(jinja_inputs_base_dir)'],
- },
- }],
- ],
- 'action': [
- 'python', '<(DEPTH)/build/android/gyp/jinja_template.py',
- '--inputs', '<(jinja_inputs)',
- '--variables', '<(jinja_variables)',
- '<@(jinja_args)',
- ],
- },
- ],
-}
diff --git a/build/android/lighttpd_server.py b/build/android/lighttpd_server.py
deleted file mode 100755
index a5195ac..0000000
--- a/build/android/lighttpd_server.py
+++ /dev/null
@@ -1,256 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Provides a convenient wrapper for spawning a test lighttpd instance.
-
-Usage:
- lighttpd_server PATH_TO_DOC_ROOT
-"""
-
-import codecs
-import contextlib
-import httplib
-import os
-import random
-import shutil
-import socket
-import subprocess
-import sys
-import tempfile
-import time
-
-from pylib import constants
-from pylib import pexpect
-
-class LighttpdServer(object):
- """Wraps lighttpd server, providing robust startup.
-
- Args:
- document_root: Path to root of this server's hosted files.
- port: TCP port on the _host_ machine that the server will listen on. If
- ommitted it will attempt to use 9000, or if unavailable it will find
- a free port from 8001 - 8999.
- lighttpd_path, lighttpd_module_path: Optional paths to lighttpd binaries.
- base_config_path: If supplied this file will replace the built-in default
- lighttpd config file.
- extra_config_contents: If specified, this string will be appended to the
- base config (default built-in, or from base_config_path).
- config_path, error_log, access_log: Optional paths where the class should
- place temprary files for this session.
- """
-
- def __init__(self, document_root, port=None,
- lighttpd_path=None, lighttpd_module_path=None,
- base_config_path=None, extra_config_contents=None,
- config_path=None, error_log=None, access_log=None):
- self.temp_dir = tempfile.mkdtemp(prefix='lighttpd_for_chrome_android')
- self.document_root = os.path.abspath(document_root)
- self.fixed_port = port
- self.port = port or constants.LIGHTTPD_DEFAULT_PORT
- self.server_tag = 'LightTPD ' + str(random.randint(111111, 999999))
- self.lighttpd_path = lighttpd_path or '/usr/sbin/lighttpd'
- self.lighttpd_module_path = lighttpd_module_path or '/usr/lib/lighttpd'
- self.base_config_path = base_config_path
- self.extra_config_contents = extra_config_contents
- self.config_path = config_path or self._Mktmp('config')
- self.error_log = error_log or self._Mktmp('error_log')
- self.access_log = access_log or self._Mktmp('access_log')
- self.pid_file = self._Mktmp('pid_file')
- self.process = None
-
- def _Mktmp(self, name):
- return os.path.join(self.temp_dir, name)
-
- @staticmethod
- def _GetRandomPort():
- # The ports of test server is arranged in constants.py.
- return random.randint(constants.LIGHTTPD_RANDOM_PORT_FIRST,
- constants.LIGHTTPD_RANDOM_PORT_LAST)
-
- def StartupHttpServer(self):
- """Starts up a http server with specified document root and port."""
- # If we want a specific port, make sure no one else is listening on it.
- if self.fixed_port:
- self._KillProcessListeningOnPort(self.fixed_port)
- while True:
- if self.base_config_path:
- # Read the config
- with codecs.open(self.base_config_path, 'r', 'utf-8') as f:
- config_contents = f.read()
- else:
- config_contents = self._GetDefaultBaseConfig()
- if self.extra_config_contents:
- config_contents += self.extra_config_contents
- # Write out the config, filling in placeholders from the members of |self|
- with codecs.open(self.config_path, 'w', 'utf-8') as f:
- f.write(config_contents % self.__dict__)
- if (not os.path.exists(self.lighttpd_path) or
- not os.access(self.lighttpd_path, os.X_OK)):
- raise EnvironmentError(
- 'Could not find lighttpd at %s.\n'
- 'It may need to be installed (e.g. sudo apt-get install lighttpd)'
- % self.lighttpd_path)
- self.process = pexpect.spawn(self.lighttpd_path,
- ['-D', '-f', self.config_path,
- '-m', self.lighttpd_module_path],
- cwd=self.temp_dir)
- client_error, server_error = self._TestServerConnection()
- if not client_error:
- assert int(open(self.pid_file, 'r').read()) == self.process.pid
- break
- self.process.close()
-
- if self.fixed_port or not 'in use' in server_error:
- print 'Client error:', client_error
- print 'Server error:', server_error
- return False
- self.port = self._GetRandomPort()
- return True
-
- def ShutdownHttpServer(self):
- """Shuts down our lighttpd processes."""
- if self.process:
- self.process.terminate()
- shutil.rmtree(self.temp_dir, ignore_errors=True)
-
- def _TestServerConnection(self):
- # Wait for server to start
- server_msg = ''
- for timeout in xrange(1, 5):
- client_error = None
- try:
- with contextlib.closing(httplib.HTTPConnection(
- '127.0.0.1', self.port, timeout=timeout)) as http:
- http.set_debuglevel(timeout > 3)
- http.request('HEAD', '/')
- r = http.getresponse()
- r.read()
- if (r.status == 200 and r.reason == 'OK' and
- r.getheader('Server') == self.server_tag):
- return (None, server_msg)
- client_error = ('Bad response: %s %s version %s\n ' %
- (r.status, r.reason, r.version) +
- '\n '.join([': '.join(h) for h in r.getheaders()]))
- except (httplib.HTTPException, socket.error) as client_error:
- pass # Probably too quick connecting: try again
- # Check for server startup error messages
- ix = self.process.expect([pexpect.TIMEOUT, pexpect.EOF, '.+'],
- timeout=timeout)
- if ix == 2: # stdout spew from the server
- server_msg += self.process.match.group(0)
- elif ix == 1: # EOF -- server has quit so giveup.
- client_error = client_error or 'Server exited'
- break
- return (client_error or 'Timeout', server_msg)
-
- @staticmethod
- def _KillProcessListeningOnPort(port):
- """Checks if there is a process listening on port number |port| and
- terminates it if found.
-
- Args:
- port: Port number to check.
- """
- if subprocess.call(['fuser', '-kv', '%d/tcp' % port]) == 0:
- # Give the process some time to terminate and check that it is gone.
- time.sleep(2)
- assert subprocess.call(['fuser', '-v', '%d/tcp' % port]) != 0, \
- 'Unable to kill process listening on port %d.' % port
-
- @staticmethod
- def _GetDefaultBaseConfig():
- return """server.tag = "%(server_tag)s"
-server.modules = ( "mod_access",
- "mod_accesslog",
- "mod_alias",
- "mod_cgi",
- "mod_rewrite" )
-
-# default document root required
-#server.document-root = "."
-
-# files to check for if .../ is requested
-index-file.names = ( "index.php", "index.pl", "index.cgi",
- "index.html", "index.htm", "default.htm" )
-# mimetype mapping
-mimetype.assign = (
- ".gif" => "image/gif",
- ".jpg" => "image/jpeg",
- ".jpeg" => "image/jpeg",
- ".png" => "image/png",
- ".svg" => "image/svg+xml",
- ".css" => "text/css",
- ".html" => "text/html",
- ".htm" => "text/html",
- ".xhtml" => "application/xhtml+xml",
- ".xhtmlmp" => "application/vnd.wap.xhtml+xml",
- ".js" => "application/x-javascript",
- ".log" => "text/plain",
- ".conf" => "text/plain",
- ".text" => "text/plain",
- ".txt" => "text/plain",
- ".dtd" => "text/xml",
- ".xml" => "text/xml",
- ".manifest" => "text/cache-manifest",
- )
-
-# Use the "Content-Type" extended attribute to obtain mime type if possible
-mimetype.use-xattr = "enable"
-
-##
-# which extensions should not be handle via static-file transfer
-#
-# .php, .pl, .fcgi are most often handled by mod_fastcgi or mod_cgi
-static-file.exclude-extensions = ( ".php", ".pl", ".cgi" )
-
-server.bind = "127.0.0.1"
-server.port = %(port)s
-
-## virtual directory listings
-dir-listing.activate = "enable"
-#dir-listing.encoding = "iso-8859-2"
-#dir-listing.external-css = "style/oldstyle.css"
-
-## enable debugging
-#debug.log-request-header = "enable"
-#debug.log-response-header = "enable"
-#debug.log-request-handling = "enable"
-#debug.log-file-not-found = "enable"
-
-#### SSL engine
-#ssl.engine = "enable"
-#ssl.pemfile = "server.pem"
-
-# Autogenerated test-specific config follows.
-
-cgi.assign = ( ".cgi" => "/usr/bin/env",
- ".pl" => "/usr/bin/env",
- ".asis" => "/bin/cat",
- ".php" => "/usr/bin/php-cgi" )
-
-server.errorlog = "%(error_log)s"
-accesslog.filename = "%(access_log)s"
-server.upload-dirs = ( "/tmp" )
-server.pid-file = "%(pid_file)s"
-server.document-root = "%(document_root)s"
-
-"""
-
-
-def main(argv):
- server = LighttpdServer(*argv[1:])
- try:
- if server.StartupHttpServer():
- raw_input('Server running at http://127.0.0.1:%s -'
- ' press Enter to exit it.' % server.port)
- else:
- print 'Server exit code:', server.process.exitstatus
- finally:
- server.ShutdownHttpServer()
-
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv))
diff --git a/build/android/lint/OWNERS b/build/android/lint/OWNERS
deleted file mode 100644
index cd396e7..0000000
--- a/build/android/lint/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-newt@chromium.org
-aurimas@chromium.org
diff --git a/build/android/lint/suppress.py b/build/android/lint/suppress.py
deleted file mode 100755
index 52d7579..0000000
--- a/build/android/lint/suppress.py
+++ /dev/null
@@ -1,115 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (c) 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Add all generated lint_result.xml files to suppressions.xml"""
-
-
-import collections
-import optparse
-import os
-import sys
-from xml.dom import minidom
-
-_BUILD_ANDROID_DIR = os.path.join(os.path.dirname(__file__), '..')
-sys.path.append(_BUILD_ANDROID_DIR)
-
-from pylib import constants
-
-
-_THIS_FILE = os.path.abspath(__file__)
-_CONFIG_PATH = os.path.join(os.path.dirname(_THIS_FILE), 'suppressions.xml')
-_DOC = (
- '\nSTOP! It looks like you want to suppress some lint errors:\n'
- '- Have you tried identifing the offending patch?\n'
- ' Ask the author for a fix and/or revert the patch.\n'
- '- It is preferred to add suppressions in the code instead of\n'
- ' sweeping it under the rug here. See:\n\n'
- ' http://developer.android.com/tools/debugging/improving-w-lint.html\n'
- '\n'
- 'Still reading?\n'
- '- You can edit this file manually to suppress an issue\n'
- ' globally if it is not applicable to the project.\n'
- '- You can also automatically add issues found so for in the\n'
- ' build process by running:\n\n'
- ' ' + os.path.relpath(_THIS_FILE, constants.DIR_SOURCE_ROOT) + '\n\n'
- ' which will generate this file (Comments are not preserved).\n'
- ' Note: PRODUCT_DIR will be substituted at run-time with actual\n'
- ' directory path (e.g. out/Debug)\n'
-)
-
-
-_Issue = collections.namedtuple('Issue', ['severity', 'paths'])
-
-
-def _ParseConfigFile(config_path):
- print 'Parsing %s' % config_path
- issues_dict = {}
- dom = minidom.parse(config_path)
- for issue in dom.getElementsByTagName('issue'):
- issue_id = issue.attributes['id'].value
- severity = issue.getAttribute('severity')
- paths = set(
- [p.attributes['path'].value for p in
- issue.getElementsByTagName('ignore')])
- issues_dict[issue_id] = _Issue(severity, paths)
- return issues_dict
-
-
-def _ParseAndMergeResultFile(result_path, issues_dict):
- print 'Parsing and merging %s' % result_path
- dom = minidom.parse(result_path)
- for issue in dom.getElementsByTagName('issue'):
- issue_id = issue.attributes['id'].value
- severity = issue.attributes['severity'].value
- path = issue.getElementsByTagName('location')[0].attributes['file'].value
- if issue_id not in issues_dict:
- issues_dict[issue_id] = _Issue(severity, set())
- issues_dict[issue_id].paths.add(path)
-
-
-def _WriteConfigFile(config_path, issues_dict):
- new_dom = minidom.getDOMImplementation().createDocument(None, 'lint', None)
- top_element = new_dom.documentElement
- top_element.appendChild(new_dom.createComment(_DOC))
- for issue_id in sorted(issues_dict.keys()):
- severity = issues_dict[issue_id].severity
- paths = issues_dict[issue_id].paths
- issue = new_dom.createElement('issue')
- issue.attributes['id'] = issue_id
- if severity:
- issue.attributes['severity'] = severity
- if severity == 'ignore':
- print 'Warning: [%s] is suppressed globally.' % issue_id
- else:
- for path in sorted(paths):
- ignore = new_dom.createElement('ignore')
- ignore.attributes['path'] = path
- issue.appendChild(ignore)
- top_element.appendChild(issue)
-
- with open(config_path, 'w') as f:
- f.write(new_dom.toprettyxml(indent=' ', encoding='utf-8'))
- print 'Updated %s' % config_path
-
-
-def _Suppress(config_path, result_path):
- issues_dict = _ParseConfigFile(config_path)
- _ParseAndMergeResultFile(result_path, issues_dict)
- _WriteConfigFile(config_path, issues_dict)
-
-
-def main():
- parser = optparse.OptionParser(usage='%prog RESULT-FILE')
- _, args = parser.parse_args()
-
- if len(args) != 1 or not os.path.exists(args[0]):
- parser.error('Must provide RESULT-FILE')
-
- _Suppress(_CONFIG_PATH, args[0])
-
-
-if __name__ == '__main__':
- main()
diff --git a/build/android/lint/suppressions.xml b/build/android/lint/suppressions.xml
deleted file mode 100644
index cb77c1f..0000000
--- a/build/android/lint/suppressions.xml
+++ /dev/null
@@ -1,111 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<lint>
- <!--
-STOP! It looks like you want to suppress some lint errors:
-- Have you tried identifing the offending patch?
- Ask the author for a fix and/or revert the patch.
-- It is preferred to add suppressions in the code instead of
- sweeping it under the rug here. See:
-
- http://developer.android.com/tools/debugging/improving-w-lint.html
-
-Still reading?
-- You can edit this file manually to suppress an issue
- globally if it is not applicable to the project.
-- You can also automatically add issues found so for in the
- build process by running:
-
- build/android/lint/suppress.py
-
- which will generate this file (Comments are not preserved).
- Note: PRODUCT_DIR will be substituted at run-time with actual
- directory path (e.g. out/Debug)
--->
- <issue id="AllowBackup">
- <ignore path="AndroidManifest.xml"/>
- </issue>
- <issue id="Assert" severity="ignore"/>
- <issue id="CommitPrefEdits">
- <ignore path="third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/ticl/android2/channel/AndroidChannelPreferences.java"/>
- </issue>
- <issue id="DefaultLocale">
- <ignore path="third_party/cacheinvalidation/src/java/com/google/ipc/invalidation/external/client/contrib/AndroidListenerState.java"/>
- </issue>
- <issue id="DrawAllocation">
- <ignore path="content/public/android/java/src/org/chromium/content/browser/ContentViewRenderView.java"/>
- <ignore path="content/public/android/java/src/org/chromium/content/browser/PopupZoomer.java"/>
- </issue>
- <issue id="ExportedContentProvider">
- <ignore path="AndroidManifest.xml"/>
- </issue>
- <issue id="HandlerLeak">
- <ignore path="remoting/android/java/src/org/chromium/chromoting/TapGestureDetector.java"/>
- </issue>
- <issue id="HardcodedDebugMode" severity="Fatal">
- <ignore path="AndroidManifest.xml"/>
- </issue>
- <issue id="IconDensities">
- <!-- crbug.com/457918 is tracking missing assets -->
- <ignore path="components/web_contents_delegate_android/android/java/res/drawable-xxhdpi"/>
- <ignore path="components/web_contents_delegate_android/android/java/res/drawable-xxxhdpi"/>
- <ignore path="content/public/android/java/res/drawable-xxhdpi"/>
- <ignore path="content/public/android/java/res/drawable-xxxhdpi"/>
- <ignore path="chrome/android/java/res/drawable-xxhdpi"/>
- <ignore path="chrome/android/java/res/drawable-xxxhdpi"/>
- <ignore path="ui/android/java/res/drawable-xxhdpi"/>
- <ignore path="ui/android/java/res/drawable-xxxhdpi"/>
- <ignore regexp=".*: reader_mode_bar_background.9.png, tabs_moved_htc.png, tabs_moved_nexus.png, tabs_moved_samsung.png$"/>
- </issue>
- <issue id="IconLocation">
- <!-- It is OK for content_shell_apk and chrome_shell_apk to have missing assets. -->
- <ignore path="content/shell/android/java/res/"/>
- <ignore path="chrome/android/shell/res/"/>
- <!-- Suppression for chrome/test/chromedriver/test/webview_shell/java/res/drawable/icon.png -->
- <ignore path="res/drawable/icon.png"/>
- <!-- TODO(lambroslambrou) remove this once crbug.com/502030 is fixed. -->
- <ignore path="remoting/android/java/res"/>
- </issue>
- <issue id="InconsistentLayout" severity="ignore"/>
- <issue id="InflateParams" severity="ignore"/>
- <issue id="MissingApplicationIcon" severity="ignore"/>
- <issue id="MissingRegistered" severity="ignore"/>
- <issue id="MissingVersion">
- <ignore path="AndroidManifest.xml"/>
- </issue>
- <issue id="InlinedApi" severity="ignore"/>
- <issue id="NewApi">
- <ignore regexp="Attribute `paddingStart` referenced here can result in a crash on some specific devices older than API 17"/>
- <ignore path="org/chromium/base/AnimationFrameTimeHistogram$Recorder.class"/>
- <ignore path="org/chromium/base/JavaHandlerThread.class"/>
- <ignore path="org/chromium/base/SysUtils.class"/>
- <ignore path="org/chromium/chrome/browser/TtsPlatformImpl.class"/>
- <ignore path="org/chromium/chrome/browser/TtsPlatformImpl$*.class"/>
- <ignore path="chrome/android/java/res/values-v17/styles.xml"/>
- </issue>
- <issue id="OldTargetApi">
- <ignore path="AndroidManifest.xml"/>
- </issue>
- <issue id="Overdraw" severity="ignore"/>
- <issue id="Recycle" severity="ignore"/>
- <issue id="Registered" severity="ignore"/>
- <issue id="RtlCompat" severity="ignore"/>
- <issue id="RtlEnabled" severity="ignore"/>
- <issue id="RtlSymmetry" severity="ignore"/>
- <issue id="SdCardPath">
- <ignore path="content/public/android/java/src/org/chromium/content/browser/MediaResourceGetter.java"/>
- </issue>
- <issue id="SetJavaScriptEnabled" severity="ignore"/>
- <issue id="UnusedResources">
- <!-- Used by chrome/android/java/AndroidManifest.xml -->
- <ignore path="chrome/android/java/res/drawable/window_background.xml" />
- <ignore path="chrome/android/java/res/xml/bookmark_thumbnail_widget_info.xml" />
- <ignore path="chrome/android/java/res/xml/file_paths.xml" />
-
- <ignore path="content/shell/android/shell_apk/res/layout/content_shell_activity.xml" />
- <ignore path="content/shell/android/shell_apk/res/values/strings.xml" />
- </issue>
- <issue id="SignatureOrSystemPermissions" severity="ignore"/>
- <issue id="UnusedAttribute" severity="ignore"/>
- <issue id="ViewConstructor" severity="ignore"/>
- <issue id="WrongCall" severity="ignore"/>
-</lint>
diff --git a/build/android/lint_action.gypi b/build/android/lint_action.gypi
deleted file mode 100644
index e1adf1f..0000000
--- a/build/android/lint_action.gypi
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included into an action to provide a rule to
-# run lint on java/class files.
-
-{
- 'action_name': 'lint_<(_target_name)',
- 'message': 'Linting <(_target_name)',
- 'variables': {
- 'conditions': [
- ['chromium_code != 0 and android_lint != 0 and never_lint == 0', {
- 'is_enabled': '--enable',
- }, {
- 'is_enabled': '',
- }]
- ],
- 'android_manifest_path%': '<(DEPTH)/build/android/AndroidManifest.xml',
- 'resource_dir%': '<(DEPTH)/build/android/ant/empty/res',
- },
- 'inputs': [
- '<(DEPTH)/build/android/gyp/util/build_utils.py',
- '<(DEPTH)/build/android/gyp/lint.py',
- '<(DEPTH)/build/android/lint/suppressions.xml',
- '<(lint_jar_path)',
- ],
- 'action': [
- 'python', '<(DEPTH)/build/android/gyp/lint.py',
- '--lint-path=<(android_sdk_root)/tools/lint',
- '--config-path=<(DEPTH)/build/android/lint/suppressions.xml',
- '--processed-config-path=<(config_path)',
- '--manifest-path=<(android_manifest_path)',
- '--result-path=<(result_path)',
- '--resource-dir=<(resource_dir)',
- '--product-dir=<(PRODUCT_DIR)',
- '--src-dirs=>(src_dirs)',
- '--jar-path=<(lint_jar_path)',
- '--can-fail-build',
- '--stamp=<(stamp_path)',
- '<(is_enabled)',
- ],
-}
diff --git a/build/android/locale_pak_resources.gypi b/build/android/locale_pak_resources.gypi
deleted file mode 100644
index 6f8e56f..0000000
--- a/build/android/locale_pak_resources.gypi
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# Creates a resources.zip with locale.pak files placed into appropriate
-# resource configs (e.g. en-GB.pak -> res/raw-en/en_gb.pak). Also generates
-# a locale_paks TypedArray so that resource files can be enumerated at runtime.
-#
-# If this target is included in the deps of an android resources/library/apk,
-# the resources will be included with that target.
-#
-# Variables:
-# locale_pak_files - List of .pak files to process.
-# Names must be of the form "en.pak" or "en-US.pak".
-#
-# Example
-# {
-# 'target_name': 'my_locale_resources',
-# 'type': 'none',
-# 'variables': {
-# 'locale_paks_files': ['path1/fr.pak'],
-# },
-# 'includes': [ '../build/android/locale_pak_resources.gypi' ],
-# },
-#
-{
- 'variables': {
- 'resources_zip_path': '<(PRODUCT_DIR)/res.java/<(_target_name).zip',
- },
- 'all_dependent_settings': {
- 'variables': {
- 'additional_input_paths': ['<(resources_zip_path)'],
- 'dependencies_res_zip_paths': ['<(resources_zip_path)'],
- },
- },
- 'actions': [{
- 'action_name': '<(_target_name)_locale_pak_resources',
- 'inputs': [
- '<(DEPTH)/build/android/gyp/util/build_utils.py',
- '<(DEPTH)/build/android/gyp/locale_pak_resources.py',
- '<@(locale_pak_files)',
- ],
- 'outputs': [
- '<(resources_zip_path)',
- ],
- 'action': [
- 'python', '<(DEPTH)/build/android/gyp/locale_pak_resources.py',
- '--locale-paks', '<(locale_pak_files)',
- '--resources-zip', '<(resources_zip_path)',
- ],
- }],
-}
diff --git a/build/android/method_count.py b/build/android/method_count.py
deleted file mode 100755
index 93250b5..0000000
--- a/build/android/method_count.py
+++ /dev/null
@@ -1,55 +0,0 @@
-#! /usr/bin/env python
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import argparse
-import os
-import re
-import sys
-
-from pylib import constants
-from pylib.sdk import dexdump
-
-sys.path.append(os.path.join(constants.DIR_SOURCE_ROOT, 'build', 'util', 'lib',
- 'common'))
-import perf_tests_results_helper
-
-
-_METHOD_IDS_SIZE_RE = re.compile(r'^method_ids_size +: +(\d+)$')
-
-def MethodCount(dexfile):
- for line in dexdump.DexDump(dexfile, file_summary=True):
- m = _METHOD_IDS_SIZE_RE.match(line)
- if m:
- return m.group(1)
- raise Exception('"method_ids_size" not found in dex dump of %s' % dexfile)
-
-def main():
- parser = argparse.ArgumentParser()
- parser.add_argument(
- '--apk-name', help='Name of the APK to which the dexfile corresponds.')
- parser.add_argument('dexfile')
-
- args = parser.parse_args()
-
- if not args.apk_name:
- dirname, basename = os.path.split(args.dexfile)
- while basename:
- if 'apk' in basename:
- args.apk_name = basename
- break
- dirname, basename = os.path.split(dirname)
- else:
- parser.error(
- 'Unable to determine apk name from %s, '
- 'and --apk-name was not provided.' % args.dexfile)
-
- method_count = MethodCount(args.dexfile)
- perf_tests_results_helper.PrintPerfResult(
- '%s_methods' % args.apk_name, 'total', [method_count], 'methods')
- return 0
-
-if __name__ == '__main__':
- sys.exit(main())
-
diff --git a/build/android/native_app_dependencies.gypi b/build/android/native_app_dependencies.gypi
deleted file mode 100644
index 6032274..0000000
--- a/build/android/native_app_dependencies.gypi
+++ /dev/null
@@ -1,67 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included into a target to provide a rule
-# to strip and place dependent shared libraries required by a native binary in a
-# single folder that can later be pushed to the device.
-#
-# NOTE: consider packaging your binary as an apk instead of running a native
-# library.
-#
-# To use this, create a gyp target with the following form:
-# {
-# 'target_name': 'target_that_depends_on_my_binary',
-# 'type': 'none',
-# 'dependencies': [
-# 'my_binary',
-# ],
-# 'variables': {
-# 'native_binary': '<(PRODUCT_DIR)/my_binary',
-# 'output_dir': 'location to place binary and dependent libraries'
-# },
-# 'includes': [ '../../build/android/native_app_dependencies.gypi' ],
-# },
-#
-
-{
- 'variables': {
- 'include_main_binary%': 1,
- },
- 'conditions': [
- ['component == "shared_library"', {
- 'dependencies': [
- '<(DEPTH)/build/android/setup.gyp:copy_system_libraries',
- ],
- 'variables': {
- 'intermediate_dir': '<(PRODUCT_DIR)/<(_target_name)',
- 'ordered_libraries_file': '<(intermediate_dir)/native_libraries.json',
- },
- 'actions': [
- {
- 'variables': {
- 'input_libraries': ['<(native_binary)'],
- },
- 'includes': ['../../build/android/write_ordered_libraries.gypi'],
- },
- {
- 'action_name': 'stripping native libraries',
- 'variables': {
- 'stripped_libraries_dir%': '<(output_dir)',
- 'input_paths': ['<(native_binary)'],
- 'stamp': '<(intermediate_dir)/strip.stamp',
- },
- 'includes': ['../../build/android/strip_native_libraries.gypi'],
- },
- ],
- }],
- ['include_main_binary==1', {
- 'copies': [
- {
- 'destination': '<(output_dir)',
- 'files': [ '<(native_binary)' ],
- }
- ],
- }],
- ],
-}
diff --git a/build/android/ndk.gyp b/build/android/ndk.gyp
deleted file mode 100644
index 2838a98..0000000
--- a/build/android/ndk.gyp
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (c) 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
- 'targets': [
- {
- 'target_name': 'cpu_features',
- 'type': 'static_library',
- 'direct_dependent_settings': {
- 'include_dirs': [
- '<(android_ndk_root)/sources/android/cpufeatures',
- ],
- },
- 'sources': [
- '<(android_ndk_root)/sources/android/cpufeatures/cpu-features.c',
- ],
- },
- ],
-}
diff --git a/build/android/pack_relocations.gypi b/build/android/pack_relocations.gypi
deleted file mode 100644
index 8567fa6..0000000
--- a/build/android/pack_relocations.gypi
+++ /dev/null
@@ -1,77 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included into an action to provide a rule that
-# packs relocations in Release builds of native libraries.
-#
-# To use this, create a gyp target with the following form:
-# {
-# 'action_name': 'pack_relocations',
-# 'actions': [
-# 'variables': {
-# 'enable_packing': 'pack relocations if 1, plain file copy if 0'
-# 'exclude_packing_list': 'names of libraries explicitly not packed',
-# 'ordered_libraries_file': 'file generated by write_ordered_libraries'
-# 'input_paths': 'files to be added to the list of inputs'
-# 'stamp': 'file to touch when the action is complete'
-# 'stripped_libraries_dir': 'directory holding stripped libraries',
-# 'packed_libraries_dir': 'directory holding packed libraries',
-# 'includes': [ '../../build/android/pack_relocations.gypi' ],
-# ],
-# },
-#
-
-{
- 'variables': {
- 'input_paths': [],
- },
- 'inputs': [
- '<(DEPTH)/build/android/gyp/util/build_utils.py',
- '<(DEPTH)/build/android/gyp/pack_relocations.py',
- '<(ordered_libraries_file)',
- '>@(input_paths)',
- ],
- 'outputs': [
- '<(stamp)',
- ],
- 'conditions': [
- ['enable_packing == 1', {
- 'message': 'Packing relocations for <(_target_name)',
- 'dependencies': [
- '<(DEPTH)/third_party/android_platform/relocation_packer.gyp:android_relocation_packer#host',
- ],
- 'inputs': [
- '<(PRODUCT_DIR)/android_relocation_packer',
- ],
- 'action': [
- 'python', '<(DEPTH)/build/android/gyp/pack_relocations.py',
- '--configuration-name=<(CONFIGURATION_NAME)',
- '--enable-packing=1',
- '--exclude-packing-list=<@(exclude_packing_list)',
- '--android-pack-relocations=<(PRODUCT_DIR)/android_relocation_packer',
- '--stripped-libraries-dir=<(stripped_libraries_dir)',
- '--packed-libraries-dir=<(packed_libraries_dir)',
- '--libraries=@FileArg(<(ordered_libraries_file):libraries)',
- '--stamp=<(stamp)',
- ],
- }, {
- 'message': 'Copying libraries (no relocation packing) for <(_target_name)',
- 'action': [
- 'python', '<(DEPTH)/build/android/gyp/pack_relocations.py',
- '--configuration-name=<(CONFIGURATION_NAME)',
- '--enable-packing=0',
- '--stripped-libraries-dir=<(stripped_libraries_dir)',
- '--packed-libraries-dir=<(packed_libraries_dir)',
- '--libraries=@FileArg(<(ordered_libraries_file):libraries)',
- '--stamp=<(stamp)',
- ],
- }],
- ['component == "shared_library"', {
- # Add a fake output to force the build to always re-run this step. This
- # is required because the real inputs are not known at gyp-time and
- # changing base.so may not trigger changes to dependent libraries.
- 'outputs': [ '<(stamp).fake' ]
- }],
- ],
-}
diff --git a/build/android/package_resources_action.gypi b/build/android/package_resources_action.gypi
deleted file mode 100644
index eb60871..0000000
--- a/build/android/package_resources_action.gypi
+++ /dev/null
@@ -1,97 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is a helper to java_apk.gypi. It should be used to create an
-# action that runs ApkBuilder via ANT.
-#
-# Required variables:
-# apk_name - File name (minus path & extension) of the output apk.
-# android_manifest_path - Path to AndroidManifest.xml.
-# app_manifest_version_name - set the apps 'human readable' version number.
-# app_manifest_version_code - set the apps version number.
-# Optional variables:
-# asset_location - The directory where assets are located (if any).
-# create_density_splits - Whether to create density-based apk splits. Splits
-# are supported only for minSdkVersion >= 21.
-# language_splits - List of languages to create apk splits for.
-# resource_zips - List of paths to resource zip files.
-# shared_resources - Make a resource package that can be loaded by a different
-# application at runtime to access the package's resources.
-# extensions_to_not_compress - E.g.: 'pak,dat,bin'
-# extra_inputs - List of extra action inputs.
-{
- 'variables': {
- 'asset_location%': '',
- 'create_density_splits%': 0,
- 'resource_zips%': [],
- 'shared_resources%': 0,
- 'extensions_to_not_compress%': '',
- 'extra_inputs%': [],
- 'resource_packaged_apk_name': '<(apk_name)-resources.ap_',
- 'resource_packaged_apk_path': '<(intermediate_dir)/<(resource_packaged_apk_name)',
- },
- 'action_name': 'package_resources_<(apk_name)',
- 'message': 'packaging resources for <(apk_name)',
- 'inputs': [
- # TODO: This isn't always rerun correctly, http://crbug.com/351928
- '<(DEPTH)/build/android/gyp/util/build_utils.py',
- '<(DEPTH)/build/android/gyp/package_resources.py',
- '<(android_manifest_path)',
- '<@(extra_inputs)',
- ],
- 'outputs': [
- '<(resource_packaged_apk_path)',
- ],
- 'action': [
- 'python', '<(DEPTH)/build/android/gyp/package_resources.py',
- '--android-sdk', '<(android_sdk)',
- '--aapt-path', '<(android_aapt_path)',
- '--configuration-name', '<(CONFIGURATION_NAME)',
- '--android-manifest', '<(android_manifest_path)',
- '--version-code', '<(app_manifest_version_code)',
- '--version-name', '<(app_manifest_version_name)',
- '--no-compress', '<(extensions_to_not_compress)',
- '--apk-path', '<(resource_packaged_apk_path)',
- ],
- 'conditions': [
- ['shared_resources == 1', {
- 'action': [
- '--shared-resources',
- ],
- }],
- ['asset_location != ""', {
- 'action': [
- '--asset-dir', '<(asset_location)',
- ],
- }],
- ['create_density_splits == 1', {
- 'action': [
- '--create-density-splits',
- ],
- 'outputs': [
- '<(resource_packaged_apk_path)_hdpi',
- '<(resource_packaged_apk_path)_xhdpi',
- '<(resource_packaged_apk_path)_xxhdpi',
- '<(resource_packaged_apk_path)_xxxhdpi',
- '<(resource_packaged_apk_path)_tvdpi',
- ],
- }],
- ['language_splits != []', {
- 'action': [
- '--language-splits=<(language_splits)',
- ],
- 'outputs': [
- "<!@(python <(DEPTH)/build/apply_locales.py '<(resource_packaged_apk_path)_ZZLOCALE' <(language_splits))",
- ],
- }],
- ['resource_zips != []', {
- 'action': [
- '--resource-zips', '>(resource_zips)',
- ],
- 'inputs': [
- '>@(resource_zips)',
- ],
- }],
- ],
-}
diff --git a/build/android/preprocess_google_play_services.config.json b/build/android/preprocess_google_play_services.config.json
deleted file mode 100644
index 8b3198b..0000000
--- a/build/android/preprocess_google_play_services.config.json
+++ /dev/null
@@ -1,90 +0,0 @@
-{
- "lib_version": "7.3.0",
- "clients": [
- "play-services-base",
- "play-services-cast",
- "play-services-identity"
- ],
- "client_filter": [
- "res/drawable*",
- "res/values-af",
- "res/values-az",
- "res/values-be",
- "res/values-bn",
- "res/values-bn-rBD",
- "res/values-de-rAT",
- "res/values-de-rCH",
- "res/values-en-rIE",
- "res/values-en-rIN",
- "res/values-en-rSG",
- "res/values-en-rZA",
- "res/values-es-rAR",
- "res/values-es-rBO",
- "res/values-es-rCL",
- "res/values-es-rCO",
- "res/values-es-rCR",
- "res/values-es-rDO",
- "res/values-es-rEC",
- "res/values-es-rGT",
- "res/values-es-rHN",
- "res/values-es-rMX",
- "res/values-es-rNI",
- "res/values-es-rPA",
- "res/values-es-rPE",
- "res/values-es-rPR",
- "res/values-es-rPY",
- "res/values-es-rSV",
- "res/values-es-rUS",
- "res/values-es-rUY",
- "res/values-es-rVE",
- "res/values-eu-rES",
- "res/values-fr-rCA",
- "res/values-fr-rCH",
- "res/values-gl",
- "res/values-gl-rES",
- "res/values-gu",
- "res/values-he",
- "res/values-hy",
- "res/values-hy-rAM",
- "res/values-in",
- "res/values-is",
- "res/values-is-rIS",
- "res/values-ka",
- "res/values-ka-rGE",
- "res/values-kk-rKZ",
- "res/values-km",
- "res/values-km-rKH",
- "res/values-kn",
- "res/values-kn-rIN",
- "res/values-ky",
- "res/values-ky-rKG",
- "res/values-lo",
- "res/values-lo-rLA",
- "res/values-mk-rMK",
- "res/values-ml",
- "res/values-ml-rIN",
- "res/values-mn",
- "res/values-mn-rMN",
- "res/values-mo",
- "res/values-mr",
- "res/values-mr-rIN",
- "res/values-ms",
- "res/values-ms-rMY",
- "res/values-my-rMM",
- "res/values-nb",
- "res/values-ne",
- "res/values-ne-rNP",
- "res/values-si",
- "res/values-si-rLK",
- "res/values-ta",
- "res/values-ta-rIN",
- "res/values-te",
- "res/values-te-rIN",
- "res/values-tl",
- "res/values-ur-rPK",
- "res/values-uz-rUZ",
- "res/values-zh",
- "res/values-zh-rHK",
- "res/values-zu"
- ]
-}
diff --git a/build/android/preprocess_google_play_services.py b/build/android/preprocess_google_play_services.py
deleted file mode 100755
index 85d239a..0000000
--- a/build/android/preprocess_google_play_services.py
+++ /dev/null
@@ -1,238 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-'''Prepares the Google Play services split client libraries before usage by
-Chrome's build system.
-
-We need to preprocess Google Play services before using it in Chrome
-builds for 2 main reasons:
-
-- Getting rid of unused resources: unsupported languages, unused
-drawables, etc.
-
-- Merging the differents jars so that it can be proguarded more
-easily. This is necessary since debug and test apks get very close
-to the dex limit.
-
-The script is supposed to be used with the maven repository that can be obtained
-by downloading the "extra-google-m2repository" from the Android SDK Manager. It
-also supports importing from already extracted AAR files using the
---is-extracted-repo flag.
-
-The json config (see the -c argument) file should provide the following fields:
-
-- lib_version: String. Used when building from the maven repository. It should
- be the package's version (e.g. "7.3.0")
-
-- clients: String array. List of clients to pick. For example, when building
- from the maven repository, it's the artifactId (e.g. "play-services-base") of
- each client.
-
-- client_filter: String array. Pattern of files to prune from the clients once
- extracted. Metacharacters are allowed. (e.g. "res/drawable*")
-
-The output is a directory with the following structure:
-
- OUT_DIR
- +-- google-play-services.jar
- +-- res
- | +-- CLIENT_1
- | | +-- color
- | | +-- values
- | | +-- etc.
- | +-- CLIENT_2
- | +-- ...
- +-- stub
- +-- res/[.git-keep-directory]
- +-- src/android/UnusedStub.java
-
-Requires the `jar` utility in the path.
-
-'''
-
-import argparse
-import glob
-import itertools
-import json
-import os
-import shutil
-import stat
-import sys
-
-from pylib import cmd_helper
-from pylib import constants
-
-sys.path.append(
- os.path.join(constants.DIR_SOURCE_ROOT, 'build', 'android', 'gyp'))
-from util import build_utils
-
-
-M2_PKG_PATH = os.path.join('com', 'google', 'android', 'gms')
-
-
-def main():
- parser = argparse.ArgumentParser(description=("Prepares the Google Play "
- "services split client libraries before usage by Chrome's build system"))
- parser.add_argument('-r',
- '--repository',
- help='The Google Play services repository location',
- required=True,
- metavar='FILE')
- parser.add_argument('-o',
- '--out-dir',
- help='The output directory',
- required=True,
- metavar='FILE')
- parser.add_argument('-c',
- '--config-file',
- help='Config file path',
- required=True,
- metavar='FILE')
- parser.add_argument('-g',
- '--git-friendly',
- action='store_true',
- default=False,
- help='Add a .gitkeep file to the empty directories')
- parser.add_argument('-x',
- '--is-extracted-repo',
- action='store_true',
- default=False,
- help='The provided repository is not made of AAR files.')
-
- args = parser.parse_args()
-
- ProcessGooglePlayServices(args.repository,
- args.out_dir,
- args.config_file,
- args.git_friendly,
- args.is_extracted_repo)
-
-
-def ProcessGooglePlayServices(repo, out_dir, config_path, git_friendly,
- is_extracted_repo):
- with open(config_path, 'r') as json_file:
- config = json.load(json_file)
-
- with build_utils.TempDir() as tmp_root:
- tmp_paths = _SetupTempDir(tmp_root)
-
- if is_extracted_repo:
- _ImportFromExtractedRepo(config, tmp_paths, repo)
- else:
- _ImportFromAars(config, tmp_paths, repo)
-
- _GenerateCombinedJar(tmp_paths)
- _ProcessResources(config, tmp_paths)
- _BuildOutput(config, tmp_paths, out_dir, git_friendly)
-
-
-def _SetupTempDir(tmp_root):
- tmp_paths = {
- 'root': tmp_root,
- 'imported_clients': os.path.join(tmp_root, 'imported_clients'),
- 'extracted_jars': os.path.join(tmp_root, 'jar'),
- 'combined_jar': os.path.join(tmp_root, 'google-play-services.jar'),
- }
- os.mkdir(tmp_paths['imported_clients'])
- os.mkdir(tmp_paths['extracted_jars'])
-
- return tmp_paths
-
-
-def _SetupOutputDir(out_dir):
- out_paths = {
- 'root': out_dir,
- 'res': os.path.join(out_dir, 'res'),
- 'jar': os.path.join(out_dir, 'google-play-services.jar'),
- 'stub': os.path.join(out_dir, 'stub'),
- }
-
- shutil.rmtree(out_paths['jar'], ignore_errors=True)
- shutil.rmtree(out_paths['res'], ignore_errors=True)
- shutil.rmtree(out_paths['stub'], ignore_errors=True)
-
- return out_paths
-
-
-def _MakeWritable(dir_path):
- for root, dirs, files in os.walk(dir_path):
- for path in itertools.chain(dirs, files):
- st = os.stat(os.path.join(root, path))
- os.chmod(os.path.join(root, path), st.st_mode | stat.S_IWUSR)
-
-
-def _ImportFromAars(config, tmp_paths, repo):
- for client in config['clients']:
- aar_name = '%s-%s.aar' % (client, config['lib_version'])
- aar_path = os.path.join(repo, M2_PKG_PATH, client,
- config['lib_version'], aar_name)
- aar_out_path = os.path.join(tmp_paths['imported_clients'], client)
- build_utils.ExtractAll(aar_path, aar_out_path)
-
- client_jar_path = os.path.join(aar_out_path, 'classes.jar')
- build_utils.ExtractAll(client_jar_path, tmp_paths['extracted_jars'],
- no_clobber=False)
-
-
-def _ImportFromExtractedRepo(config, tmp_paths, repo):
- # Import the clients
- try:
- for client in config['clients']:
- client_out_dir = os.path.join(tmp_paths['imported_clients'], client)
- shutil.copytree(os.path.join(repo, client), client_out_dir)
-
- client_jar_path = os.path.join(client_out_dir, 'classes.jar')
- build_utils.ExtractAll(client_jar_path, tmp_paths['extracted_jars'],
- no_clobber=False)
- finally:
- _MakeWritable(tmp_paths['imported_clients'])
-
-
-def _GenerateCombinedJar(tmp_paths):
- out_file_name = tmp_paths['combined_jar']
- working_dir = tmp_paths['extracted_jars']
- cmd_helper.Call(['jar', '-cf', out_file_name, '-C', working_dir, '.'])
-
-
-def _ProcessResources(config, tmp_paths):
- # Prune unused resources
- for res_filter in config['client_filter']:
- glob_pattern = os.path.join(tmp_paths['imported_clients'], '*', res_filter)
- for prune_target in glob.glob(glob_pattern):
- shutil.rmtree(prune_target)
-
-
-def _BuildOutput(config, tmp_paths, out_dir, git_friendly):
- out_paths = _SetupOutputDir(out_dir)
-
- # Copy the resources to the output dir
- for client in config['clients']:
- res_in_tmp_dir = os.path.join(tmp_paths['imported_clients'], client, 'res')
- if os.path.isdir(res_in_tmp_dir) and os.listdir(res_in_tmp_dir):
- res_in_final_dir = os.path.join(out_paths['res'], client)
- shutil.copytree(res_in_tmp_dir, res_in_final_dir)
-
- # Copy the jar
- shutil.copyfile(tmp_paths['combined_jar'], out_paths['jar'])
-
- # Write the java dummy stub. Needed for gyp to create the resource jar
- stub_location = os.path.join(out_paths['stub'], 'src', 'android')
- os.makedirs(stub_location)
- with open(os.path.join(stub_location, 'UnusedStub.java'), 'w') as stub:
- stub.write('package android;'
- 'public final class UnusedStub {'
- ' private UnusedStub() {}'
- '}')
-
- # Create the main res directory. Will be empty but is needed by gyp
- stub_res_location = os.path.join(out_paths['stub'], 'res')
- os.makedirs(stub_res_location)
- if git_friendly:
- build_utils.Touch(os.path.join(stub_res_location, '.git-keep-directory'))
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/build/android/provision_devices.py b/build/android/provision_devices.py
deleted file mode 100755
index a5f8fc6..0000000
--- a/build/android/provision_devices.py
+++ /dev/null
@@ -1,349 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (c) 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Provisions Android devices with settings required for bots.
-
-Usage:
- ./provision_devices.py [-d <device serial number>]
-"""
-
-import argparse
-import json
-import logging
-import os
-import posixpath
-import re
-import subprocess
-import sys
-import time
-
-from pylib import constants
-from pylib import device_settings
-from pylib.device import battery_utils
-from pylib.device import device_blacklist
-from pylib.device import device_errors
-from pylib.device import device_utils
-from pylib.utils import run_tests_helper
-from pylib.utils import timeout_retry
-
-sys.path.append(os.path.join(constants.DIR_SOURCE_ROOT,
- 'third_party', 'android_testrunner'))
-import errors
-
-
-class _DEFAULT_TIMEOUTS(object):
- # L can take a while to reboot after a wipe.
- LOLLIPOP = 600
- PRE_LOLLIPOP = 180
-
- HELP_TEXT = '{}s on L, {}s on pre-L'.format(LOLLIPOP, PRE_LOLLIPOP)
-
-
-class _PHASES(object):
- WIPE = 'wipe'
- PROPERTIES = 'properties'
- FINISH = 'finish'
-
- ALL = [WIPE, PROPERTIES, FINISH]
-
-
-def ProvisionDevices(options):
- devices = device_utils.DeviceUtils.HealthyDevices()
- if options.device:
- devices = [d for d in devices if d == options.device]
- if not devices:
- raise device_errors.DeviceUnreachableError(options.device)
-
- parallel_devices = device_utils.DeviceUtils.parallel(devices)
- parallel_devices.pMap(ProvisionDevice, options)
- if options.auto_reconnect:
- _LaunchHostHeartbeat()
- blacklist = device_blacklist.ReadBlacklist()
- if options.output_device_blacklist:
- with open(options.output_device_blacklist, 'w') as f:
- json.dump(blacklist, f)
- if all(d in blacklist for d in devices):
- raise device_errors.NoDevicesError
- return 0
-
-
-def ProvisionDevice(device, options):
- if options.reboot_timeout:
- reboot_timeout = options.reboot_timeout
- elif (device.build_version_sdk >=
- constants.ANDROID_SDK_VERSION_CODES.LOLLIPOP):
- reboot_timeout = _DEFAULT_TIMEOUTS.LOLLIPOP
- else:
- reboot_timeout = _DEFAULT_TIMEOUTS.PRE_LOLLIPOP
-
- def should_run_phase(phase_name):
- return not options.phases or phase_name in options.phases
-
- def run_phase(phase_func, reboot=True):
- try:
- device.WaitUntilFullyBooted(timeout=reboot_timeout, retries=0)
- except device_errors.CommandTimeoutError:
- logging.error('Device did not finish booting. Will try to reboot.')
- device.Reboot(timeout=reboot_timeout)
- phase_func(device, options)
- if reboot:
- device.Reboot(False, retries=0)
- device.adb.WaitForDevice()
-
- try:
- if should_run_phase(_PHASES.WIPE):
- run_phase(WipeDevice)
-
- if should_run_phase(_PHASES.PROPERTIES):
- run_phase(SetProperties)
-
- if should_run_phase(_PHASES.FINISH):
- run_phase(FinishProvisioning, reboot=False)
-
- except (errors.WaitForResponseTimedOutError,
- device_errors.CommandTimeoutError):
- logging.exception('Timed out waiting for device %s. Adding to blacklist.',
- str(device))
- device_blacklist.ExtendBlacklist([str(device)])
-
- except device_errors.CommandFailedError:
- logging.exception('Failed to provision device %s. Adding to blacklist.',
- str(device))
- device_blacklist.ExtendBlacklist([str(device)])
-
-
-def WipeDevice(device, options):
- """Wipes data from device, keeping only the adb_keys for authorization.
-
- After wiping data on a device that has been authorized, adb can still
- communicate with the device, but after reboot the device will need to be
- re-authorized because the adb keys file is stored in /data/misc/adb/.
- Thus, adb_keys file is rewritten so the device does not need to be
- re-authorized.
-
- Arguments:
- device: the device to wipe
- """
- if options.skip_wipe:
- return
-
- try:
- device.EnableRoot()
- device_authorized = device.FileExists(constants.ADB_KEYS_FILE)
- if device_authorized:
- adb_keys = device.ReadFile(constants.ADB_KEYS_FILE,
- as_root=True).splitlines()
- device.RunShellCommand(['wipe', 'data'],
- as_root=True, check_return=True)
- device.adb.WaitForDevice()
-
- if device_authorized:
- adb_keys_set = set(adb_keys)
- for adb_key_file in options.adb_key_files or []:
- try:
- with open(adb_key_file, 'r') as f:
- adb_public_keys = f.readlines()
- adb_keys_set.update(adb_public_keys)
- except IOError:
- logging.warning('Unable to find adb keys file %s.' % adb_key_file)
- _WriteAdbKeysFile(device, '\n'.join(adb_keys_set))
- except device_errors.CommandFailedError:
- logging.exception('Possible failure while wiping the device. '
- 'Attempting to continue.')
-
-
-def _WriteAdbKeysFile(device, adb_keys_string):
- dir_path = posixpath.dirname(constants.ADB_KEYS_FILE)
- device.RunShellCommand(['mkdir', '-p', dir_path],
- as_root=True, check_return=True)
- device.RunShellCommand(['restorecon', dir_path],
- as_root=True, check_return=True)
- device.WriteFile(constants.ADB_KEYS_FILE, adb_keys_string, as_root=True)
- device.RunShellCommand(['restorecon', constants.ADB_KEYS_FILE],
- as_root=True, check_return=True)
-
-
-def SetProperties(device, options):
- try:
- device.EnableRoot()
- except device_errors.CommandFailedError as e:
- logging.warning(str(e))
-
- _ConfigureLocalProperties(device, options.enable_java_debug)
- device_settings.ConfigureContentSettings(
- device, device_settings.DETERMINISTIC_DEVICE_SETTINGS)
- if options.disable_location:
- device_settings.ConfigureContentSettings(
- device, device_settings.DISABLE_LOCATION_SETTINGS)
- else:
- device_settings.ConfigureContentSettings(
- device, device_settings.ENABLE_LOCATION_SETTINGS)
-
- if options.disable_mock_location:
- device_settings.ConfigureContentSettings(
- device, device_settings.DISABLE_MOCK_LOCATION_SETTINGS)
- else:
- device_settings.ConfigureContentSettings(
- device, device_settings.ENABLE_MOCK_LOCATION_SETTINGS)
-
- device_settings.SetLockScreenSettings(device)
- if options.disable_network:
- device_settings.ConfigureContentSettings(
- device, device_settings.NETWORK_DISABLED_SETTINGS)
-
-def _ConfigureLocalProperties(device, java_debug=True):
- """Set standard readonly testing device properties prior to reboot."""
- local_props = [
- 'persist.sys.usb.config=adb',
- 'ro.monkey=1',
- 'ro.test_harness=1',
- 'ro.audio.silent=1',
- 'ro.setupwizard.mode=DISABLED',
- ]
- if java_debug:
- local_props.append(
- '%s=all' % device_utils.DeviceUtils.JAVA_ASSERT_PROPERTY)
- local_props.append('debug.checkjni=1')
- try:
- device.WriteFile(
- constants.DEVICE_LOCAL_PROPERTIES_PATH,
- '\n'.join(local_props), as_root=True)
- # Android will not respect the local props file if it is world writable.
- device.RunShellCommand(
- ['chmod', '644', constants.DEVICE_LOCAL_PROPERTIES_PATH],
- as_root=True, check_return=True)
- except device_errors.CommandFailedError:
- logging.exception('Failed to configure local properties.')
-
-
-def FinishProvisioning(device, options):
- if options.min_battery_level is not None:
- try:
- battery = battery_utils.BatteryUtils(device)
- battery.ChargeDeviceToLevel(options.min_battery_level)
- except device_errors.CommandFailedError:
- logging.exception('Unable to charge device to specified level.')
-
- if options.max_battery_temp is not None:
- try:
- battery = battery_utils.BatteryUtils(device)
- battery.LetBatteryCoolToTemperature(options.max_battery_temp)
- except device_errors.CommandFailedError:
- logging.exception('Unable to let battery cool to specified temperature.')
-
- device.RunShellCommand(
- ['date', '-s', time.strftime('%Y%m%d.%H%M%S', time.gmtime())],
- as_root=True, check_return=True)
- props = device.RunShellCommand('getprop', check_return=True)
- for prop in props:
- logging.info(' %s' % prop)
- if options.auto_reconnect:
- _PushAndLaunchAdbReboot(device, options.target)
-
-
-def _PushAndLaunchAdbReboot(device, target):
- """Pushes and launches the adb_reboot binary on the device.
-
- Arguments:
- device: The DeviceUtils instance for the device to which the adb_reboot
- binary should be pushed.
- target: The build target (example, Debug or Release) which helps in
- locating the adb_reboot binary.
- """
- logging.info('Will push and launch adb_reboot on %s' % str(device))
- # Kill if adb_reboot is already running.
- device.KillAll('adb_reboot', blocking=True, timeout=2, quiet=True)
- # Push adb_reboot
- logging.info(' Pushing adb_reboot ...')
- adb_reboot = os.path.join(constants.DIR_SOURCE_ROOT,
- 'out/%s/adb_reboot' % target)
- device.PushChangedFiles([(adb_reboot, '/data/local/tmp/')])
- # Launch adb_reboot
- logging.info(' Launching adb_reboot ...')
- device.RunShellCommand(
- ['/data/local/tmp/adb_reboot'],
- check_return=True)
-
-
-def _LaunchHostHeartbeat():
- # Kill if existing host_heartbeat
- KillHostHeartbeat()
- # Launch a new host_heartbeat
- logging.info('Spawning host heartbeat...')
- subprocess.Popen([os.path.join(constants.DIR_SOURCE_ROOT,
- 'build/android/host_heartbeat.py')])
-
-
-def KillHostHeartbeat():
- ps = subprocess.Popen(['ps', 'aux'], stdout=subprocess.PIPE)
- stdout, _ = ps.communicate()
- matches = re.findall('\\n.*host_heartbeat.*', stdout)
- for match in matches:
- logging.info('An instance of host heart beart running... will kill')
- pid = re.findall(r'(\S+)', match)[1]
- subprocess.call(['kill', str(pid)])
-
-
-def main():
- # Recommended options on perf bots:
- # --disable-network
- # TODO(tonyg): We eventually want network on. However, currently radios
- # can cause perfbots to drain faster than they charge.
- # --min-battery-level 95
- # Some perf bots run benchmarks with USB charging disabled which leads
- # to gradual draining of the battery. We must wait for a full charge
- # before starting a run in order to keep the devices online.
-
- parser = argparse.ArgumentParser(
- description='Provision Android devices with settings required for bots.')
- parser.add_argument('-d', '--device', metavar='SERIAL',
- help='the serial number of the device to be provisioned'
- ' (the default is to provision all devices attached)')
- parser.add_argument('--phase', action='append', choices=_PHASES.ALL,
- dest='phases',
- help='Phases of provisioning to run. '
- '(If omitted, all phases will be run.)')
- parser.add_argument('--skip-wipe', action='store_true', default=False,
- help="don't wipe device data during provisioning")
- parser.add_argument('--reboot-timeout', metavar='SECS', type=int,
- help='when wiping the device, max number of seconds to'
- ' wait after each reboot '
- '(default: %s)' % _DEFAULT_TIMEOUTS.HELP_TEXT)
- parser.add_argument('--min-battery-level', type=int, metavar='NUM',
- help='wait for the device to reach this minimum battery'
- ' level before trying to continue')
- parser.add_argument('--disable-location', action='store_true',
- help='disable Google location services on devices')
- parser.add_argument('--disable-mock-location', action='store_true',
- default=False, help='Set ALLOW_MOCK_LOCATION to false')
- parser.add_argument('--disable-network', action='store_true',
- help='disable network access on devices')
- parser.add_argument('--disable-java-debug', action='store_false',
- dest='enable_java_debug', default=True,
- help='disable Java property asserts and JNI checking')
- parser.add_argument('-t', '--target', default='Debug',
- help='the build target (default: %(default)s)')
- parser.add_argument('-r', '--auto-reconnect', action='store_true',
- help='push binary which will reboot the device on adb'
- ' disconnections')
- parser.add_argument('--adb-key-files', type=str, nargs='+',
- help='list of adb keys to push to device')
- parser.add_argument('-v', '--verbose', action='count', default=1,
- help='Log more information.')
- parser.add_argument('--max-battery-temp', type=int, metavar='NUM',
- help='Wait for the battery to have this temp or lower.')
- parser.add_argument('--output-device-blacklist',
- help='Json file to output the device blacklist.')
- args = parser.parse_args()
- constants.SetBuildType(args.target)
-
- run_tests_helper.SetLogLevel(args.verbose)
-
- return ProvisionDevices(args)
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/build/android/push_libraries.gypi b/build/android/push_libraries.gypi
deleted file mode 100644
index 773c44f..0000000
--- a/build/android/push_libraries.gypi
+++ /dev/null
@@ -1,49 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included into an action to provide a rule that
-# pushes stripped shared libraries to the attached Android device. This should
-# only be used with the gyp_managed_install flag set.
-#
-# To use this, create a gyp target with the following form:
-# {
-# 'actions': [
-# 'variables': {
-# 'ordered_libraries_file': 'file generated by write_ordered_libraries'
-# 'strip_stamp': 'stamp from strip action to block on'
-# 'libraries_source_dir': 'location where stripped libraries are stored'
-# 'device_library_dir': 'location on the device where to put pushed libraries',
-# 'push_stamp': 'file to touch when the action is complete'
-# 'configuration_name': 'The build CONFIGURATION_NAME'
-# },
-# 'includes': [ '../../build/android/push_libraries.gypi' ],
-# ],
-# },
-#
-
-{
- 'action_name': 'push_libraries_<(_target_name)',
- 'message': 'Pushing libraries to device for <(_target_name)',
- 'inputs': [
- '<(DEPTH)/build/android/gyp/util/build_utils.py',
- '<(DEPTH)/build/android/gyp/util/md5_check.py',
- '<(DEPTH)/build/android/gyp/push_libraries.py',
- '<(strip_stamp)',
- '<(strip_additional_stamp)',
- '<(build_device_config_path)',
- '<(pack_relocations_stamp)',
- ],
- 'outputs': [
- '<(push_stamp)',
- ],
- 'action': [
- 'python', '<(DEPTH)/build/android/gyp/push_libraries.py',
- '--build-device-configuration=<(build_device_config_path)',
- '--libraries-dir=<(libraries_source_dir)',
- '--device-dir=<(device_library_dir)',
- '--libraries=@FileArg(<(ordered_libraries_file):libraries)',
- '--stamp=<(push_stamp)',
- '--configuration-name=<(configuration_name)',
- ],
-}
diff --git a/build/android/pylib/OWNERS b/build/android/pylib/OWNERS
deleted file mode 100644
index dbbbba7..0000000
--- a/build/android/pylib/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-jbudorick@chromium.org
-klundberg@chromium.org
-navabi@chromium.org
-skyostil@chromium.org
diff --git a/build/android/pylib/__init__.py b/build/android/pylib/__init__.py
deleted file mode 100644
index 96196cf..0000000
--- a/build/android/pylib/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
diff --git a/build/android/pylib/android_commands.py b/build/android/pylib/android_commands.py
deleted file mode 100644
index f7191f7..0000000
--- a/build/android/pylib/android_commands.py
+++ /dev/null
@@ -1,1976 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Provides an interface to communicate with the device via the adb command.
-
-Assumes adb binary is currently on system path.
-
-Note that this module is deprecated.
-"""
-# TODO(jbudorick): Delete this file once no clients use it.
-
-# pylint: skip-file
-
-import collections
-import datetime
-import inspect
-import logging
-import os
-import random
-import re
-import shlex
-import signal
-import subprocess
-import sys
-import tempfile
-import time
-
-import cmd_helper
-import constants
-import system_properties
-from utils import host_utils
-
-try:
- from pylib import pexpect
-except ImportError:
- pexpect = None
-
-sys.path.append(os.path.join(
- constants.DIR_SOURCE_ROOT, 'third_party', 'android_testrunner'))
-import adb_interface
-import am_instrument_parser
-import errors
-
-from pylib.device import device_blacklist
-from pylib.device import device_errors
-
-# Pattern to search for the next whole line of pexpect output and capture it
-# into a match group. We can't use ^ and $ for line start end with pexpect,
-# see http://www.noah.org/python/pexpect/#doc for explanation why.
-PEXPECT_LINE_RE = re.compile('\n([^\r]*)\r')
-
-# Set the adb shell prompt to be a unique marker that will [hopefully] not
-# appear at the start of any line of a command's output.
-SHELL_PROMPT = '~+~PQ\x17RS~+~'
-
-# Java properties file
-LOCAL_PROPERTIES_PATH = constants.DEVICE_LOCAL_PROPERTIES_PATH
-
-# Property in /data/local.prop that controls Java assertions.
-JAVA_ASSERT_PROPERTY = 'dalvik.vm.enableassertions'
-
-# Keycode "enum" suitable for passing to AndroidCommands.SendKey().
-KEYCODE_HOME = 3
-KEYCODE_BACK = 4
-KEYCODE_DPAD_UP = 19
-KEYCODE_DPAD_DOWN = 20
-KEYCODE_DPAD_RIGHT = 22
-KEYCODE_ENTER = 66
-KEYCODE_MENU = 82
-
-MD5SUM_DEVICE_FOLDER = constants.TEST_EXECUTABLE_DIR + '/md5sum/'
-MD5SUM_DEVICE_PATH = MD5SUM_DEVICE_FOLDER + 'md5sum_bin'
-
-PIE_WRAPPER_PATH = constants.TEST_EXECUTABLE_DIR + '/run_pie'
-
-CONTROL_USB_CHARGING_COMMANDS = [
- {
- # Nexus 4
- 'witness_file': '/sys/module/pm8921_charger/parameters/disabled',
- 'enable_command': 'echo 0 > /sys/module/pm8921_charger/parameters/disabled',
- 'disable_command':
- 'echo 1 > /sys/module/pm8921_charger/parameters/disabled',
- },
- {
- # Nexus 5
- # Setting the HIZ bit of the bq24192 causes the charger to actually ignore
- # energy coming from USB. Setting the power_supply offline just updates the
- # Android system to reflect that.
- 'witness_file': '/sys/kernel/debug/bq24192/INPUT_SRC_CONT',
- 'enable_command': (
- 'echo 0x4A > /sys/kernel/debug/bq24192/INPUT_SRC_CONT && '
- 'echo 1 > /sys/class/power_supply/usb/online'),
- 'disable_command': (
- 'echo 0xCA > /sys/kernel/debug/bq24192/INPUT_SRC_CONT && '
- 'chmod 644 /sys/class/power_supply/usb/online && '
- 'echo 0 > /sys/class/power_supply/usb/online'),
- },
-]
-
-class DeviceTempFile(object):
- def __init__(self, android_commands, prefix='temp_file', suffix=''):
- """Find an unused temporary file path in the devices external directory.
-
- When this object is closed, the file will be deleted on the device.
- """
- self.android_commands = android_commands
- while True:
- # TODO(cjhopman): This could actually return the same file in multiple
- # calls if the caller doesn't write to the files immediately. This is
- # expected to never happen.
- i = random.randint(0, 1000000)
- self.name = '%s/%s-%d-%010d%s' % (
- android_commands.GetExternalStorage(),
- prefix, int(time.time()), i, suffix)
- if not android_commands.FileExistsOnDevice(self.name):
- break
-
- def __enter__(self):
- return self
-
- def __exit__(self, type, value, traceback):
- self.close()
-
- def close(self):
- self.android_commands.RunShellCommand('rm ' + self.name)
-
-
-def GetAVDs():
- """Returns a list of AVDs."""
- re_avd = re.compile('^[ ]+Name: ([a-zA-Z0-9_:.-]+)', re.MULTILINE)
- avds = re_avd.findall(cmd_helper.GetCmdOutput(['android', 'list', 'avd']))
- return avds
-
-def ResetBadDevices():
- """Removes the blacklist that keeps track of bad devices for a current
- build.
- """
- device_blacklist.ResetBlacklist()
-
-def ExtendBadDevices(devices):
- """Adds devices to the blacklist that keeps track of bad devices for a
- current build.
-
- The devices listed in the bad devices file will not be returned by
- GetAttachedDevices.
-
- Args:
- devices: list of bad devices to be added to the bad devices file.
- """
- device_blacklist.ExtendBlacklist(devices)
-
-
-def GetAttachedDevices(hardware=True, emulator=True, offline=False):
- """Returns a list of attached, android devices and emulators.
-
- If a preferred device has been set with ANDROID_SERIAL, it will be first in
- the returned list. The arguments specify what devices to include in the list.
-
- Example output:
-
- * daemon not running. starting it now on port 5037 *
- * daemon started successfully *
- List of devices attached
- 027c10494100b4d7 device
- emulator-5554 offline
-
- Args:
- hardware: Include attached actual devices that are online.
- emulator: Include emulators (i.e. AVD's) currently on host.
- offline: Include devices and emulators that are offline.
-
- Returns: List of devices.
- """
- adb_devices_output = cmd_helper.GetCmdOutput([constants.GetAdbPath(),
- 'devices'])
-
- re_device = re.compile('^([a-zA-Z0-9_:.-]+)\tdevice$', re.MULTILINE)
- online_devices = re_device.findall(adb_devices_output)
-
- re_device = re.compile('^(emulator-[0-9]+)\tdevice', re.MULTILINE)
- emulator_devices = re_device.findall(adb_devices_output)
-
- re_device = re.compile('^([a-zA-Z0-9_:.-]+)\t(?:offline|unauthorized)$',
- re.MULTILINE)
- offline_devices = re_device.findall(adb_devices_output)
-
- devices = []
- # First determine list of online devices (e.g. hardware and/or emulator).
- if hardware and emulator:
- devices = online_devices
- elif hardware:
- devices = [device for device in online_devices
- if device not in emulator_devices]
- elif emulator:
- devices = emulator_devices
-
- # Now add offline devices if offline is true
- if offline:
- devices = devices + offline_devices
-
- # Remove any devices in the blacklist.
- blacklist = device_blacklist.ReadBlacklist()
- if len(blacklist):
- logging.info('Avoiding bad devices %s', ' '.join(blacklist))
- devices = [device for device in devices if device not in blacklist]
-
- preferred_device = os.environ.get('ANDROID_SERIAL')
- if preferred_device in devices:
- devices.remove(preferred_device)
- devices.insert(0, preferred_device)
- return devices
-
-
-def IsDeviceAttached(device):
- """Return true if the device is attached and online."""
- return device in GetAttachedDevices()
-
-
-def _GetFilesFromRecursiveLsOutput(path, ls_output, re_file, utc_offset=None):
- """Gets a list of files from `ls` command output.
-
- Python's os.walk isn't used because it doesn't work over adb shell.
-
- Args:
- path: The path to list.
- ls_output: A list of lines returned by an `ls -lR` command.
- re_file: A compiled regular expression which parses a line into named groups
- consisting of at minimum "filename", "date", "time", "size" and
- optionally "timezone".
- utc_offset: A 5-character string of the form +HHMM or -HHMM, where HH is a
- 2-digit string giving the number of UTC offset hours, and MM is a
- 2-digit string giving the number of UTC offset minutes. If the input
- utc_offset is None, will try to look for the value of "timezone" if it
- is specified in re_file.
-
- Returns:
- A dict of {"name": (size, lastmod), ...} where:
- name: The file name relative to |path|'s directory.
- size: The file size in bytes (0 for directories).
- lastmod: The file last modification date in UTC.
- """
- re_directory = re.compile('^%s/(?P<dir>[^:]+):$' % re.escape(path))
- path_dir = os.path.dirname(path)
-
- current_dir = ''
- files = {}
- for line in ls_output:
- directory_match = re_directory.match(line)
- if directory_match:
- current_dir = directory_match.group('dir')
- continue
- file_match = re_file.match(line)
- if file_match:
- filename = os.path.join(current_dir, file_match.group('filename'))
- if filename.startswith(path_dir):
- filename = filename[len(path_dir) + 1:]
- lastmod = datetime.datetime.strptime(
- file_match.group('date') + ' ' + file_match.group('time')[:5],
- '%Y-%m-%d %H:%M')
- if not utc_offset and 'timezone' in re_file.groupindex:
- utc_offset = file_match.group('timezone')
- if isinstance(utc_offset, str) and len(utc_offset) == 5:
- utc_delta = datetime.timedelta(hours=int(utc_offset[1:3]),
- minutes=int(utc_offset[3:5]))
- if utc_offset[0:1] == '-':
- utc_delta = -utc_delta
- lastmod -= utc_delta
- files[filename] = (int(file_match.group('size')), lastmod)
- return files
-
-
-def _ParseMd5SumOutput(md5sum_output):
- """Returns a list of tuples from the provided md5sum output.
-
- Args:
- md5sum_output: output directly from md5sum binary.
-
- Returns:
- List of namedtuples with attributes |hash| and |path|, where |path| is the
- absolute path to the file with an Md5Sum of |hash|.
- """
- HashAndPath = collections.namedtuple('HashAndPath', ['hash', 'path'])
- split_lines = [line.split(' ') for line in md5sum_output]
- return [HashAndPath._make(s) for s in split_lines if len(s) == 2]
-
-
-def _HasAdbPushSucceeded(command_output):
- """Returns whether adb push has succeeded from the provided output."""
- # TODO(frankf): We should look at the return code instead of the command
- # output for many of the commands in this file.
- if not command_output:
- return True
- # Success looks like this: "3035 KB/s (12512056 bytes in 4.025s)"
- # Errors look like this: "failed to copy ... "
- if not re.search('^[0-9]', command_output.splitlines()[-1]):
- logging.critical('PUSH FAILED: ' + command_output)
- return False
- return True
-
-
-def GetLogTimestamp(log_line, year):
- """Returns the timestamp of the given |log_line| in the given year."""
- try:
- return datetime.datetime.strptime('%s-%s' % (year, log_line[:18]),
- '%Y-%m-%d %H:%M:%S.%f')
- except (ValueError, IndexError):
- logging.critical('Error reading timestamp from ' + log_line)
- return None
-
-
-class AndroidCommands(object):
- """Helper class for communicating with Android device via adb."""
-
- def __init__(self, device=None):
- """Constructor.
-
- Args:
- device: If given, adb commands are only send to the device of this ID.
- Otherwise commands are sent to all attached devices.
- """
- self._adb = adb_interface.AdbInterface(constants.GetAdbPath())
- if device:
- self._adb.SetTargetSerial(device)
- self._device = device
- self._logcat = None
- self.logcat_process = None
- self._logcat_tmpoutfile = None
- self._pushed_files = []
- self._device_utc_offset = None
- self._potential_push_size = 0
- self._actual_push_size = 0
- self._external_storage = ''
- self._util_wrapper = ''
- self._system_properties = system_properties.SystemProperties(self.Adb())
- self._push_if_needed_cache = {}
- self._control_usb_charging_command = {
- 'command': None,
- 'cached': False,
- }
- self._protected_file_access_method_initialized = None
- self._privileged_command_runner = None
- self._pie_wrapper = None
-
- @property
- def system_properties(self):
- return self._system_properties
-
- def _LogShell(self, cmd):
- """Logs the adb shell command."""
- if self._device:
- device_repr = self._device[-4:]
- else:
- device_repr = '????'
- logging.info('[%s]> %s', device_repr, cmd)
-
- def Adb(self):
- """Returns our AdbInterface to avoid us wrapping all its methods."""
- # TODO(tonyg): Goal should be to git rid of this method by making this API
- # complete and alleviating the need.
- return self._adb
-
- def GetDevice(self):
- """Returns the device serial."""
- return self._device
-
- def IsOnline(self):
- """Checks whether the device is online.
-
- Returns:
- True if device is in 'device' mode, False otherwise.
- """
- # TODO(aurimas): revert to using adb get-state when android L adb is fixed.
- #out = self._adb.SendCommand('get-state')
- #return out.strip() == 'device'
-
- out = self._adb.SendCommand('devices')
- for line in out.split('\n'):
- if self._device in line and 'device' in line:
- return True
- return False
-
- def IsRootEnabled(self):
- """Checks if root is enabled on the device."""
- root_test_output = self.RunShellCommand('ls /root') or ['']
- return not 'Permission denied' in root_test_output[0]
-
- def EnableAdbRoot(self):
- """Enables adb root on the device.
-
- Returns:
- True: if output from executing adb root was as expected.
- False: otherwise.
- """
- if self.GetBuildType() == 'user':
- logging.warning("Can't enable root in production builds with type user")
- return False
- else:
- return_value = self._adb.EnableAdbRoot()
- # EnableAdbRoot inserts a call for wait-for-device only when adb logcat
- # output matches what is expected. Just to be safe add a call to
- # wait-for-device.
- self._adb.SendCommand('wait-for-device')
- return return_value
-
- def GetDeviceYear(self):
- """Returns the year information of the date on device."""
- return self.RunShellCommand('date +%Y')[0]
-
- def GetExternalStorage(self):
- if not self._external_storage:
- self._external_storage = self.RunShellCommand('echo $EXTERNAL_STORAGE')[0]
- if not self._external_storage:
- raise device_errors.CommandFailedError(
- ['shell', "'echo $EXTERNAL_STORAGE'"],
- 'Unable to find $EXTERNAL_STORAGE')
- return self._external_storage
-
- def WaitForDevicePm(self, timeout=120):
- """Blocks until the device's package manager is available.
-
- To workaround http://b/5201039, we restart the shell and retry if the
- package manager isn't back after 120 seconds.
-
- Raises:
- errors.WaitForResponseTimedOutError after max retries reached.
- """
- last_err = None
- retries = 3
- while retries:
- try:
- self._adb.WaitForDevicePm(wait_time=timeout)
- return # Success
- except errors.WaitForResponseTimedOutError as e:
- last_err = e
- logging.warning('Restarting and retrying after timeout: %s', e)
- retries -= 1
- self.RestartShell()
- raise last_err # Only reached after max retries, re-raise the last error.
-
- def RestartShell(self):
- """Restarts the shell on the device. Does not block for it to return."""
- self.RunShellCommand('stop')
- self.RunShellCommand('start')
-
- def Reboot(self, full_reboot=True):
- """Reboots the device and waits for the package manager to return.
-
- Args:
- full_reboot: Whether to fully reboot the device or just restart the shell.
- """
- # TODO(torne): hive can't reboot the device either way without breaking the
- # connection; work out if we can handle this better
- if os.environ.get('USING_HIVE'):
- logging.warning('Ignoring reboot request as we are on hive')
- return
- if full_reboot or not self.IsRootEnabled():
- self._adb.SendCommand('reboot')
- self._system_properties = system_properties.SystemProperties(self.Adb())
- timeout = 300
- retries = 1
- # Wait for the device to disappear.
- while retries < 10 and self.IsOnline():
- time.sleep(1)
- retries += 1
- else:
- self.RestartShell()
- timeout = 120
- # To run tests we need at least the package manager and the sd card (or
- # other external storage) to be ready.
- self.WaitForDevicePm(timeout)
- self.WaitForSdCardReady(timeout)
-
- def Shutdown(self):
- """Shuts down the device."""
- self._adb.SendCommand('reboot -p')
- self._system_properties = system_properties.SystemProperties(self.Adb())
-
- def Uninstall(self, package):
- """Uninstalls the specified package from the device.
-
- Args:
- package: Name of the package to remove.
-
- Returns:
- A status string returned by adb uninstall
- """
- uninstall_command = 'uninstall %s' % package
-
- self._LogShell(uninstall_command)
- return self._adb.SendCommand(uninstall_command, timeout_time=60)
-
- def Install(self, package_file_path, reinstall=False):
- """Installs the specified package to the device.
-
- Args:
- package_file_path: Path to .apk file to install.
- reinstall: Reinstall an existing apk, keeping the data.
-
- Returns:
- A status string returned by adb install
- """
- assert os.path.isfile(package_file_path), ('<%s> is not file' %
- package_file_path)
-
- install_cmd = ['install']
-
- if reinstall:
- install_cmd.append('-r')
-
- install_cmd.append(package_file_path)
- install_cmd = ' '.join(install_cmd)
-
- self._LogShell(install_cmd)
- return self._adb.SendCommand(install_cmd,
- timeout_time=2 * 60,
- retry_count=0)
-
- def ManagedInstall(self, apk_path, keep_data=False, package_name=None,
- reboots_on_timeout=2):
- """Installs specified package and reboots device on timeouts.
-
- If package_name is supplied, checks if the package is already installed and
- doesn't reinstall if the apk md5sums match.
-
- Args:
- apk_path: Path to .apk file to install.
- keep_data: Reinstalls instead of uninstalling first, preserving the
- application data.
- package_name: Package name (only needed if keep_data=False).
- reboots_on_timeout: number of time to reboot if package manager is frozen.
- """
- # Check if package is already installed and up to date.
- if package_name:
- installed_apk_path = self.GetApplicationPath(package_name)
- if (installed_apk_path and
- not self.GetFilesChanged(apk_path, installed_apk_path,
- ignore_filenames=True)):
- logging.info('Skipped install: identical %s APK already installed' %
- package_name)
- return
- # Install.
- reboots_left = reboots_on_timeout
- while True:
- try:
- if not keep_data:
- assert package_name
- self.Uninstall(package_name)
- install_status = self.Install(apk_path, reinstall=keep_data)
- if 'Success' in install_status:
- return
- else:
- raise Exception('Install failure: %s' % install_status)
- except errors.WaitForResponseTimedOutError:
- print '@@@STEP_WARNINGS@@@'
- logging.info('Timeout on installing %s on device %s', apk_path,
- self._device)
-
- if reboots_left <= 0:
- raise Exception('Install timed out')
-
- # Force a hard reboot on last attempt
- self.Reboot(full_reboot=(reboots_left == 1))
- reboots_left -= 1
-
- def MakeSystemFolderWritable(self):
- """Remounts the /system folder rw."""
- out = self._adb.SendCommand('remount')
- if out.strip() != 'remount succeeded':
- raise errors.MsgException('Remount failed: %s' % out)
-
- def RestartAdbdOnDevice(self):
- logging.info('Restarting adbd on the device...')
- with DeviceTempFile(self, suffix=".sh") as temp_script_file:
- host_script_path = os.path.join(constants.DIR_SOURCE_ROOT,
- 'build',
- 'android',
- 'pylib',
- 'restart_adbd.sh')
- self._adb.Push(host_script_path, temp_script_file.name)
- self.RunShellCommand('. %s' % temp_script_file.name)
- self._adb.SendCommand('wait-for-device')
-
- def RestartAdbServer(self):
- """Restart the adb server."""
- ret = self.KillAdbServer()
- if ret != 0:
- raise errors.MsgException('KillAdbServer: %d' % ret)
-
- ret = self.StartAdbServer()
- if ret != 0:
- raise errors.MsgException('StartAdbServer: %d' % ret)
-
- @staticmethod
- def KillAdbServer():
- """Kill adb server."""
- adb_cmd = [constants.GetAdbPath(), 'kill-server']
- ret = cmd_helper.RunCmd(adb_cmd)
- retry = 0
- while retry < 3:
- ret, _ = cmd_helper.GetCmdStatusAndOutput(['pgrep', 'adb'])
- if ret != 0:
- # pgrep didn't find adb, kill-server succeeded.
- return 0
- retry += 1
- time.sleep(retry)
- return ret
-
- def StartAdbServer(self):
- """Start adb server."""
- adb_cmd = ['taskset', '-c', '0', constants.GetAdbPath(), 'start-server']
- ret, _ = cmd_helper.GetCmdStatusAndOutput(adb_cmd)
- retry = 0
- while retry < 3:
- ret, _ = cmd_helper.GetCmdStatusAndOutput(['pgrep', 'adb'])
- if ret == 0:
- # pgrep found adb, start-server succeeded.
- # Waiting for device to reconnect before returning success.
- self._adb.SendCommand('wait-for-device')
- return 0
- retry += 1
- time.sleep(retry)
- return ret
-
- def WaitForSystemBootCompleted(self, wait_time):
- """Waits for targeted system's boot_completed flag to be set.
-
- Args:
- wait_time: time in seconds to wait
-
- Raises:
- WaitForResponseTimedOutError if wait_time elapses and flag still not
- set.
- """
- logging.info('Waiting for system boot completed...')
- self._adb.SendCommand('wait-for-device')
- # Now the device is there, but system not boot completed.
- # Query the sys.boot_completed flag with a basic command
- boot_completed = False
- attempts = 0
- wait_period = 5
- while not boot_completed and (attempts * wait_period) < wait_time:
- output = self.system_properties['sys.boot_completed']
- output = output.strip()
- if output == '1':
- boot_completed = True
- else:
- # If 'error: xxx' returned when querying the flag, it means
- # adb server lost the connection to the emulator, so restart the adb
- # server.
- if 'error:' in output:
- self.RestartAdbServer()
- time.sleep(wait_period)
- attempts += 1
- if not boot_completed:
- raise errors.WaitForResponseTimedOutError(
- 'sys.boot_completed flag was not set after %s seconds' % wait_time)
-
- def WaitForSdCardReady(self, timeout_time):
- """Wait for the SD card ready before pushing data into it."""
- logging.info('Waiting for SD card ready...')
- sdcard_ready = False
- attempts = 0
- wait_period = 5
- external_storage = self.GetExternalStorage()
- while not sdcard_ready and attempts * wait_period < timeout_time:
- output = self.RunShellCommand('ls ' + external_storage)
- if output:
- sdcard_ready = True
- else:
- time.sleep(wait_period)
- attempts += 1
- if not sdcard_ready:
- raise errors.WaitForResponseTimedOutError(
- 'SD card not ready after %s seconds' % timeout_time)
-
- def GetAndroidToolStatusAndOutput(self, command, lib_path=None, *args, **kw):
- """Runs a native Android binary, wrapping the command as necessary.
-
- This is a specialization of GetShellCommandStatusAndOutput, which is meant
- for running tools/android/ binaries and handle properly: (1) setting the
- lib path (for component=shared_library), (2) using the PIE wrapper on ICS.
- See crbug.com/373219 for more context.
-
- Args:
- command: String containing the command to send.
- lib_path: (optional) path to the folder containing the dependent libs.
- Same other arguments of GetCmdStatusAndOutput.
- """
- # The first time this command is run the device is inspected to check
- # whether a wrapper for running PIE executable is needed (only Android ICS)
- # or not. The results is cached, so the wrapper is pushed only once.
- if self._pie_wrapper is None:
- # None: did not check; '': did check and not needed; '/path': use /path.
- self._pie_wrapper = ''
- if self.GetBuildId().startswith('I'): # Ixxxx = Android ICS.
- run_pie_dist_path = os.path.join(constants.GetOutDirectory(), 'run_pie')
- assert os.path.exists(run_pie_dist_path), 'Please build run_pie'
- # The PIE loader must be pushed manually (i.e. no PushIfNeeded) because
- # PushIfNeeded requires md5sum and md5sum requires the wrapper as well.
- adb_command = 'push %s %s' % (run_pie_dist_path, PIE_WRAPPER_PATH)
- assert _HasAdbPushSucceeded(self._adb.SendCommand(adb_command))
- self._pie_wrapper = PIE_WRAPPER_PATH
-
- if self._pie_wrapper:
- command = '%s %s' % (self._pie_wrapper, command)
- if lib_path:
- command = 'LD_LIBRARY_PATH=%s %s' % (lib_path, command)
- return self.GetShellCommandStatusAndOutput(command, *args, **kw)
-
- # It is tempting to turn this function into a generator, however this is not
- # possible without using a private (local) adb_shell instance (to ensure no
- # other command interleaves usage of it), which would defeat the main aim of
- # being able to reuse the adb shell instance across commands.
- def RunShellCommand(self, command, timeout_time=20, log_result=False):
- """Send a command to the adb shell and return the result.
-
- Args:
- command: String containing the shell command to send.
- timeout_time: Number of seconds to wait for command to respond before
- retrying, used by AdbInterface.SendShellCommand.
- log_result: Boolean to indicate whether we should log the result of the
- shell command.
-
- Returns:
- list containing the lines of output received from running the command
- """
- self._LogShell(command)
- if "'" in command:
- command = command.replace('\'', '\'\\\'\'')
- result = self._adb.SendShellCommand(
- "'%s'" % command, timeout_time).splitlines()
- # TODO(b.kelemen): we should really be able to drop the stderr of the
- # command or raise an exception based on what the caller wants.
- result = [ l for l in result if not l.startswith('WARNING') ]
- if ['error: device not found'] == result:
- raise errors.DeviceUnresponsiveError('device not found')
- if log_result:
- self._LogShell('\n'.join(result))
- return result
-
- def GetShellCommandStatusAndOutput(self, command, timeout_time=20,
- log_result=False):
- """See RunShellCommand() above.
-
- Returns:
- The tuple (exit code, list of output lines).
- """
- lines = self.RunShellCommand(
- command + '; echo %$?', timeout_time, log_result)
- last_line = lines[-1]
- status_pos = last_line.rfind('%')
- assert status_pos >= 0
- status = int(last_line[status_pos + 1:])
- if status_pos == 0:
- lines = lines[:-1]
- else:
- lines = lines[:-1] + [last_line[:status_pos]]
- return (status, lines)
-
- def KillAll(self, process, signum=9, with_su=False):
- """Android version of killall, connected via adb.
-
- Args:
- process: name of the process to kill off.
- signum: signal to use, 9 (SIGKILL) by default.
- with_su: wether or not to use su to kill the processes.
-
- Returns:
- the number of processes killed
- """
- pids = self.ExtractPid(process)
- if pids:
- cmd = 'kill -%d %s' % (signum, ' '.join(pids))
- if with_su:
- self.RunShellCommandWithSU(cmd)
- else:
- self.RunShellCommand(cmd)
- return len(pids)
-
- def KillAllBlocking(self, process, timeout_sec, signum=9, with_su=False):
- """Blocking version of killall, connected via adb.
-
- This waits until no process matching the corresponding name appears in ps'
- output anymore.
-
- Args:
- process: name of the process to kill off
- timeout_sec: the timeout in seconds
- signum: same as |KillAll|
- with_su: same as |KillAll|
- Returns:
- the number of processes killed
- """
- processes_killed = self.KillAll(process, signum=signum, with_su=with_su)
- if processes_killed:
- elapsed = 0
- wait_period = 0.1
- # Note that this doesn't take into account the time spent in ExtractPid().
- while self.ExtractPid(process) and elapsed < timeout_sec:
- time.sleep(wait_period)
- elapsed += wait_period
- if elapsed >= timeout_sec:
- return processes_killed - self.ExtractPid(process)
- return processes_killed
-
- @staticmethod
- def _GetActivityCommand(package, activity, wait_for_completion, action,
- category, data, extras, trace_file_name, force_stop,
- flags):
- """Creates command to start |package|'s activity on the device.
-
- Args - as for StartActivity
-
- Returns:
- the command to run on the target to start the activity
- """
- cmd = 'am start -a %s' % action
- if force_stop:
- cmd += ' -S'
- if wait_for_completion:
- cmd += ' -W'
- if category:
- cmd += ' -c %s' % category
- if package and activity:
- cmd += ' -n %s/%s' % (package, activity)
- if data:
- cmd += ' -d "%s"' % data
- if extras:
- for key in extras:
- value = extras[key]
- if isinstance(value, str):
- cmd += ' --es'
- elif isinstance(value, bool):
- cmd += ' --ez'
- elif isinstance(value, int):
- cmd += ' --ei'
- else:
- raise NotImplementedError(
- 'Need to teach StartActivity how to pass %s extras' % type(value))
- cmd += ' %s %s' % (key, value)
- if trace_file_name:
- cmd += ' --start-profiler ' + trace_file_name
- if flags:
- cmd += ' -f %s' % flags
- return cmd
-
- def StartActivity(self, package, activity, wait_for_completion=False,
- action='android.intent.action.VIEW',
- category=None, data=None,
- extras=None, trace_file_name=None,
- force_stop=False, flags=None):
- """Starts |package|'s activity on the device.
-
- Args:
- package: Name of package to start (e.g. 'com.google.android.apps.chrome').
- activity: Name of activity (e.g. '.Main' or
- 'com.google.android.apps.chrome.Main').
- wait_for_completion: wait for the activity to finish launching (-W flag).
- action: string (e.g. "android.intent.action.MAIN"). Default is VIEW.
- category: string (e.g. "android.intent.category.HOME")
- data: Data string to pass to activity (e.g. 'http://www.example.com/').
- extras: Dict of extras to pass to activity. Values are significant.
- trace_file_name: If used, turns on and saves the trace to this file name.
- force_stop: force stop the target app before starting the activity (-S
- flag).
- Returns:
- The output of the underlying command as a list of lines.
- """
- cmd = self._GetActivityCommand(package, activity, wait_for_completion,
- action, category, data, extras,
- trace_file_name, force_stop, flags)
- return self.RunShellCommand(cmd)
-
- def StartActivityTimed(self, package, activity, wait_for_completion=False,
- action='android.intent.action.VIEW',
- category=None, data=None,
- extras=None, trace_file_name=None,
- force_stop=False, flags=None):
- """Starts |package|'s activity on the device, returning the start time
-
- Args - as for StartActivity
-
- Returns:
- A tuple containing:
- - the output of the underlying command as a list of lines, and
- - a timestamp string for the time at which the activity started
- """
- cmd = self._GetActivityCommand(package, activity, wait_for_completion,
- action, category, data, extras,
- trace_file_name, force_stop, flags)
- self.StartMonitoringLogcat()
- out = self.RunShellCommand('log starting activity; ' + cmd)
- activity_started_re = re.compile('.*starting activity.*')
- m = self.WaitForLogMatch(activity_started_re, None)
- assert m
- start_line = m.group(0)
- return (out, GetLogTimestamp(start_line, self.GetDeviceYear()))
-
- def StartCrashUploadService(self, package):
- # TODO(frankf): We really need a python wrapper around Intent
- # to be shared with StartActivity/BroadcastIntent.
- cmd = (
- 'am startservice -a %s.crash.ACTION_FIND_ALL -n '
- '%s/%s.crash.MinidumpUploadService' %
- (constants.PACKAGE_INFO['chrome'].package,
- package,
- constants.PACKAGE_INFO['chrome'].package))
- am_output = self.RunShellCommandWithSU(cmd)
- assert am_output and 'Starting' in am_output[-1], (
- 'Service failed to start: %s' % am_output)
- time.sleep(15)
-
- def BroadcastIntent(self, package, intent, *args):
- """Send a broadcast intent.
-
- Args:
- package: Name of package containing the intent.
- intent: Name of the intent.
- args: Optional extra arguments for the intent.
- """
- cmd = 'am broadcast -a %s.%s %s' % (package, intent, ' '.join(args))
- self.RunShellCommand(cmd)
-
- def GoHome(self):
- """Tell the device to return to the home screen. Blocks until completion."""
- self.RunShellCommand('am start -W '
- '-a android.intent.action.MAIN -c android.intent.category.HOME')
-
- def CloseApplication(self, package):
- """Attempt to close down the application, using increasing violence.
-
- Args:
- package: Name of the process to kill off, e.g.
- com.google.android.apps.chrome
- """
- self.RunShellCommand('am force-stop ' + package)
-
- def GetApplicationPath(self, package):
- """Get the installed apk path on the device for the given package.
-
- Args:
- package: Name of the package.
-
- Returns:
- Path to the apk on the device if it exists, None otherwise.
- """
- pm_path_output = self.RunShellCommand('pm path ' + package)
- # The path output contains anything if and only if the package
- # exists.
- if pm_path_output:
- # pm_path_output is of the form: "package:/path/to/foo.apk"
- return pm_path_output[0].split(':')[1]
- else:
- return None
-
- def ClearApplicationState(self, package):
- """Closes and clears all state for the given |package|."""
- # Check that the package exists before clearing it. Necessary because
- # calling pm clear on a package that doesn't exist may never return.
- pm_path_output = self.RunShellCommand('pm path ' + package)
- # The path output only contains anything if and only if the package exists.
- if pm_path_output:
- self.RunShellCommand('pm clear ' + package)
-
- def SendKeyEvent(self, keycode):
- """Sends keycode to the device.
-
- Args:
- keycode: Numeric keycode to send (see "enum" at top of file).
- """
- self.RunShellCommand('input keyevent %d' % keycode)
-
- def _RunMd5Sum(self, host_path, device_path):
- """Gets the md5sum of a host path and device path.
-
- Args:
- host_path: Path (file or directory) on the host.
- device_path: Path on the device.
-
- Returns:
- A tuple containing lists of the host and device md5sum results as
- created by _ParseMd5SumOutput().
- """
- md5sum_dist_path = os.path.join(constants.GetOutDirectory(),
- 'md5sum_dist')
- assert os.path.exists(md5sum_dist_path), 'Please build md5sum.'
- md5sum_dist_mtime = os.stat(md5sum_dist_path).st_mtime
- if (md5sum_dist_path not in self._push_if_needed_cache or
- self._push_if_needed_cache[md5sum_dist_path] != md5sum_dist_mtime):
- command = 'push %s %s' % (md5sum_dist_path, MD5SUM_DEVICE_FOLDER)
- assert _HasAdbPushSucceeded(self._adb.SendCommand(command))
- self._push_if_needed_cache[md5sum_dist_path] = md5sum_dist_mtime
-
- (_, md5_device_output) = self.GetAndroidToolStatusAndOutput(
- self._util_wrapper + ' ' + MD5SUM_DEVICE_PATH + ' ' + device_path,
- lib_path=MD5SUM_DEVICE_FOLDER,
- timeout_time=2 * 60)
- device_hash_tuples = _ParseMd5SumOutput(md5_device_output)
- assert os.path.exists(host_path), 'Local path not found %s' % host_path
- md5sum_output = cmd_helper.GetCmdOutput(
- [os.path.join(constants.GetOutDirectory(), 'md5sum_bin_host'),
- host_path])
- host_hash_tuples = _ParseMd5SumOutput(md5sum_output.splitlines())
- return (host_hash_tuples, device_hash_tuples)
-
- def GetFilesChanged(self, host_path, device_path, ignore_filenames=False):
- """Compares the md5sum of a host path against a device path.
-
- Note: Ignores extra files on the device.
-
- Args:
- host_path: Path (file or directory) on the host.
- device_path: Path on the device.
- ignore_filenames: If True only the file contents are considered when
- checking whether a file has changed, otherwise the relative path
- must also match.
-
- Returns:
- A list of tuples of the form (host_path, device_path) for files whose
- md5sums do not match.
- """
-
- # Md5Sum resolves symbolic links in path names so the calculation of
- # relative path names from its output will need the real path names of the
- # base directories. Having calculated these they are used throughout the
- # function since this makes us less subject to any future changes to Md5Sum.
- real_host_path = os.path.realpath(host_path)
- real_device_path = self.RunShellCommand('realpath "%s"' % device_path)[0]
-
- host_hash_tuples, device_hash_tuples = self._RunMd5Sum(
- real_host_path, real_device_path)
-
- if len(host_hash_tuples) > len(device_hash_tuples):
- logging.info('%s files do not exist on the device' %
- (len(host_hash_tuples) - len(device_hash_tuples)))
-
- host_rel = [(os.path.relpath(os.path.normpath(t.path), real_host_path),
- t.hash)
- for t in host_hash_tuples]
-
- if os.path.isdir(real_host_path):
- def RelToRealPaths(rel_path):
- return (os.path.join(real_host_path, rel_path),
- os.path.join(real_device_path, rel_path))
- else:
- assert len(host_rel) == 1
- def RelToRealPaths(_):
- return (real_host_path, real_device_path)
-
- if ignore_filenames:
- # If we are ignoring file names, then we want to push any file for which
- # a file with an equivalent MD5 sum does not exist on the device.
- device_hashes = set([h.hash for h in device_hash_tuples])
- ShouldPush = lambda p, h: h not in device_hashes
- else:
- # Otherwise, we want to push any file on the host for which a file with
- # an equivalent MD5 sum does not exist at the same relative path on the
- # device.
- device_rel = dict([(os.path.relpath(os.path.normpath(t.path),
- real_device_path),
- t.hash)
- for t in device_hash_tuples])
- ShouldPush = lambda p, h: p not in device_rel or h != device_rel[p]
-
- return [RelToRealPaths(path) for path, host_hash in host_rel
- if ShouldPush(path, host_hash)]
-
- def PushIfNeeded(self, host_path, device_path):
- """Pushes |host_path| to |device_path|.
-
- Works for files and directories. This method skips copying any paths in
- |test_data_paths| that already exist on the device with the same hash.
-
- All pushed files can be removed by calling RemovePushedFiles().
- """
- MAX_INDIVIDUAL_PUSHES = 50
- if not os.path.exists(host_path):
- raise device_errors.CommandFailedError(
- 'Local path not found %s' % host_path, device=str(self))
-
- # See if the file on the host changed since the last push (if any) and
- # return early if it didn't. Note that this shortcut assumes that the tests
- # on the device don't modify the files.
- if not os.path.isdir(host_path):
- if host_path in self._push_if_needed_cache:
- host_path_mtime = self._push_if_needed_cache[host_path]
- if host_path_mtime == os.stat(host_path).st_mtime:
- return
-
- size = host_utils.GetRecursiveDiskUsage(host_path)
- self._pushed_files.append(device_path)
- self._potential_push_size += size
-
- if os.path.isdir(host_path):
- self.RunShellCommand('mkdir -p "%s"' % device_path)
-
- changed_files = self.GetFilesChanged(host_path, device_path)
- logging.info('Found %d files that need to be pushed to %s',
- len(changed_files), device_path)
- if not changed_files:
- return
-
- def Push(host, device):
- # NOTE: We can't use adb_interface.Push() because it hardcodes a timeout
- # of 60 seconds which isn't sufficient for a lot of users of this method.
- push_command = 'push %s %s' % (host, device)
- self._LogShell(push_command)
-
- # Retry push with increasing backoff if the device is busy.
- retry = 0
- while True:
- output = self._adb.SendCommand(push_command, timeout_time=30 * 60)
- if _HasAdbPushSucceeded(output):
- if not os.path.isdir(host_path):
- self._push_if_needed_cache[host] = os.stat(host).st_mtime
- return
- if retry < 3:
- retry += 1
- wait_time = 5 * retry
- logging.error('Push failed, retrying in %d seconds: %s' %
- (wait_time, output))
- time.sleep(wait_time)
- else:
- raise Exception('Push failed: %s' % output)
-
- diff_size = 0
- if len(changed_files) <= MAX_INDIVIDUAL_PUSHES:
- diff_size = sum(host_utils.GetRecursiveDiskUsage(f[0])
- for f in changed_files)
-
- # TODO(craigdh): Replace this educated guess with a heuristic that
- # approximates the push time for each method.
- if len(changed_files) > MAX_INDIVIDUAL_PUSHES or diff_size > 0.5 * size:
- self._actual_push_size += size
- Push(host_path, device_path)
- else:
- for f in changed_files:
- Push(f[0], f[1])
- self._actual_push_size += diff_size
-
- def GetPushSizeInfo(self):
- """Get total size of pushes to the device done via PushIfNeeded()
-
- Returns:
- A tuple:
- 1. Total size of push requests to PushIfNeeded (MB)
- 2. Total size that was actually pushed (MB)
- """
- return (self._potential_push_size, self._actual_push_size)
-
- def GetFileContents(self, filename, log_result=False):
- """Gets contents from the file specified by |filename|."""
- return self.RunShellCommand('cat "%s" 2>/dev/null' % filename,
- log_result=log_result)
-
- def SetFileContents(self, filename, contents):
- """Writes |contents| to the file specified by |filename|."""
- with tempfile.NamedTemporaryFile() as f:
- f.write(contents)
- f.flush()
- self._adb.Push(f.name, filename)
-
- def RunShellCommandWithSU(self, command, timeout_time=20, log_result=False):
- return self.RunShellCommand('su -c %s' % command, timeout_time, log_result)
-
- def CanAccessProtectedFileContents(self):
- """Returns True if Get/SetProtectedFileContents would work via "su" or adb
- shell running as root.
-
- Devices running user builds don't have adb root, but may provide "su" which
- can be used for accessing protected files.
- """
- return (self._GetProtectedFileCommandRunner() != None)
-
- def _GetProtectedFileCommandRunner(self):
- """Finds the best method to access protected files on the device.
-
- Returns:
- 1. None when privileged files cannot be accessed on the device.
- 2. Otherwise: A function taking a single parameter: a string with command
- line arguments. Running that function executes the command with
- the appropriate method.
- """
- if self._protected_file_access_method_initialized:
- return self._privileged_command_runner
-
- self._privileged_command_runner = None
- self._protected_file_access_method_initialized = True
-
- for cmd in [self.RunShellCommand, self.RunShellCommandWithSU]:
- # Get contents of the auxv vector for the init(8) process from a small
- # binary file that always exists on linux and is always read-protected.
- contents = cmd('cat /proc/1/auxv')
- # The leading 4 or 8-bytes of auxv vector is a_type. There are not many
- # reserved a_type values, hence byte 2 must always be '\0' for a realistic
- # auxv. See /usr/include/elf.h.
- if len(contents) > 0 and (contents[0][2] == '\0'):
- self._privileged_command_runner = cmd
- break
- return self._privileged_command_runner
-
- def GetProtectedFileContents(self, filename):
- """Gets contents from the protected file specified by |filename|.
-
- This is potentially less efficient than GetFileContents.
- """
- command = 'cat "%s" 2> /dev/null' % filename
- command_runner = self._GetProtectedFileCommandRunner()
- if command_runner:
- return command_runner(command)
- else:
- logging.warning('Could not access protected file: %s' % filename)
- return []
-
- def SetProtectedFileContents(self, filename, contents):
- """Writes |contents| to the protected file specified by |filename|.
-
- This is less efficient than SetFileContents.
- """
- with DeviceTempFile(self) as temp_file:
- with DeviceTempFile(self, suffix=".sh") as temp_script:
- # Put the contents in a temporary file
- self.SetFileContents(temp_file.name, contents)
- # Create a script to copy the file contents to its final destination
- self.SetFileContents(temp_script.name,
- 'cat %s > %s' % (temp_file.name, filename))
-
- command = 'sh %s' % temp_script.name
- command_runner = self._GetProtectedFileCommandRunner()
- if command_runner:
- return command_runner(command)
- else:
- logging.warning(
- 'Could not set contents of protected file: %s' % filename)
-
-
- def RemovePushedFiles(self):
- """Removes all files pushed with PushIfNeeded() from the device."""
- for p in self._pushed_files:
- self.RunShellCommand('rm -r %s' % p, timeout_time=2 * 60)
-
- def ListPathContents(self, path):
- """Lists files in all subdirectories of |path|.
-
- Args:
- path: The path to list.
-
- Returns:
- A dict of {"name": (size, lastmod), ...}.
- """
- # Example output:
- # /foo/bar:
- # -rw-r----- user group 102 2011-05-12 12:29:54.131623387 +0100 baz.txt
- re_file = re.compile('^-(?P<perms>[^\s]+)\s+'
- '(?P<user>[^\s]+)\s+'
- '(?P<group>[^\s]+)\s+'
- '(?P<size>[^\s]+)\s+'
- '(?P<date>[^\s]+)\s+'
- '(?P<time>[^\s]+)\s+'
- '(?P<filename>[^\s]+)$')
- return _GetFilesFromRecursiveLsOutput(
- path, self.RunShellCommand('ls -lR %s' % path), re_file,
- self.GetUtcOffset())
-
- def GetUtcOffset(self):
- if not self._device_utc_offset:
- self._device_utc_offset = self.RunShellCommand('date +%z')[0]
- return self._device_utc_offset
-
- def SetJavaAssertsEnabled(self, enable):
- """Sets or removes the device java assertions property.
-
- Args:
- enable: If True the property will be set.
-
- Returns:
- True if the file was modified (reboot is required for it to take effect).
- """
- # First ensure the desired property is persisted.
- temp_props_file = tempfile.NamedTemporaryFile()
- properties = ''
- if self._adb.Pull(LOCAL_PROPERTIES_PATH, temp_props_file.name):
- with open(temp_props_file.name) as f:
- properties = f.read()
- re_search = re.compile(r'^\s*' + re.escape(JAVA_ASSERT_PROPERTY) +
- r'\s*=\s*all\s*$', re.MULTILINE)
- if enable != bool(re.search(re_search, properties)):
- re_replace = re.compile(r'^\s*' + re.escape(JAVA_ASSERT_PROPERTY) +
- r'\s*=\s*\w+\s*$', re.MULTILINE)
- properties = re.sub(re_replace, '', properties)
- if enable:
- properties += '\n%s=all\n' % JAVA_ASSERT_PROPERTY
-
- file(temp_props_file.name, 'w').write(properties)
- self._adb.Push(temp_props_file.name, LOCAL_PROPERTIES_PATH)
-
- # Next, check the current runtime value is what we need, and
- # if not, set it and report that a reboot is required.
- was_set = 'all' in self.system_properties[JAVA_ASSERT_PROPERTY]
- if was_set == enable:
- return False
- self.system_properties[JAVA_ASSERT_PROPERTY] = enable and 'all' or ''
- return True
-
- def GetBuildId(self):
- """Returns the build ID of the system (e.g. JRM79C)."""
- build_id = self.system_properties['ro.build.id']
- assert build_id
- return build_id
-
- def GetBuildType(self):
- """Returns the build type of the system (e.g. eng)."""
- build_type = self.system_properties['ro.build.type']
- assert build_type
- return build_type
-
- def GetBuildProduct(self):
- """Returns the build product of the device (e.g. maguro)."""
- build_product = self.system_properties['ro.build.product']
- assert build_product
- return build_product
-
- def GetProductName(self):
- """Returns the product name of the device (e.g. takju)."""
- name = self.system_properties['ro.product.name']
- assert name
- return name
-
- def GetBuildFingerprint(self):
- """Returns the build fingerprint of the device."""
- build_fingerprint = self.system_properties['ro.build.fingerprint']
- assert build_fingerprint
- return build_fingerprint
-
- def GetDescription(self):
- """Returns the description of the system.
-
- For example, "yakju-userdebug 4.1 JRN54F 364167 dev-keys".
- """
- description = self.system_properties['ro.build.description']
- assert description
- return description
-
- def GetProductModel(self):
- """Returns the name of the product model (e.g. "Galaxy Nexus") """
- model = self.system_properties['ro.product.model']
- assert model
- return model
-
- def GetWifiIP(self):
- """Returns the wifi IP on the device."""
- wifi_ip = self.system_properties['dhcp.wlan0.ipaddress']
- # Do not assert here. Devices (e.g. emulators) may not have a WifiIP.
- return wifi_ip
-
- def GetSubscriberInfo(self):
- """Returns the device subscriber info (e.g. GSM and device ID) as string."""
- iphone_sub = self.RunShellCommand('dumpsys iphonesubinfo')
- # Do not assert here. Devices (e.g. Nakasi on K) may not have iphonesubinfo.
- return '\n'.join(iphone_sub)
-
- def GetBatteryInfo(self):
- """Returns a {str: str} dict of battery info (e.g. status, level, etc)."""
- battery = self.RunShellCommand('dumpsys battery')
- assert battery
- battery_info = {}
- for line in battery[1:]:
- k, _, v = line.partition(': ')
- battery_info[k.strip()] = v.strip()
- return battery_info
-
- def GetSetupWizardStatus(self):
- """Returns the status of the device setup wizard (e.g. DISABLED)."""
- status = self.system_properties['ro.setupwizard.mode']
- # On some devices, the status is empty if not otherwise set. In such cases
- # the caller should expect an empty string to be returned.
- return status
-
- def StartMonitoringLogcat(self, clear=True, logfile=None, filters=None):
- """Starts monitoring the output of logcat, for use with WaitForLogMatch.
-
- Args:
- clear: If True the existing logcat output will be cleared, to avoiding
- matching historical output lurking in the log.
- filters: A list of logcat filters to be used.
- """
- if clear:
- self.RunShellCommand('logcat -c')
- args = []
- if self._adb._target_arg:
- args += shlex.split(self._adb._target_arg)
- args += ['logcat', '-v', 'threadtime']
- if filters:
- args.extend(filters)
- else:
- args.append('*:v')
-
- if logfile:
- logfile = NewLineNormalizer(logfile)
-
- # Spawn logcat and synchronize with it.
- for _ in range(4):
- self._logcat = pexpect.spawn(constants.GetAdbPath(), args, timeout=10,
- logfile=logfile)
- if not clear or self.SyncLogCat():
- break
- self._logcat.close(force=True)
- else:
- logging.critical('Error reading from logcat: ' + str(self._logcat.match))
- sys.exit(1)
-
- def SyncLogCat(self):
- """Synchronize with logcat.
-
- Synchronize with the monitored logcat so that WaitForLogMatch will only
- consider new message that are received after this point in time.
-
- Returns:
- True if the synchronization succeeded.
- """
- assert self._logcat
- tag = 'logcat_sync_%s' % time.time()
- self.RunShellCommand('log ' + tag)
- return self._logcat.expect([tag, pexpect.EOF, pexpect.TIMEOUT]) == 0
-
- def GetMonitoredLogCat(self):
- """Returns an "adb logcat" command as created by pexpected.spawn."""
- if not self._logcat:
- self.StartMonitoringLogcat(clear=False)
- return self._logcat
-
- def WaitForLogMatch(self, success_re, error_re, clear=False, timeout=10):
- """Blocks until a matching line is logged or a timeout occurs.
-
- Args:
- success_re: A compiled re to search each line for.
- error_re: A compiled re which, if found, terminates the search for
- |success_re|. If None is given, no error condition will be detected.
- clear: If True the existing logcat output will be cleared, defaults to
- false.
- timeout: Timeout in seconds to wait for a log match.
-
- Raises:
- pexpect.TIMEOUT after |timeout| seconds without a match for |success_re|
- or |error_re|.
-
- Returns:
- The re match object if |success_re| is matched first or None if |error_re|
- is matched first.
- """
- logging.info('<<< Waiting for logcat:' + str(success_re.pattern))
- t0 = time.time()
- while True:
- if not self._logcat:
- self.StartMonitoringLogcat(clear)
- try:
- while True:
- # Note this will block for upto the timeout _per log line_, so we need
- # to calculate the overall timeout remaining since t0.
- time_remaining = t0 + timeout - time.time()
- if time_remaining < 0:
- raise pexpect.TIMEOUT(self._logcat)
- self._logcat.expect(PEXPECT_LINE_RE, timeout=time_remaining)
- line = self._logcat.match.group(1)
- if error_re:
- error_match = error_re.search(line)
- if error_match:
- return None
- success_match = success_re.search(line)
- if success_match:
- return success_match
- logging.info('<<< Skipped Logcat Line:' + str(line))
- except pexpect.TIMEOUT:
- raise pexpect.TIMEOUT(
- 'Timeout (%ds) exceeded waiting for pattern "%s" (tip: use -vv '
- 'to debug)' %
- (timeout, success_re.pattern))
- except pexpect.EOF:
- # It seems that sometimes logcat can end unexpectedly. This seems
- # to happen during Chrome startup after a reboot followed by a cache
- # clean. I don't understand why this happens, but this code deals with
- # getting EOF in logcat.
- logging.critical('Found EOF in adb logcat. Restarting...')
- # Rerun spawn with original arguments. Note that self._logcat.args[0] is
- # the path of adb, so we don't want it in the arguments.
- self._logcat = pexpect.spawn(constants.GetAdbPath(),
- self._logcat.args[1:],
- timeout=self._logcat.timeout,
- logfile=self._logcat.logfile)
-
- def StartRecordingLogcat(self, clear=True, filters=None):
- """Starts recording logcat output to eventually be saved as a string.
-
- This call should come before some series of tests are run, with either
- StopRecordingLogcat or SearchLogcatRecord following the tests.
-
- Args:
- clear: True if existing log output should be cleared.
- filters: A list of logcat filters to be used.
- """
- if not filters:
- filters = ['*:v']
- if clear:
- self._adb.SendCommand('logcat -c')
- logcat_command = 'adb %s logcat -v threadtime %s' % (self._adb._target_arg,
- ' '.join(filters))
- self._logcat_tmpoutfile = tempfile.NamedTemporaryFile(bufsize=0)
- self.logcat_process = subprocess.Popen(logcat_command, shell=True,
- stdout=self._logcat_tmpoutfile)
-
- def GetCurrentRecordedLogcat(self):
- """Return the current content of the logcat being recorded.
- Call this after StartRecordingLogcat() and before StopRecordingLogcat().
- This can be useful to perform timed polling/parsing.
- Returns:
- Current logcat output as a single string, or None if
- StopRecordingLogcat() was already called.
- """
- if not self._logcat_tmpoutfile:
- return None
-
- with open(self._logcat_tmpoutfile.name) as f:
- return f.read()
-
- def StopRecordingLogcat(self):
- """Stops an existing logcat recording subprocess and returns output.
-
- Returns:
- The logcat output as a string or an empty string if logcat was not
- being recorded at the time.
- """
- if not self.logcat_process:
- return ''
- # Cannot evaluate directly as 0 is a possible value.
- # Better to read the self.logcat_process.stdout before killing it,
- # Otherwise the communicate may return incomplete output due to pipe break.
- if self.logcat_process.poll() is None:
- self.logcat_process.kill()
- self.logcat_process.wait()
- self.logcat_process = None
- self._logcat_tmpoutfile.seek(0)
- output = self._logcat_tmpoutfile.read()
- self._logcat_tmpoutfile.close()
- self._logcat_tmpoutfile = None
- return output
-
- @staticmethod
- def SearchLogcatRecord(record, message, thread_id=None, proc_id=None,
- log_level=None, component=None):
- """Searches the specified logcat output and returns results.
-
- This method searches through the logcat output specified by record for a
- certain message, narrowing results by matching them against any other
- specified criteria. It returns all matching lines as described below.
-
- Args:
- record: A string generated by Start/StopRecordingLogcat to search.
- message: An output string to search for.
- thread_id: The thread id that is the origin of the message.
- proc_id: The process that is the origin of the message.
- log_level: The log level of the message.
- component: The name of the component that would create the message.
-
- Returns:
- A list of dictionaries represeting matching entries, each containing keys
- thread_id, proc_id, log_level, component, and message.
- """
- if thread_id:
- thread_id = str(thread_id)
- if proc_id:
- proc_id = str(proc_id)
- results = []
- reg = re.compile('(\d+)\s+(\d+)\s+([A-Z])\s+([A-Za-z]+)\s*:(.*)$',
- re.MULTILINE)
- log_list = reg.findall(record)
- for (tid, pid, log_lev, comp, msg) in log_list:
- if ((not thread_id or thread_id == tid) and
- (not proc_id or proc_id == pid) and
- (not log_level or log_level == log_lev) and
- (not component or component == comp) and msg.find(message) > -1):
- match = dict({'thread_id': tid, 'proc_id': pid,
- 'log_level': log_lev, 'component': comp,
- 'message': msg})
- results.append(match)
- return results
-
- def ExtractPid(self, process_name):
- """Extracts Process Ids for a given process name from Android Shell.
-
- Args:
- process_name: name of the process on the device.
-
- Returns:
- List of all the process ids (as strings) that match the given name.
- If the name of a process exactly matches the given name, the pid of
- that process will be inserted to the front of the pid list.
- """
- pids = []
- for line in self.RunShellCommand('ps', log_result=False):
- data = line.split()
- try:
- if process_name in data[-1]: # name is in the last column
- if process_name == data[-1]:
- pids.insert(0, data[1]) # PID is in the second column
- else:
- pids.append(data[1])
- except IndexError:
- pass
- return pids
-
- def GetIoStats(self):
- """Gets cumulative disk IO stats since boot (for all processes).
-
- Returns:
- Dict of {num_reads, num_writes, read_ms, write_ms} or None if there
- was an error.
- """
- IoStats = collections.namedtuple(
- 'IoStats',
- ['device',
- 'num_reads_issued',
- 'num_reads_merged',
- 'num_sectors_read',
- 'ms_spent_reading',
- 'num_writes_completed',
- 'num_writes_merged',
- 'num_sectors_written',
- 'ms_spent_writing',
- 'num_ios_in_progress',
- 'ms_spent_doing_io',
- 'ms_spent_doing_io_weighted',
- ])
-
- for line in self.GetFileContents('/proc/diskstats', log_result=False):
- fields = line.split()
- stats = IoStats._make([fields[2]] + [int(f) for f in fields[3:]])
- if stats.device == 'mmcblk0':
- return {
- 'num_reads': stats.num_reads_issued,
- 'num_writes': stats.num_writes_completed,
- 'read_ms': stats.ms_spent_reading,
- 'write_ms': stats.ms_spent_writing,
- }
- logging.warning('Could not find disk IO stats.')
- return None
-
- def GetMemoryUsageForPid(self, pid):
- """Returns the memory usage for given pid.
-
- Args:
- pid: The pid number of the specific process running on device.
-
- Returns:
- Dict of {metric:usage_kb}, for the process which has specified pid.
- The metric keys which may be included are: Size, Rss, Pss, Shared_Clean,
- Shared_Dirty, Private_Clean, Private_Dirty, VmHWM.
- """
- showmap = self.RunShellCommand('showmap %d' % pid)
- if not showmap or not showmap[-1].endswith('TOTAL'):
- logging.warning('Invalid output for showmap %s', str(showmap))
- return {}
- items = showmap[-1].split()
- if len(items) != 9:
- logging.warning('Invalid TOTAL for showmap %s', str(items))
- return {}
- usage_dict = collections.defaultdict(int)
- usage_dict.update({
- 'Size': int(items[0].strip()),
- 'Rss': int(items[1].strip()),
- 'Pss': int(items[2].strip()),
- 'Shared_Clean': int(items[3].strip()),
- 'Shared_Dirty': int(items[4].strip()),
- 'Private_Clean': int(items[5].strip()),
- 'Private_Dirty': int(items[6].strip()),
- })
- peak_value_kb = 0
- for line in self.GetProtectedFileContents('/proc/%s/status' % pid):
- if not line.startswith('VmHWM:'): # Format: 'VmHWM: +[0-9]+ kB'
- continue
- peak_value_kb = int(line.split(':')[1].strip().split(' ')[0])
- break
- usage_dict['VmHWM'] = peak_value_kb
- if not peak_value_kb:
- logging.warning('Could not find memory peak value for pid ' + str(pid))
-
- return usage_dict
-
- def ProcessesUsingDevicePort(self, device_port):
- """Lists processes using the specified device port on loopback interface.
-
- Args:
- device_port: Port on device we want to check.
-
- Returns:
- A list of (pid, process_name) tuples using the specified port.
- """
- tcp_results = self.RunShellCommand('cat /proc/net/tcp', log_result=False)
- tcp_address = '0100007F:%04X' % device_port
- pids = []
- for single_connect in tcp_results:
- connect_results = single_connect.split()
- # Column 1 is the TCP port, and Column 9 is the inode of the socket
- if connect_results[1] == tcp_address:
- socket_inode = connect_results[9]
- socket_name = 'socket:[%s]' % socket_inode
- lsof_results = self.RunShellCommand('lsof', log_result=False)
- for single_process in lsof_results:
- process_results = single_process.split()
- # Ignore the line if it has less than nine columns in it, which may
- # be the case when a process stops while lsof is executing.
- if len(process_results) <= 8:
- continue
- # Column 0 is the executable name
- # Column 1 is the pid
- # Column 8 is the Inode in use
- if process_results[8] == socket_name:
- pids.append((int(process_results[1]), process_results[0]))
- break
- logging.info('PidsUsingDevicePort: %s', pids)
- return pids
-
- def FileExistsOnDevice(self, file_name):
- """Checks whether the given file exists on the device.
-
- Args:
- file_name: Full path of file to check.
-
- Returns:
- True if the file exists, False otherwise.
- """
- assert '"' not in file_name, 'file_name cannot contain double quotes'
- try:
- status = self._adb.SendShellCommand(
- '\'test -e "%s"; echo $?\'' % (file_name))
- if 'test: not found' not in status:
- return int(status) == 0
-
- status = self._adb.SendShellCommand(
- '\'ls "%s" >/dev/null 2>&1; echo $?\'' % (file_name))
- return int(status) == 0
- except ValueError:
- if IsDeviceAttached(self._device):
- raise errors.DeviceUnresponsiveError('Device may be offline.')
-
- return False
-
- def IsFileWritableOnDevice(self, file_name):
- """Checks whether the given file (or directory) is writable on the device.
-
- Args:
- file_name: Full path of file/directory to check.
-
- Returns:
- True if writable, False otherwise.
- """
- assert '"' not in file_name, 'file_name cannot contain double quotes'
- try:
- status = self._adb.SendShellCommand(
- '\'test -w "%s"; echo $?\'' % (file_name))
- if 'test: not found' not in status:
- return int(status) == 0
- raise errors.AbortError('"test" binary not found. OS too old.')
-
- except ValueError:
- if IsDeviceAttached(self._device):
- raise errors.DeviceUnresponsiveError('Device may be offline.')
-
- return False
-
- @staticmethod
- def GetTimestamp():
- return time.strftime('%Y-%m-%d-%H%M%S', time.localtime())
-
- @staticmethod
- def EnsureHostDirectory(host_file):
- host_dir = os.path.dirname(os.path.abspath(host_file))
- if not os.path.exists(host_dir):
- os.makedirs(host_dir)
-
- def TakeScreenshot(self, host_file=None):
- """Saves a screenshot image to |host_file| on the host.
-
- Args:
- host_file: Absolute path to the image file to store on the host or None to
- use an autogenerated file name.
-
- Returns:
- Resulting host file name of the screenshot.
- """
- host_file = os.path.abspath(host_file or
- 'screenshot-%s.png' % self.GetTimestamp())
- self.EnsureHostDirectory(host_file)
- device_file = '%s/screenshot.png' % self.GetExternalStorage()
- self.RunShellCommand(
- '/system/bin/screencap -p %s' % device_file)
- self.PullFileFromDevice(device_file, host_file)
- self.RunShellCommand('rm -f "%s"' % device_file)
- return host_file
-
- def PullFileFromDevice(self, device_file, host_file):
- """Download |device_file| on the device from to |host_file| on the host.
-
- Args:
- device_file: Absolute path to the file to retrieve from the device.
- host_file: Absolute path to the file to store on the host.
- """
- if not self._adb.Pull(device_file, host_file):
- raise device_errors.AdbCommandFailedError(
- ['pull', device_file, host_file], 'Failed to pull file from device.')
- assert os.path.exists(host_file)
-
- def SetUtilWrapper(self, util_wrapper):
- """Sets a wrapper prefix to be used when running a locally-built
- binary on the device (ex.: md5sum_bin).
- """
- self._util_wrapper = util_wrapper
-
- def RunUIAutomatorTest(self, test, test_package, timeout):
- """Runs a single uiautomator test.
-
- Args:
- test: Test class/method.
- test_package: Name of the test jar.
- timeout: Timeout time in seconds.
-
- Returns:
- An instance of am_instrument_parser.TestResult object.
- """
- cmd = 'uiautomator runtest %s -e class %s' % (test_package, test)
- self._LogShell(cmd)
- output = self._adb.SendShellCommand(cmd, timeout_time=timeout)
- # uiautomator doesn't fully conform to the instrumenation test runner
- # convention and doesn't terminate with INSTRUMENTATION_CODE.
- # Just assume the first result is valid.
- (test_results, _) = am_instrument_parser.ParseAmInstrumentOutput(output)
- if not test_results:
- raise errors.InstrumentationError(
- 'no test results... device setup correctly?')
- return test_results[0]
-
- def DismissCrashDialogIfNeeded(self):
- """Dismiss the error/ANR dialog if present.
-
- Returns: Name of the crashed package if a dialog is focused,
- None otherwise.
- """
- re_focus = re.compile(
- r'\s*mCurrentFocus.*Application (Error|Not Responding): (\S+)}')
-
- def _FindFocusedWindow():
- match = None
- for line in self.RunShellCommand('dumpsys window windows'):
- match = re.match(re_focus, line)
- if match:
- break
- return match
-
- match = _FindFocusedWindow()
- if not match:
- return
- package = match.group(2)
- logging.warning('Trying to dismiss %s dialog for %s' % match.groups())
- self.SendKeyEvent(KEYCODE_DPAD_RIGHT)
- self.SendKeyEvent(KEYCODE_DPAD_RIGHT)
- self.SendKeyEvent(KEYCODE_ENTER)
- match = _FindFocusedWindow()
- if match:
- logging.error('Still showing a %s dialog for %s' % match.groups())
- return package
-
- def EfficientDeviceDirectoryCopy(self, source, dest):
- """ Copy a directory efficiently on the device
-
- Uses a shell script running on the target to copy new and changed files the
- source directory to the destination directory and remove added files. This
- is in some cases much faster than cp -r.
-
- Args:
- source: absolute path of source directory
- dest: absolute path of destination directory
- """
- logging.info('In EfficientDeviceDirectoryCopy %s %s', source, dest)
- with DeviceTempFile(self, suffix=".sh") as temp_script_file:
- host_script_path = os.path.join(constants.DIR_SOURCE_ROOT,
- 'build',
- 'android',
- 'pylib',
- 'efficient_android_directory_copy.sh')
- self._adb.Push(host_script_path, temp_script_file.name)
- out = self.RunShellCommand(
- 'sh %s %s %s' % (temp_script_file.name, source, dest),
- timeout_time=120)
- if self._device:
- device_repr = self._device[-4:]
- else:
- device_repr = '????'
- for line in out:
- logging.info('[%s]> %s', device_repr, line)
-
- def _GetControlUsbChargingCommand(self):
- if self._control_usb_charging_command['cached']:
- return self._control_usb_charging_command['command']
- self._control_usb_charging_command['cached'] = True
- if not self.IsRootEnabled():
- return None
- for command in CONTROL_USB_CHARGING_COMMANDS:
- # Assert command is valid.
- assert 'disable_command' in command
- assert 'enable_command' in command
- assert 'witness_file' in command
- witness_file = command['witness_file']
- if self.FileExistsOnDevice(witness_file):
- self._control_usb_charging_command['command'] = command
- return command
- return None
-
- def CanControlUsbCharging(self):
- return self._GetControlUsbChargingCommand() is not None
-
- def DisableUsbCharging(self, timeout=10):
- command = self._GetControlUsbChargingCommand()
- if not command:
- raise Exception('Unable to act on usb charging.')
- disable_command = command['disable_command']
- t0 = time.time()
- # Do not loop directly on self.IsDeviceCharging to cut the number of calls
- # to the device.
- while True:
- if t0 + timeout - time.time() < 0:
- raise pexpect.TIMEOUT('Unable to disable USB charging in time: %s' % (
- self.GetBatteryInfo()))
- self.RunShellCommand(disable_command)
- if not self.IsDeviceCharging():
- break
-
- def EnableUsbCharging(self, timeout=10):
- command = self._GetControlUsbChargingCommand()
- if not command:
- raise Exception('Unable to act on usb charging.')
- disable_command = command['enable_command']
- t0 = time.time()
- # Do not loop directly on self.IsDeviceCharging to cut the number of calls
- # to the device.
- while True:
- if t0 + timeout - time.time() < 0:
- raise pexpect.TIMEOUT('Unable to enable USB charging in time.')
- self.RunShellCommand(disable_command)
- if self.IsDeviceCharging():
- break
-
- def IsDeviceCharging(self):
- for line in self.RunShellCommand('dumpsys battery'):
- if 'powered: ' in line:
- if line.split('powered: ')[1] == 'true':
- return True
-
-
-class NewLineNormalizer(object):
- """A file-like object to normalize EOLs to '\n'.
-
- Pexpect runs adb within a pseudo-tty device (see
- http://www.noah.org/wiki/pexpect), so any '\n' printed by adb is written
- as '\r\n' to the logfile. Since adb already uses '\r\n' to terminate
- lines, the log ends up having '\r\r\n' at the end of each line. This
- filter replaces the above with a single '\n' in the data stream.
- """
- def __init__(self, output):
- self._output = output
-
- def write(self, data):
- data = data.replace('\r\r\n', '\n')
- self._output.write(data)
-
- def flush(self):
- self._output.flush()
diff --git a/build/android/pylib/android_commands_unittest.py b/build/android/pylib/android_commands_unittest.py
deleted file mode 100644
index 21c34f9..0000000
--- a/build/android/pylib/android_commands_unittest.py
+++ /dev/null
@@ -1,191 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import shutil
-import sys
-import unittest
-
-sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir))
-
-from pylib import android_commands
-
-# pylint: disable=W0212,W0702
-
-class TestDeviceTempFile(unittest.TestCase):
- def setUp(self):
- if not os.getenv('BUILDTYPE'):
- os.environ['BUILDTYPE'] = 'Debug'
-
- devices = android_commands.GetAttachedDevices()
- self.assertGreater(len(devices), 0, 'No device attached!')
- self.ac = android_commands.AndroidCommands(device=devices[0])
-
- def testTempFileDeleted(self):
- """Tests that DeviceTempFile deletes files when closed."""
- temp_file = android_commands.DeviceTempFile(self.ac)
- self.assertFalse(self.ac.FileExistsOnDevice(temp_file.name))
- self.ac.SetFileContents(temp_file.name, "contents")
- self.assertTrue(self.ac.FileExistsOnDevice(temp_file.name))
- temp_file.close()
- self.assertFalse(self.ac.FileExistsOnDevice(temp_file.name))
-
- with android_commands.DeviceTempFile(self.ac) as with_temp_file:
- self.assertFalse(self.ac.FileExistsOnDevice(with_temp_file.name))
- self.ac.SetFileContents(with_temp_file.name, "contents")
- self.assertTrue(self.ac.FileExistsOnDevice(with_temp_file.name))
-
- self.assertFalse(self.ac.FileExistsOnDevice(with_temp_file.name))
-
- def testTempFileNotWritten(self):
- """Tests that device temp files work successfully even if not written to."""
- temp_file = android_commands.DeviceTempFile(self.ac)
- temp_file.close()
- self.assertFalse(self.ac.FileExistsOnDevice(temp_file.name))
-
- with android_commands.DeviceTempFile(self.ac) as with_temp_file:
- pass
- self.assertFalse(self.ac.FileExistsOnDevice(with_temp_file.name))
-
- def testNaming(self):
- """Tests that returned filenames are as requested."""
- temp_file = android_commands.DeviceTempFile(self.ac, prefix="cat")
- self.assertTrue(os.path.basename(temp_file.name).startswith("cat"))
-
- temp_file = android_commands.DeviceTempFile(self.ac, suffix="dog")
- self.assertTrue(temp_file.name.endswith("dog"))
-
- temp_file = android_commands.DeviceTempFile(
- self.ac, prefix="cat", suffix="dog")
- self.assertTrue(os.path.basename(temp_file.name).startswith("cat"))
- self.assertTrue(temp_file.name.endswith("dog"))
-
-
-class TestGetFilesChanged(unittest.TestCase):
-
- def setUp(self):
- if not os.getenv('BUILDTYPE'):
- os.environ['BUILDTYPE'] = 'Debug'
-
- devices = android_commands.GetAttachedDevices()
- self.assertGreater(len(devices), 0, 'No device attached!')
- self.ac = android_commands.AndroidCommands(device=devices[0])
- self.host_data_dir = os.path.realpath('test_push_data')
- self.device_data_dir = '%s/test_push_data' % (
- self.ac.RunShellCommand('realpath %s' %
- self.ac.GetExternalStorage())[0])
-
- os.mkdir(self.host_data_dir)
- for i in xrange(1, 10):
- with open('%s/%d.txt' % (self.host_data_dir, i), 'w') as f:
- f.write('file #%d' % i)
-
- self.ac.RunShellCommand('mkdir %s' % self.device_data_dir)
-
- def testGetFilesChangedAllNeeded(self):
- """ Tests GetFilesChanged when none of the files are on the device.
- """
- expected = [('%s/%d.txt' % (self.host_data_dir, i),
- '%s/%d.txt' % (self.device_data_dir, i))
- for i in xrange(1, 10)]
- actual = self.ac.GetFilesChanged(self.host_data_dir, self.device_data_dir)
- self.assertSequenceEqual(expected, actual)
-
- def testGetFilesChangedSomeIdentical(self):
- """ Tests GetFilesChanged when some of the files are on the device.
- """
- for i in xrange(1, 5):
- self.ac._adb.Push('%s/%d.txt' % (self.host_data_dir, i),
- self.device_data_dir)
- expected = [('%s/%d.txt' % (self.host_data_dir, i),
- '%s/%d.txt' % (self.device_data_dir, i))
- for i in xrange(5, 10)]
- actual = self.ac.GetFilesChanged(self.host_data_dir, self.device_data_dir)
- self.assertSequenceEqual(expected, actual)
-
- def testGetFilesChangedAllIdentical(self):
- """ Tests GetFilesChanged when all of the files are on the device.
- """
- for i in xrange(1, 10):
- self.ac._adb.Push('%s/%d.txt' % (self.host_data_dir, i),
- self.device_data_dir)
- expected = []
- actual = self.ac.GetFilesChanged(self.host_data_dir, self.device_data_dir)
- self.assertSequenceEqual(expected, actual)
-
- def testGetFilesChangedRename(self):
- """ Tests GetFilesChanged when one of the files has been renamed.
-
- This tests both with and without the ignore_filenames flag set.
- """
- for i in xrange(5, 10):
- self.ac._adb.Push('%s/%d.txt' % (self.host_data_dir, i),
- self.device_data_dir)
- os.rename('%s/5.txt' % (self.host_data_dir),
- '%s/99.txt' % (self.host_data_dir))
-
- expected = [('%s/%d.txt' % (self.host_data_dir, i),
- '%s/%d.txt' % (self.device_data_dir, i))
- for i in xrange(1, 5)]
- actual = self.ac.GetFilesChanged(self.host_data_dir, self.device_data_dir,
- ignore_filenames=True)
- self.assertSequenceEqual(expected, actual)
-
- expected.append(('%s/99.txt' % self.host_data_dir,
- '%s/99.txt' % self.device_data_dir))
- actual = self.ac.GetFilesChanged(self.host_data_dir, self.device_data_dir)
- self.assertSequenceEqual(expected, actual)
-
- def testGetFilesChangedCopy(self):
- """ Tests GetFilesChanged when one of the files has been copied.
-
- This tests both with and without the ignore_filenames flag set.
- """
- for i in xrange(5, 10):
- self.ac._adb.Push('%s/%d.txt' % (self.host_data_dir, i),
- self.device_data_dir)
- shutil.copy('%s/5.txt' % self.host_data_dir,
- '%s/99.txt' % self.host_data_dir)
-
- expected = [('%s/%d.txt' % (self.host_data_dir, i),
- '%s/%d.txt' % (self.device_data_dir, i))
- for i in xrange(1, 5)]
- actual = self.ac.GetFilesChanged(self.host_data_dir, self.device_data_dir,
- ignore_filenames=True)
- self.assertSequenceEqual(expected, actual)
-
- expected.append(('%s/99.txt' % self.host_data_dir,
- '%s/99.txt' % self.device_data_dir))
- actual = self.ac.GetFilesChanged(self.host_data_dir, self.device_data_dir)
- self.assertSequenceEqual(expected, actual)
-
- def testGetFilesChangedIndividual(self):
- """ Tests GetFilesChanged when provided one file.
- """
- expected = [('%s/1.txt' % self.host_data_dir,
- '%s/1.txt' % self.device_data_dir)]
- actual = self.ac.GetFilesChanged('%s/1.txt' % self.host_data_dir,
- '%s/1.txt' % self.device_data_dir)
- self.assertSequenceEqual(expected, actual)
-
- def testGetFilesChangedFileToDirectory(self):
- """ Tests GetFilesChanged when provided a file from the host and a
- directory on the device.
- """
- expected = [('%s/1.txt' % self.host_data_dir,
- '%s' % self.device_data_dir)]
- actual = self.ac.GetFilesChanged('%s/1.txt' % self.host_data_dir,
- '%s' % self.device_data_dir)
- self.assertSequenceEqual(expected, actual)
-
- def tearDown(self):
- try:
- shutil.rmtree(self.host_data_dir)
- self.ac.RunShellCommand('rm -rf %s' % self.device_data_dir)
- except:
- pass
-
-if __name__ == '__main__':
- unittest.main()
-
diff --git a/build/android/pylib/base/__init__.py b/build/android/pylib/base/__init__.py
deleted file mode 100644
index 727e987..0000000
--- a/build/android/pylib/base/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
diff --git a/build/android/pylib/base/base_setup.py b/build/android/pylib/base/base_setup.py
deleted file mode 100644
index a416380..0000000
--- a/build/android/pylib/base/base_setup.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# Copyright (c) 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Base script for doing test setup."""
-
-import logging
-import os
-
-from pylib import constants
-from pylib import valgrind_tools
-from pylib.utils import isolator
-
-def GenerateDepsDirUsingIsolate(suite_name, isolate_file_path,
- isolate_file_paths, deps_exclusion_list):
- """Generate the dependency dir for the test suite using isolate.
-
- Args:
- suite_name: Name of the test suite (e.g. base_unittests).
- isolate_file_path: .isolate file path to use. If there is a default .isolate
- file path for the suite_name, this will override it.
- isolate_file_paths: Dictionary with the default .isolate file paths for
- the test suites.
- deps_exclusion_list: A list of files that are listed as dependencies in the
- .isolate files but should not be pushed to the device.
- Returns:
- The Isolator instance used to remap the dependencies, or None.
- """
- if isolate_file_path:
- if os.path.isabs(isolate_file_path):
- isolate_abs_path = isolate_file_path
- else:
- isolate_abs_path = os.path.join(constants.DIR_SOURCE_ROOT,
- isolate_file_path)
- else:
- isolate_rel_path = isolate_file_paths.get(suite_name)
- if not isolate_rel_path:
- logging.info('Did not find an isolate file for the test suite.')
- return
- isolate_abs_path = os.path.join(constants.DIR_SOURCE_ROOT, isolate_rel_path)
-
- isolated_abs_path = os.path.join(
- constants.GetOutDirectory(), '%s.isolated' % suite_name)
- assert os.path.exists(isolate_abs_path), 'Cannot find %s' % isolate_abs_path
-
- i = isolator.Isolator(constants.ISOLATE_DEPS_DIR)
- i.Clear()
- i.Remap(isolate_abs_path, isolated_abs_path)
- # We're relying on the fact that timestamps are preserved
- # by the remap command (hardlinked). Otherwise, all the data
- # will be pushed to the device once we move to using time diff
- # instead of md5sum. Perform a sanity check here.
- i.VerifyHardlinks()
- i.PurgeExcluded(deps_exclusion_list)
- i.MoveOutputDeps()
- return i
-
-
-def PushDataDeps(device, device_dir, test_options):
- valgrind_tools.PushFilesForTool(test_options.tool, device)
- if os.path.exists(constants.ISOLATE_DEPS_DIR):
- device.PushChangedFiles([(constants.ISOLATE_DEPS_DIR, device_dir)],
- delete_device_stale=test_options.delete_stale_data)
diff --git a/build/android/pylib/base/base_test_result.py b/build/android/pylib/base/base_test_result.py
deleted file mode 100644
index 58200f6..0000000
--- a/build/android/pylib/base/base_test_result.py
+++ /dev/null
@@ -1,216 +0,0 @@
-# Copyright (c) 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Module containing base test results classes."""
-
-class ResultType(object):
- """Class enumerating test types."""
- PASS = 'PASS'
- SKIP = 'SKIP'
- FAIL = 'FAIL'
- CRASH = 'CRASH'
- TIMEOUT = 'TIMEOUT'
- UNKNOWN = 'UNKNOWN'
-
- @staticmethod
- def GetTypes():
- """Get a list of all test types."""
- return [ResultType.PASS, ResultType.SKIP, ResultType.FAIL,
- ResultType.CRASH, ResultType.TIMEOUT, ResultType.UNKNOWN]
-
-
-class BaseTestResult(object):
- """Base class for a single test result."""
-
- def __init__(self, name, test_type, duration=0, log=''):
- """Construct a BaseTestResult.
-
- Args:
- name: Name of the test which defines uniqueness.
- test_type: Type of the test result as defined in ResultType.
- duration: Time it took for the test to run in milliseconds.
- log: An optional string listing any errors.
- """
- assert name
- assert test_type in ResultType.GetTypes()
- self._name = name
- self._test_type = test_type
- self._duration = duration
- self._log = log
-
- def __str__(self):
- return self._name
-
- def __repr__(self):
- return self._name
-
- def __cmp__(self, other):
- # pylint: disable=W0212
- return cmp(self._name, other._name)
-
- def __hash__(self):
- return hash(self._name)
-
- def SetName(self, name):
- """Set the test name.
-
- Because we're putting this into a set, this should only be used if moving
- this test result into another set.
- """
- self._name = name
-
- def GetName(self):
- """Get the test name."""
- return self._name
-
- def SetType(self, test_type):
- """Set the test result type."""
- assert test_type in ResultType.GetTypes()
- self._test_type = test_type
-
- def GetType(self):
- """Get the test result type."""
- return self._test_type
-
- def GetDuration(self):
- """Get the test duration."""
- return self._duration
-
- def SetLog(self, log):
- """Set the test log."""
- self._log = log
-
- def GetLog(self):
- """Get the test log."""
- return self._log
-
-
-class TestRunResults(object):
- """Set of results for a test run."""
-
- def __init__(self):
- self._results = set()
-
- def GetLogs(self):
- """Get the string representation of all test logs."""
- s = []
- for test_type in ResultType.GetTypes():
- if test_type != ResultType.PASS:
- for t in sorted(self._GetType(test_type)):
- log = t.GetLog()
- if log:
- s.append('[%s] %s:' % (test_type, t))
- s.append(log)
- return '\n'.join(s)
-
- def GetGtestForm(self):
- """Get the gtest string representation of this object."""
- s = []
- plural = lambda n, s, p: '%d %s' % (n, p if n != 1 else s)
- tests = lambda n: plural(n, 'test', 'tests')
-
- s.append('[==========] %s ran.' % (tests(len(self.GetAll()))))
- s.append('[ PASSED ] %s.' % (tests(len(self.GetPass()))))
-
- skipped = self.GetSkip()
- if skipped:
- s.append('[ SKIPPED ] Skipped %s, listed below:' % tests(len(skipped)))
- for t in sorted(skipped):
- s.append('[ SKIPPED ] %s' % str(t))
-
- all_failures = self.GetFail().union(self.GetCrash(), self.GetTimeout(),
- self.GetUnknown())
- if all_failures:
- s.append('[ FAILED ] %s, listed below:' % tests(len(all_failures)))
- for t in sorted(self.GetFail()):
- s.append('[ FAILED ] %s' % str(t))
- for t in sorted(self.GetCrash()):
- s.append('[ FAILED ] %s (CRASHED)' % str(t))
- for t in sorted(self.GetTimeout()):
- s.append('[ FAILED ] %s (TIMEOUT)' % str(t))
- for t in sorted(self.GetUnknown()):
- s.append('[ FAILED ] %s (UNKNOWN)' % str(t))
- s.append('')
- s.append(plural(len(all_failures), 'FAILED TEST', 'FAILED TESTS'))
- return '\n'.join(s)
-
- def GetShortForm(self):
- """Get the short string representation of this object."""
- s = []
- s.append('ALL: %d' % len(self._results))
- for test_type in ResultType.GetTypes():
- s.append('%s: %d' % (test_type, len(self._GetType(test_type))))
- return ''.join([x.ljust(15) for x in s])
-
- def __str__(self):
- return self.GetLongForm()
-
- def AddResult(self, result):
- """Add |result| to the set.
-
- Args:
- result: An instance of BaseTestResult.
- """
- assert isinstance(result, BaseTestResult)
- self._results.add(result)
-
- def AddResults(self, results):
- """Add |results| to the set.
-
- Args:
- results: An iterable of BaseTestResult objects.
- """
- for t in results:
- self.AddResult(t)
-
- def AddTestRunResults(self, results):
- """Add the set of test results from |results|.
-
- Args:
- results: An instance of TestRunResults.
- """
- assert isinstance(results, TestRunResults)
- # pylint: disable=W0212
- self._results.update(results._results)
-
- def GetAll(self):
- """Get the set of all test results."""
- return self._results.copy()
-
- def _GetType(self, test_type):
- """Get the set of test results with the given test type."""
- return set(t for t in self._results if t.GetType() == test_type)
-
- def GetPass(self):
- """Get the set of all passed test results."""
- return self._GetType(ResultType.PASS)
-
- def GetSkip(self):
- """Get the set of all skipped test results."""
- return self._GetType(ResultType.SKIP)
-
- def GetFail(self):
- """Get the set of all failed test results."""
- return self._GetType(ResultType.FAIL)
-
- def GetCrash(self):
- """Get the set of all crashed test results."""
- return self._GetType(ResultType.CRASH)
-
- def GetTimeout(self):
- """Get the set of all timed out test results."""
- return self._GetType(ResultType.TIMEOUT)
-
- def GetUnknown(self):
- """Get the set of all unknown test results."""
- return self._GetType(ResultType.UNKNOWN)
-
- def GetNotPass(self):
- """Get the set of all non-passed test results."""
- return self.GetAll() - self.GetPass()
-
- def DidRunPass(self):
- """Return whether the test run was successful."""
- return not self.GetNotPass() - self.GetSkip()
-
diff --git a/build/android/pylib/base/base_test_result_unittest.py b/build/android/pylib/base/base_test_result_unittest.py
deleted file mode 100644
index 6f0cba7..0000000
--- a/build/android/pylib/base/base_test_result_unittest.py
+++ /dev/null
@@ -1,82 +0,0 @@
-# Copyright (c) 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Unittests for TestRunResults."""
-
-import unittest
-
-from pylib.base.base_test_result import BaseTestResult
-from pylib.base.base_test_result import TestRunResults
-from pylib.base.base_test_result import ResultType
-
-
-class TestTestRunResults(unittest.TestCase):
- def setUp(self):
- self.p1 = BaseTestResult('p1', ResultType.PASS, log='pass1')
- other_p1 = BaseTestResult('p1', ResultType.PASS)
- self.p2 = BaseTestResult('p2', ResultType.PASS)
- self.f1 = BaseTestResult('f1', ResultType.FAIL, log='failure1')
- self.c1 = BaseTestResult('c1', ResultType.CRASH, log='crash1')
- self.u1 = BaseTestResult('u1', ResultType.UNKNOWN)
- self.tr = TestRunResults()
- self.tr.AddResult(self.p1)
- self.tr.AddResult(other_p1)
- self.tr.AddResult(self.p2)
- self.tr.AddResults(set([self.f1, self.c1, self.u1]))
-
- def testGetAll(self):
- self.assertFalse(
- self.tr.GetAll().symmetric_difference(
- [self.p1, self.p2, self.f1, self.c1, self.u1]))
-
- def testGetPass(self):
- self.assertFalse(self.tr.GetPass().symmetric_difference(
- [self.p1, self.p2]))
-
- def testGetNotPass(self):
- self.assertFalse(self.tr.GetNotPass().symmetric_difference(
- [self.f1, self.c1, self.u1]))
-
- def testGetAddTestRunResults(self):
- tr2 = TestRunResults()
- other_p1 = BaseTestResult('p1', ResultType.PASS)
- f2 = BaseTestResult('f2', ResultType.FAIL)
- tr2.AddResult(other_p1)
- tr2.AddResult(f2)
- tr2.AddTestRunResults(self.tr)
- self.assertFalse(
- tr2.GetAll().symmetric_difference(
- [self.p1, self.p2, self.f1, self.c1, self.u1, f2]))
-
- def testGetLogs(self):
- log_print = ('[FAIL] f1:\n'
- 'failure1\n'
- '[CRASH] c1:\n'
- 'crash1')
- self.assertEqual(self.tr.GetLogs(), log_print)
-
- def testGetShortForm(self):
- short_print = ('ALL: 5 PASS: 2 FAIL: 1 '
- 'CRASH: 1 TIMEOUT: 0 UNKNOWN: 1 ')
- self.assertEqual(self.tr.GetShortForm(), short_print)
-
- def testGetGtestForm(self):
- gtest_print = ('[==========] 5 tests ran.\n'
- '[ PASSED ] 2 tests.\n'
- '[ FAILED ] 3 tests, listed below:\n'
- '[ FAILED ] f1\n'
- '[ FAILED ] c1 (CRASHED)\n'
- '[ FAILED ] u1 (UNKNOWN)\n'
- '\n'
- '3 FAILED TESTS')
- self.assertEqual(gtest_print, self.tr.GetGtestForm())
-
- def testRunPassed(self):
- self.assertFalse(self.tr.DidRunPass())
- tr2 = TestRunResults()
- self.assertTrue(tr2.DidRunPass())
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/build/android/pylib/base/base_test_runner.py b/build/android/pylib/base/base_test_runner.py
deleted file mode 100644
index 2a7fdd3..0000000
--- a/build/android/pylib/base/base_test_runner.py
+++ /dev/null
@@ -1,138 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Base class for running tests on a single device."""
-
-# TODO(jbudorick) Deprecate and remove this class and all subclasses after
-# any relevant parts have been ported to the new environment + test instance
-# model.
-
-import logging
-
-from pylib import ports
-from pylib.device import device_utils
-from pylib.forwarder import Forwarder
-from pylib.valgrind_tools import CreateTool
-# TODO(frankf): Move this to pylib/utils
-import lighttpd_server
-
-
-# A file on device to store ports of net test server. The format of the file is
-# test-spawner-server-port:test-server-port
-NET_TEST_SERVER_PORT_INFO_FILE = 'net-test-server-ports'
-
-
-class BaseTestRunner(object):
- """Base class for running tests on a single device."""
-
- def __init__(self, device, tool):
- """
- Args:
- device: An instance of DeviceUtils that the tests will run on.
- tool: Name of the Valgrind tool.
- """
- assert isinstance(device, device_utils.DeviceUtils)
- self.device = device
- self.device_serial = self.device.adb.GetDeviceSerial()
- self.tool = CreateTool(tool, self.device)
- self._http_server = None
- self._forwarder_device_port = 8000
- self.forwarder_base_url = ('http://localhost:%d' %
- self._forwarder_device_port)
- # We will allocate port for test server spawner when calling method
- # LaunchChromeTestServerSpawner and allocate port for test server when
- # starting it in TestServerThread.
- self.test_server_spawner_port = 0
- self.test_server_port = 0
-
- def _PushTestServerPortInfoToDevice(self):
- """Pushes the latest port information to device."""
- self.device.WriteFile(
- self.device.GetExternalStoragePath() + '/' +
- NET_TEST_SERVER_PORT_INFO_FILE,
- '%d:%d' % (self.test_server_spawner_port, self.test_server_port))
-
- def RunTest(self, test):
- """Runs a test. Needs to be overridden.
-
- Args:
- test: A test to run.
-
- Returns:
- Tuple containing:
- (base_test_result.TestRunResults, tests to rerun or None)
- """
- raise NotImplementedError
-
- def InstallTestPackage(self):
- """Installs the test package once before all tests are run."""
- pass
-
- def SetUp(self):
- """Run once before all tests are run."""
- self.InstallTestPackage()
-
- def TearDown(self):
- """Run once after all tests are run."""
- self.ShutdownHelperToolsForTestSuite()
-
- def LaunchTestHttpServer(self, document_root, port=None,
- extra_config_contents=None):
- """Launches an HTTP server to serve HTTP tests.
-
- Args:
- document_root: Document root of the HTTP server.
- port: port on which we want to the http server bind.
- extra_config_contents: Extra config contents for the HTTP server.
- """
- self._http_server = lighttpd_server.LighttpdServer(
- document_root, port=port, extra_config_contents=extra_config_contents)
- if self._http_server.StartupHttpServer():
- logging.info('http server started: http://localhost:%s',
- self._http_server.port)
- else:
- logging.critical('Failed to start http server')
- self._ForwardPortsForHttpServer()
- return (self._forwarder_device_port, self._http_server.port)
-
- def _ForwardPorts(self, port_pairs):
- """Forwards a port."""
- Forwarder.Map(port_pairs, self.device, self.tool)
-
- def _UnmapPorts(self, port_pairs):
- """Unmap previously forwarded ports."""
- for (device_port, _) in port_pairs:
- Forwarder.UnmapDevicePort(device_port, self.device)
-
- # Deprecated: Use ForwardPorts instead.
- def StartForwarder(self, port_pairs):
- """Starts TCP traffic forwarding for the given |port_pairs|.
-
- Args:
- host_port_pairs: A list of (device_port, local_port) tuples to forward.
- """
- self._ForwardPorts(port_pairs)
-
- def _ForwardPortsForHttpServer(self):
- """Starts a forwarder for the HTTP server.
-
- The forwarder forwards HTTP requests and responses between host and device.
- """
- self._ForwardPorts([(self._forwarder_device_port, self._http_server.port)])
-
- def _RestartHttpServerForwarderIfNecessary(self):
- """Restarts the forwarder if it's not open."""
- # Checks to see if the http server port is being used. If not forwards the
- # request.
- # TODO(dtrainor): This is not always reliable because sometimes the port
- # will be left open even after the forwarder has been killed.
- if not ports.IsDevicePortUsed(self.device, self._forwarder_device_port):
- self._ForwardPortsForHttpServer()
-
- def ShutdownHelperToolsForTestSuite(self):
- """Shuts down the server and the forwarder."""
- if self._http_server:
- self._UnmapPorts([(self._forwarder_device_port, self._http_server.port)])
- self._http_server.ShutdownHttpServer()
-
diff --git a/build/android/pylib/base/environment.py b/build/android/pylib/base/environment.py
deleted file mode 100644
index 3f49f41..0000000
--- a/build/android/pylib/base/environment.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-
-class Environment(object):
- """An environment in which tests can be run.
-
- This is expected to handle all logic that is applicable to an entire specific
- environment but is independent of the test type.
-
- Examples include:
- - The local device environment, for running tests on devices attached to
- the local machine.
- - The local machine environment, for running tests directly on the local
- machine.
- """
-
- def __init__(self):
- pass
-
- def SetUp(self):
- raise NotImplementedError
-
- def TearDown(self):
- raise NotImplementedError
-
- def __enter__(self):
- self.SetUp()
- return self
-
- def __exit__(self, _exc_type, _exc_val, _exc_tb):
- self.TearDown()
-
diff --git a/build/android/pylib/base/environment_factory.py b/build/android/pylib/base/environment_factory.py
deleted file mode 100644
index 31b4952..0000000
--- a/build/android/pylib/base/environment_factory.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from pylib import constants
-from pylib.local.device import local_device_environment
-from pylib.remote.device import remote_device_environment
-
-def CreateEnvironment(args, error_func):
-
- if args.environment == 'local':
- if args.command not in constants.LOCAL_MACHINE_TESTS:
- return local_device_environment.LocalDeviceEnvironment(args, error_func)
- # TODO(jbudorick) Add local machine environment.
- if args.environment == 'remote_device':
- return remote_device_environment.RemoteDeviceEnvironment(args,
- error_func)
- error_func('Unable to create %s environment.' % args.environment)
diff --git a/build/android/pylib/base/test_collection.py b/build/android/pylib/base/test_collection.py
deleted file mode 100644
index de51027..0000000
--- a/build/android/pylib/base/test_collection.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import threading
-
-class TestCollection(object):
- """A threadsafe collection of tests.
-
- Args:
- tests: List of tests to put in the collection.
- """
-
- def __init__(self, tests=None):
- if not tests:
- tests = []
- self._lock = threading.Lock()
- self._tests = []
- self._tests_in_progress = 0
- # Used to signal that an item is available or all items have been handled.
- self._item_available_or_all_done = threading.Event()
- for t in tests:
- self.add(t)
-
- def _pop(self):
- """Pop a test from the collection.
-
- Waits until a test is available or all tests have been handled.
-
- Returns:
- A test or None if all tests have been handled.
- """
- while True:
- # Wait for a test to be available or all tests to have been handled.
- self._item_available_or_all_done.wait()
- with self._lock:
- # Check which of the two conditions triggered the signal.
- if self._tests_in_progress == 0:
- return None
- try:
- return self._tests.pop(0)
- except IndexError:
- # Another thread beat us to the available test, wait again.
- self._item_available_or_all_done.clear()
-
- def add(self, test):
- """Add a test to the collection.
-
- Args:
- test: A test to add.
- """
- with self._lock:
- self._tests.append(test)
- self._item_available_or_all_done.set()
- self._tests_in_progress += 1
-
- def test_completed(self):
- """Indicate that a test has been fully handled."""
- with self._lock:
- self._tests_in_progress -= 1
- if self._tests_in_progress == 0:
- # All tests have been handled, signal all waiting threads.
- self._item_available_or_all_done.set()
-
- def __iter__(self):
- """Iterate through tests in the collection until all have been handled."""
- while True:
- r = self._pop()
- if r is None:
- break
- yield r
-
- def __len__(self):
- """Return the number of tests currently in the collection."""
- return len(self._tests)
-
- def test_names(self):
- """Return a list of the names of the tests currently in the collection."""
- with self._lock:
- return list(t.test for t in self._tests)
diff --git a/build/android/pylib/base/test_dispatcher.py b/build/android/pylib/base/test_dispatcher.py
deleted file mode 100644
index f919965..0000000
--- a/build/android/pylib/base/test_dispatcher.py
+++ /dev/null
@@ -1,332 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Dispatches tests, either sharding or replicating them.
-
-Performs the following steps:
-* Create a test collection factory, using the given tests
- - If sharding: test collection factory returns the same shared test collection
- to all test runners
- - If replciating: test collection factory returns a unique test collection to
- each test runner, with the same set of tests in each.
-* Create a test runner for each device.
-* Run each test runner in its own thread, grabbing tests from the test
- collection until there are no tests left.
-"""
-
-# TODO(jbudorick) Deprecate and remove this class after any relevant parts have
-# been ported to the new environment / test instance model.
-
-import logging
-import threading
-
-from pylib import constants
-from pylib.base import base_test_result
-from pylib.base import test_collection
-from pylib.device import device_errors
-from pylib.utils import reraiser_thread
-from pylib.utils import watchdog_timer
-
-
-DEFAULT_TIMEOUT = 7 * 60 # seven minutes
-
-
-class _ThreadSafeCounter(object):
- """A threadsafe counter."""
-
- def __init__(self):
- self._lock = threading.Lock()
- self._value = 0
-
- def GetAndIncrement(self):
- """Get the current value and increment it atomically.
-
- Returns:
- The value before incrementing.
- """
- with self._lock:
- pre_increment = self._value
- self._value += 1
- return pre_increment
-
-
-class _Test(object):
- """Holds a test with additional metadata."""
-
- def __init__(self, test, tries=0):
- """Initializes the _Test object.
-
- Args:
- test: The test.
- tries: Number of tries so far.
- """
- self.test = test
- self.tries = tries
-
-
-def _RunTestsFromQueue(runner, collection, out_results, watcher,
- num_retries, tag_results_with_device=False):
- """Runs tests from the collection until empty using the given runner.
-
- Adds TestRunResults objects to the out_results list and may add tests to the
- out_retry list.
-
- Args:
- runner: A TestRunner object used to run the tests.
- collection: A TestCollection from which to get _Test objects to run.
- out_results: A list to add TestRunResults to.
- watcher: A watchdog_timer.WatchdogTimer object, used as a shared timeout.
- num_retries: Number of retries for a test.
- tag_results_with_device: If True, appends the name of the device on which
- the test was run to the test name. Used when replicating to identify
- which device ran each copy of the test, and to ensure each copy of the
- test is recorded separately.
- """
-
- def TagTestRunResults(test_run_results):
- """Tags all results with the last 4 digits of the device id.
-
- Used when replicating tests to distinguish the same tests run on different
- devices. We use a set to store test results, so the hash (generated from
- name and tag) must be unique to be considered different results.
- """
- new_test_run_results = base_test_result.TestRunResults()
- for test_result in test_run_results.GetAll():
- test_result.SetName('%s_%s' % (runner.device_serial[-4:],
- test_result.GetName()))
- new_test_run_results.AddResult(test_result)
- return new_test_run_results
-
- for test in collection:
- watcher.Reset()
- try:
- if not runner.device.IsOnline():
- # Device is unresponsive, stop handling tests on this device.
- msg = 'Device %s is unresponsive.' % runner.device_serial
- logging.warning(msg)
- raise device_errors.DeviceUnreachableError(msg)
- result, retry = runner.RunTest(test.test)
- if tag_results_with_device:
- result = TagTestRunResults(result)
- test.tries += 1
- if retry and test.tries <= num_retries:
- # Retry non-passing results, only record passing results.
- pass_results = base_test_result.TestRunResults()
- pass_results.AddResults(result.GetPass())
- out_results.append(pass_results)
- logging.warning('Will retry test %s, try #%s.', retry, test.tries)
- collection.add(_Test(test=retry, tries=test.tries))
- else:
- # All tests passed or retry limit reached. Either way, record results.
- out_results.append(result)
- except:
- # An unhandleable exception, ensure tests get run by another device and
- # reraise this exception on the main thread.
- collection.add(test)
- raise
- finally:
- # Retries count as separate tasks so always mark the popped test as done.
- collection.test_completed()
-
-
-def _SetUp(runner_factory, device, out_runners, threadsafe_counter):
- """Creates a test runner for each device and calls SetUp() in parallel.
-
- Note: if a device is unresponsive the corresponding TestRunner will not be
- added to out_runners.
-
- Args:
- runner_factory: Callable that takes a device and index and returns a
- TestRunner object.
- device: The device serial number to set up.
- out_runners: List to add the successfully set up TestRunner object.
- threadsafe_counter: A _ThreadSafeCounter object used to get shard indices.
- """
- try:
- index = threadsafe_counter.GetAndIncrement()
- logging.warning('Creating shard %s for device %s.', index, device)
- runner = runner_factory(device, index)
- runner.SetUp()
- out_runners.append(runner)
- except device_errors.DeviceUnreachableError as e:
- logging.warning('Failed to create shard for %s: [%s]', device, e)
-
-
-def _RunAllTests(runners, test_collection_factory, num_retries, timeout=None,
- tag_results_with_device=False):
- """Run all tests using the given TestRunners.
-
- Args:
- runners: A list of TestRunner objects.
- test_collection_factory: A callable to generate a TestCollection object for
- each test runner.
- num_retries: Number of retries for a test.
- timeout: Watchdog timeout in seconds.
- tag_results_with_device: If True, appends the name of the device on which
- the test was run to the test name. Used when replicating to identify
- which device ran each copy of the test, and to ensure each copy of the
- test is recorded separately.
-
- Returns:
- A tuple of (TestRunResults object, exit code)
- """
- logging.warning('Running tests with %s test runners.' % (len(runners)))
- results = []
- exit_code = 0
- run_results = base_test_result.TestRunResults()
- watcher = watchdog_timer.WatchdogTimer(timeout)
- test_collections = [test_collection_factory() for _ in runners]
-
- threads = [
- reraiser_thread.ReraiserThread(
- _RunTestsFromQueue,
- [r, tc, results, watcher, num_retries, tag_results_with_device],
- name=r.device_serial[-4:])
- for r, tc in zip(runners, test_collections)]
-
- workers = reraiser_thread.ReraiserThreadGroup(threads)
- workers.StartAll()
-
- # Catch DeviceUnreachableErrors and set a warning exit code
- try:
- workers.JoinAll(watcher)
- except device_errors.DeviceUnreachableError as e:
- logging.error(e)
-
- if not all((len(tc) == 0 for tc in test_collections)):
- logging.error('Only ran %d tests (all devices are likely offline).' %
- len(results))
- for tc in test_collections:
- run_results.AddResults(base_test_result.BaseTestResult(
- t, base_test_result.ResultType.UNKNOWN) for t in tc.test_names())
-
- for r in results:
- run_results.AddTestRunResults(r)
- if not run_results.DidRunPass():
- exit_code = constants.ERROR_EXIT_CODE
- return (run_results, exit_code)
-
-
-def _CreateRunners(runner_factory, devices, timeout=None):
- """Creates a test runner for each device and calls SetUp() in parallel.
-
- Note: if a device is unresponsive the corresponding TestRunner will not be
- included in the returned list.
-
- Args:
- runner_factory: Callable that takes a device and index and returns a
- TestRunner object.
- devices: List of device serial numbers as strings.
- timeout: Watchdog timeout in seconds, defaults to the default timeout.
-
- Returns:
- A list of TestRunner objects.
- """
- logging.warning('Creating %s test runners.' % len(devices))
- runners = []
- counter = _ThreadSafeCounter()
- threads = reraiser_thread.ReraiserThreadGroup(
- [reraiser_thread.ReraiserThread(_SetUp,
- [runner_factory, d, runners, counter],
- name=str(d)[-4:])
- for d in devices])
- threads.StartAll()
- threads.JoinAll(watchdog_timer.WatchdogTimer(timeout))
- return runners
-
-
-def _TearDownRunners(runners, timeout=None):
- """Calls TearDown() for each test runner in parallel.
-
- Args:
- runners: A list of TestRunner objects.
- timeout: Watchdog timeout in seconds, defaults to the default timeout.
- """
- threads = reraiser_thread.ReraiserThreadGroup(
- [reraiser_thread.ReraiserThread(r.TearDown, name=r.device_serial[-4:])
- for r in runners])
- threads.StartAll()
- threads.JoinAll(watchdog_timer.WatchdogTimer(timeout))
-
-
-def ApplyMaxPerRun(tests, max_per_run):
- """Rearrange the tests so that no group contains more than max_per_run tests.
-
- Args:
- tests:
- max_per_run:
-
- Returns:
- A list of tests with no more than max_per_run per run.
- """
- tests_expanded = []
- for test_group in tests:
- if type(test_group) != str:
- # Do not split test objects which are not strings.
- tests_expanded.append(test_group)
- else:
- test_split = test_group.split(':')
- for i in range(0, len(test_split), max_per_run):
- tests_expanded.append(':'.join(test_split[i:i+max_per_run]))
- return tests_expanded
-
-
-def RunTests(tests, runner_factory, devices, shard=True,
- test_timeout=DEFAULT_TIMEOUT, setup_timeout=DEFAULT_TIMEOUT,
- num_retries=2, max_per_run=256):
- """Run all tests on attached devices, retrying tests that don't pass.
-
- Args:
- tests: List of tests to run.
- runner_factory: Callable that takes a device and index and returns a
- TestRunner object.
- devices: List of attached devices.
- shard: True if we should shard, False if we should replicate tests.
- - Sharding tests will distribute tests across all test runners through a
- shared test collection.
- - Replicating tests will copy all tests to each test runner through a
- unique test collection for each test runner.
- test_timeout: Watchdog timeout in seconds for running tests.
- setup_timeout: Watchdog timeout in seconds for creating and cleaning up
- test runners.
- num_retries: Number of retries for a test.
- max_per_run: Maximum number of tests to run in any group.
-
- Returns:
- A tuple of (base_test_result.TestRunResults object, exit code).
- """
- if not tests:
- logging.critical('No tests to run.')
- return (base_test_result.TestRunResults(), constants.ERROR_EXIT_CODE)
-
- tests_expanded = ApplyMaxPerRun(tests, max_per_run)
- if shard:
- # Generate a shared TestCollection object for all test runners, so they
- # draw from a common pool of tests.
- shared_test_collection = test_collection.TestCollection(
- [_Test(t) for t in tests_expanded])
- test_collection_factory = lambda: shared_test_collection
- tag_results_with_device = False
- log_string = 'sharded across devices'
- else:
- # Generate a unique TestCollection object for each test runner, but use
- # the same set of tests.
- test_collection_factory = lambda: test_collection.TestCollection(
- [_Test(t) for t in tests_expanded])
- tag_results_with_device = True
- log_string = 'replicated on each device'
-
- logging.info('Will run %d tests (%s): %s',
- len(tests_expanded), log_string, str(tests_expanded))
- runners = _CreateRunners(runner_factory, devices, setup_timeout)
- try:
- return _RunAllTests(runners, test_collection_factory,
- num_retries, test_timeout, tag_results_with_device)
- finally:
- try:
- _TearDownRunners(runners, setup_timeout)
- except device_errors.DeviceUnreachableError as e:
- logging.warning('Device unresponsive during TearDown: [%s]', e)
- except Exception as e:
- logging.error('Unexpected exception caught during TearDown: %s' % str(e))
diff --git a/build/android/pylib/base/test_dispatcher_unittest.py b/build/android/pylib/base/test_dispatcher_unittest.py
deleted file mode 100755
index cace9a6..0000000
--- a/build/android/pylib/base/test_dispatcher_unittest.py
+++ /dev/null
@@ -1,241 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Unittests for test_dispatcher.py."""
-# pylint: disable=R0201
-# pylint: disable=W0212
-
-import os
-import sys
-import unittest
-
-
-from pylib import constants
-from pylib.base import base_test_result
-from pylib.base import test_collection
-from pylib.base import test_dispatcher
-from pylib.device import adb_wrapper
-from pylib.device import device_utils
-from pylib.utils import watchdog_timer
-
-sys.path.append(
- os.path.join(constants.DIR_SOURCE_ROOT, 'third_party', 'pymock'))
-import mock
-
-
-class TestException(Exception):
- pass
-
-
-def _MockDevice(serial):
- d = mock.MagicMock(spec=device_utils.DeviceUtils)
- d.__str__.return_value = serial
- d.adb = mock.MagicMock(spec=adb_wrapper.AdbWrapper)
- d.adb.GetDeviceSerial = mock.MagicMock(return_value=serial)
- d.IsOnline = mock.MagicMock(return_value=True)
- return d
-
-
-class MockRunner(object):
- """A mock TestRunner."""
- def __init__(self, device=None, shard_index=0):
- self.device = device or _MockDevice('0')
- self.device_serial = self.device.adb.GetDeviceSerial()
- self.shard_index = shard_index
- self.setups = 0
- self.teardowns = 0
-
- def RunTest(self, test):
- results = base_test_result.TestRunResults()
- results.AddResult(
- base_test_result.BaseTestResult(test, base_test_result.ResultType.PASS))
- return (results, None)
-
- def SetUp(self):
- self.setups += 1
-
- def TearDown(self):
- self.teardowns += 1
-
-
-class MockRunnerFail(MockRunner):
- def RunTest(self, test):
- results = base_test_result.TestRunResults()
- results.AddResult(
- base_test_result.BaseTestResult(test, base_test_result.ResultType.FAIL))
- return (results, test)
-
-
-class MockRunnerFailTwice(MockRunner):
- def __init__(self, device=None, shard_index=0):
- super(MockRunnerFailTwice, self).__init__(device, shard_index)
- self._fails = 0
-
- def RunTest(self, test):
- self._fails += 1
- results = base_test_result.TestRunResults()
- if self._fails <= 2:
- results.AddResult(base_test_result.BaseTestResult(
- test, base_test_result.ResultType.FAIL))
- return (results, test)
- else:
- results.AddResult(base_test_result.BaseTestResult(
- test, base_test_result.ResultType.PASS))
- return (results, None)
-
-
-class MockRunnerException(MockRunner):
- def RunTest(self, test):
- raise TestException
-
-
-class TestFunctions(unittest.TestCase):
- """Tests test_dispatcher._RunTestsFromQueue."""
- @staticmethod
- def _RunTests(mock_runner, tests):
- results = []
- tests = test_collection.TestCollection(
- [test_dispatcher._Test(t) for t in tests])
- test_dispatcher._RunTestsFromQueue(mock_runner, tests, results,
- watchdog_timer.WatchdogTimer(None), 2)
- run_results = base_test_result.TestRunResults()
- for r in results:
- run_results.AddTestRunResults(r)
- return run_results
-
- def testRunTestsFromQueue(self):
- results = TestFunctions._RunTests(MockRunner(), ['a', 'b'])
- self.assertEqual(len(results.GetPass()), 2)
- self.assertEqual(len(results.GetNotPass()), 0)
-
- def testRunTestsFromQueueRetry(self):
- results = TestFunctions._RunTests(MockRunnerFail(), ['a', 'b'])
- self.assertEqual(len(results.GetPass()), 0)
- self.assertEqual(len(results.GetFail()), 2)
-
- def testRunTestsFromQueueFailTwice(self):
- results = TestFunctions._RunTests(MockRunnerFailTwice(), ['a', 'b'])
- self.assertEqual(len(results.GetPass()), 2)
- self.assertEqual(len(results.GetNotPass()), 0)
-
- def testSetUp(self):
- runners = []
- counter = test_dispatcher._ThreadSafeCounter()
- test_dispatcher._SetUp(MockRunner, _MockDevice('0'), runners, counter)
- self.assertEqual(len(runners), 1)
- self.assertEqual(runners[0].setups, 1)
-
- def testThreadSafeCounter(self):
- counter = test_dispatcher._ThreadSafeCounter()
- for i in xrange(5):
- self.assertEqual(counter.GetAndIncrement(), i)
-
- def testApplyMaxPerRun(self):
- self.assertEqual(
- ['A:B', 'C:D', 'E', 'F:G', 'H:I'],
- test_dispatcher.ApplyMaxPerRun(['A:B', 'C:D:E', 'F:G:H:I'], 2))
-
-
-class TestThreadGroupFunctions(unittest.TestCase):
- """Tests test_dispatcher._RunAllTests and test_dispatcher._CreateRunners."""
- def setUp(self):
- self.tests = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
- shared_test_collection = test_collection.TestCollection(
- [test_dispatcher._Test(t) for t in self.tests])
- self.test_collection_factory = lambda: shared_test_collection
-
- def testCreate(self):
- runners = test_dispatcher._CreateRunners(
- MockRunner, [_MockDevice('0'), _MockDevice('1')])
- for runner in runners:
- self.assertEqual(runner.setups, 1)
- self.assertEqual(set([r.device_serial for r in runners]),
- set(['0', '1']))
- self.assertEqual(set([r.shard_index for r in runners]),
- set([0, 1]))
-
- def testRun(self):
- runners = [MockRunner(_MockDevice('0')), MockRunner(_MockDevice('1'))]
- results, exit_code = test_dispatcher._RunAllTests(
- runners, self.test_collection_factory, 0)
- self.assertEqual(len(results.GetPass()), len(self.tests))
- self.assertEqual(exit_code, 0)
-
- def testTearDown(self):
- runners = [MockRunner(_MockDevice('0')), MockRunner(_MockDevice('1'))]
- test_dispatcher._TearDownRunners(runners)
- for runner in runners:
- self.assertEqual(runner.teardowns, 1)
-
- def testRetry(self):
- runners = test_dispatcher._CreateRunners(
- MockRunnerFail, [_MockDevice('0'), _MockDevice('1')])
- results, exit_code = test_dispatcher._RunAllTests(
- runners, self.test_collection_factory, 0)
- self.assertEqual(len(results.GetFail()), len(self.tests))
- self.assertEqual(exit_code, constants.ERROR_EXIT_CODE)
-
- def testReraise(self):
- runners = test_dispatcher._CreateRunners(
- MockRunnerException, [_MockDevice('0'), _MockDevice('1')])
- with self.assertRaises(TestException):
- test_dispatcher._RunAllTests(runners, self.test_collection_factory, 0)
-
-
-class TestShard(unittest.TestCase):
- """Tests test_dispatcher.RunTests with sharding."""
- @staticmethod
- def _RunShard(runner_factory):
- return test_dispatcher.RunTests(
- ['a', 'b', 'c'], runner_factory, [_MockDevice('0'), _MockDevice('1')],
- shard=True)
-
- def testShard(self):
- results, exit_code = TestShard._RunShard(MockRunner)
- self.assertEqual(len(results.GetPass()), 3)
- self.assertEqual(exit_code, 0)
-
- def testFailing(self):
- results, exit_code = TestShard._RunShard(MockRunnerFail)
- self.assertEqual(len(results.GetPass()), 0)
- self.assertEqual(len(results.GetFail()), 3)
- self.assertEqual(exit_code, constants.ERROR_EXIT_CODE)
-
- def testNoTests(self):
- results, exit_code = test_dispatcher.RunTests(
- [], MockRunner, [_MockDevice('0'), _MockDevice('1')], shard=True)
- self.assertEqual(len(results.GetAll()), 0)
- self.assertEqual(exit_code, constants.ERROR_EXIT_CODE)
-
-
-class TestReplicate(unittest.TestCase):
- """Tests test_dispatcher.RunTests with replication."""
- @staticmethod
- def _RunReplicate(runner_factory):
- return test_dispatcher.RunTests(
- ['a', 'b', 'c'], runner_factory, [_MockDevice('0'), _MockDevice('1')],
- shard=False)
-
- def testReplicate(self):
- results, exit_code = TestReplicate._RunReplicate(MockRunner)
- # We expect 6 results since each test should have been run on every device
- self.assertEqual(len(results.GetPass()), 6)
- self.assertEqual(exit_code, 0)
-
- def testFailing(self):
- results, exit_code = TestReplicate._RunReplicate(MockRunnerFail)
- self.assertEqual(len(results.GetPass()), 0)
- self.assertEqual(len(results.GetFail()), 6)
- self.assertEqual(exit_code, constants.ERROR_EXIT_CODE)
-
- def testNoTests(self):
- results, exit_code = test_dispatcher.RunTests(
- [], MockRunner, [_MockDevice('0'), _MockDevice('1')], shard=False)
- self.assertEqual(len(results.GetAll()), 0)
- self.assertEqual(exit_code, constants.ERROR_EXIT_CODE)
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/build/android/pylib/base/test_instance.py b/build/android/pylib/base/test_instance.py
deleted file mode 100644
index cdf678f..0000000
--- a/build/android/pylib/base/test_instance.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-
-class TestInstance(object):
- """A type of test.
-
- This is expected to handle all logic that is test-type specific but
- independent of the environment or device.
-
- Examples include:
- - gtests
- - instrumentation tests
- """
-
- def __init__(self):
- pass
-
- def TestType(self):
- raise NotImplementedError
-
- def SetUp(self):
- raise NotImplementedError
-
- def TearDown(self):
- raise NotImplementedError
-
- def __enter__(self):
- self.SetUp()
- return self
-
- def __exit__(self, _exc_type, _exc_val, _exc_tb):
- self.TearDown()
-
diff --git a/build/android/pylib/base/test_instance_factory.py b/build/android/pylib/base/test_instance_factory.py
deleted file mode 100644
index 7e7cb0c..0000000
--- a/build/android/pylib/base/test_instance_factory.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from pylib import constants
-from pylib.gtest import gtest_test_instance
-from pylib.instrumentation import instrumentation_test_instance
-from pylib.utils import isolator
-from pylib.uirobot import uirobot_test_instance
-
-
-
-def CreateTestInstance(args, error_func):
-
- if args.command == 'gtest':
- return gtest_test_instance.GtestTestInstance(
- args, isolator.Isolator(constants.ISOLATE_DEPS_DIR), error_func)
- elif args.command == 'instrumentation':
- return instrumentation_test_instance.InstrumentationTestInstance(
- args, isolator.Isolator(constants.ISOLATE_DEPS_DIR), error_func)
- elif args.command == 'uirobot':
- return uirobot_test_instance.UirobotTestInstance(args, error_func)
-
- error_func('Unable to create %s test instance.' % args.command)
diff --git a/build/android/pylib/base/test_run.py b/build/android/pylib/base/test_run.py
deleted file mode 100644
index 7380e78..0000000
--- a/build/android/pylib/base/test_run.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-
-class TestRun(object):
- """An execution of a particular test on a particular device.
-
- This is expected to handle all logic that is specific to the combination of
- environment and test type.
-
- Examples include:
- - local gtests
- - local instrumentation tests
- """
-
- def __init__(self, env, test_instance):
- self._env = env
- self._test_instance = test_instance
-
- def TestPackage(self):
- raise NotImplementedError
-
- def SetUp(self):
- raise NotImplementedError
-
- def RunTests(self):
- raise NotImplementedError
-
- def TearDown(self):
- raise NotImplementedError
-
- def __enter__(self):
- self.SetUp()
- return self
-
- def __exit__(self, exc_type, exc_val, exc_tb):
- self.TearDown()
-
diff --git a/build/android/pylib/base/test_run_factory.py b/build/android/pylib/base/test_run_factory.py
deleted file mode 100644
index 8c71ebbd..0000000
--- a/build/android/pylib/base/test_run_factory.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from pylib.gtest import gtest_test_instance
-from pylib.gtest import local_device_gtest_run
-from pylib.instrumentation import instrumentation_test_instance
-from pylib.local.device import local_device_environment
-from pylib.local.device import local_device_instrumentation_test_run
-from pylib.remote.device import remote_device_environment
-from pylib.remote.device import remote_device_gtest_run
-from pylib.remote.device import remote_device_instrumentation_test_run
-from pylib.remote.device import remote_device_uirobot_test_run
-from pylib.uirobot import uirobot_test_instance
-
-
-def CreateTestRun(_args, env, test_instance, error_func):
- if isinstance(env, local_device_environment.LocalDeviceEnvironment):
- if isinstance(test_instance, gtest_test_instance.GtestTestInstance):
- return local_device_gtest_run.LocalDeviceGtestRun(env, test_instance)
- if isinstance(test_instance,
- instrumentation_test_instance.InstrumentationTestInstance):
- return (local_device_instrumentation_test_run
- .LocalDeviceInstrumentationTestRun(env, test_instance))
-
- if isinstance(env, remote_device_environment.RemoteDeviceEnvironment):
- if isinstance(test_instance, gtest_test_instance.GtestTestInstance):
- return remote_device_gtest_run.RemoteDeviceGtestTestRun(
- env, test_instance)
- if isinstance(test_instance,
- instrumentation_test_instance.InstrumentationTestInstance):
- return (remote_device_instrumentation_test_run
- .RemoteDeviceInstrumentationTestRun(env, test_instance))
- if isinstance(test_instance, uirobot_test_instance.UirobotTestInstance):
- return remote_device_uirobot_test_run.RemoteDeviceUirobotTestRun(
- env, test_instance)
-
-
- error_func('Unable to create test run for %s tests in %s environment'
- % (str(test_instance), str(env)))
-
diff --git a/build/android/pylib/base/test_server.py b/build/android/pylib/base/test_server.py
deleted file mode 100644
index 085a51e..0000000
--- a/build/android/pylib/base/test_server.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-class TestServer(object):
- """Base class for any server that needs to be set up for the tests."""
-
- def __init__(self, *args, **kwargs):
- pass
-
- def SetUp(self):
- raise NotImplementedError
-
- def Reset(self):
- raise NotImplementedError
-
- def TearDown(self):
- raise NotImplementedError
-
diff --git a/build/android/pylib/chrome_test_server_spawner.py b/build/android/pylib/chrome_test_server_spawner.py
deleted file mode 100644
index 052c2fd..0000000
--- a/build/android/pylib/chrome_test_server_spawner.py
+++ /dev/null
@@ -1,422 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""A "Test Server Spawner" that handles killing/stopping per-test test servers.
-
-It's used to accept requests from the device to spawn and kill instances of the
-chrome test server on the host.
-"""
-# pylint: disable=W0702
-
-import BaseHTTPServer
-import json
-import logging
-import os
-import select
-import struct
-import subprocess
-import sys
-import threading
-import time
-import urlparse
-
-from pylib import constants
-from pylib import ports
-
-from pylib.forwarder import Forwarder
-
-
-# Path that are needed to import necessary modules when launching a testserver.
-os.environ['PYTHONPATH'] = os.environ.get('PYTHONPATH', '') + (':%s:%s:%s:%s:%s'
- % (os.path.join(constants.DIR_SOURCE_ROOT, 'third_party'),
- os.path.join(constants.DIR_SOURCE_ROOT, 'third_party', 'tlslite'),
- os.path.join(constants.DIR_SOURCE_ROOT, 'third_party', 'pyftpdlib',
- 'src'),
- os.path.join(constants.DIR_SOURCE_ROOT, 'net', 'tools', 'testserver'),
- os.path.join(constants.DIR_SOURCE_ROOT, 'sync', 'tools', 'testserver')))
-
-
-SERVER_TYPES = {
- 'http': '',
- 'ftp': '-f',
- 'sync': '', # Sync uses its own script, and doesn't take a server type arg.
- 'tcpecho': '--tcp-echo',
- 'udpecho': '--udp-echo',
-}
-
-
-# The timeout (in seconds) of starting up the Python test server.
-TEST_SERVER_STARTUP_TIMEOUT = 10
-
-def _WaitUntil(predicate, max_attempts=5):
- """Blocks until the provided predicate (function) is true.
-
- Returns:
- Whether the provided predicate was satisfied once (before the timeout).
- """
- sleep_time_sec = 0.025
- for _ in xrange(1, max_attempts):
- if predicate():
- return True
- time.sleep(sleep_time_sec)
- sleep_time_sec = min(1, sleep_time_sec * 2) # Don't wait more than 1 sec.
- return False
-
-
-def _CheckPortAvailable(port):
- """Returns True if |port| is available."""
- return _WaitUntil(lambda: ports.IsHostPortAvailable(port))
-
-
-def _CheckPortNotAvailable(port):
- """Returns True if |port| is not available."""
- return _WaitUntil(lambda: not ports.IsHostPortAvailable(port))
-
-
-def _CheckDevicePortStatus(device, port):
- """Returns whether the provided port is used."""
- return _WaitUntil(lambda: ports.IsDevicePortUsed(device, port))
-
-
-def _GetServerTypeCommandLine(server_type):
- """Returns the command-line by the given server type.
-
- Args:
- server_type: the server type to be used (e.g. 'http').
-
- Returns:
- A string containing the command-line argument.
- """
- if server_type not in SERVER_TYPES:
- raise NotImplementedError('Unknown server type: %s' % server_type)
- if server_type == 'udpecho':
- raise Exception('Please do not run UDP echo tests because we do not have '
- 'a UDP forwarder tool.')
- return SERVER_TYPES[server_type]
-
-
-class TestServerThread(threading.Thread):
- """A thread to run the test server in a separate process."""
-
- def __init__(self, ready_event, arguments, device, tool):
- """Initialize TestServerThread with the following argument.
-
- Args:
- ready_event: event which will be set when the test server is ready.
- arguments: dictionary of arguments to run the test server.
- device: An instance of DeviceUtils.
- tool: instance of runtime error detection tool.
- """
- threading.Thread.__init__(self)
- self.wait_event = threading.Event()
- self.stop_flag = False
- self.ready_event = ready_event
- self.ready_event.clear()
- self.arguments = arguments
- self.device = device
- self.tool = tool
- self.test_server_process = None
- self.is_ready = False
- self.host_port = self.arguments['port']
- assert isinstance(self.host_port, int)
- # The forwarder device port now is dynamically allocated.
- self.forwarder_device_port = 0
- # Anonymous pipe in order to get port info from test server.
- self.pipe_in = None
- self.pipe_out = None
- self.process = None
- self.command_line = []
-
- def _WaitToStartAndGetPortFromTestServer(self):
- """Waits for the Python test server to start and gets the port it is using.
-
- The port information is passed by the Python test server with a pipe given
- by self.pipe_out. It is written as a result to |self.host_port|.
-
- Returns:
- Whether the port used by the test server was successfully fetched.
- """
- assert self.host_port == 0 and self.pipe_out and self.pipe_in
- (in_fds, _, _) = select.select([self.pipe_in, ], [], [],
- TEST_SERVER_STARTUP_TIMEOUT)
- if len(in_fds) == 0:
- logging.error('Failed to wait to the Python test server to be started.')
- return False
- # First read the data length as an unsigned 4-byte value. This
- # is _not_ using network byte ordering since the Python test server packs
- # size as native byte order and all Chromium platforms so far are
- # configured to use little-endian.
- # TODO(jnd): Change the Python test server and local_test_server_*.cc to
- # use a unified byte order (either big-endian or little-endian).
- data_length = os.read(self.pipe_in, struct.calcsize('=L'))
- if data_length:
- (data_length,) = struct.unpack('=L', data_length)
- assert data_length
- if not data_length:
- logging.error('Failed to get length of server data.')
- return False
- port_json = os.read(self.pipe_in, data_length)
- if not port_json:
- logging.error('Failed to get server data.')
- return False
- logging.info('Got port json data: %s', port_json)
- port_json = json.loads(port_json)
- if port_json.has_key('port') and isinstance(port_json['port'], int):
- self.host_port = port_json['port']
- return _CheckPortNotAvailable(self.host_port)
- logging.error('Failed to get port information from the server data.')
- return False
-
- def _GenerateCommandLineArguments(self):
- """Generates the command line to run the test server.
-
- Note that all options are processed by following the definitions in
- testserver.py.
- """
- if self.command_line:
- return
-
- args_copy = dict(self.arguments)
-
- # Translate the server type.
- type_cmd = _GetServerTypeCommandLine(args_copy.pop('server-type'))
- if type_cmd:
- self.command_line.append(type_cmd)
-
- # Use a pipe to get the port given by the instance of Python test server
- # if the test does not specify the port.
- assert self.host_port == args_copy['port']
- if self.host_port == 0:
- (self.pipe_in, self.pipe_out) = os.pipe()
- self.command_line.append('--startup-pipe=%d' % self.pipe_out)
-
- # Pass the remaining arguments as-is.
- for key, values in args_copy.iteritems():
- if not isinstance(values, list):
- values = [values]
- for value in values:
- if value is None:
- self.command_line.append('--%s' % key)
- else:
- self.command_line.append('--%s=%s' % (key, value))
-
- def _CloseUnnecessaryFDsForTestServerProcess(self):
- # This is required to avoid subtle deadlocks that could be caused by the
- # test server child process inheriting undesirable file descriptors such as
- # file lock file descriptors.
- for fd in xrange(0, 1024):
- if fd != self.pipe_out:
- try:
- os.close(fd)
- except:
- pass
-
- def run(self):
- logging.info('Start running the thread!')
- self.wait_event.clear()
- self._GenerateCommandLineArguments()
- command = constants.DIR_SOURCE_ROOT
- if self.arguments['server-type'] == 'sync':
- command = [os.path.join(command, 'sync', 'tools', 'testserver',
- 'sync_testserver.py')] + self.command_line
- else:
- command = [os.path.join(command, 'net', 'tools', 'testserver',
- 'testserver.py')] + self.command_line
- logging.info('Running: %s', command)
- # Pass DIR_SOURCE_ROOT as the child's working directory so that relative
- # paths in the arguments are resolved correctly.
- self.process = subprocess.Popen(
- command, preexec_fn=self._CloseUnnecessaryFDsForTestServerProcess,
- cwd=constants.DIR_SOURCE_ROOT)
- if self.process:
- if self.pipe_out:
- self.is_ready = self._WaitToStartAndGetPortFromTestServer()
- else:
- self.is_ready = _CheckPortNotAvailable(self.host_port)
- if self.is_ready:
- Forwarder.Map([(0, self.host_port)], self.device, self.tool)
- # Check whether the forwarder is ready on the device.
- self.is_ready = False
- device_port = Forwarder.DevicePortForHostPort(self.host_port)
- if device_port and _CheckDevicePortStatus(self.device, device_port):
- self.is_ready = True
- self.forwarder_device_port = device_port
- # Wake up the request handler thread.
- self.ready_event.set()
- # Keep thread running until Stop() gets called.
- _WaitUntil(lambda: self.stop_flag, max_attempts=sys.maxint)
- if self.process.poll() is None:
- self.process.kill()
- Forwarder.UnmapDevicePort(self.forwarder_device_port, self.device)
- self.process = None
- self.is_ready = False
- if self.pipe_out:
- os.close(self.pipe_in)
- os.close(self.pipe_out)
- self.pipe_in = None
- self.pipe_out = None
- logging.info('Test-server has died.')
- self.wait_event.set()
-
- def Stop(self):
- """Blocks until the loop has finished.
-
- Note that this must be called in another thread.
- """
- if not self.process:
- return
- self.stop_flag = True
- self.wait_event.wait()
-
-
-class SpawningServerRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
- """A handler used to process http GET/POST request."""
-
- def _SendResponse(self, response_code, response_reason, additional_headers,
- contents):
- """Generates a response sent to the client from the provided parameters.
-
- Args:
- response_code: number of the response status.
- response_reason: string of reason description of the response.
- additional_headers: dict of additional headers. Each key is the name of
- the header, each value is the content of the header.
- contents: string of the contents we want to send to client.
- """
- self.send_response(response_code, response_reason)
- self.send_header('Content-Type', 'text/html')
- # Specify the content-length as without it the http(s) response will not
- # be completed properly (and the browser keeps expecting data).
- self.send_header('Content-Length', len(contents))
- for header_name in additional_headers:
- self.send_header(header_name, additional_headers[header_name])
- self.end_headers()
- self.wfile.write(contents)
- self.wfile.flush()
-
- def _StartTestServer(self):
- """Starts the test server thread."""
- logging.info('Handling request to spawn a test server.')
- content_type = self.headers.getheader('content-type')
- if content_type != 'application/json':
- raise Exception('Bad content-type for start request.')
- content_length = self.headers.getheader('content-length')
- if not content_length:
- content_length = 0
- try:
- content_length = int(content_length)
- except:
- raise Exception('Bad content-length for start request.')
- logging.info(content_length)
- test_server_argument_json = self.rfile.read(content_length)
- logging.info(test_server_argument_json)
- assert not self.server.test_server_instance
- ready_event = threading.Event()
- self.server.test_server_instance = TestServerThread(
- ready_event,
- json.loads(test_server_argument_json),
- self.server.device,
- self.server.tool)
- self.server.test_server_instance.setDaemon(True)
- self.server.test_server_instance.start()
- ready_event.wait()
- if self.server.test_server_instance.is_ready:
- self._SendResponse(200, 'OK', {}, json.dumps(
- {'port': self.server.test_server_instance.forwarder_device_port,
- 'message': 'started'}))
- logging.info('Test server is running on port: %d.',
- self.server.test_server_instance.host_port)
- else:
- self.server.test_server_instance.Stop()
- self.server.test_server_instance = None
- self._SendResponse(500, 'Test Server Error.', {}, '')
- logging.info('Encounter problem during starting a test server.')
-
- def _KillTestServer(self):
- """Stops the test server instance."""
- # There should only ever be one test server at a time. This may do the
- # wrong thing if we try and start multiple test servers.
- if not self.server.test_server_instance:
- return
- port = self.server.test_server_instance.host_port
- logging.info('Handling request to kill a test server on port: %d.', port)
- self.server.test_server_instance.Stop()
- # Make sure the status of test server is correct before sending response.
- if _CheckPortAvailable(port):
- self._SendResponse(200, 'OK', {}, 'killed')
- logging.info('Test server on port %d is killed', port)
- else:
- self._SendResponse(500, 'Test Server Error.', {}, '')
- logging.info('Encounter problem during killing a test server.')
- self.server.test_server_instance = None
-
- def do_POST(self):
- parsed_path = urlparse.urlparse(self.path)
- action = parsed_path.path
- logging.info('Action for POST method is: %s.', action)
- if action == '/start':
- self._StartTestServer()
- else:
- self._SendResponse(400, 'Unknown request.', {}, '')
- logging.info('Encounter unknown request: %s.', action)
-
- def do_GET(self):
- parsed_path = urlparse.urlparse(self.path)
- action = parsed_path.path
- params = urlparse.parse_qs(parsed_path.query, keep_blank_values=1)
- logging.info('Action for GET method is: %s.', action)
- for param in params:
- logging.info('%s=%s', param, params[param][0])
- if action == '/kill':
- self._KillTestServer()
- elif action == '/ping':
- # The ping handler is used to check whether the spawner server is ready
- # to serve the requests. We don't need to test the status of the test
- # server when handling ping request.
- self._SendResponse(200, 'OK', {}, 'ready')
- logging.info('Handled ping request and sent response.')
- else:
- self._SendResponse(400, 'Unknown request', {}, '')
- logging.info('Encounter unknown request: %s.', action)
-
-
-class SpawningServer(object):
- """The class used to start/stop a http server."""
-
- def __init__(self, test_server_spawner_port, device, tool):
- logging.info('Creating new spawner on port: %d.', test_server_spawner_port)
- self.server = BaseHTTPServer.HTTPServer(('', test_server_spawner_port),
- SpawningServerRequestHandler)
- self.server.device = device
- self.server.tool = tool
- self.server.test_server_instance = None
- self.server.build_type = constants.GetBuildType()
-
- def _Listen(self):
- logging.info('Starting test server spawner')
- self.server.serve_forever()
-
- def Start(self):
- """Starts the test server spawner."""
- listener_thread = threading.Thread(target=self._Listen)
- listener_thread.setDaemon(True)
- listener_thread.start()
-
- def Stop(self):
- """Stops the test server spawner.
-
- Also cleans the server state.
- """
- self.CleanupState()
- self.server.shutdown()
-
- def CleanupState(self):
- """Cleans up the spawning server state.
-
- This should be called if the test server spawner is reused,
- to avoid sharing the test server instance.
- """
- if self.server.test_server_instance:
- self.server.test_server_instance.Stop()
- self.server.test_server_instance = None
diff --git a/build/android/pylib/cmd_helper.py b/build/android/pylib/cmd_helper.py
deleted file mode 100644
index f881553..0000000
--- a/build/android/pylib/cmd_helper.py
+++ /dev/null
@@ -1,261 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""A wrapper for subprocess to make calling shell commands easier."""
-
-import logging
-import os
-import pipes
-import select
-import signal
-import string
-import StringIO
-import subprocess
-import time
-
-# fcntl is not available on Windows.
-try:
- import fcntl
-except ImportError:
- fcntl = None
-
-_SafeShellChars = frozenset(string.ascii_letters + string.digits + '@%_-+=:,./')
-
-def SingleQuote(s):
- """Return an shell-escaped version of the string using single quotes.
-
- Reliably quote a string which may contain unsafe characters (e.g. space,
- quote, or other special characters such as '$').
-
- The returned value can be used in a shell command line as one token that gets
- to be interpreted literally.
-
- Args:
- s: The string to quote.
-
- Return:
- The string quoted using single quotes.
- """
- return pipes.quote(s)
-
-def DoubleQuote(s):
- """Return an shell-escaped version of the string using double quotes.
-
- Reliably quote a string which may contain unsafe characters (e.g. space
- or quote characters), while retaining some shell features such as variable
- interpolation.
-
- The returned value can be used in a shell command line as one token that gets
- to be further interpreted by the shell.
-
- The set of characters that retain their special meaning may depend on the
- shell implementation. This set usually includes: '$', '`', '\', '!', '*',
- and '@'.
-
- Args:
- s: The string to quote.
-
- Return:
- The string quoted using double quotes.
- """
- if not s:
- return '""'
- elif all(c in _SafeShellChars for c in s):
- return s
- else:
- return '"' + s.replace('"', '\\"') + '"'
-
-
-def Popen(args, stdout=None, stderr=None, shell=None, cwd=None, env=None):
- return subprocess.Popen(
- args=args, cwd=cwd, stdout=stdout, stderr=stderr,
- shell=shell, close_fds=True, env=env,
- preexec_fn=lambda: signal.signal(signal.SIGPIPE, signal.SIG_DFL))
-
-
-def Call(args, stdout=None, stderr=None, shell=None, cwd=None, env=None):
- pipe = Popen(args, stdout=stdout, stderr=stderr, shell=shell, cwd=cwd,
- env=env)
- pipe.communicate()
- return pipe.wait()
-
-
-def RunCmd(args, cwd=None):
- """Opens a subprocess to execute a program and returns its return value.
-
- Args:
- args: A string or a sequence of program arguments. The program to execute is
- the string or the first item in the args sequence.
- cwd: If not None, the subprocess's current directory will be changed to
- |cwd| before it's executed.
-
- Returns:
- Return code from the command execution.
- """
- logging.info(str(args) + ' ' + (cwd or ''))
- return Call(args, cwd=cwd)
-
-
-def GetCmdOutput(args, cwd=None, shell=False):
- """Open a subprocess to execute a program and returns its output.
-
- Args:
- args: A string or a sequence of program arguments. The program to execute is
- the string or the first item in the args sequence.
- cwd: If not None, the subprocess's current directory will be changed to
- |cwd| before it's executed.
- shell: Whether to execute args as a shell command.
-
- Returns:
- Captures and returns the command's stdout.
- Prints the command's stderr to logger (which defaults to stdout).
- """
- (_, output) = GetCmdStatusAndOutput(args, cwd, shell)
- return output
-
-
-def _ValidateAndLogCommand(args, cwd, shell):
- if isinstance(args, basestring):
- if not shell:
- raise Exception('string args must be run with shell=True')
- else:
- if shell:
- raise Exception('array args must be run with shell=False')
- args = ' '.join(SingleQuote(c) for c in args)
- if cwd is None:
- cwd = ''
- else:
- cwd = ':' + cwd
- logging.info('[host]%s> %s', cwd, args)
- return args
-
-
-def GetCmdStatusAndOutput(args, cwd=None, shell=False):
- """Executes a subprocess and returns its exit code and output.
-
- Args:
- args: A string or a sequence of program arguments. The program to execute is
- the string or the first item in the args sequence.
- cwd: If not None, the subprocess's current directory will be changed to
- |cwd| before it's executed.
- shell: Whether to execute args as a shell command. Must be True if args
- is a string and False if args is a sequence.
-
- Returns:
- The 2-tuple (exit code, output).
- """
- _ValidateAndLogCommand(args, cwd, shell)
- pipe = Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
- shell=shell, cwd=cwd)
- stdout, stderr = pipe.communicate()
-
- if stderr:
- logging.critical(stderr)
- if len(stdout) > 4096:
- logging.debug('Truncated output:')
- logging.debug(stdout[:4096])
- return (pipe.returncode, stdout)
-
-
-class TimeoutError(Exception):
- """Module-specific timeout exception."""
- pass
-
-
-def _IterProcessStdout(process, timeout=None, buffer_size=4096,
- poll_interval=1):
- assert fcntl, 'fcntl module is required'
- try:
- # Enable non-blocking reads from the child's stdout.
- child_fd = process.stdout.fileno()
- fl = fcntl.fcntl(child_fd, fcntl.F_GETFL)
- fcntl.fcntl(child_fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
-
- end_time = (time.time() + timeout) if timeout else None
- while True:
- if end_time and time.time() > end_time:
- raise TimeoutError
- read_fds, _, _ = select.select([child_fd], [], [], poll_interval)
- if child_fd in read_fds:
- data = os.read(child_fd, buffer_size)
- if not data:
- break
- yield data
- if process.poll() is not None:
- break
- finally:
- try:
- # Make sure the process doesn't stick around if we fail with an
- # exception.
- process.kill()
- except OSError:
- pass
- process.wait()
-
-
-def GetCmdStatusAndOutputWithTimeout(args, timeout, cwd=None, shell=False,
- logfile=None):
- """Executes a subprocess with a timeout.
-
- Args:
- args: List of arguments to the program, the program to execute is the first
- element.
- timeout: the timeout in seconds or None to wait forever.
- cwd: If not None, the subprocess's current directory will be changed to
- |cwd| before it's executed.
- shell: Whether to execute args as a shell command. Must be True if args
- is a string and False if args is a sequence.
- logfile: Optional file-like object that will receive output from the
- command as it is running.
-
- Returns:
- The 2-tuple (exit code, output).
- """
- _ValidateAndLogCommand(args, cwd, shell)
- output = StringIO.StringIO()
- process = Popen(args, cwd=cwd, shell=shell, stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT)
- for data in _IterProcessStdout(process, timeout=timeout):
- if logfile:
- logfile.write(data)
- output.write(data)
- return process.returncode, output.getvalue()
-
-
-def IterCmdOutputLines(args, timeout=None, cwd=None, shell=False,
- check_status=True):
- """Executes a subprocess and continuously yields lines from its output.
-
- Args:
- args: List of arguments to the program, the program to execute is the first
- element.
- cwd: If not None, the subprocess's current directory will be changed to
- |cwd| before it's executed.
- shell: Whether to execute args as a shell command. Must be True if args
- is a string and False if args is a sequence.
- check_status: A boolean indicating whether to check the exit status of the
- process after all output has been read.
-
- Yields:
- The output of the subprocess, line by line.
-
- Raises:
- CalledProcessError if check_status is True and the process exited with a
- non-zero exit status.
- """
- cmd = _ValidateAndLogCommand(args, cwd, shell)
- process = Popen(args, cwd=cwd, shell=shell, stdout=subprocess.PIPE,
- stderr=subprocess.STDOUT)
- buffer_output = ''
- for data in _IterProcessStdout(process, timeout=timeout):
- buffer_output += data
- has_incomplete_line = buffer_output[-1] not in '\r\n'
- lines = buffer_output.splitlines()
- buffer_output = lines.pop() if has_incomplete_line else ''
- for line in lines:
- yield line
- if buffer_output:
- yield buffer_output
- if check_status and process.returncode:
- raise subprocess.CalledProcessError(process.returncode, cmd)
diff --git a/build/android/pylib/cmd_helper_test.py b/build/android/pylib/cmd_helper_test.py
deleted file mode 100644
index 5155cea..0000000
--- a/build/android/pylib/cmd_helper_test.py
+++ /dev/null
@@ -1,83 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Tests for the cmd_helper module."""
-
-import unittest
-import subprocess
-
-from pylib import cmd_helper
-
-
-class CmdHelperSingleQuoteTest(unittest.TestCase):
-
- def testSingleQuote_basic(self):
- self.assertEquals('hello',
- cmd_helper.SingleQuote('hello'))
-
- def testSingleQuote_withSpaces(self):
- self.assertEquals("'hello world'",
- cmd_helper.SingleQuote('hello world'))
-
- def testSingleQuote_withUnsafeChars(self):
- self.assertEquals("""'hello'"'"'; rm -rf /'""",
- cmd_helper.SingleQuote("hello'; rm -rf /"))
-
- def testSingleQuote_dontExpand(self):
- test_string = 'hello $TEST_VAR'
- cmd = 'TEST_VAR=world; echo %s' % cmd_helper.SingleQuote(test_string)
- self.assertEquals(test_string,
- cmd_helper.GetCmdOutput(cmd, shell=True).rstrip())
-
-
-class CmdHelperDoubleQuoteTest(unittest.TestCase):
-
- def testDoubleQuote_basic(self):
- self.assertEquals('hello',
- cmd_helper.DoubleQuote('hello'))
-
- def testDoubleQuote_withSpaces(self):
- self.assertEquals('"hello world"',
- cmd_helper.DoubleQuote('hello world'))
-
- def testDoubleQuote_withUnsafeChars(self):
- self.assertEquals('''"hello\\"; rm -rf /"''',
- cmd_helper.DoubleQuote('hello"; rm -rf /'))
-
- def testSingleQuote_doExpand(self):
- test_string = 'hello $TEST_VAR'
- cmd = 'TEST_VAR=world; echo %s' % cmd_helper.DoubleQuote(test_string)
- self.assertEquals('hello world',
- cmd_helper.GetCmdOutput(cmd, shell=True).rstrip())
-
-
-class CmdHelperIterCmdOutputLinesTest(unittest.TestCase):
- """Test IterCmdOutputLines with some calls to the unix 'seq' command."""
-
- def testIterCmdOutputLines_success(self):
- for num, line in enumerate(
- cmd_helper.IterCmdOutputLines(['seq', '10']), 1):
- self.assertEquals(num, int(line))
-
- def testIterCmdOutputLines_exitStatusFail(self):
- with self.assertRaises(subprocess.CalledProcessError):
- for num, line in enumerate(
- cmd_helper.IterCmdOutputLines('seq 10 && false', shell=True), 1):
- self.assertEquals(num, int(line))
- # after reading all the output we get an exit status of 1
-
- def testIterCmdOutputLines_exitStatusIgnored(self):
- for num, line in enumerate(
- cmd_helper.IterCmdOutputLines('seq 10 && false', shell=True,
- check_status=False), 1):
- self.assertEquals(num, int(line))
-
- def testIterCmdOutputLines_exitStatusSkipped(self):
- for num, line in enumerate(
- cmd_helper.IterCmdOutputLines('seq 10 && false', shell=True), 1):
- self.assertEquals(num, int(line))
- # no exception will be raised because we don't attempt to read past
- # the end of the output and, thus, the status never gets checked
- if num == 10:
- break
diff --git a/build/android/pylib/constants/__init__.py b/build/android/pylib/constants/__init__.py
deleted file mode 100644
index 8821f97..0000000
--- a/build/android/pylib/constants/__init__.py
+++ /dev/null
@@ -1,308 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Defines a set of constants shared by test runners and other scripts."""
-
-# TODO(jbudorick): Split these constants into coherent modules.
-
-# pylint: disable=W0212
-
-import collections
-import logging
-import os
-import subprocess
-
-
-DIR_SOURCE_ROOT = os.environ.get('CHECKOUT_SOURCE_ROOT',
- os.path.abspath(os.path.join(os.path.dirname(__file__),
- os.pardir, os.pardir, os.pardir, os.pardir)))
-ISOLATE_DEPS_DIR = os.path.join(DIR_SOURCE_ROOT, 'isolate_deps_dir')
-
-CHROME_SHELL_HOST_DRIVEN_DIR = os.path.join(
- DIR_SOURCE_ROOT, 'chrome', 'android')
-
-
-PackageInfo = collections.namedtuple('PackageInfo',
- ['package', 'activity', 'cmdline_file', 'devtools_socket',
- 'test_package'])
-
-PACKAGE_INFO = {
- 'chrome_document': PackageInfo(
- 'com.google.android.apps.chrome.document',
- 'com.google.android.apps.chrome.document.ChromeLauncherActivity',
- '/data/local/chrome-command-line',
- 'chrome_devtools_remote',
- None),
- 'chrome': PackageInfo(
- 'com.google.android.apps.chrome',
- 'com.google.android.apps.chrome.Main',
- '/data/local/chrome-command-line',
- 'chrome_devtools_remote',
- 'com.google.android.apps.chrome.tests'),
- 'chrome_beta': PackageInfo(
- 'com.chrome.beta',
- 'com.google.android.apps.chrome.Main',
- '/data/local/chrome-command-line',
- 'chrome_devtools_remote',
- None),
- 'chrome_stable': PackageInfo(
- 'com.android.chrome',
- 'com.google.android.apps.chrome.Main',
- '/data/local/chrome-command-line',
- 'chrome_devtools_remote',
- None),
- 'chrome_dev': PackageInfo(
- 'com.chrome.dev',
- 'com.google.android.apps.chrome.Main',
- '/data/local/chrome-command-line',
- 'chrome_devtools_remote',
- None),
- 'chrome_canary': PackageInfo(
- 'com.chrome.canary',
- 'com.google.android.apps.chrome.Main',
- '/data/local/chrome-command-line',
- 'chrome_devtools_remote',
- None),
- 'chrome_work': PackageInfo(
- 'com.chrome.work',
- 'com.google.android.apps.chrome.Main',
- '/data/local/chrome-command-line',
- 'chrome_devtools_remote',
- None),
- 'chromium': PackageInfo(
- 'org.chromium.chrome',
- 'com.google.android.apps.chrome.Main',
- '/data/local/chrome-command-line',
- 'chrome_devtools_remote',
- None),
- 'legacy_browser': PackageInfo(
- 'com.google.android.browser',
- 'com.android.browser.BrowserActivity',
- None,
- None,
- None),
- 'chromecast_shell': PackageInfo(
- 'com.google.android.apps.mediashell',
- 'com.google.android.apps.mediashell.MediaShellActivity',
- '/data/local/tmp/castshell-command-line',
- None,
- None),
- 'content_shell': PackageInfo(
- 'org.chromium.content_shell_apk',
- 'org.chromium.content_shell_apk.ContentShellActivity',
- '/data/local/tmp/content-shell-command-line',
- None,
- 'org.chromium.content_shell_apk.tests'),
- 'chrome_shell': PackageInfo(
- 'org.chromium.chrome.shell',
- 'org.chromium.chrome.shell.ChromeShellActivity',
- '/data/local/tmp/chrome-shell-command-line',
- 'chrome_shell_devtools_remote',
- 'org.chromium.chrome.shell.tests'),
- 'android_webview_shell': PackageInfo(
- 'org.chromium.android_webview.shell',
- 'org.chromium.android_webview.shell.AwShellActivity',
- '/data/local/tmp/android-webview-command-line',
- None,
- 'org.chromium.android_webview.test'),
- 'gtest': PackageInfo(
- 'org.chromium.native_test',
- 'org.chromium.native_test.NativeUnitTestActivity',
- '/data/local/tmp/chrome-native-tests-command-line',
- None,
- None),
- 'components_browsertests': PackageInfo(
- 'org.chromium.components_browsertests_apk',
- ('org.chromium.components_browsertests_apk' +
- '.ComponentsBrowserTestsActivity'),
- '/data/local/tmp/chrome-native-tests-command-line',
- None,
- None),
- 'content_browsertests': PackageInfo(
- 'org.chromium.content_browsertests_apk',
- 'org.chromium.content_browsertests_apk.ContentBrowserTestsActivity',
- '/data/local/tmp/chrome-native-tests-command-line',
- None,
- None),
- 'chromedriver_webview_shell': PackageInfo(
- 'org.chromium.chromedriver_webview_shell',
- 'org.chromium.chromedriver_webview_shell.Main',
- None,
- None,
- None),
-}
-
-
-# Ports arrangement for various test servers used in Chrome for Android.
-# Lighttpd server will attempt to use 9000 as default port, if unavailable it
-# will find a free port from 8001 - 8999.
-LIGHTTPD_DEFAULT_PORT = 9000
-LIGHTTPD_RANDOM_PORT_FIRST = 8001
-LIGHTTPD_RANDOM_PORT_LAST = 8999
-TEST_SYNC_SERVER_PORT = 9031
-TEST_SEARCH_BY_IMAGE_SERVER_PORT = 9041
-TEST_POLICY_SERVER_PORT = 9051
-
-# The net test server is started from port 10201.
-# TODO(pliard): http://crbug.com/239014. Remove this dirty workaround once
-# http://crbug.com/239014 is fixed properly.
-TEST_SERVER_PORT_FIRST = 10201
-TEST_SERVER_PORT_LAST = 30000
-# A file to record next valid port of test server.
-TEST_SERVER_PORT_FILE = '/tmp/test_server_port'
-TEST_SERVER_PORT_LOCKFILE = '/tmp/test_server_port.lock'
-
-TEST_EXECUTABLE_DIR = '/data/local/tmp'
-# Directories for common java libraries for SDK build.
-# These constants are defined in build/android/ant/common.xml
-SDK_BUILD_JAVALIB_DIR = 'lib.java'
-SDK_BUILD_TEST_JAVALIB_DIR = 'test.lib.java'
-SDK_BUILD_APKS_DIR = 'apks'
-
-ADB_KEYS_FILE = '/data/misc/adb/adb_keys'
-
-PERF_OUTPUT_DIR = os.path.join(DIR_SOURCE_ROOT, 'out', 'step_results')
-# The directory on the device where perf test output gets saved to.
-DEVICE_PERF_OUTPUT_DIR = (
- '/data/data/' + PACKAGE_INFO['chrome'].package + '/files')
-
-SCREENSHOTS_DIR = os.path.join(DIR_SOURCE_ROOT, 'out_screenshots')
-
-class ANDROID_SDK_VERSION_CODES(object):
- """Android SDK version codes.
-
- http://developer.android.com/reference/android/os/Build.VERSION_CODES.html
- """
-
- JELLY_BEAN = 16
- JELLY_BEAN_MR1 = 17
- JELLY_BEAN_MR2 = 18
- KITKAT = 19
- KITKAT_WATCH = 20
- LOLLIPOP = 21
- LOLLIPOP_MR1 = 22
-
-ANDROID_SDK_VERSION = ANDROID_SDK_VERSION_CODES.LOLLIPOP_MR1
-ANDROID_SDK_BUILD_TOOLS_VERSION = '22.0.1'
-ANDROID_SDK_ROOT = os.path.join(DIR_SOURCE_ROOT,
- 'third_party/android_tools/sdk')
-ANDROID_SDK_TOOLS = os.path.join(ANDROID_SDK_ROOT,
- 'build-tools', ANDROID_SDK_BUILD_TOOLS_VERSION)
-ANDROID_NDK_ROOT = os.path.join(DIR_SOURCE_ROOT,
- 'third_party/android_tools/ndk')
-
-EMULATOR_SDK_ROOT = os.environ.get('ANDROID_EMULATOR_SDK_ROOT',
- os.path.join(DIR_SOURCE_ROOT,
- 'android_emulator_sdk'))
-
-BAD_DEVICES_JSON = os.path.join(DIR_SOURCE_ROOT,
- os.environ.get('CHROMIUM_OUT_DIR', 'out'),
- 'bad_devices.json')
-
-UPSTREAM_FLAKINESS_SERVER = 'test-results.appspot.com'
-
-DEVICE_LOCAL_PROPERTIES_PATH = '/data/local.prop'
-
-PYTHON_UNIT_TEST_SUITES = {
- 'pylib_py_unittests': {
- 'path': os.path.join(DIR_SOURCE_ROOT, 'build', 'android'),
- 'test_modules': [
- 'pylib.cmd_helper_test',
- 'pylib.device.device_utils_test',
- 'pylib.results.json_results_test',
- 'pylib.utils.md5sum_test',
- ]
- },
- 'gyp_py_unittests': {
- 'path': os.path.join(DIR_SOURCE_ROOT, 'build', 'android', 'gyp'),
- 'test_modules': [
- 'java_cpp_enum_tests',
- ]
- },
-}
-
-LOCAL_MACHINE_TESTS = ['junit', 'python']
-VALID_ENVIRONMENTS = ['local', 'remote_device']
-VALID_TEST_TYPES = ['gtest', 'instrumentation', 'junit', 'linker', 'monkey',
- 'perf', 'python', 'uiautomator', 'uirobot']
-VALID_DEVICE_TYPES = ['Android', 'iOS']
-
-
-def GetBuildType():
- try:
- return os.environ['BUILDTYPE']
- except KeyError:
- raise EnvironmentError(
- 'The BUILDTYPE environment variable has not been set')
-
-
-def SetBuildType(build_type):
- os.environ['BUILDTYPE'] = build_type
-
-
-def SetBuildDirectory(build_directory):
- os.environ['CHROMIUM_OUT_DIR'] = build_directory
-
-
-def SetOutputDirectory(output_directory):
- os.environ['CHROMIUM_OUTPUT_DIR'] = output_directory
-
-
-def GetOutDirectory(build_type=None):
- """Returns the out directory where the output binaries are built.
-
- Args:
- build_type: Build type, generally 'Debug' or 'Release'. Defaults to the
- globally set build type environment variable BUILDTYPE.
- """
- if 'CHROMIUM_OUTPUT_DIR' in os.environ:
- return os.path.abspath(os.path.join(
- DIR_SOURCE_ROOT, os.environ.get('CHROMIUM_OUTPUT_DIR')))
-
- return os.path.abspath(os.path.join(
- DIR_SOURCE_ROOT, os.environ.get('CHROMIUM_OUT_DIR', 'out'),
- GetBuildType() if build_type is None else build_type))
-
-
-def _Memoize(func):
- def Wrapper():
- try:
- return func._result
- except AttributeError:
- func._result = func()
- return func._result
- return Wrapper
-
-
-def SetAdbPath(adb_path):
- os.environ['ADB_PATH'] = adb_path
-
-
-def GetAdbPath():
- # Check if a custom adb path as been set. If not, try to find adb
- # on the system.
- if os.environ.get('ADB_PATH'):
- return os.environ.get('ADB_PATH')
- else:
- return _FindAdbPath()
-
-
-@_Memoize
-def _FindAdbPath():
- if os.environ.get('ANDROID_SDK_ROOT'):
- return 'adb'
- # If envsetup.sh hasn't been sourced and there's no adb in the path,
- # set it here.
- try:
- with file(os.devnull, 'w') as devnull:
- subprocess.call(['adb', 'version'], stdout=devnull, stderr=devnull)
- return 'adb'
- except OSError:
- logging.debug('No adb found in $PATH, fallback to checked in binary.')
- return os.path.join(ANDROID_SDK_ROOT, 'platform-tools', 'adb')
-
-# Exit codes
-ERROR_EXIT_CODE = 1
-INFRA_EXIT_CODE = 87
-WARNING_EXIT_CODE = 88
diff --git a/build/android/pylib/constants/keyevent.py b/build/android/pylib/constants/keyevent.py
deleted file mode 100644
index 06736b3..0000000
--- a/build/android/pylib/constants/keyevent.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Android KeyEvent constants.
-
-http://developer.android.com/reference/android/view/KeyEvent.html
-"""
-
-KEYCODE_BACK = 4
-KEYCODE_DPAD_RIGHT = 22
-KEYCODE_ENTER = 66
-KEYCODE_MENU = 82
-
diff --git a/build/android/pylib/content_settings.py b/build/android/pylib/content_settings.py
deleted file mode 100644
index 8594140..0000000
--- a/build/android/pylib/content_settings.py
+++ /dev/null
@@ -1,82 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from pylib import constants
-
-
-class ContentSettings(dict):
-
- """A dict interface to interact with device content settings.
-
- System properties are key/value pairs as exposed by adb shell content.
- """
-
- def __init__(self, table, device):
- super(ContentSettings, self).__init__()
- self._table = table
- self._device = device
-
- @staticmethod
- def _GetTypeBinding(value):
- if isinstance(value, bool):
- return 'b'
- if isinstance(value, float):
- return 'f'
- if isinstance(value, int):
- return 'i'
- if isinstance(value, long):
- return 'l'
- if isinstance(value, str):
- return 's'
- raise ValueError('Unsupported type %s' % type(value))
-
- def iteritems(self):
- # Example row:
- # 'Row: 0 _id=13, name=logging_id2, value=-1fccbaa546705b05'
- for row in self._device.RunShellCommand(
- 'content query --uri content://%s' % self._table, as_root=True):
- fields = row.split(', ')
- key = None
- value = None
- for field in fields:
- k, _, v = field.partition('=')
- if k == 'name':
- key = v
- elif k == 'value':
- value = v
- if not key:
- continue
- if not value:
- value = ''
- yield key, value
-
- def __getitem__(self, key):
- return self._device.RunShellCommand(
- 'content query --uri content://%s --where "name=\'%s\'" '
- '--projection value' % (self._table, key), as_root=True).strip()
-
- def __setitem__(self, key, value):
- if key in self:
- self._device.RunShellCommand(
- 'content update --uri content://%s '
- '--bind value:%s:%s --where "name=\'%s\'"' % (
- self._table,
- self._GetTypeBinding(value), value, key),
- as_root=True)
- else:
- self._device.RunShellCommand(
- 'content insert --uri content://%s '
- '--bind name:%s:%s --bind value:%s:%s' % (
- self._table,
- self._GetTypeBinding(key), key,
- self._GetTypeBinding(value), value),
- as_root=True)
-
- def __delitem__(self, key):
- self._device.RunShellCommand(
- 'content delete --uri content://%s '
- '--bind name:%s:%s' % (
- self._table,
- self._GetTypeBinding(key), key),
- as_root=True)
diff --git a/build/android/pylib/device/OWNERS b/build/android/pylib/device/OWNERS
deleted file mode 100644
index c35d7ac..0000000
--- a/build/android/pylib/device/OWNERS
+++ /dev/null
@@ -1,2 +0,0 @@
-jbudorick@chromium.org
-perezju@chromium.org
diff --git a/build/android/pylib/device/__init__.py b/build/android/pylib/device/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/build/android/pylib/device/__init__.py
+++ /dev/null
diff --git a/build/android/pylib/device/adb_wrapper.py b/build/android/pylib/device/adb_wrapper.py
deleted file mode 100644
index e897326..0000000
--- a/build/android/pylib/device/adb_wrapper.py
+++ /dev/null
@@ -1,608 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""This module wraps Android's adb tool.
-
-This is a thin wrapper around the adb interface. Any additional complexity
-should be delegated to a higher level (ex. DeviceUtils).
-"""
-
-import collections
-import errno
-import logging
-import os
-import re
-
-from pylib import cmd_helper
-from pylib import constants
-from pylib.device import decorators
-from pylib.device import device_errors
-from pylib.utils import timeout_retry
-
-
-_DEFAULT_TIMEOUT = 30
-_DEFAULT_RETRIES = 2
-
-_EMULATOR_RE = re.compile(r'^emulator-[0-9]+$')
-
-_READY_STATE = 'device'
-
-
-def _VerifyLocalFileExists(path):
- """Verifies a local file exists.
-
- Args:
- path: Path to the local file.
-
- Raises:
- IOError: If the file doesn't exist.
- """
- if not os.path.exists(path):
- raise IOError(errno.ENOENT, os.strerror(errno.ENOENT), path)
-
-
-DeviceStat = collections.namedtuple('DeviceStat',
- ['st_mode', 'st_size', 'st_time'])
-
-
-class AdbWrapper(object):
- """A wrapper around a local Android Debug Bridge executable."""
-
- def __init__(self, device_serial):
- """Initializes the AdbWrapper.
-
- Args:
- device_serial: The device serial number as a string.
- """
- if not device_serial:
- raise ValueError('A device serial must be specified')
- self._device_serial = str(device_serial)
-
- # pylint: disable=unused-argument
- @classmethod
- def _BuildAdbCmd(cls, args, device_serial, cpu_affinity=None):
- if cpu_affinity is not None:
- cmd = ['taskset', '-c', str(cpu_affinity)]
- else:
- cmd = []
- cmd.append(constants.GetAdbPath())
- if device_serial is not None:
- cmd.extend(['-s', device_serial])
- cmd.extend(args)
- return cmd
- # pylint: enable=unused-argument
-
- # pylint: disable=unused-argument
- @classmethod
- @decorators.WithTimeoutAndRetries
- def _RunAdbCmd(cls, args, timeout=None, retries=None, device_serial=None,
- check_error=True, cpu_affinity=None):
- status, output = cmd_helper.GetCmdStatusAndOutputWithTimeout(
- cls._BuildAdbCmd(args, device_serial, cpu_affinity=cpu_affinity),
- timeout_retry.CurrentTimeoutThread().GetRemainingTime())
- if status != 0:
- raise device_errors.AdbCommandFailedError(
- args, output, status, device_serial)
- # This catches some errors, including when the device drops offline;
- # unfortunately adb is very inconsistent with error reporting so many
- # command failures present differently.
- if check_error and output.startswith('error:'):
- raise device_errors.AdbCommandFailedError(args, output)
- return output
- # pylint: enable=unused-argument
-
- def _RunDeviceAdbCmd(self, args, timeout, retries, check_error=True):
- """Runs an adb command on the device associated with this object.
-
- Args:
- args: A list of arguments to adb.
- timeout: Timeout in seconds.
- retries: Number of retries.
- check_error: Check that the command doesn't return an error message. This
- does NOT check the exit status of shell commands.
-
- Returns:
- The output of the command.
- """
- return self._RunAdbCmd(args, timeout=timeout, retries=retries,
- device_serial=self._device_serial,
- check_error=check_error)
-
- def _IterRunDeviceAdbCmd(self, args, timeout):
- """Runs an adb command and returns an iterator over its output lines.
-
- Args:
- args: A list of arguments to adb.
- timeout: Timeout in seconds.
-
- Yields:
- The output of the command line by line.
- """
- return cmd_helper.IterCmdOutputLines(
- self._BuildAdbCmd(args, self._device_serial), timeout=timeout)
-
- def __eq__(self, other):
- """Consider instances equal if they refer to the same device.
-
- Args:
- other: The instance to compare equality with.
-
- Returns:
- True if the instances are considered equal, false otherwise.
- """
- return self._device_serial == str(other)
-
- def __str__(self):
- """The string representation of an instance.
-
- Returns:
- The device serial number as a string.
- """
- return self._device_serial
-
- def __repr__(self):
- return '%s(\'%s\')' % (self.__class__.__name__, self)
-
- # pylint: disable=unused-argument
- @classmethod
- def IsServerOnline(cls):
- status, output = cmd_helper.GetCmdStatusAndOutput(['pgrep', 'adb'])
- output = [int(x) for x in output.split()]
- logging.info('PIDs for adb found: %r', output)
- return status == 0
- # pylint: enable=unused-argument
-
- @classmethod
- def KillServer(cls, timeout=_DEFAULT_TIMEOUT, retries=_DEFAULT_RETRIES):
- cls._RunAdbCmd(['kill-server'], timeout=timeout, retries=retries)
-
- @classmethod
- def StartServer(cls, timeout=_DEFAULT_TIMEOUT, retries=_DEFAULT_RETRIES):
- # CPU affinity is used to reduce adb instability http://crbug.com/268450
- cls._RunAdbCmd(['start-server'], timeout=timeout, retries=retries,
- cpu_affinity=0)
-
- @classmethod
- def GetDevices(cls, timeout=_DEFAULT_TIMEOUT, retries=_DEFAULT_RETRIES):
- """DEPRECATED. Refer to Devices(...) below."""
- # TODO(jbudorick): Remove this function once no more clients are using it.
- return cls.Devices(timeout=timeout, retries=retries)
-
- @classmethod
- def Devices(cls, is_ready=True, timeout=_DEFAULT_TIMEOUT,
- retries=_DEFAULT_RETRIES):
- """Get the list of active attached devices.
-
- Args:
- is_ready: Whether the devices should be limited to only those that are
- ready for use.
- timeout: (optional) Timeout per try in seconds.
- retries: (optional) Number of retries to attempt.
-
- Yields:
- AdbWrapper instances.
- """
- output = cls._RunAdbCmd(['devices'], timeout=timeout, retries=retries)
- lines = (line.split() for line in output.splitlines())
- return [AdbWrapper(line[0]) for line in lines
- if len(line) == 2 and (not is_ready or line[1] == _READY_STATE)]
-
- def GetDeviceSerial(self):
- """Gets the device serial number associated with this object.
-
- Returns:
- Device serial number as a string.
- """
- return self._device_serial
-
- def Push(self, local, remote, timeout=60*5, retries=_DEFAULT_RETRIES):
- """Pushes a file from the host to the device.
-
- Args:
- local: Path on the host filesystem.
- remote: Path on the device filesystem.
- timeout: (optional) Timeout per try in seconds.
- retries: (optional) Number of retries to attempt.
- """
- _VerifyLocalFileExists(local)
- self._RunDeviceAdbCmd(['push', local, remote], timeout, retries)
-
- def Pull(self, remote, local, timeout=60*5, retries=_DEFAULT_RETRIES):
- """Pulls a file from the device to the host.
-
- Args:
- remote: Path on the device filesystem.
- local: Path on the host filesystem.
- timeout: (optional) Timeout per try in seconds.
- retries: (optional) Number of retries to attempt.
- """
- cmd = ['pull', remote, local]
- self._RunDeviceAdbCmd(cmd, timeout, retries)
- try:
- _VerifyLocalFileExists(local)
- except IOError:
- raise device_errors.AdbCommandFailedError(
- cmd, 'File not found on host: %s' % local, device_serial=str(self))
-
- def Shell(self, command, expect_status=0, timeout=_DEFAULT_TIMEOUT,
- retries=_DEFAULT_RETRIES):
- """Runs a shell command on the device.
-
- Args:
- command: A string with the shell command to run.
- expect_status: (optional) Check that the command's exit status matches
- this value. Default is 0. If set to None the test is skipped.
- timeout: (optional) Timeout per try in seconds.
- retries: (optional) Number of retries to attempt.
-
- Returns:
- The output of the shell command as a string.
-
- Raises:
- device_errors.AdbCommandFailedError: If the exit status doesn't match
- |expect_status|.
- """
- if expect_status is None:
- args = ['shell', command]
- else:
- args = ['shell', '%s; echo %%$?;' % command.rstrip()]
- output = self._RunDeviceAdbCmd(args, timeout, retries, check_error=False)
- if expect_status is not None:
- output_end = output.rfind('%')
- if output_end < 0:
- # causes the status string to become empty and raise a ValueError
- output_end = len(output)
-
- try:
- status = int(output[output_end+1:])
- except ValueError:
- logging.warning('exit status of shell command %r missing.', command)
- raise device_errors.AdbShellCommandFailedError(
- command, output, status=None, device_serial=self._device_serial)
- output = output[:output_end]
- if status != expect_status:
- raise device_errors.AdbShellCommandFailedError(
- command, output, status=status, device_serial=self._device_serial)
- return output
-
- def IterShell(self, command, timeout):
- """Runs a shell command and returns an iterator over its output lines.
-
- Args:
- command: A string with the shell command to run.
- timeout: Timeout in seconds.
-
- Yields:
- The output of the command line by line.
- """
- args = ['shell', command]
- return cmd_helper.IterCmdOutputLines(
- self._BuildAdbCmd(args, self._device_serial), timeout=timeout)
-
- def Ls(self, path, timeout=_DEFAULT_TIMEOUT, retries=_DEFAULT_RETRIES):
- """List the contents of a directory on the device.
-
- Args:
- path: Path on the device filesystem.
- timeout: (optional) Timeout per try in seconds.
- retries: (optional) Number of retries to attempt.
-
- Returns:
- A list of pairs (filename, stat) for each file found in the directory,
- where the stat object has the properties: st_mode, st_size, and st_time.
-
- Raises:
- AdbCommandFailedError if |path| does not specify a valid and accessible
- directory in the device.
- """
- def ParseLine(line):
- cols = line.split(None, 3)
- filename = cols.pop()
- stat = DeviceStat(*[int(num, base=16) for num in cols])
- return (filename, stat)
-
- cmd = ['ls', path]
- lines = self._RunDeviceAdbCmd(
- cmd, timeout=timeout, retries=retries).splitlines()
- if lines:
- return [ParseLine(line) for line in lines]
- else:
- raise device_errors.AdbCommandFailedError(
- cmd, 'path does not specify an accessible directory in the device',
- device_serial=self._device_serial)
-
- def Logcat(self, clear=False, dump=False, filter_specs=None,
- logcat_format=None, ring_buffer=None, timeout=None,
- retries=_DEFAULT_RETRIES):
- """Get an iterable over the logcat output.
-
- Args:
- clear: If true, clear the logcat.
- dump: If true, dump the current logcat contents.
- filter_specs: If set, a list of specs to filter the logcat.
- logcat_format: If set, the format in which the logcat should be output.
- Options include "brief", "process", "tag", "thread", "raw", "time",
- "threadtime", and "long"
- ring_buffer: If set, a list of alternate ring buffers to request.
- Options include "main", "system", "radio", "events", "crash" or "all".
- The default is equivalent to ["main", "system", "crash"].
- timeout: (optional) If set, timeout per try in seconds. If clear or dump
- is set, defaults to _DEFAULT_TIMEOUT.
- retries: (optional) If clear or dump is set, the number of retries to
- attempt. Otherwise, does nothing.
-
- Yields:
- logcat output line by line.
- """
- cmd = ['logcat']
- use_iter = True
- if clear:
- cmd.append('-c')
- use_iter = False
- if dump:
- cmd.append('-d')
- use_iter = False
- if logcat_format:
- cmd.extend(['-v', logcat_format])
- if ring_buffer:
- for buffer_name in ring_buffer:
- cmd.extend(['-b', buffer_name])
- if filter_specs:
- cmd.extend(filter_specs)
-
- if use_iter:
- return self._IterRunDeviceAdbCmd(cmd, timeout)
- else:
- timeout = timeout if timeout is not None else _DEFAULT_TIMEOUT
- return self._RunDeviceAdbCmd(cmd, timeout, retries).splitlines()
-
- def Forward(self, local, remote, timeout=_DEFAULT_TIMEOUT,
- retries=_DEFAULT_RETRIES):
- """Forward socket connections from the local socket to the remote socket.
-
- Sockets are specified by one of:
- tcp:<port>
- localabstract:<unix domain socket name>
- localreserved:<unix domain socket name>
- localfilesystem:<unix domain socket name>
- dev:<character device name>
- jdwp:<process pid> (remote only)
-
- Args:
- local: The host socket.
- remote: The device socket.
- timeout: (optional) Timeout per try in seconds.
- retries: (optional) Number of retries to attempt.
- """
- self._RunDeviceAdbCmd(['forward', str(local), str(remote)], timeout,
- retries)
-
- def JDWP(self, timeout=_DEFAULT_TIMEOUT, retries=_DEFAULT_RETRIES):
- """List of PIDs of processes hosting a JDWP transport.
-
- Args:
- timeout: (optional) Timeout per try in seconds.
- retries: (optional) Number of retries to attempt.
-
- Returns:
- A list of PIDs as strings.
- """
- return [a.strip() for a in
- self._RunDeviceAdbCmd(['jdwp'], timeout, retries).split('\n')]
-
- def Install(self, apk_path, forward_lock=False, reinstall=False,
- sd_card=False, timeout=60*2, retries=_DEFAULT_RETRIES):
- """Install an apk on the device.
-
- Args:
- apk_path: Host path to the APK file.
- forward_lock: (optional) If set forward-locks the app.
- reinstall: (optional) If set reinstalls the app, keeping its data.
- sd_card: (optional) If set installs on the SD card.
- timeout: (optional) Timeout per try in seconds.
- retries: (optional) Number of retries to attempt.
- """
- _VerifyLocalFileExists(apk_path)
- cmd = ['install']
- if forward_lock:
- cmd.append('-l')
- if reinstall:
- cmd.append('-r')
- if sd_card:
- cmd.append('-s')
- cmd.append(apk_path)
- output = self._RunDeviceAdbCmd(cmd, timeout, retries)
- if 'Success' not in output:
- raise device_errors.AdbCommandFailedError(
- cmd, output, device_serial=self._device_serial)
-
- def InstallMultiple(self, apk_paths, forward_lock=False, reinstall=False,
- sd_card=False, allow_downgrade=False, partial=False,
- timeout=60*2, retries=_DEFAULT_RETRIES):
- """Install an apk with splits on the device.
-
- Args:
- apk_paths: Host path to the APK file.
- forward_lock: (optional) If set forward-locks the app.
- reinstall: (optional) If set reinstalls the app, keeping its data.
- sd_card: (optional) If set installs on the SD card.
- timeout: (optional) Timeout per try in seconds.
- retries: (optional) Number of retries to attempt.
- allow_downgrade: (optional) Allow versionCode downgrade.
- partial: (optional) Package ID if apk_paths doesn't include all .apks.
- """
- for path in apk_paths:
- _VerifyLocalFileExists(path)
- cmd = ['install-multiple']
- if forward_lock:
- cmd.append('-l')
- if reinstall:
- cmd.append('-r')
- if sd_card:
- cmd.append('-s')
- if allow_downgrade:
- cmd.append('-d')
- if partial:
- cmd.extend(('-p', partial))
- cmd.extend(apk_paths)
- output = self._RunDeviceAdbCmd(cmd, timeout, retries)
- if 'Success' not in output:
- raise device_errors.AdbCommandFailedError(
- cmd, output, device_serial=self._device_serial)
-
- def Uninstall(self, package, keep_data=False, timeout=_DEFAULT_TIMEOUT,
- retries=_DEFAULT_RETRIES):
- """Remove the app |package| from the device.
-
- Args:
- package: The package to uninstall.
- keep_data: (optional) If set keep the data and cache directories.
- timeout: (optional) Timeout per try in seconds.
- retries: (optional) Number of retries to attempt.
- """
- cmd = ['uninstall']
- if keep_data:
- cmd.append('-k')
- cmd.append(package)
- output = self._RunDeviceAdbCmd(cmd, timeout, retries)
- if 'Failure' in output:
- raise device_errors.AdbCommandFailedError(
- cmd, output, device_serial=self._device_serial)
-
- def Backup(self, path, packages=None, apk=False, shared=False,
- nosystem=True, include_all=False, timeout=_DEFAULT_TIMEOUT,
- retries=_DEFAULT_RETRIES):
- """Write an archive of the device's data to |path|.
-
- Args:
- path: Local path to store the backup file.
- packages: List of to packages to be backed up.
- apk: (optional) If set include the .apk files in the archive.
- shared: (optional) If set buckup the device's SD card.
- nosystem: (optional) If set exclude system applications.
- include_all: (optional) If set back up all installed applications and
- |packages| is optional.
- timeout: (optional) Timeout per try in seconds.
- retries: (optional) Number of retries to attempt.
- """
- cmd = ['backup', '-f', path]
- if apk:
- cmd.append('-apk')
- if shared:
- cmd.append('-shared')
- if nosystem:
- cmd.append('-nosystem')
- if include_all:
- cmd.append('-all')
- if packages:
- cmd.extend(packages)
- assert bool(packages) ^ bool(include_all), (
- 'Provide \'packages\' or set \'include_all\' but not both.')
- ret = self._RunDeviceAdbCmd(cmd, timeout, retries)
- _VerifyLocalFileExists(path)
- return ret
-
- def Restore(self, path, timeout=_DEFAULT_TIMEOUT, retries=_DEFAULT_RETRIES):
- """Restore device contents from the backup archive.
-
- Args:
- path: Host path to the backup archive.
- timeout: (optional) Timeout per try in seconds.
- retries: (optional) Number of retries to attempt.
- """
- _VerifyLocalFileExists(path)
- self._RunDeviceAdbCmd(['restore'] + [path], timeout, retries)
-
- def WaitForDevice(self, timeout=60*5, retries=_DEFAULT_RETRIES):
- """Block until the device is online.
-
- Args:
- timeout: (optional) Timeout per try in seconds.
- retries: (optional) Number of retries to attempt.
- """
- self._RunDeviceAdbCmd(['wait-for-device'], timeout, retries)
-
- def GetState(self, timeout=_DEFAULT_TIMEOUT, retries=_DEFAULT_RETRIES):
- """Get device state.
-
- Args:
- timeout: (optional) Timeout per try in seconds.
- retries: (optional) Number of retries to attempt.
-
- Returns:
- One of 'offline', 'bootloader', or 'device'.
- """
- return self._RunDeviceAdbCmd(['get-state'], timeout, retries).strip()
-
- def GetDevPath(self, timeout=_DEFAULT_TIMEOUT, retries=_DEFAULT_RETRIES):
- """Gets the device path.
-
- Args:
- timeout: (optional) Timeout per try in seconds.
- retries: (optional) Number of retries to attempt.
-
- Returns:
- The device path (e.g. usb:3-4)
- """
- return self._RunDeviceAdbCmd(['get-devpath'], timeout, retries)
-
- def Remount(self, timeout=_DEFAULT_TIMEOUT, retries=_DEFAULT_RETRIES):
- """Remounts the /system partition on the device read-write."""
- self._RunDeviceAdbCmd(['remount'], timeout, retries)
-
- def Reboot(self, to_bootloader=False, timeout=60*5,
- retries=_DEFAULT_RETRIES):
- """Reboots the device.
-
- Args:
- to_bootloader: (optional) If set reboots to the bootloader.
- timeout: (optional) Timeout per try in seconds.
- retries: (optional) Number of retries to attempt.
- """
- if to_bootloader:
- cmd = ['reboot-bootloader']
- else:
- cmd = ['reboot']
- self._RunDeviceAdbCmd(cmd, timeout, retries)
-
- def Root(self, timeout=_DEFAULT_TIMEOUT, retries=_DEFAULT_RETRIES):
- """Restarts the adbd daemon with root permissions, if possible.
-
- Args:
- timeout: (optional) Timeout per try in seconds.
- retries: (optional) Number of retries to attempt.
- """
- output = self._RunDeviceAdbCmd(['root'], timeout, retries)
- if 'cannot' in output:
- raise device_errors.AdbCommandFailedError(
- ['root'], output, device_serial=self._device_serial)
-
- def Emu(self, cmd, timeout=_DEFAULT_TIMEOUT,
- retries=_DEFAULT_RETRIES):
- """Runs an emulator console command.
-
- See http://developer.android.com/tools/devices/emulator.html#console
-
- Args:
- cmd: The command to run on the emulator console.
- timeout: (optional) Timeout per try in seconds.
- retries: (optional) Number of retries to attempt.
-
- Returns:
- The output of the emulator console command.
- """
- if isinstance(cmd, basestring):
- cmd = [cmd]
- return self._RunDeviceAdbCmd(['emu'] + cmd, timeout, retries)
-
- @property
- def is_emulator(self):
- return _EMULATOR_RE.match(self._device_serial)
-
- @property
- def is_ready(self):
- try:
- return self.GetState() == _READY_STATE
- except device_errors.CommandFailedError:
- return False
diff --git a/build/android/pylib/device/adb_wrapper_test.py b/build/android/pylib/device/adb_wrapper_test.py
deleted file mode 100644
index 5fc9eb6..0000000
--- a/build/android/pylib/device/adb_wrapper_test.py
+++ /dev/null
@@ -1,96 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Tests for the AdbWrapper class."""
-
-import os
-import tempfile
-import time
-import unittest
-
-from pylib.device import adb_wrapper
-from pylib.device import device_errors
-
-
-class TestAdbWrapper(unittest.TestCase):
-
- def setUp(self):
- devices = adb_wrapper.AdbWrapper.Devices()
- assert devices, 'A device must be attached'
- self._adb = devices[0]
- self._adb.WaitForDevice()
-
- @staticmethod
- def _MakeTempFile(contents):
- """Make a temporary file with the given contents.
-
- Args:
- contents: string to write to the temporary file.
-
- Returns:
- The absolute path to the file.
- """
- fi, path = tempfile.mkstemp()
- with os.fdopen(fi, 'wb') as f:
- f.write(contents)
- return path
-
- def testShell(self):
- output = self._adb.Shell('echo test', expect_status=0)
- self.assertEqual(output.strip(), 'test')
- output = self._adb.Shell('echo test')
- self.assertEqual(output.strip(), 'test')
- with self.assertRaises(device_errors.AdbCommandFailedError):
- self._adb.Shell('echo test', expect_status=1)
-
- def testPushLsPull(self):
- path = self._MakeTempFile('foo')
- device_path = '/data/local/tmp/testfile.txt'
- local_tmpdir = os.path.dirname(path)
- self._adb.Push(path, device_path)
- files = dict(self._adb.Ls('/data/local/tmp'))
- self.assertTrue('testfile.txt' in files)
- self.assertEquals(3, files['testfile.txt'].st_size)
- self.assertEqual(self._adb.Shell('cat %s' % device_path), 'foo')
- self._adb.Pull(device_path, local_tmpdir)
- with open(os.path.join(local_tmpdir, 'testfile.txt'), 'r') as f:
- self.assertEqual(f.read(), 'foo')
-
- def testInstall(self):
- path = self._MakeTempFile('foo')
- with self.assertRaises(device_errors.AdbCommandFailedError):
- self._adb.Install(path)
-
- def testForward(self):
- with self.assertRaises(device_errors.AdbCommandFailedError):
- self._adb.Forward(0, 0)
-
- def testUninstall(self):
- with self.assertRaises(device_errors.AdbCommandFailedError):
- self._adb.Uninstall('some.nonexistant.package')
-
- def testRebootWaitForDevice(self):
- self._adb.Reboot()
- print 'waiting for device to reboot...'
- while self._adb.GetState() == 'device':
- time.sleep(1)
- self._adb.WaitForDevice()
- self.assertEqual(self._adb.GetState(), 'device')
- print 'waiting for package manager...'
- while 'package:' not in self._adb.Shell('pm path android'):
- time.sleep(1)
-
- def testRootRemount(self):
- self._adb.Root()
- while True:
- try:
- self._adb.Shell('start')
- break
- except device_errors.AdbCommandFailedError:
- time.sleep(1)
- self._adb.Remount()
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/build/android/pylib/device/battery_utils.py b/build/android/pylib/device/battery_utils.py
deleted file mode 100644
index eab558e..0000000
--- a/build/android/pylib/device/battery_utils.py
+++ /dev/null
@@ -1,593 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Provides a variety of device interactions with power.
-"""
-# pylint: disable=unused-argument
-
-import collections
-import contextlib
-import csv
-import logging
-
-from pylib import constants
-from pylib.device import decorators
-from pylib.device import device_errors
-from pylib.device import device_utils
-from pylib.utils import timeout_retry
-
-_DEFAULT_TIMEOUT = 30
-_DEFAULT_RETRIES = 3
-
-
-_DEVICE_PROFILES = [
- {
- 'name': 'Nexus 4',
- 'witness_file': '/sys/module/pm8921_charger/parameters/disabled',
- 'enable_command': (
- 'echo 0 > /sys/module/pm8921_charger/parameters/disabled && '
- 'dumpsys battery reset'),
- 'disable_command': (
- 'echo 1 > /sys/module/pm8921_charger/parameters/disabled && '
- 'dumpsys battery set ac 0 && dumpsys battery set usb 0'),
- 'charge_counter': None,
- 'voltage': None,
- 'current': None,
- },
- {
- 'name': 'Nexus 5',
- # Nexus 5
- # Setting the HIZ bit of the bq24192 causes the charger to actually ignore
- # energy coming from USB. Setting the power_supply offline just updates the
- # Android system to reflect that.
- 'witness_file': '/sys/kernel/debug/bq24192/INPUT_SRC_CONT',
- 'enable_command': (
- 'echo 0x4A > /sys/kernel/debug/bq24192/INPUT_SRC_CONT && '
- 'echo 1 > /sys/class/power_supply/usb/online &&'
- 'dumpsys battery reset'),
- 'disable_command': (
- 'echo 0xCA > /sys/kernel/debug/bq24192/INPUT_SRC_CONT && '
- 'chmod 644 /sys/class/power_supply/usb/online && '
- 'echo 0 > /sys/class/power_supply/usb/online && '
- 'dumpsys battery set ac 0 && dumpsys battery set usb 0'),
- 'charge_counter': None,
- 'voltage': None,
- 'current': None,
- },
- {
- 'name': 'Nexus 6',
- 'witness_file': None,
- 'enable_command': (
- 'echo 1 > /sys/class/power_supply/battery/charging_enabled && '
- 'dumpsys battery reset'),
- 'disable_command': (
- 'echo 0 > /sys/class/power_supply/battery/charging_enabled && '
- 'dumpsys battery set ac 0 && dumpsys battery set usb 0'),
- 'charge_counter': (
- '/sys/class/power_supply/max170xx_battery/charge_counter_ext'),
- 'voltage': '/sys/class/power_supply/max170xx_battery/voltage_now',
- 'current': '/sys/class/power_supply/max170xx_battery/current_now',
- },
- {
- 'name': 'Nexus 9',
- 'witness_file': None,
- 'enable_command': (
- 'echo Disconnected > '
- '/sys/bus/i2c/drivers/bq2419x/0-006b/input_cable_state && '
- 'dumpsys battery reset'),
- 'disable_command': (
- 'echo Connected > '
- '/sys/bus/i2c/drivers/bq2419x/0-006b/input_cable_state && '
- 'dumpsys battery set ac 0 && dumpsys battery set usb 0'),
- 'charge_counter': '/sys/class/power_supply/battery/charge_counter_ext',
- 'voltage': '/sys/class/power_supply/battery/voltage_now',
- 'current': '/sys/class/power_supply/battery/current_now',
- },
- {
- 'name': 'Nexus 10',
- 'witness_file': None,
- 'enable_command': None,
- 'disable_command': None,
- 'charge_counter': None,
- 'voltage': '/sys/class/power_supply/ds2784-fuelgauge/voltage_now',
- 'current': '/sys/class/power_supply/ds2784-fuelgauge/current_now',
-
- },
-]
-
-# The list of useful dumpsys columns.
-# Index of the column containing the format version.
-_DUMP_VERSION_INDEX = 0
-# Index of the column containing the type of the row.
-_ROW_TYPE_INDEX = 3
-# Index of the column containing the uid.
-_PACKAGE_UID_INDEX = 4
-# Index of the column containing the application package.
-_PACKAGE_NAME_INDEX = 5
-# The column containing the uid of the power data.
-_PWI_UID_INDEX = 1
-# The column containing the type of consumption. Only consumtion since last
-# charge are of interest here.
-_PWI_AGGREGATION_INDEX = 2
-# The column containing the amount of power used, in mah.
-_PWI_POWER_CONSUMPTION_INDEX = 5
-
-
-class BatteryUtils(object):
-
- def __init__(self, device, default_timeout=_DEFAULT_TIMEOUT,
- default_retries=_DEFAULT_RETRIES):
- """BatteryUtils constructor.
-
- Args:
- device: A DeviceUtils instance.
- default_timeout: An integer containing the default number of seconds to
- wait for an operation to complete if no explicit value
- is provided.
- default_retries: An integer containing the default number or times an
- operation should be retried on failure if no explicit
- value is provided.
-
- Raises:
- TypeError: If it is not passed a DeviceUtils instance.
- """
- if not isinstance(device, device_utils.DeviceUtils):
- raise TypeError('Must be initialized with DeviceUtils object.')
- self._device = device
- self._cache = device.GetClientCache(self.__class__.__name__)
- self._default_timeout = default_timeout
- self._default_retries = default_retries
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def SupportsFuelGauge(self, timeout=None, retries=None):
- """Detect if fuel gauge chip is present.
-
- Args:
- timeout: timeout in seconds
- retries: number of retries
-
- Returns:
- True if known fuel gauge files are present.
- False otherwise.
- """
- self._DiscoverDeviceProfile()
- return (self._cache['profile']['enable_command'] != None
- and self._cache['profile']['charge_counter'] != None)
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def GetFuelGaugeChargeCounter(self, timeout=None, retries=None):
- """Get value of charge_counter on fuel gauge chip.
-
- Device must have charging disabled for this, not just battery updates
- disabled. The only device that this currently works with is the nexus 5.
-
- Args:
- timeout: timeout in seconds
- retries: number of retries
-
- Returns:
- value of charge_counter for fuel gauge chip in units of nAh.
-
- Raises:
- device_errors.CommandFailedError: If fuel gauge chip not found.
- """
- if self.SupportsFuelGauge():
- return int(self._device.ReadFile(
- self._cache['profile']['charge_counter']))
- raise device_errors.CommandFailedError(
- 'Unable to find fuel gauge.')
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def GetNetworkData(self, package, timeout=None, retries=None):
- """Get network data for specific package.
-
- Args:
- package: package name you want network data for.
- timeout: timeout in seconds
- retries: number of retries
-
- Returns:
- Tuple of (sent_data, recieved_data)
- None if no network data found
- """
- # If device_utils clears cache, cache['uids'] doesn't exist
- if 'uids' not in self._cache:
- self._cache['uids'] = {}
- if package not in self._cache['uids']:
- self.GetPowerData()
- if package not in self._cache['uids']:
- logging.warning('No UID found for %s. Can\'t get network data.',
- package)
- return None
-
- network_data_path = '/proc/uid_stat/%s/' % self._cache['uids'][package]
- try:
- send_data = int(self._device.ReadFile(network_data_path + 'tcp_snd'))
- # If ReadFile throws exception, it means no network data usage file for
- # package has been recorded. Return 0 sent and 0 received.
- except device_errors.AdbShellCommandFailedError:
- logging.warning('No sent data found for package %s', package)
- send_data = 0
- try:
- recv_data = int(self._device.ReadFile(network_data_path + 'tcp_rcv'))
- except device_errors.AdbShellCommandFailedError:
- logging.warning('No received data found for package %s', package)
- recv_data = 0
- return (send_data, recv_data)
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def GetPowerData(self, timeout=None, retries=None):
- """Get power data for device.
-
- Args:
- timeout: timeout in seconds
- retries: number of retries
-
- Returns:
- Dict of power data, keyed on package names.
- {
- package_name: {
- 'uid': uid,
- 'data': [1,2,3]
- },
- }
- """
- if 'uids' not in self._cache:
- self._cache['uids'] = {}
- dumpsys_output = self._device.RunShellCommand(
- ['dumpsys', 'batterystats', '-c'], check_return=True)
- csvreader = csv.reader(dumpsys_output)
- pwi_entries = collections.defaultdict(list)
- for entry in csvreader:
- if entry[_DUMP_VERSION_INDEX] not in ['8', '9']:
- # Wrong dumpsys version.
- raise device_errors.DeviceVersionError(
- 'Dumpsys version must be 8 or 9. %s found.'
- % entry[_DUMP_VERSION_INDEX])
- if _ROW_TYPE_INDEX < len(entry) and entry[_ROW_TYPE_INDEX] == 'uid':
- current_package = entry[_PACKAGE_NAME_INDEX]
- if (self._cache['uids'].get(current_package)
- and self._cache['uids'].get(current_package)
- != entry[_PACKAGE_UID_INDEX]):
- raise device_errors.CommandFailedError(
- 'Package %s found multiple times with differnt UIDs %s and %s'
- % (current_package, self._cache['uids'][current_package],
- entry[_PACKAGE_UID_INDEX]))
- self._cache['uids'][current_package] = entry[_PACKAGE_UID_INDEX]
- elif (_PWI_POWER_CONSUMPTION_INDEX < len(entry)
- and entry[_ROW_TYPE_INDEX] == 'pwi'
- and entry[_PWI_AGGREGATION_INDEX] == 'l'):
- pwi_entries[entry[_PWI_UID_INDEX]].append(
- float(entry[_PWI_POWER_CONSUMPTION_INDEX]))
-
- return {p: {'uid': uid, 'data': pwi_entries[uid]}
- for p, uid in self._cache['uids'].iteritems()}
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def GetPackagePowerData(self, package, timeout=None, retries=None):
- """Get power data for particular package.
-
- Args:
- package: Package to get power data on.
-
- returns:
- Dict of UID and power data.
- {
- 'uid': uid,
- 'data': [1,2,3]
- }
- None if the package is not found in the power data.
- """
- return self.GetPowerData().get(package)
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def GetBatteryInfo(self, timeout=None, retries=None):
- """Gets battery info for the device.
-
- Args:
- timeout: timeout in seconds
- retries: number of retries
- Returns:
- A dict containing various battery information as reported by dumpsys
- battery.
- """
- result = {}
- # Skip the first line, which is just a header.
- for line in self._device.RunShellCommand(
- ['dumpsys', 'battery'], check_return=True)[1:]:
- # If usb charging has been disabled, an extra line of header exists.
- if 'UPDATES STOPPED' in line:
- logging.warning('Dumpsys battery not receiving updates. '
- 'Run dumpsys battery reset if this is in error.')
- elif ':' not in line:
- logging.warning('Unknown line found in dumpsys battery: "%s"', line)
- else:
- k, v = line.split(':', 1)
- result[k.strip()] = v.strip()
- return result
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def GetCharging(self, timeout=None, retries=None):
- """Gets the charging state of the device.
-
- Args:
- timeout: timeout in seconds
- retries: number of retries
- Returns:
- True if the device is charging, false otherwise.
- """
- battery_info = self.GetBatteryInfo()
- for k in ('AC powered', 'USB powered', 'Wireless powered'):
- if (k in battery_info and
- battery_info[k].lower() in ('true', '1', 'yes')):
- return True
- return False
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def SetCharging(self, enabled, timeout=None, retries=None):
- """Enables or disables charging on the device.
-
- Args:
- enabled: A boolean indicating whether charging should be enabled or
- disabled.
- timeout: timeout in seconds
- retries: number of retries
-
- Raises:
- device_errors.CommandFailedError: If method of disabling charging cannot
- be determined.
- """
- self._DiscoverDeviceProfile()
- if not self._cache['profile']['enable_command']:
- raise device_errors.CommandFailedError(
- 'Unable to find charging commands.')
-
- if enabled:
- command = self._cache['profile']['enable_command']
- else:
- command = self._cache['profile']['disable_command']
-
- def set_and_verify_charging():
- self._device.RunShellCommand(command, check_return=True)
- return self.GetCharging() == enabled
-
- timeout_retry.WaitFor(set_and_verify_charging, wait_period=1)
-
- # TODO(rnephew): Make private when all use cases can use the context manager.
- @decorators.WithTimeoutAndRetriesFromInstance()
- def DisableBatteryUpdates(self, timeout=None, retries=None):
- """Resets battery data and makes device appear like it is not
- charging so that it will collect power data since last charge.
-
- Args:
- timeout: timeout in seconds
- retries: number of retries
-
- Raises:
- device_errors.CommandFailedError: When resetting batterystats fails to
- reset power values.
- device_errors.DeviceVersionError: If device is not L or higher.
- """
- def battery_updates_disabled():
- return self.GetCharging() is False
-
- self._ClearPowerData()
- self._device.RunShellCommand(['dumpsys', 'battery', 'set', 'ac', '0'],
- check_return=True)
- self._device.RunShellCommand(['dumpsys', 'battery', 'set', 'usb', '0'],
- check_return=True)
- timeout_retry.WaitFor(battery_updates_disabled, wait_period=1)
-
- # TODO(rnephew): Make private when all use cases can use the context manager.
- @decorators.WithTimeoutAndRetriesFromInstance()
- def EnableBatteryUpdates(self, timeout=None, retries=None):
- """Restarts device charging so that dumpsys no longer collects power data.
-
- Args:
- timeout: timeout in seconds
- retries: number of retries
-
- Raises:
- device_errors.DeviceVersionError: If device is not L or higher.
- """
- def battery_updates_enabled():
- return (self.GetCharging()
- or not bool('UPDATES STOPPED' in self._device.RunShellCommand(
- ['dumpsys', 'battery'], check_return=True)))
-
- self._device.RunShellCommand(['dumpsys', 'battery', 'reset'],
- check_return=True)
- timeout_retry.WaitFor(battery_updates_enabled, wait_period=1)
-
- @contextlib.contextmanager
- def BatteryMeasurement(self, timeout=None, retries=None):
- """Context manager that enables battery data collection. It makes
- the device appear to stop charging so that dumpsys will start collecting
- power data since last charge. Once the with block is exited, charging is
- resumed and power data since last charge is no longer collected.
-
- Only for devices L and higher.
-
- Example usage:
- with BatteryMeasurement():
- browser_actions()
- get_power_data() # report usage within this block
- after_measurements() # Anything that runs after power
- # measurements are collected
-
- Args:
- timeout: timeout in seconds
- retries: number of retries
-
- Raises:
- device_errors.DeviceVersionError: If device is not L or higher.
- """
- if (self._device.build_version_sdk <
- constants.ANDROID_SDK_VERSION_CODES.LOLLIPOP):
- raise device_errors.DeviceVersionError('Device must be L or higher.')
- try:
- self.DisableBatteryUpdates(timeout=timeout, retries=retries)
- yield
- finally:
- self.EnableBatteryUpdates(timeout=timeout, retries=retries)
-
- def ChargeDeviceToLevel(self, level, wait_period=60):
- """Enables charging and waits for device to be charged to given level.
-
- Args:
- level: level of charge to wait for.
- wait_period: time in seconds to wait between checking.
- """
- self.SetCharging(True)
-
- def device_charged():
- battery_level = self.GetBatteryInfo().get('level')
- if battery_level is None:
- logging.warning('Unable to find current battery level.')
- battery_level = 100
- else:
- logging.info('current battery level: %s', battery_level)
- battery_level = int(battery_level)
- return battery_level >= level
-
- timeout_retry.WaitFor(device_charged, wait_period=wait_period)
-
- def LetBatteryCoolToTemperature(self, target_temp, wait_period=60):
- """Lets device sit to give battery time to cool down
- Args:
- temp: maximum temperature to allow in tenths of degrees c.
- wait_period: time in seconds to wait between checking.
- """
- def cool_device():
- temp = self.GetBatteryInfo().get('temperature')
- if temp is None:
- logging.warning('Unable to find current battery temperature.')
- temp = 0
- else:
- logging.info('Current battery temperature: %s', temp)
- return int(temp) <= target_temp
- self.EnableBatteryUpdates()
- logging.info('Waiting for the device to cool down to %s (0.1 C)',
- target_temp)
- timeout_retry.WaitFor(cool_device, wait_period=wait_period)
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def TieredSetCharging(self, enabled, timeout=None, retries=None):
- """Enables or disables charging on the device.
-
- Args:
- enabled: A boolean indicating whether charging should be enabled or
- disabled.
- timeout: timeout in seconds
- retries: number of retries
- """
- if self.GetCharging() == enabled:
- logging.warning('Device charging already in expected state: %s', enabled)
- return
-
- if enabled:
- try:
- self.SetCharging(enabled)
- except device_errors.CommandFailedError:
- logging.info('Unable to enable charging via hardware.'
- ' Falling back to software enabling.')
- self.EnableBatteryUpdates()
- else:
- try:
- self._ClearPowerData()
- self.SetCharging(enabled)
- except device_errors.CommandFailedError:
- logging.info('Unable to disable charging via hardware.'
- ' Falling back to software disabling.')
- self.DisableBatteryUpdates()
-
- @contextlib.contextmanager
- def PowerMeasurement(self, timeout=None, retries=None):
- """Context manager that enables battery power collection.
-
- Once the with block is exited, charging is resumed. Will attempt to disable
- charging at the hardware level, and if that fails will fall back to software
- disabling of battery updates.
-
- Only for devices L and higher.
-
- Example usage:
- with PowerMeasurement():
- browser_actions()
- get_power_data() # report usage within this block
- after_measurements() # Anything that runs after power
- # measurements are collected
-
- Args:
- timeout: timeout in seconds
- retries: number of retries
- """
- try:
- self.TieredSetCharging(False, timeout=timeout, retries=retries)
- yield
- finally:
- self.TieredSetCharging(True, timeout=timeout, retries=retries)
-
- def _ClearPowerData(self):
- """Resets battery data and makes device appear like it is not
- charging so that it will collect power data since last charge.
-
- Returns:
- True if power data cleared.
- False if power data clearing is not supported (pre-L)
-
- Raises:
- device_errors.DeviceVersionError: If power clearing is supported,
- but fails.
- """
- if (self._device.build_version_sdk <
- constants.ANDROID_SDK_VERSION_CODES.LOLLIPOP):
- logging.warning('Dumpsys power data only available on 5.0 and above. '
- 'Cannot clear power data.')
- return False
-
- self._device.RunShellCommand(
- ['dumpsys', 'battery', 'set', 'usb', '1'], check_return=True)
- self._device.RunShellCommand(
- ['dumpsys', 'battery', 'set', 'ac', '1'], check_return=True)
- self._device.RunShellCommand(
- ['dumpsys', 'batterystats', '--reset'], check_return=True)
- battery_data = self._device.RunShellCommand(
- ['dumpsys', 'batterystats', '--charged', '--checkin'],
- check_return=True, large_output=True)
- for line in battery_data:
- l = line.split(',')
- if (len(l) > _PWI_POWER_CONSUMPTION_INDEX and l[_ROW_TYPE_INDEX] == 'pwi'
- and l[_PWI_POWER_CONSUMPTION_INDEX] != 0):
- self._device.RunShellCommand(
- ['dumpsys', 'battery', 'reset'], check_return=True)
- raise device_errors.CommandFailedError(
- 'Non-zero pmi value found after reset.')
- self._device.RunShellCommand(
- ['dumpsys', 'battery', 'reset'], check_return=True)
- return True
-
- def _DiscoverDeviceProfile(self):
- """Checks and caches device information.
-
- Returns:
- True if profile is found, false otherwise.
- """
-
- if 'profile' in self._cache:
- return True
- for profile in _DEVICE_PROFILES:
- if self._device.product_model == profile['name']:
- self._cache['profile'] = profile
- return True
- self._cache['profile'] = {
- 'name': None,
- 'witness_file': None,
- 'enable_command': None,
- 'disable_command': None,
- 'charge_counter': None,
- 'voltage': None,
- 'current': None,
- }
- return False
diff --git a/build/android/pylib/device/battery_utils_test.py b/build/android/pylib/device/battery_utils_test.py
deleted file mode 100755
index b968fa6..0000000
--- a/build/android/pylib/device/battery_utils_test.py
+++ /dev/null
@@ -1,574 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""
-Unit tests for the contents of battery_utils.py
-"""
-
-# pylint: disable=W0613
-
-import logging
-import os
-import sys
-import unittest
-
-from pylib import constants
-from pylib.device import battery_utils
-from pylib.device import device_errors
-from pylib.device import device_utils
-from pylib.device import device_utils_test
-from pylib.utils import mock_calls
-
-# RunCommand from third_party/android_testrunner/run_command.py is mocked
-# below, so its path needs to be in sys.path.
-sys.path.append(os.path.join(
- constants.DIR_SOURCE_ROOT, 'third_party', 'android_testrunner'))
-
-sys.path.append(os.path.join(
- constants.DIR_SOURCE_ROOT, 'third_party', 'pymock'))
-import mock # pylint: disable=F0401
-
-_DUMPSYS_OUTPUT = [
- '9,0,i,uid,1000,test_package1',
- '9,0,i,uid,1001,test_package2',
- '9,1000,l,pwi,uid,1',
- '9,1001,l,pwi,uid,2'
-]
-
-
-class BatteryUtilsTest(mock_calls.TestCase):
-
- _NEXUS_5 = {
- 'name': 'Nexus 5',
- 'witness_file': '/sys/kernel/debug/bq24192/INPUT_SRC_CONT',
- 'enable_command': (
- 'echo 0x4A > /sys/kernel/debug/bq24192/INPUT_SRC_CONT && '
- 'echo 1 > /sys/class/power_supply/usb/online'),
- 'disable_command': (
- 'echo 0xCA > /sys/kernel/debug/bq24192/INPUT_SRC_CONT && '
- 'chmod 644 /sys/class/power_supply/usb/online && '
- 'echo 0 > /sys/class/power_supply/usb/online'),
- 'charge_counter': None,
- 'voltage': None,
- 'current': None,
- }
-
- _NEXUS_6 = {
- 'name': 'Nexus 6',
- 'witness_file': None,
- 'enable_command': None,
- 'disable_command': None,
- 'charge_counter': (
- '/sys/class/power_supply/max170xx_battery/charge_counter_ext'),
- 'voltage': '/sys/class/power_supply/max170xx_battery/voltage_now',
- 'current': '/sys/class/power_supply/max170xx_battery/current_now',
- }
-
- _NEXUS_10 = {
- 'name': 'Nexus 10',
- 'witness_file': None,
- 'enable_command': None,
- 'disable_command': None,
- 'charge_counter': (
- '/sys/class/power_supply/ds2784-fuelgauge/charge_counter_ext'),
- 'voltage': '/sys/class/power_supply/ds2784-fuelgauge/voltage_now',
- 'current': '/sys/class/power_supply/ds2784-fuelgauge/current_now',
- }
-
- def ShellError(self, output=None, status=1):
- def action(cmd, *args, **kwargs):
- raise device_errors.AdbShellCommandFailedError(
- cmd, output, status, str(self.device))
- if output is None:
- output = 'Permission denied\n'
- return action
-
- def setUp(self):
- self.adb = device_utils_test._AdbWrapperMock('0123456789abcdef')
- self.device = device_utils.DeviceUtils(
- self.adb, default_timeout=10, default_retries=0)
- self.watchMethodCalls(self.call.adb, ignore=['GetDeviceSerial'])
- self.battery = battery_utils.BatteryUtils(
- self.device, default_timeout=10, default_retries=0)
-
-
-class BatteryUtilsInitTest(unittest.TestCase):
-
- def testInitWithDeviceUtil(self):
- serial = '0fedcba987654321'
- d = device_utils.DeviceUtils(serial)
- b = battery_utils.BatteryUtils(d)
- self.assertEqual(d, b._device)
-
- def testInitWithMissing_fails(self):
- with self.assertRaises(TypeError):
- battery_utils.BatteryUtils(None)
- with self.assertRaises(TypeError):
- battery_utils.BatteryUtils('')
-
-
-class BatteryUtilsSetChargingTest(BatteryUtilsTest):
-
- @mock.patch('time.sleep', mock.Mock())
- def testSetCharging_enabled(self):
- self.battery._cache['profile'] = self._NEXUS_5
- with self.assertCalls(
- (self.call.device.RunShellCommand(mock.ANY, check_return=True), []),
- (self.call.battery.GetCharging(), False),
- (self.call.device.RunShellCommand(mock.ANY, check_return=True), []),
- (self.call.battery.GetCharging(), True)):
- self.battery.SetCharging(True)
-
- def testSetCharging_alreadyEnabled(self):
- self.battery._cache['profile'] = self._NEXUS_5
- with self.assertCalls(
- (self.call.device.RunShellCommand(mock.ANY, check_return=True), []),
- (self.call.battery.GetCharging(), True)):
- self.battery.SetCharging(True)
-
- @mock.patch('time.sleep', mock.Mock())
- def testSetCharging_disabled(self):
- self.battery._cache['profile'] = self._NEXUS_5
- with self.assertCalls(
- (self.call.device.RunShellCommand(mock.ANY, check_return=True), []),
- (self.call.battery.GetCharging(), True),
- (self.call.device.RunShellCommand(mock.ANY, check_return=True), []),
- (self.call.battery.GetCharging(), False)):
- self.battery.SetCharging(False)
-
-
-class BatteryUtilsSetBatteryMeasurementTest(BatteryUtilsTest):
-
- @mock.patch('time.sleep', mock.Mock())
- def testBatteryMeasurementWifi(self):
- with self.assertCalls(
- (self.call.device.RunShellCommand(
- mock.ANY, retries=0, single_line=True,
- timeout=10, check_return=True), '22'),
- (self.call.battery._ClearPowerData(), True),
- (self.call.device.RunShellCommand(
- ['dumpsys', 'battery', 'set', 'ac', '0'], check_return=True), []),
- (self.call.device.RunShellCommand(
- ['dumpsys', 'battery', 'set', 'usb', '0'], check_return=True), []),
- (self.call.battery.GetCharging(), False),
- (self.call.device.RunShellCommand(
- ['dumpsys', 'battery', 'reset'], check_return=True), []),
- (self.call.battery.GetCharging(), False),
- (self.call.device.RunShellCommand(
- ['dumpsys', 'battery'], check_return=True), ['UPDATES STOPPED']),
- (self.call.battery.GetCharging(), False),
- (self.call.device.RunShellCommand(
- ['dumpsys', 'battery'], check_return=True), [])):
- with self.battery.BatteryMeasurement():
- pass
-
- @mock.patch('time.sleep', mock.Mock())
- def testBatteryMeasurementUsb(self):
- with self.assertCalls(
- (self.call.device.RunShellCommand(
- mock.ANY, retries=0, single_line=True,
- timeout=10, check_return=True), '22'),
- (self.call.battery._ClearPowerData(), True),
- (self.call.device.RunShellCommand(
- ['dumpsys', 'battery', 'set', 'ac', '0'], check_return=True), []),
- (self.call.device.RunShellCommand(
- ['dumpsys', 'battery', 'set', 'usb', '0'], check_return=True), []),
- (self.call.battery.GetCharging(), False),
- (self.call.device.RunShellCommand(
- ['dumpsys', 'battery', 'reset'], check_return=True), []),
- (self.call.battery.GetCharging(), False),
- (self.call.device.RunShellCommand(
- ['dumpsys', 'battery'], check_return=True), ['UPDATES STOPPED']),
- (self.call.battery.GetCharging(), True)):
- with self.battery.BatteryMeasurement():
- pass
-
-
-class BatteryUtilsGetPowerData(BatteryUtilsTest):
-
- def testGetPowerData(self):
- with self.assertCalls(
- (self.call.device.RunShellCommand(
- ['dumpsys', 'batterystats', '-c'], check_return=True),
- _DUMPSYS_OUTPUT)):
- data = self.battery.GetPowerData()
- check = {
- 'test_package1': {'uid': '1000', 'data': [1.0]},
- 'test_package2': {'uid': '1001', 'data': [2.0]}
- }
- self.assertEqual(data, check)
-
- def testGetPowerData_packageCollisionSame(self):
- self.battery._cache['uids'] = {'test_package1': '1000'}
- with self.assertCall(
- self.call.device.RunShellCommand(
- ['dumpsys', 'batterystats', '-c'], check_return=True),
- _DUMPSYS_OUTPUT):
- data = self.battery.GetPowerData()
- check = {
- 'test_package1': {'uid': '1000', 'data': [1.0]},
- 'test_package2': {'uid': '1001', 'data': [2.0]}
- }
- self.assertEqual(data, check)
-
- def testGetPowerData_packageCollisionDifferent(self):
- self.battery._cache['uids'] = {'test_package1': '1'}
- with self.assertCall(
- self.call.device.RunShellCommand(
- ['dumpsys', 'batterystats', '-c'], check_return=True),
- _DUMPSYS_OUTPUT):
- with self.assertRaises(device_errors.CommandFailedError):
- self.battery.GetPowerData()
-
- def testGetPowerData_cacheCleared(self):
- with self.assertCalls(
- (self.call.device.RunShellCommand(
- ['dumpsys', 'batterystats', '-c'], check_return=True),
- _DUMPSYS_OUTPUT)):
- self.battery._cache.clear()
- data = self.battery.GetPowerData()
- check = {
- 'test_package1': {'uid': '1000', 'data': [1.0]},
- 'test_package2': {'uid': '1001', 'data': [2.0]}
- }
- self.assertEqual(data, check)
-
- def testGetPackagePowerData(self):
- with self.assertCalls(
- (self.call.device.RunShellCommand(
- ['dumpsys', 'batterystats', '-c'], check_return=True),
- _DUMPSYS_OUTPUT)):
- data = self.battery.GetPackagePowerData('test_package2')
- self.assertEqual(data, {'uid': '1001', 'data': [2.0]})
-
- def testGetPackagePowerData_badPackage(self):
- with self.assertCalls(
- (self.call.device.RunShellCommand(
- ['dumpsys', 'batterystats', '-c'], check_return=True),
- _DUMPSYS_OUTPUT)):
- data = self.battery.GetPackagePowerData('not_a_package')
- self.assertEqual(data, None)
-
-
-class BatteryUtilsChargeDevice(BatteryUtilsTest):
-
- @mock.patch('time.sleep', mock.Mock())
- def testChargeDeviceToLevel(self):
- with self.assertCalls(
- (self.call.battery.SetCharging(True)),
- (self.call.battery.GetBatteryInfo(), {'level': '50'}),
- (self.call.battery.GetBatteryInfo(), {'level': '100'})):
- self.battery.ChargeDeviceToLevel(95)
-
-
-class BatteryUtilsGetBatteryInfoTest(BatteryUtilsTest):
-
- def testGetBatteryInfo_normal(self):
- with self.assertCall(
- self.call.device.RunShellCommand(
- ['dumpsys', 'battery'], check_return=True),
- [
- 'Current Battery Service state:',
- ' AC powered: false',
- ' USB powered: true',
- ' level: 100',
- ' temperature: 321',
- ]):
- self.assertEquals(
- {
- 'AC powered': 'false',
- 'USB powered': 'true',
- 'level': '100',
- 'temperature': '321',
- },
- self.battery.GetBatteryInfo())
-
- def testGetBatteryInfo_nothing(self):
- with self.assertCall(
- self.call.device.RunShellCommand(
- ['dumpsys', 'battery'], check_return=True), []):
- self.assertEquals({}, self.battery.GetBatteryInfo())
-
-
-class BatteryUtilsGetChargingTest(BatteryUtilsTest):
-
- def testGetCharging_usb(self):
- with self.assertCall(
- self.call.battery.GetBatteryInfo(), {'USB powered': 'true'}):
- self.assertTrue(self.battery.GetCharging())
-
- def testGetCharging_usbFalse(self):
- with self.assertCall(
- self.call.battery.GetBatteryInfo(), {'USB powered': 'false'}):
- self.assertFalse(self.battery.GetCharging())
-
- def testGetCharging_ac(self):
- with self.assertCall(
- self.call.battery.GetBatteryInfo(), {'AC powered': 'true'}):
- self.assertTrue(self.battery.GetCharging())
-
- def testGetCharging_wireless(self):
- with self.assertCall(
- self.call.battery.GetBatteryInfo(), {'Wireless powered': 'true'}):
- self.assertTrue(self.battery.GetCharging())
-
- def testGetCharging_unknown(self):
- with self.assertCall(
- self.call.battery.GetBatteryInfo(), {'level': '42'}):
- self.assertFalse(self.battery.GetCharging())
-
-
-class BatteryUtilsGetNetworkDataTest(BatteryUtilsTest):
-
- def testGetNetworkData_noDataUsage(self):
- with self.assertCalls(
- (self.call.device.RunShellCommand(
- ['dumpsys', 'batterystats', '-c'], check_return=True),
- _DUMPSYS_OUTPUT),
- (self.call.device.ReadFile('/proc/uid_stat/1000/tcp_snd'),
- self.ShellError()),
- (self.call.device.ReadFile('/proc/uid_stat/1000/tcp_rcv'),
- self.ShellError())):
- self.assertEquals(self.battery.GetNetworkData('test_package1'), (0, 0))
-
- def testGetNetworkData_badPackage(self):
- with self.assertCall(
- self.call.device.RunShellCommand(
- ['dumpsys', 'batterystats', '-c'], check_return=True),
- _DUMPSYS_OUTPUT):
- self.assertEqual(self.battery.GetNetworkData('asdf'), None)
-
- def testGetNetworkData_packageNotCached(self):
- with self.assertCalls(
- (self.call.device.RunShellCommand(
- ['dumpsys', 'batterystats', '-c'], check_return=True),
- _DUMPSYS_OUTPUT),
- (self.call.device.ReadFile('/proc/uid_stat/1000/tcp_snd'), 1),
- (self.call.device.ReadFile('/proc/uid_stat/1000/tcp_rcv'), 2)):
- self.assertEqual(self.battery.GetNetworkData('test_package1'), (1,2))
-
- def testGetNetworkData_packageCached(self):
- self.battery._cache['uids'] = {'test_package1': '1000'}
- with self.assertCalls(
- (self.call.device.ReadFile('/proc/uid_stat/1000/tcp_snd'), 1),
- (self.call.device.ReadFile('/proc/uid_stat/1000/tcp_rcv'), 2)):
- self.assertEqual(self.battery.GetNetworkData('test_package1'), (1,2))
-
- def testGetNetworkData_clearedCache(self):
- with self.assertCalls(
- (self.call.device.RunShellCommand(
- ['dumpsys', 'batterystats', '-c'], check_return=True),
- _DUMPSYS_OUTPUT),
- (self.call.device.ReadFile('/proc/uid_stat/1000/tcp_snd'), 1),
- (self.call.device.ReadFile('/proc/uid_stat/1000/tcp_rcv'), 2)):
- self.battery._cache.clear()
- self.assertEqual(self.battery.GetNetworkData('test_package1'), (1,2))
-
-
-class BatteryUtilsLetBatteryCoolToTemperatureTest(BatteryUtilsTest):
-
- @mock.patch('time.sleep', mock.Mock())
- def testLetBatteryCoolToTemperature_startUnder(self):
- with self.assertCalls(
- (self.call.battery.EnableBatteryUpdates(), []),
- (self.call.battery.GetBatteryInfo(), {'temperature': '500'})):
- self.battery.LetBatteryCoolToTemperature(600)
-
- @mock.patch('time.sleep', mock.Mock())
- def testLetBatteryCoolToTemperature_startOver(self):
- with self.assertCalls(
- (self.call.battery.EnableBatteryUpdates(), []),
- (self.call.battery.GetBatteryInfo(), {'temperature': '500'}),
- (self.call.battery.GetBatteryInfo(), {'temperature': '400'})):
- self.battery.LetBatteryCoolToTemperature(400)
-
-class BatteryUtilsSupportsFuelGaugeTest(BatteryUtilsTest):
-
- def testSupportsFuelGauge_false(self):
- self.battery._cache['profile'] = self._NEXUS_5
- self.assertFalse(self.battery.SupportsFuelGauge())
-
- def testSupportsFuelGauge_trueMax(self):
- self.battery._cache['profile'] = self._NEXUS_6
- # TODO(rnephew): Change this to assertTrue when we have support for
- # disabling hardware charging on nexus 6.
- self.assertFalse(self.battery.SupportsFuelGauge())
-
- def testSupportsFuelGauge_trueDS(self):
- self.battery._cache['profile'] = self._NEXUS_10
- # TODO(rnephew): Change this to assertTrue when we have support for
- # disabling hardware charging on nexus 10.
- self.assertFalse(self.battery.SupportsFuelGauge())
-
-
-class BatteryUtilsGetFuelGaugeChargeCounterTest(BatteryUtilsTest):
-
- def testGetFuelGaugeChargeCounter_noFuelGauge(self):
- self.battery._cache['profile'] = self._NEXUS_5
- with self.assertRaises(device_errors.CommandFailedError):
- self.battery.GetFuelGaugeChargeCounter()
-
- def testGetFuelGaugeChargeCounter_fuelGaugePresent(self):
- self.battery._cache['profile']= self._NEXUS_6
- with self.assertCalls(
- (self.call.battery.SupportsFuelGauge(), True),
- (self.call.device.ReadFile(mock.ANY), '123')):
- self.assertEqual(self.battery.GetFuelGaugeChargeCounter(), 123)
-
-
-class BatteryUtilsTieredSetCharging(BatteryUtilsTest):
-
- @mock.patch('time.sleep', mock.Mock())
- def testTieredSetCharging_softwareSetTrue(self):
- self.battery._cache['profile'] = self._NEXUS_6
- with self.assertCalls(
- (self.call.battery.GetCharging(), False),
- (self.call.device.RunShellCommand(
- ['dumpsys', 'battery', 'reset'], check_return=True), []),
- (self.call.battery.GetCharging(), False),
- (self.call.device.RunShellCommand(
- ['dumpsys', 'battery'], check_return=True), ['UPDATES STOPPED']),
- (self.call.battery.GetCharging(), True)):
- self.battery.TieredSetCharging(True)
-
- @mock.patch('time.sleep', mock.Mock())
- def testTieredSetCharging_softwareSetFalse(self):
- self.battery._cache['profile'] = self._NEXUS_6
- with self.assertCalls(
- (self.call.battery.GetCharging(), True),
- (self.call.battery._ClearPowerData(), True),
- (self.call.battery._ClearPowerData(), True),
- (self.call.device.RunShellCommand(
- ['dumpsys', 'battery', 'set', 'ac', '0'], check_return=True), []),
- (self.call.device.RunShellCommand(
- ['dumpsys', 'battery', 'set', 'usb', '0'], check_return=True), []),
- (self.call.battery.GetCharging(), False)):
- self.battery.TieredSetCharging(False)
-
- @mock.patch('time.sleep', mock.Mock())
- def testTieredSetCharging_hardwareSetTrue(self):
- self.battery._cache['profile'] = self._NEXUS_5
- with self.assertCalls(
- (self.call.battery.GetCharging(), False),
- (self.call.battery.SetCharging(True))):
- self.battery.TieredSetCharging(True)
-
- @mock.patch('time.sleep', mock.Mock())
- def testTieredSetCharging_hardwareSetFalse(self):
- self.battery._cache['profile'] = self._NEXUS_5
- with self.assertCalls(
- (self.call.battery.GetCharging(), True),
- (self.call.battery._ClearPowerData(), True),
- (self.call.battery.SetCharging(False))):
- self.battery.TieredSetCharging(False)
-
- def testTieredSetCharging_expectedStateAlreadyTrue(self):
- with self.assertCalls((self.call.battery.GetCharging(), True)):
- self.battery.TieredSetCharging(True)
-
- def testTieredSetCharging_expectedStateAlreadyFalse(self):
- with self.assertCalls((self.call.battery.GetCharging(), False)):
- self.battery.TieredSetCharging(False)
-
-
-class BatteryUtilsPowerMeasurement(BatteryUtilsTest):
-
- def testPowerMeasurement_hardware(self):
- self.battery._cache['profile'] = self._NEXUS_5
- with self.assertCalls(
- (self.call.battery.GetCharging(), True),
- (self.call.battery._ClearPowerData(), True),
- (self.call.battery.SetCharging(False)),
- (self.call.battery.GetCharging(), False),
- (self.call.battery.SetCharging(True))):
- with self.battery.PowerMeasurement():
- pass
-
- @mock.patch('time.sleep', mock.Mock())
- def testPowerMeasurement_software(self):
- self.battery._cache['profile'] = self._NEXUS_6
- with self.assertCalls(
- (self.call.battery.GetCharging(), True),
- (self.call.battery._ClearPowerData(), True),
- (self.call.battery._ClearPowerData(), True),
- (self.call.device.RunShellCommand(
- ['dumpsys', 'battery', 'set', 'ac', '0'], check_return=True), []),
- (self.call.device.RunShellCommand(
- ['dumpsys', 'battery', 'set', 'usb', '0'], check_return=True), []),
- (self.call.battery.GetCharging(), False),
- (self.call.battery.GetCharging(), False),
- (self.call.device.RunShellCommand(
- ['dumpsys', 'battery', 'reset'], check_return=True), []),
- (self.call.battery.GetCharging(), False),
- (self.call.device.RunShellCommand(
- ['dumpsys', 'battery'], check_return=True), ['UPDATES STOPPED']),
- (self.call.battery.GetCharging(), True)):
- with self.battery.PowerMeasurement():
- pass
-
-
-class BatteryUtilsDiscoverDeviceProfile(BatteryUtilsTest):
-
- def testDiscoverDeviceProfile_known(self):
- with self.assertCalls(
- (self.call.adb.Shell('getprop ro.product.model'), "Nexus 4")):
- self.battery._DiscoverDeviceProfile()
- self.assertEqual(self.battery._cache['profile']['name'], "Nexus 4")
-
- def testDiscoverDeviceProfile_unknown(self):
- with self.assertCalls(
- (self.call.adb.Shell('getprop ro.product.model'), "Other")):
- self.battery._DiscoverDeviceProfile()
- self.assertEqual(self.battery._cache['profile']['name'], None)
-
-
-class BatteryUtilsClearPowerData(BatteryUtilsTest):
-
- def testClearPowerData_preL(self):
- with self.assertCalls(
- (self.call.device.RunShellCommand(mock.ANY, retries=0,
- single_line=True, timeout=10, check_return=True), '20')):
- self.assertFalse(self.battery._ClearPowerData())
-
- def testClearPowerData_clearedL(self):
- with self.assertCalls(
- (self.call.device.RunShellCommand(mock.ANY, retries=0,
- single_line=True, timeout=10, check_return=True), '22'),
- (self.call.device.RunShellCommand(
- ['dumpsys', 'battery', 'set', 'usb', '1'], check_return=True), []),
- (self.call.device.RunShellCommand(
- ['dumpsys', 'battery', 'set', 'ac', '1'], check_return=True), []),
- (self.call.device.RunShellCommand(
- ['dumpsys', 'batterystats', '--reset'], check_return=True), []),
- (self.call.device.RunShellCommand(
- ['dumpsys', 'batterystats', '--charged', '--checkin'],
- check_return=True, large_output=True), []),
- (self.call.device.RunShellCommand(
- ['dumpsys', 'battery', 'reset'], check_return=True), [])):
- self.assertTrue(self.battery._ClearPowerData())
-
- def testClearPowerData_notClearedL(self):
- with self.assertCalls(
- (self.call.device.RunShellCommand(mock.ANY, retries=0,
- single_line=True, timeout=10, check_return=True), '22'),
- (self.call.device.RunShellCommand(
- ['dumpsys', 'battery', 'set', 'usb', '1'], check_return=True), []),
- (self.call.device.RunShellCommand(
- ['dumpsys', 'battery', 'set', 'ac', '1'], check_return=True), []),
- (self.call.device.RunShellCommand(
- ['dumpsys', 'batterystats', '--reset'], check_return=True), []),
- (self.call.device.RunShellCommand(
- ['dumpsys', 'batterystats', '--charged', '--checkin'],
- check_return=True, large_output=True),
- ['9,1000,l,pwi,uid,0.0327']),
- (self.call.device.RunShellCommand(
- ['dumpsys', 'battery', 'reset'], check_return=True), [])):
- with self.assertRaises(device_errors.CommandFailedError):
- self.battery._ClearPowerData()
-
-
-if __name__ == '__main__':
- logging.getLogger().setLevel(logging.DEBUG)
- unittest.main(verbosity=2)
diff --git a/build/android/pylib/device/commands/BUILD.gn b/build/android/pylib/device/commands/BUILD.gn
deleted file mode 100644
index 66e1010..0000000
--- a/build/android/pylib/device/commands/BUILD.gn
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/config/android/rules.gni")
-
-group("commands") {
- datadeps = [
- ":chromium_commands",
- ]
-}
-
-# GYP: //build/android/pylib/device/commands/commands.gyp:chromium_commands
-android_library("chromium_commands") {
- java_files = [ "java/src/org/chromium/android/commands/unzip/Unzip.java" ]
- dex_path = "$root_build_dir/lib.java/chromium_commands.dex.jar"
-}
diff --git a/build/android/pylib/device/commands/__init__.py b/build/android/pylib/device/commands/__init__.py
deleted file mode 100644
index 4d6aabb..0000000
--- a/build/android/pylib/device/commands/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
diff --git a/build/android/pylib/device/commands/commands.gyp b/build/android/pylib/device/commands/commands.gyp
deleted file mode 100644
index b5b5bc8..0000000
--- a/build/android/pylib/device/commands/commands.gyp
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
- 'targets': [
- {
- # GN version: //build/android/pylib/devices/commands:chromium_commands
- 'target_name': 'chromium_commands',
- 'type': 'none',
- 'variables': {
- 'add_to_dependents_classpaths': 0,
- 'java_in_dir': ['java'],
- },
- 'includes': [
- '../../../../../build/java.gypi',
- ],
- }
- ],
-}
diff --git a/build/android/pylib/device/commands/install_commands.py b/build/android/pylib/device/commands/install_commands.py
deleted file mode 100644
index 58c56cc..0000000
--- a/build/android/pylib/device/commands/install_commands.py
+++ /dev/null
@@ -1,51 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-
-from pylib import constants
-
-BIN_DIR = '%s/bin' % constants.TEST_EXECUTABLE_DIR
-_FRAMEWORK_DIR = '%s/framework' % constants.TEST_EXECUTABLE_DIR
-
-_COMMANDS = {
- 'unzip': 'org.chromium.android.commands.unzip.Unzip',
-}
-
-_SHELL_COMMAND_FORMAT = (
-"""#!/system/bin/sh
-base=%s
-export CLASSPATH=$base/framework/chromium_commands.jar
-exec app_process $base/bin %s $@
-""")
-
-
-def Installed(device):
- return (all(device.FileExists('%s/%s' % (BIN_DIR, c)) for c in _COMMANDS)
- and device.FileExists('%s/chromium_commands.jar' % _FRAMEWORK_DIR))
-
-def InstallCommands(device):
- if device.IsUserBuild():
- raise Exception('chromium_commands currently requires a userdebug build.')
-
- chromium_commands_jar_path = os.path.join(
- constants.GetOutDirectory(), constants.SDK_BUILD_JAVALIB_DIR,
- 'chromium_commands.dex.jar')
- if not os.path.exists(chromium_commands_jar_path):
- raise Exception('%s not found. Please build chromium_commands.'
- % chromium_commands_jar_path)
-
- device.RunShellCommand(['mkdir', BIN_DIR, _FRAMEWORK_DIR])
- for command, main_class in _COMMANDS.iteritems():
- shell_command = _SHELL_COMMAND_FORMAT % (
- constants.TEST_EXECUTABLE_DIR, main_class)
- shell_file = '%s/%s' % (BIN_DIR, command)
- device.WriteFile(shell_file, shell_command)
- device.RunShellCommand(
- ['chmod', '755', shell_file], check_return=True)
-
- device.adb.Push(
- chromium_commands_jar_path,
- '%s/chromium_commands.jar' % _FRAMEWORK_DIR)
-
diff --git a/build/android/pylib/device/commands/java/src/org/chromium/android/commands/unzip/Unzip.java b/build/android/pylib/device/commands/java/src/org/chromium/android/commands/unzip/Unzip.java
deleted file mode 100644
index 7cbbb73..0000000
--- a/build/android/pylib/device/commands/java/src/org/chromium/android/commands/unzip/Unzip.java
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.android.commands.unzip;
-
-import android.util.Log;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.PrintStream;
-import java.util.zip.ZipEntry;
-import java.util.zip.ZipInputStream;
-
-/**
- * Minimal implementation of the command-line unzip utility for Android.
- */
-public class Unzip {
-
- private static final String TAG = "Unzip";
-
- public static void main(String[] args) {
- try {
- (new Unzip()).run(args);
- } catch (RuntimeException e) {
- Log.e(TAG, e.toString());
- System.exit(1);
- }
- }
-
- private void showUsage(PrintStream s) {
- s.println("Usage:");
- s.println("unzip [zipfile]");
- }
-
- @SuppressWarnings("Finally")
- private void unzip(String[] args) {
- ZipInputStream zis = null;
- try {
- String zipfile = args[0];
- zis = new ZipInputStream(new BufferedInputStream(new FileInputStream(zipfile)));
- ZipEntry ze = null;
-
- byte[] bytes = new byte[1024];
- while ((ze = zis.getNextEntry()) != null) {
- File outputFile = new File(ze.getName());
- if (ze.isDirectory()) {
- if (!outputFile.exists() && !outputFile.mkdirs()) {
- throw new RuntimeException(
- "Failed to create directory: " + outputFile.toString());
- }
- } else {
- File parentDir = outputFile.getParentFile();
- if (!parentDir.exists() && !parentDir.mkdirs()) {
- throw new RuntimeException(
- "Failed to create directory: " + parentDir.toString());
- }
- OutputStream out = new BufferedOutputStream(new FileOutputStream(outputFile));
- int actual_bytes = 0;
- int total_bytes = 0;
- while ((actual_bytes = zis.read(bytes)) != -1) {
- out.write(bytes, 0, actual_bytes);
- total_bytes += actual_bytes;
- }
- out.close();
- }
- zis.closeEntry();
- }
-
- } catch (IOException e) {
- throw new RuntimeException("Error while unzipping: " + e.toString());
- } finally {
- try {
- if (zis != null) zis.close();
- } catch (IOException e) {
- throw new RuntimeException("Error while closing zip: " + e.toString());
- }
- }
- }
-
- public void run(String[] args) {
- if (args.length != 1) {
- showUsage(System.err);
- throw new RuntimeException("Incorrect usage.");
- }
-
- unzip(args);
- }
-}
-
diff --git a/build/android/pylib/device/decorators.py b/build/android/pylib/device/decorators.py
deleted file mode 100644
index 73c13da..0000000
--- a/build/android/pylib/device/decorators.py
+++ /dev/null
@@ -1,157 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""
-Function/method decorators that provide timeout and retry logic.
-"""
-
-import functools
-import os
-import sys
-import threading
-
-from pylib import cmd_helper
-from pylib import constants
-from pylib.device import device_errors
-from pylib.utils import reraiser_thread
-from pylib.utils import timeout_retry
-
-# TODO(jbudorick) Remove once the DeviceUtils implementations are no longer
-# backed by AndroidCommands / android_testrunner.
-sys.path.append(os.path.join(constants.DIR_SOURCE_ROOT, 'third_party',
- 'android_testrunner'))
-import errors as old_errors
-
-DEFAULT_TIMEOUT_ATTR = '_default_timeout'
-DEFAULT_RETRIES_ATTR = '_default_retries'
-
-
-def _TimeoutRetryWrapper(f, timeout_func, retries_func, pass_values=False):
- """ Wraps a funcion with timeout and retry handling logic.
-
- Args:
- f: The function to wrap.
- timeout_func: A callable that returns the timeout value.
- retries_func: A callable that returns the retries value.
- pass_values: If True, passes the values returned by |timeout_func| and
- |retries_func| to the wrapped function as 'timeout' and
- 'retries' kwargs, respectively.
- Returns:
- The wrapped function.
- """
- @functools.wraps(f)
- def TimeoutRetryWrapper(*args, **kwargs):
- timeout = timeout_func(*args, **kwargs)
- retries = retries_func(*args, **kwargs)
- if pass_values:
- kwargs['timeout'] = timeout
- kwargs['retries'] = retries
- def impl():
- return f(*args, **kwargs)
- try:
- if isinstance(threading.current_thread(),
- timeout_retry.TimeoutRetryThread):
- return impl()
- else:
- return timeout_retry.Run(impl, timeout, retries)
- except old_errors.WaitForResponseTimedOutError as e:
- raise device_errors.CommandTimeoutError(str(e)), None, (
- sys.exc_info()[2])
- except old_errors.DeviceUnresponsiveError as e:
- raise device_errors.DeviceUnreachableError(str(e)), None, (
- sys.exc_info()[2])
- except reraiser_thread.TimeoutError as e:
- raise device_errors.CommandTimeoutError(str(e)), None, (
- sys.exc_info()[2])
- except cmd_helper.TimeoutError as e:
- raise device_errors.CommandTimeoutError(str(e)), None, (
- sys.exc_info()[2])
- return TimeoutRetryWrapper
-
-
-def WithTimeoutAndRetries(f):
- """A decorator that handles timeouts and retries.
-
- 'timeout' and 'retries' kwargs must be passed to the function.
-
- Args:
- f: The function to decorate.
- Returns:
- The decorated function.
- """
- get_timeout = lambda *a, **kw: kw['timeout']
- get_retries = lambda *a, **kw: kw['retries']
- return _TimeoutRetryWrapper(f, get_timeout, get_retries)
-
-
-def WithExplicitTimeoutAndRetries(timeout, retries):
- """Returns a decorator that handles timeouts and retries.
-
- The provided |timeout| and |retries| values are always used.
-
- Args:
- timeout: The number of seconds to wait for the decorated function to
- return. Always used.
- retries: The number of times the decorated function should be retried on
- failure. Always used.
- Returns:
- The actual decorator.
- """
- def decorator(f):
- get_timeout = lambda *a, **kw: timeout
- get_retries = lambda *a, **kw: retries
- return _TimeoutRetryWrapper(f, get_timeout, get_retries)
- return decorator
-
-
-def WithTimeoutAndRetriesDefaults(default_timeout, default_retries):
- """Returns a decorator that handles timeouts and retries.
-
- The provided |default_timeout| and |default_retries| values are used only
- if timeout and retries values are not provided.
-
- Args:
- default_timeout: The number of seconds to wait for the decorated function
- to return. Only used if a 'timeout' kwarg is not passed
- to the decorated function.
- default_retries: The number of times the decorated function should be
- retried on failure. Only used if a 'retries' kwarg is not
- passed to the decorated function.
- Returns:
- The actual decorator.
- """
- def decorator(f):
- get_timeout = lambda *a, **kw: kw.get('timeout', default_timeout)
- get_retries = lambda *a, **kw: kw.get('retries', default_retries)
- return _TimeoutRetryWrapper(f, get_timeout, get_retries, pass_values=True)
- return decorator
-
-
-def WithTimeoutAndRetriesFromInstance(
- default_timeout_name=DEFAULT_TIMEOUT_ATTR,
- default_retries_name=DEFAULT_RETRIES_ATTR):
- """Returns a decorator that handles timeouts and retries.
-
- The provided |default_timeout_name| and |default_retries_name| are used to
- get the default timeout value and the default retries value from the object
- instance if timeout and retries values are not provided.
-
- Note that this should only be used to decorate methods, not functions.
-
- Args:
- default_timeout_name: The name of the default timeout attribute of the
- instance.
- default_retries_name: The name of the default retries attribute of the
- instance.
- Returns:
- The actual decorator.
- """
- def decorator(f):
- def get_timeout(inst, *_args, **kwargs):
- return kwargs.get('timeout', getattr(inst, default_timeout_name))
- def get_retries(inst, *_args, **kwargs):
- return kwargs.get('retries', getattr(inst, default_retries_name))
- return _TimeoutRetryWrapper(f, get_timeout, get_retries, pass_values=True)
- return decorator
-
diff --git a/build/android/pylib/device/decorators_test.py b/build/android/pylib/device/decorators_test.py
deleted file mode 100644
index b75618b..0000000
--- a/build/android/pylib/device/decorators_test.py
+++ /dev/null
@@ -1,365 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""
-Unit tests for decorators.py.
-"""
-
-# pylint: disable=W0613
-
-import os
-import sys
-import time
-import traceback
-import unittest
-
-from pylib import constants
-from pylib.device import decorators
-from pylib.device import device_errors
-from pylib.utils import reraiser_thread
-
-# TODO(jbudorick) Remove once the DeviceUtils implementations are no longer
-# backed by AndroidCommands / android_testrunner.
-sys.path.append(os.path.join(constants.DIR_SOURCE_ROOT, 'third_party',
- 'android_testrunner'))
-import errors as old_errors
-
-_DEFAULT_TIMEOUT = 30
-_DEFAULT_RETRIES = 3
-
-class DecoratorsTest(unittest.TestCase):
- _decorated_function_called_count = 0
-
- def testFunctionDecoratorDoesTimeouts(self):
- """Tests that the base decorator handles the timeout logic."""
- DecoratorsTest._decorated_function_called_count = 0
- @decorators.WithTimeoutAndRetries
- def alwaysTimesOut(timeout=None, retries=None):
- DecoratorsTest._decorated_function_called_count += 1
- time.sleep(100)
-
- start_time = time.time()
- with self.assertRaises(device_errors.CommandTimeoutError):
- alwaysTimesOut(timeout=1, retries=0)
- elapsed_time = time.time() - start_time
- self.assertTrue(elapsed_time >= 1)
- self.assertEquals(1, DecoratorsTest._decorated_function_called_count)
-
- def testFunctionDecoratorDoesRetries(self):
- """Tests that the base decorator handles the retries logic."""
- DecoratorsTest._decorated_function_called_count = 0
- @decorators.WithTimeoutAndRetries
- def alwaysRaisesCommandFailedError(timeout=None, retries=None):
- DecoratorsTest._decorated_function_called_count += 1
- raise device_errors.CommandFailedError('testCommand failed')
-
- with self.assertRaises(device_errors.CommandFailedError):
- alwaysRaisesCommandFailedError(timeout=30, retries=10)
- self.assertEquals(11, DecoratorsTest._decorated_function_called_count)
-
- def testFunctionDecoratorRequiresParams(self):
- """Tests that the base decorator requires timeout and retries params."""
- @decorators.WithTimeoutAndRetries
- def requiresExplicitTimeoutAndRetries(timeout=None, retries=None):
- return (timeout, retries)
-
- with self.assertRaises(KeyError):
- requiresExplicitTimeoutAndRetries()
- with self.assertRaises(KeyError):
- requiresExplicitTimeoutAndRetries(timeout=10)
- with self.assertRaises(KeyError):
- requiresExplicitTimeoutAndRetries(retries=0)
- expected_timeout = 10
- expected_retries = 1
- (actual_timeout, actual_retries) = (
- requiresExplicitTimeoutAndRetries(timeout=expected_timeout,
- retries=expected_retries))
- self.assertEquals(expected_timeout, actual_timeout)
- self.assertEquals(expected_retries, actual_retries)
-
- def testFunctionDecoratorTranslatesOldExceptions(self):
- """Tests that the explicit decorator translates old exceptions."""
- @decorators.WithTimeoutAndRetries
- def alwaysRaisesProvidedException(exception, timeout=None, retries=None):
- raise exception
-
- exception_desc = 'Old response timeout error'
- with self.assertRaises(device_errors.CommandTimeoutError) as e:
- alwaysRaisesProvidedException(
- old_errors.WaitForResponseTimedOutError(exception_desc),
- timeout=10, retries=1)
- self.assertEquals(exception_desc, str(e.exception))
-
- exception_desc = 'Old device error'
- with self.assertRaises(device_errors.DeviceUnreachableError) as e:
- alwaysRaisesProvidedException(
- old_errors.DeviceUnresponsiveError(exception_desc),
- timeout=10, retries=1)
- self.assertEquals(exception_desc, str(e.exception))
-
- def testFunctionDecoratorTranslatesReraiserExceptions(self):
- """Tests that the explicit decorator translates reraiser exceptions."""
- @decorators.WithTimeoutAndRetries
- def alwaysRaisesProvidedException(exception, timeout=None, retries=None):
- raise exception
-
- exception_desc = 'Reraiser thread timeout error'
- with self.assertRaises(device_errors.CommandTimeoutError) as e:
- alwaysRaisesProvidedException(
- reraiser_thread.TimeoutError(exception_desc),
- timeout=10, retries=1)
- self.assertEquals(exception_desc, str(e.exception))
-
- def testDefaultsFunctionDecoratorDoesTimeouts(self):
- """Tests that the defaults decorator handles timeout logic."""
- DecoratorsTest._decorated_function_called_count = 0
- @decorators.WithTimeoutAndRetriesDefaults(1, 0)
- def alwaysTimesOut(timeout=None, retries=None):
- DecoratorsTest._decorated_function_called_count += 1
- time.sleep(100)
-
- start_time = time.time()
- with self.assertRaises(device_errors.CommandTimeoutError):
- alwaysTimesOut()
- elapsed_time = time.time() - start_time
- self.assertTrue(elapsed_time >= 1)
- self.assertEquals(1, DecoratorsTest._decorated_function_called_count)
-
- DecoratorsTest._decorated_function_called_count = 0
- with self.assertRaises(device_errors.CommandTimeoutError):
- alwaysTimesOut(timeout=2)
- elapsed_time = time.time() - start_time
- self.assertTrue(elapsed_time >= 2)
- self.assertEquals(1, DecoratorsTest._decorated_function_called_count)
-
- def testDefaultsFunctionDecoratorDoesRetries(self):
- """Tests that the defaults decorator handles retries logic."""
- DecoratorsTest._decorated_function_called_count = 0
- @decorators.WithTimeoutAndRetriesDefaults(30, 10)
- def alwaysRaisesCommandFailedError(timeout=None, retries=None):
- DecoratorsTest._decorated_function_called_count += 1
- raise device_errors.CommandFailedError('testCommand failed')
-
- with self.assertRaises(device_errors.CommandFailedError):
- alwaysRaisesCommandFailedError()
- self.assertEquals(11, DecoratorsTest._decorated_function_called_count)
-
- DecoratorsTest._decorated_function_called_count = 0
- with self.assertRaises(device_errors.CommandFailedError):
- alwaysRaisesCommandFailedError(retries=5)
- self.assertEquals(6, DecoratorsTest._decorated_function_called_count)
-
- def testDefaultsFunctionDecoratorPassesValues(self):
- """Tests that the defaults decorator passes timeout and retries kwargs."""
- @decorators.WithTimeoutAndRetriesDefaults(30, 10)
- def alwaysReturnsTimeouts(timeout=None, retries=None):
- return timeout
-
- self.assertEquals(30, alwaysReturnsTimeouts())
- self.assertEquals(120, alwaysReturnsTimeouts(timeout=120))
-
- @decorators.WithTimeoutAndRetriesDefaults(30, 10)
- def alwaysReturnsRetries(timeout=None, retries=None):
- return retries
-
- self.assertEquals(10, alwaysReturnsRetries())
- self.assertEquals(1, alwaysReturnsRetries(retries=1))
-
- def testDefaultsFunctionDecoratorTranslatesOldExceptions(self):
- """Tests that the explicit decorator translates old exceptions."""
- @decorators.WithTimeoutAndRetriesDefaults(30, 10)
- def alwaysRaisesProvidedException(exception, timeout=None, retries=None):
- raise exception
-
- exception_desc = 'Old response timeout error'
- with self.assertRaises(device_errors.CommandTimeoutError) as e:
- alwaysRaisesProvidedException(
- old_errors.WaitForResponseTimedOutError(exception_desc))
- self.assertEquals(exception_desc, str(e.exception))
-
- exception_desc = 'Old device error'
- with self.assertRaises(device_errors.DeviceUnreachableError) as e:
- alwaysRaisesProvidedException(
- old_errors.DeviceUnresponsiveError(exception_desc))
- self.assertEquals(exception_desc, str(e.exception))
-
- def testDefaultsFunctionDecoratorTranslatesReraiserExceptions(self):
- """Tests that the explicit decorator translates reraiser exceptions."""
- @decorators.WithTimeoutAndRetriesDefaults(30, 10)
- def alwaysRaisesProvidedException(exception, timeout=None, retries=None):
- raise exception
-
- exception_desc = 'Reraiser thread timeout error'
- with self.assertRaises(device_errors.CommandTimeoutError) as e:
- alwaysRaisesProvidedException(
- reraiser_thread.TimeoutError(exception_desc))
- self.assertEquals(exception_desc, str(e.exception))
-
- def testExplicitFunctionDecoratorDoesTimeouts(self):
- """Tests that the explicit decorator handles timeout logic."""
- DecoratorsTest._decorated_function_called_count = 0
- @decorators.WithExplicitTimeoutAndRetries(1, 0)
- def alwaysTimesOut():
- DecoratorsTest._decorated_function_called_count += 1
- time.sleep(100)
-
- start_time = time.time()
- with self.assertRaises(device_errors.CommandTimeoutError):
- alwaysTimesOut()
- elapsed_time = time.time() - start_time
- self.assertTrue(elapsed_time >= 1)
- self.assertEquals(1, DecoratorsTest._decorated_function_called_count)
-
- def testExplicitFunctionDecoratorDoesRetries(self):
- """Tests that the explicit decorator handles retries logic."""
- DecoratorsTest._decorated_function_called_count = 0
- @decorators.WithExplicitTimeoutAndRetries(30, 10)
- def alwaysRaisesCommandFailedError():
- DecoratorsTest._decorated_function_called_count += 1
- raise device_errors.CommandFailedError('testCommand failed')
-
- with self.assertRaises(device_errors.CommandFailedError):
- alwaysRaisesCommandFailedError()
- self.assertEquals(11, DecoratorsTest._decorated_function_called_count)
-
- def testExplicitDecoratorTranslatesOldExceptions(self):
- """Tests that the explicit decorator translates old exceptions."""
- @decorators.WithExplicitTimeoutAndRetries(30, 10)
- def alwaysRaisesProvidedException(exception):
- raise exception
-
- exception_desc = 'Old response timeout error'
- with self.assertRaises(device_errors.CommandTimeoutError) as e:
- alwaysRaisesProvidedException(
- old_errors.WaitForResponseTimedOutError(exception_desc))
- self.assertEquals(exception_desc, str(e.exception))
-
- exception_desc = 'Old device error'
- with self.assertRaises(device_errors.DeviceUnreachableError) as e:
- alwaysRaisesProvidedException(
- old_errors.DeviceUnresponsiveError(exception_desc))
- self.assertEquals(exception_desc, str(e.exception))
-
- def testExplicitDecoratorTranslatesReraiserExceptions(self):
- """Tests that the explicit decorator translates reraiser exceptions."""
- @decorators.WithExplicitTimeoutAndRetries(30, 10)
- def alwaysRaisesProvidedException(exception):
- raise exception
-
- exception_desc = 'Reraiser thread timeout error'
- with self.assertRaises(device_errors.CommandTimeoutError) as e:
- alwaysRaisesProvidedException(
- reraiser_thread.TimeoutError(exception_desc))
- self.assertEquals(exception_desc, str(e.exception))
-
- class _MethodDecoratorTestObject(object):
- """An object suitable for testing the method decorator."""
-
- def __init__(self, test_case, default_timeout=_DEFAULT_TIMEOUT,
- default_retries=_DEFAULT_RETRIES):
- self._test_case = test_case
- self.default_timeout = default_timeout
- self.default_retries = default_retries
- self.function_call_counters = {
- 'alwaysRaisesCommandFailedError': 0,
- 'alwaysTimesOut': 0,
- 'requiresExplicitTimeoutAndRetries': 0,
- }
-
- @decorators.WithTimeoutAndRetriesFromInstance(
- 'default_timeout', 'default_retries')
- def alwaysTimesOut(self, timeout=None, retries=None):
- self.function_call_counters['alwaysTimesOut'] += 1
- time.sleep(100)
- self._test_case.assertFalse(True, msg='Failed to time out?')
-
- @decorators.WithTimeoutAndRetriesFromInstance(
- 'default_timeout', 'default_retries')
- def alwaysRaisesCommandFailedError(self, timeout=None, retries=None):
- self.function_call_counters['alwaysRaisesCommandFailedError'] += 1
- raise device_errors.CommandFailedError('testCommand failed')
-
- # pylint: disable=no-self-use
-
- @decorators.WithTimeoutAndRetriesFromInstance(
- 'default_timeout', 'default_retries')
- def alwaysReturnsTimeout(self, timeout=None, retries=None):
- return timeout
-
- @decorators.WithTimeoutAndRetriesFromInstance(
- 'default_timeout', 'default_retries')
- def alwaysReturnsRetries(self, timeout=None, retries=None):
- return retries
-
- @decorators.WithTimeoutAndRetriesFromInstance(
- 'default_timeout', 'default_retries')
- def alwaysRaisesProvidedException(self, exception, timeout=None,
- retries=None):
- raise exception
-
- # pylint: enable=no-self-use
-
-
- def testMethodDecoratorDoesTimeout(self):
- """Tests that the method decorator handles timeout logic."""
- test_obj = self._MethodDecoratorTestObject(self)
- start_time = time.time()
- with self.assertRaises(device_errors.CommandTimeoutError):
- try:
- test_obj.alwaysTimesOut(timeout=1, retries=0)
- except:
- traceback.print_exc()
- raise
- elapsed_time = time.time() - start_time
- self.assertTrue(elapsed_time >= 1)
- self.assertEquals(1, test_obj.function_call_counters['alwaysTimesOut'])
-
- def testMethodDecoratorDoesRetries(self):
- """Tests that the method decorator handles retries logic."""
- test_obj = self._MethodDecoratorTestObject(self)
- with self.assertRaises(device_errors.CommandFailedError):
- try:
- test_obj.alwaysRaisesCommandFailedError(retries=10)
- except:
- traceback.print_exc()
- raise
- self.assertEquals(
- 11, test_obj.function_call_counters['alwaysRaisesCommandFailedError'])
-
- def testMethodDecoratorPassesValues(self):
- """Tests that the method decorator passes timeout and retries kwargs."""
- test_obj = self._MethodDecoratorTestObject(
- self, default_timeout=42, default_retries=31)
- self.assertEquals(42, test_obj.alwaysReturnsTimeout())
- self.assertEquals(41, test_obj.alwaysReturnsTimeout(timeout=41))
- self.assertEquals(31, test_obj.alwaysReturnsRetries())
- self.assertEquals(32, test_obj.alwaysReturnsRetries(retries=32))
-
- def testMethodDecoratorTranslatesOldExceptions(self):
- test_obj = self._MethodDecoratorTestObject(self)
-
- exception_desc = 'Old response timeout error'
- with self.assertRaises(device_errors.CommandTimeoutError) as e:
- test_obj.alwaysRaisesProvidedException(
- old_errors.WaitForResponseTimedOutError(exception_desc))
- self.assertEquals(exception_desc, str(e.exception))
-
- exception_desc = 'Old device error'
- with self.assertRaises(device_errors.DeviceUnreachableError) as e:
- test_obj.alwaysRaisesProvidedException(
- old_errors.DeviceUnresponsiveError(exception_desc))
- self.assertEquals(exception_desc, str(e.exception))
-
- def testMethodDecoratorTranslatesReraiserExceptions(self):
- test_obj = self._MethodDecoratorTestObject(self)
-
- exception_desc = 'Reraiser thread timeout error'
- with self.assertRaises(device_errors.CommandTimeoutError) as e:
- test_obj.alwaysRaisesProvidedException(
- reraiser_thread.TimeoutError(exception_desc))
- self.assertEquals(exception_desc, str(e.exception))
-
-if __name__ == '__main__':
- unittest.main(verbosity=2)
-
diff --git a/build/android/pylib/device/device_blacklist.py b/build/android/pylib/device/device_blacklist.py
deleted file mode 100644
index a141d62..0000000
--- a/build/android/pylib/device/device_blacklist.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import json
-import os
-import threading
-
-from pylib import constants
-_BLACKLIST_JSON = os.path.join(
- constants.DIR_SOURCE_ROOT,
- os.environ.get('CHROMIUM_OUT_DIR', 'out'),
- 'bad_devices.json')
-
-# Note that this only protects against concurrent accesses to the blacklist
-# within a process.
-_blacklist_lock = threading.RLock()
-
-def ReadBlacklist():
- """Reads the blacklist from the _BLACKLIST_JSON file.
-
- Returns:
- A list containing bad devices.
- """
- with _blacklist_lock:
- if not os.path.exists(_BLACKLIST_JSON):
- return []
-
- with open(_BLACKLIST_JSON, 'r') as f:
- return json.load(f)
-
-
-def WriteBlacklist(blacklist):
- """Writes the provided blacklist to the _BLACKLIST_JSON file.
-
- Args:
- blacklist: list of bad devices to write to the _BLACKLIST_JSON file.
- """
- with _blacklist_lock:
- with open(_BLACKLIST_JSON, 'w') as f:
- json.dump(list(set(blacklist)), f)
-
-
-def ExtendBlacklist(devices):
- """Adds devices to _BLACKLIST_JSON file.
-
- Args:
- devices: list of bad devices to be added to the _BLACKLIST_JSON file.
- """
- with _blacklist_lock:
- blacklist = ReadBlacklist()
- blacklist.extend(devices)
- WriteBlacklist(blacklist)
-
-
-def ResetBlacklist():
- """Erases the _BLACKLIST_JSON file if it exists."""
- with _blacklist_lock:
- if os.path.exists(_BLACKLIST_JSON):
- os.remove(_BLACKLIST_JSON)
-
diff --git a/build/android/pylib/device/device_errors.py b/build/android/pylib/device/device_errors.py
deleted file mode 100644
index 2492015..0000000
--- a/build/android/pylib/device/device_errors.py
+++ /dev/null
@@ -1,89 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""
-Exception classes raised by AdbWrapper and DeviceUtils.
-"""
-
-from pylib import cmd_helper
-from pylib.utils import base_error
-
-
-class CommandFailedError(base_error.BaseError):
- """Exception for command failures."""
-
- def __init__(self, message, device_serial=None):
- if device_serial is not None:
- message = '(device: %s) %s' % (device_serial, message)
- self.device_serial = device_serial
- super(CommandFailedError, self).__init__(message)
-
-
-class AdbCommandFailedError(CommandFailedError):
- """Exception for adb command failures."""
-
- def __init__(self, args, output, status=None, device_serial=None,
- message=None):
- self.args = args
- self.output = output
- self.status = status
- if not message:
- adb_cmd = ' '.join(cmd_helper.SingleQuote(arg) for arg in self.args)
- message = ['adb %s: failed ' % adb_cmd]
- if status:
- message.append('with exit status %s ' % self.status)
- if output:
- message.append('and output:\n')
- message.extend('- %s\n' % line for line in output.splitlines())
- else:
- message.append('and no output.')
- message = ''.join(message)
- super(AdbCommandFailedError, self).__init__(message, device_serial)
-
-
-class DeviceVersionError(CommandFailedError):
- """Exception for device version failures."""
-
- def __init__(self, message, device_serial=None):
- super(DeviceVersionError, self).__init__(message, device_serial)
-
-
-class AdbShellCommandFailedError(AdbCommandFailedError):
- """Exception for shell command failures run via adb."""
-
- def __init__(self, command, output, status, device_serial=None):
- self.command = command
- message = ['shell command run via adb failed on the device:\n',
- ' command: %s\n' % command]
- message.append(' exit status: %s\n' % status)
- if output:
- message.append(' output:\n')
- if isinstance(output, basestring):
- output_lines = output.splitlines()
- else:
- output_lines = output
- message.extend(' - %s\n' % line for line in output_lines)
- else:
- message.append(" output: ''\n")
- message = ''.join(message)
- super(AdbShellCommandFailedError, self).__init__(
- ['shell', command], output, status, device_serial, message)
-
-
-class CommandTimeoutError(base_error.BaseError):
- """Exception for command timeouts."""
- pass
-
-
-class DeviceUnreachableError(base_error.BaseError):
- """Exception for device unreachable failures."""
- pass
-
-
-class NoDevicesError(base_error.BaseError):
- """Exception for having no devices attached."""
-
- def __init__(self):
- super(NoDevicesError, self).__init__(
- 'No devices attached.', is_infra_error=True)
diff --git a/build/android/pylib/device/device_list.py b/build/android/pylib/device/device_list.py
deleted file mode 100644
index 0eb6acb..0000000
--- a/build/android/pylib/device/device_list.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""A module to keep track of devices across builds."""
-
-import os
-
-LAST_DEVICES_FILENAME = '.last_devices'
-LAST_MISSING_DEVICES_FILENAME = '.last_missing'
-
-
-def GetPersistentDeviceList(file_name):
- """Returns a list of devices.
-
- Args:
- file_name: the file name containing a list of devices.
-
- Returns: List of device serial numbers that were on the bot.
- """
- with open(file_name) as f:
- return f.read().splitlines()
-
-
-def WritePersistentDeviceList(file_name, device_list):
- path = os.path.dirname(file_name)
- if not os.path.exists(path):
- os.makedirs(path)
- with open(file_name, 'w') as f:
- f.write('\n'.join(set(device_list)))
diff --git a/build/android/pylib/device/device_utils.py b/build/android/pylib/device/device_utils.py
deleted file mode 100644
index f201ef3..0000000
--- a/build/android/pylib/device/device_utils.py
+++ /dev/null
@@ -1,1754 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Provides a variety of device interactions based on adb.
-
-Eventually, this will be based on adb_wrapper.
-"""
-# pylint: disable=unused-argument
-
-import collections
-import contextlib
-import itertools
-import logging
-import multiprocessing
-import os
-import posixpath
-import re
-import shutil
-import sys
-import tempfile
-import time
-import zipfile
-
-import pylib.android_commands
-from pylib import cmd_helper
-from pylib import constants
-from pylib import device_signal
-from pylib.constants import keyevent
-from pylib.device import adb_wrapper
-from pylib.device import decorators
-from pylib.device import device_blacklist
-from pylib.device import device_errors
-from pylib.device import intent
-from pylib.device import logcat_monitor
-from pylib.device.commands import install_commands
-from pylib.sdk import split_select
-from pylib.utils import apk_helper
-from pylib.utils import base_error
-from pylib.utils import device_temp_file
-from pylib.utils import host_utils
-from pylib.utils import md5sum
-from pylib.utils import parallelizer
-from pylib.utils import timeout_retry
-from pylib.utils import zip_utils
-
-_DEFAULT_TIMEOUT = 30
-_DEFAULT_RETRIES = 3
-
-# A sentinel object for default values
-# TODO(jbudorick,perezju): revisit how default values are handled by
-# the timeout_retry decorators.
-DEFAULT = object()
-
-_CONTROL_CHARGING_COMMANDS = [
- {
- # Nexus 4
- 'witness_file': '/sys/module/pm8921_charger/parameters/disabled',
- 'enable_command': 'echo 0 > /sys/module/pm8921_charger/parameters/disabled',
- 'disable_command':
- 'echo 1 > /sys/module/pm8921_charger/parameters/disabled',
- },
- {
- # Nexus 5
- # Setting the HIZ bit of the bq24192 causes the charger to actually ignore
- # energy coming from USB. Setting the power_supply offline just updates the
- # Android system to reflect that.
- 'witness_file': '/sys/kernel/debug/bq24192/INPUT_SRC_CONT',
- 'enable_command': (
- 'echo 0x4A > /sys/kernel/debug/bq24192/INPUT_SRC_CONT && '
- 'echo 1 > /sys/class/power_supply/usb/online'),
- 'disable_command': (
- 'echo 0xCA > /sys/kernel/debug/bq24192/INPUT_SRC_CONT && '
- 'chmod 644 /sys/class/power_supply/usb/online && '
- 'echo 0 > /sys/class/power_supply/usb/online'),
- },
-]
-
-
-@decorators.WithExplicitTimeoutAndRetries(
- _DEFAULT_TIMEOUT, _DEFAULT_RETRIES)
-def GetAVDs():
- """Returns a list of Android Virtual Devices.
-
- Returns:
- A list containing the configured AVDs.
- """
- lines = cmd_helper.GetCmdOutput([
- os.path.join(constants.ANDROID_SDK_ROOT, 'tools', 'android'),
- 'list', 'avd']).splitlines()
- avds = []
- for line in lines:
- if 'Name:' not in line:
- continue
- key, value = (s.strip() for s in line.split(':', 1))
- if key == 'Name':
- avds.append(value)
- return avds
-
-
-@decorators.WithExplicitTimeoutAndRetries(
- _DEFAULT_TIMEOUT, _DEFAULT_RETRIES)
-def RestartServer():
- """Restarts the adb server.
-
- Raises:
- CommandFailedError if we fail to kill or restart the server.
- """
- def adb_killed():
- return not adb_wrapper.AdbWrapper.IsServerOnline()
-
- def adb_started():
- return adb_wrapper.AdbWrapper.IsServerOnline()
-
- adb_wrapper.AdbWrapper.KillServer()
- if not timeout_retry.WaitFor(adb_killed, wait_period=1, max_tries=5):
- # TODO(perezju): raise an exception after fixng http://crbug.com/442319
- logging.warning('Failed to kill adb server')
- adb_wrapper.AdbWrapper.StartServer()
- if not timeout_retry.WaitFor(adb_started, wait_period=1, max_tries=5):
- raise device_errors.CommandFailedError('Failed to start adb server')
-
-
-def _GetTimeStamp():
- """Return a basic ISO 8601 time stamp with the current local time."""
- return time.strftime('%Y%m%dT%H%M%S', time.localtime())
-
-
-def _JoinLines(lines):
- # makes sure that the last line is also terminated, and is more memory
- # efficient than first appending an end-line to each line and then joining
- # all of them together.
- return ''.join(s for line in lines for s in (line, '\n'))
-
-
-class DeviceUtils(object):
-
- _MAX_ADB_COMMAND_LENGTH = 512
- _MAX_ADB_OUTPUT_LENGTH = 32768
- _LAUNCHER_FOCUSED_RE = re.compile(
- '\s*mCurrentFocus.*(Launcher|launcher).*')
- _VALID_SHELL_VARIABLE = re.compile('^[a-zA-Z_][a-zA-Z0-9_]*$')
-
- # Property in /data/local.prop that controls Java assertions.
- JAVA_ASSERT_PROPERTY = 'dalvik.vm.enableassertions'
-
- def __init__(self, device, default_timeout=_DEFAULT_TIMEOUT,
- default_retries=_DEFAULT_RETRIES):
- """DeviceUtils constructor.
-
- Args:
- device: Either a device serial, an existing AdbWrapper instance, or an
- an existing AndroidCommands instance.
- default_timeout: An integer containing the default number of seconds to
- wait for an operation to complete if no explicit value
- is provided.
- default_retries: An integer containing the default number or times an
- operation should be retried on failure if no explicit
- value is provided.
- """
- self.adb = None
- self.old_interface = None
- if isinstance(device, basestring):
- self.adb = adb_wrapper.AdbWrapper(device)
- self.old_interface = pylib.android_commands.AndroidCommands(device)
- elif isinstance(device, adb_wrapper.AdbWrapper):
- self.adb = device
- self.old_interface = pylib.android_commands.AndroidCommands(str(device))
- elif isinstance(device, pylib.android_commands.AndroidCommands):
- self.adb = adb_wrapper.AdbWrapper(device.GetDevice())
- self.old_interface = device
- else:
- raise ValueError('Unsupported device value: %r' % device)
- self._commands_installed = None
- self._default_timeout = default_timeout
- self._default_retries = default_retries
- self._cache = {}
- self._client_caches = {}
- assert hasattr(self, decorators.DEFAULT_TIMEOUT_ATTR)
- assert hasattr(self, decorators.DEFAULT_RETRIES_ATTR)
-
- def __eq__(self, other):
- """Checks whether |other| refers to the same device as |self|.
-
- Args:
- other: The object to compare to. This can be a basestring, an instance
- of adb_wrapper.AdbWrapper, or an instance of DeviceUtils.
- Returns:
- Whether |other| refers to the same device as |self|.
- """
- return self.adb.GetDeviceSerial() == str(other)
-
- def __lt__(self, other):
- """Compares two instances of DeviceUtils.
-
- This merely compares their serial numbers.
-
- Args:
- other: The instance of DeviceUtils to compare to.
- Returns:
- Whether |self| is less than |other|.
- """
- return self.adb.GetDeviceSerial() < other.adb.GetDeviceSerial()
-
- def __str__(self):
- """Returns the device serial."""
- return self.adb.GetDeviceSerial()
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def IsOnline(self, timeout=None, retries=None):
- """Checks whether the device is online.
-
- Args:
- timeout: timeout in seconds
- retries: number of retries
-
- Returns:
- True if the device is online, False otherwise.
-
- Raises:
- CommandTimeoutError on timeout.
- """
- try:
- return self.adb.GetState() == 'device'
- except base_error.BaseError as exc:
- logging.info('Failed to get state: %s', exc)
- return False
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def HasRoot(self, timeout=None, retries=None):
- """Checks whether or not adbd has root privileges.
-
- Args:
- timeout: timeout in seconds
- retries: number of retries
-
- Returns:
- True if adbd has root privileges, False otherwise.
-
- Raises:
- CommandTimeoutError on timeout.
- DeviceUnreachableError on missing device.
- """
- try:
- self.RunShellCommand('ls /root', check_return=True)
- return True
- except device_errors.AdbCommandFailedError:
- return False
-
- def NeedsSU(self, timeout=DEFAULT, retries=DEFAULT):
- """Checks whether 'su' is needed to access protected resources.
-
- Args:
- timeout: timeout in seconds
- retries: number of retries
-
- Returns:
- True if 'su' is available on the device and is needed to to access
- protected resources; False otherwise if either 'su' is not available
- (e.g. because the device has a user build), or not needed (because adbd
- already has root privileges).
-
- Raises:
- CommandTimeoutError on timeout.
- DeviceUnreachableError on missing device.
- """
- if 'needs_su' not in self._cache:
- try:
- self.RunShellCommand(
- 'su -c ls /root && ! ls /root', check_return=True,
- timeout=self._default_timeout if timeout is DEFAULT else timeout,
- retries=self._default_retries if retries is DEFAULT else retries)
- self._cache['needs_su'] = True
- except device_errors.AdbCommandFailedError:
- self._cache['needs_su'] = False
- return self._cache['needs_su']
-
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def EnableRoot(self, timeout=None, retries=None):
- """Restarts adbd with root privileges.
-
- Args:
- timeout: timeout in seconds
- retries: number of retries
-
- Raises:
- CommandFailedError if root could not be enabled.
- CommandTimeoutError on timeout.
- """
- if self.IsUserBuild():
- raise device_errors.CommandFailedError(
- 'Cannot enable root in user builds.', str(self))
- if 'needs_su' in self._cache:
- del self._cache['needs_su']
- self.adb.Root()
- self.WaitUntilFullyBooted()
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def IsUserBuild(self, timeout=None, retries=None):
- """Checks whether or not the device is running a user build.
-
- Args:
- timeout: timeout in seconds
- retries: number of retries
-
- Returns:
- True if the device is running a user build, False otherwise (i.e. if
- it's running a userdebug build).
-
- Raises:
- CommandTimeoutError on timeout.
- DeviceUnreachableError on missing device.
- """
- return self.build_type == 'user'
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def GetExternalStoragePath(self, timeout=None, retries=None):
- """Get the device's path to its SD card.
-
- Args:
- timeout: timeout in seconds
- retries: number of retries
-
- Returns:
- The device's path to its SD card.
-
- Raises:
- CommandFailedError if the external storage path could not be determined.
- CommandTimeoutError on timeout.
- DeviceUnreachableError on missing device.
- """
- if 'external_storage' in self._cache:
- return self._cache['external_storage']
-
- value = self.RunShellCommand('echo $EXTERNAL_STORAGE',
- single_line=True,
- check_return=True)
- if not value:
- raise device_errors.CommandFailedError('$EXTERNAL_STORAGE is not set',
- str(self))
- self._cache['external_storage'] = value
- return value
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def GetApplicationPaths(self, package, timeout=None, retries=None):
- """Get the paths of the installed apks on the device for the given package.
-
- Args:
- package: Name of the package.
-
- Returns:
- List of paths to the apks on the device for the given package.
- """
- # 'pm path' is liable to incorrectly exit with a nonzero number starting
- # in Lollipop.
- # TODO(jbudorick): Check if this is fixed as new Android versions are
- # released to put an upper bound on this.
- should_check_return = (self.build_version_sdk <
- constants.ANDROID_SDK_VERSION_CODES.LOLLIPOP)
- output = self.RunShellCommand(
- ['pm', 'path', package], check_return=should_check_return)
- apks = []
- for line in output:
- if not line.startswith('package:'):
- raise device_errors.CommandFailedError(
- 'pm path returned: %r' % '\n'.join(output), str(self))
- apks.append(line[len('package:'):])
- return apks
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def GetApplicationDataDirectory(self, package, timeout=None, retries=None):
- """Get the data directory on the device for the given package.
-
- Args:
- package: Name of the package.
-
- Returns:
- The package's data directory, or None if the package doesn't exist on the
- device.
- """
- try:
- output = self._RunPipedShellCommand(
- 'pm dump %s | grep dataDir=' % cmd_helper.SingleQuote(package))
- for line in output:
- _, _, dataDir = line.partition('dataDir=')
- if dataDir:
- return dataDir
- except device_errors.CommandFailedError:
- logging.exception('Could not find data directory for %s', package)
- return None
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def WaitUntilFullyBooted(self, wifi=False, timeout=None, retries=None):
- """Wait for the device to fully boot.
-
- This means waiting for the device to boot, the package manager to be
- available, and the SD card to be ready. It can optionally mean waiting
- for wifi to come up, too.
-
- Args:
- wifi: A boolean indicating if we should wait for wifi to come up or not.
- timeout: timeout in seconds
- retries: number of retries
-
- Raises:
- CommandFailedError on failure.
- CommandTimeoutError if one of the component waits times out.
- DeviceUnreachableError if the device becomes unresponsive.
- """
- def sd_card_ready():
- try:
- self.RunShellCommand(['test', '-d', self.GetExternalStoragePath()],
- check_return=True)
- return True
- except device_errors.AdbCommandFailedError:
- return False
-
- def pm_ready():
- try:
- return self.GetApplicationPaths('android')
- except device_errors.CommandFailedError:
- return False
-
- def boot_completed():
- return self.GetProp('sys.boot_completed') == '1'
-
- def wifi_enabled():
- return 'Wi-Fi is enabled' in self.RunShellCommand(['dumpsys', 'wifi'],
- check_return=False)
-
- self.adb.WaitForDevice()
- timeout_retry.WaitFor(sd_card_ready)
- timeout_retry.WaitFor(pm_ready)
- timeout_retry.WaitFor(boot_completed)
- if wifi:
- timeout_retry.WaitFor(wifi_enabled)
-
- REBOOT_DEFAULT_TIMEOUT = 10 * _DEFAULT_TIMEOUT
- REBOOT_DEFAULT_RETRIES = _DEFAULT_RETRIES
-
- @decorators.WithTimeoutAndRetriesDefaults(
- REBOOT_DEFAULT_TIMEOUT,
- REBOOT_DEFAULT_RETRIES)
- def Reboot(self, block=True, wifi=False, timeout=None, retries=None):
- """Reboot the device.
-
- Args:
- block: A boolean indicating if we should wait for the reboot to complete.
- wifi: A boolean indicating if we should wait for wifi to be enabled after
- the reboot. The option has no effect unless |block| is also True.
- timeout: timeout in seconds
- retries: number of retries
-
- Raises:
- CommandTimeoutError on timeout.
- DeviceUnreachableError on missing device.
- """
- def device_offline():
- return not self.IsOnline()
-
- self.adb.Reboot()
- self._ClearCache()
- timeout_retry.WaitFor(device_offline, wait_period=1)
- if block:
- self.WaitUntilFullyBooted(wifi=wifi)
-
- INSTALL_DEFAULT_TIMEOUT = 4 * _DEFAULT_TIMEOUT
- INSTALL_DEFAULT_RETRIES = _DEFAULT_RETRIES
-
- @decorators.WithTimeoutAndRetriesDefaults(
- INSTALL_DEFAULT_TIMEOUT,
- INSTALL_DEFAULT_RETRIES)
- def Install(self, apk_path, reinstall=False, timeout=None, retries=None):
- """Install an APK.
-
- Noop if an identical APK is already installed.
-
- Args:
- apk_path: A string containing the path to the APK to install.
- reinstall: A boolean indicating if we should keep any existing app data.
- timeout: timeout in seconds
- retries: number of retries
-
- Raises:
- CommandFailedError if the installation fails.
- CommandTimeoutError if the installation times out.
- DeviceUnreachableError on missing device.
- """
- package_name = apk_helper.GetPackageName(apk_path)
- device_paths = self.GetApplicationPaths(package_name)
- if device_paths:
- if len(device_paths) > 1:
- logging.warning(
- 'Installing single APK (%s) when split APKs (%s) are currently '
- 'installed.', apk_path, ' '.join(device_paths))
- (files_to_push, _) = self._GetChangedAndStaleFiles(
- apk_path, device_paths[0])
- should_install = bool(files_to_push)
- if should_install and not reinstall:
- self.adb.Uninstall(package_name)
- else:
- should_install = True
- if should_install:
- self.adb.Install(apk_path, reinstall=reinstall)
-
- @decorators.WithTimeoutAndRetriesDefaults(
- INSTALL_DEFAULT_TIMEOUT,
- INSTALL_DEFAULT_RETRIES)
- def InstallSplitApk(self, base_apk, split_apks, reinstall=False,
- timeout=None, retries=None):
- """Install a split APK.
-
- Noop if all of the APK splits are already installed.
-
- Args:
- base_apk: A string of the path to the base APK.
- split_apks: A list of strings of paths of all of the APK splits.
- reinstall: A boolean indicating if we should keep any existing app data.
- timeout: timeout in seconds
- retries: number of retries
-
- Raises:
- CommandFailedError if the installation fails.
- CommandTimeoutError if the installation times out.
- DeviceUnreachableError on missing device.
- DeviceVersionError if device SDK is less than Android L.
- """
- self._CheckSdkLevel(constants.ANDROID_SDK_VERSION_CODES.LOLLIPOP)
-
- all_apks = [base_apk] + split_select.SelectSplits(
- self, base_apk, split_apks)
- package_name = apk_helper.GetPackageName(base_apk)
- device_apk_paths = self.GetApplicationPaths(package_name)
-
- if device_apk_paths:
- partial_install_package = package_name
- device_checksums = md5sum.CalculateDeviceMd5Sums(device_apk_paths, self)
- host_checksums = md5sum.CalculateHostMd5Sums(all_apks)
- apks_to_install = [k for (k, v) in host_checksums.iteritems()
- if v not in device_checksums.values()]
- if apks_to_install and not reinstall:
- self.adb.Uninstall(package_name)
- partial_install_package = None
- apks_to_install = all_apks
- else:
- partial_install_package = None
- apks_to_install = all_apks
- if apks_to_install:
- self.adb.InstallMultiple(
- apks_to_install, partial=partial_install_package, reinstall=reinstall)
-
- def _CheckSdkLevel(self, required_sdk_level):
- """Raises an exception if the device does not have the required SDK level.
- """
- if self.build_version_sdk < required_sdk_level:
- raise device_errors.DeviceVersionError(
- ('Requires SDK level %s, device is SDK level %s' %
- (required_sdk_level, self.build_version_sdk)),
- device_serial=self.adb.GetDeviceSerial())
-
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def RunShellCommand(self, cmd, check_return=False, cwd=None, env=None,
- as_root=False, single_line=False, large_output=False,
- timeout=None, retries=None):
- """Run an ADB shell command.
-
- The command to run |cmd| should be a sequence of program arguments or else
- a single string.
-
- When |cmd| is a sequence, it is assumed to contain the name of the command
- to run followed by its arguments. In this case, arguments are passed to the
- command exactly as given, without any further processing by the shell. This
- allows to easily pass arguments containing spaces or special characters
- without having to worry about getting quoting right. Whenever possible, it
- is recomended to pass |cmd| as a sequence.
-
- When |cmd| is given as a string, it will be interpreted and run by the
- shell on the device.
-
- This behaviour is consistent with that of command runners in cmd_helper as
- well as Python's own subprocess.Popen.
-
- TODO(perezju) Change the default of |check_return| to True when callers
- have switched to the new behaviour.
-
- Args:
- cmd: A string with the full command to run on the device, or a sequence
- containing the command and its arguments.
- check_return: A boolean indicating whether or not the return code should
- be checked.
- cwd: The device directory in which the command should be run.
- env: The environment variables with which the command should be run.
- as_root: A boolean indicating whether the shell command should be run
- with root privileges.
- single_line: A boolean indicating if only a single line of output is
- expected.
- large_output: Uses a work-around for large shell command output. Without
- this large output will be truncated.
- timeout: timeout in seconds
- retries: number of retries
-
- Returns:
- If single_line is False, the output of the command as a list of lines,
- otherwise, a string with the unique line of output emmited by the command
- (with the optional newline at the end stripped).
-
- Raises:
- AdbCommandFailedError if check_return is True and the exit code of
- the command run on the device is non-zero.
- CommandFailedError if single_line is True but the output contains two or
- more lines.
- CommandTimeoutError on timeout.
- DeviceUnreachableError on missing device.
- """
- def env_quote(key, value):
- if not DeviceUtils._VALID_SHELL_VARIABLE.match(key):
- raise KeyError('Invalid shell variable name %r' % key)
- # using double quotes here to allow interpolation of shell variables
- return '%s=%s' % (key, cmd_helper.DoubleQuote(value))
-
- def run(cmd):
- return self.adb.Shell(cmd)
-
- def handle_check_return(cmd):
- try:
- return run(cmd)
- except device_errors.AdbCommandFailedError as exc:
- if check_return:
- raise
- else:
- return exc.output
-
- def handle_large_command(cmd):
- if len(cmd) < self._MAX_ADB_COMMAND_LENGTH:
- return handle_check_return(cmd)
- else:
- with device_temp_file.DeviceTempFile(self.adb, suffix='.sh') as script:
- self._WriteFileWithPush(script.name, cmd)
- logging.info('Large shell command will be run from file: %s ...',
- cmd[:100])
- return handle_check_return('sh %s' % script.name_quoted)
-
- def handle_large_output(cmd, large_output_mode):
- if large_output_mode:
- with device_temp_file.DeviceTempFile(self.adb) as large_output_file:
- cmd = '%s > %s' % (cmd, large_output_file.name)
- logging.debug('Large output mode enabled. Will write output to '
- 'device and read results from file.')
- handle_large_command(cmd)
- return self.ReadFile(large_output_file.name, force_pull=True)
- else:
- try:
- return handle_large_command(cmd)
- except device_errors.AdbCommandFailedError as exc:
- if exc.status is None:
- logging.exception('No output found for %s', cmd)
- logging.warning('Attempting to run in large_output mode.')
- logging.warning('Use RunShellCommand(..., large_output=True) for '
- 'shell commands that expect a lot of output.')
- return handle_large_output(cmd, True)
- else:
- raise
-
- if not isinstance(cmd, basestring):
- cmd = ' '.join(cmd_helper.SingleQuote(s) for s in cmd)
- if env:
- env = ' '.join(env_quote(k, v) for k, v in env.iteritems())
- cmd = '%s %s' % (env, cmd)
- if cwd:
- cmd = 'cd %s && %s' % (cmd_helper.SingleQuote(cwd), cmd)
- if as_root and self.NeedsSU():
- # "su -c sh -c" allows using shell features in |cmd|
- cmd = 'su -c sh -c %s' % cmd_helper.SingleQuote(cmd)
-
- output = handle_large_output(cmd, large_output).splitlines()
-
- if single_line:
- if not output:
- return ''
- elif len(output) == 1:
- return output[0]
- else:
- msg = 'one line of output was expected, but got: %s'
- raise device_errors.CommandFailedError(msg % output, str(self))
- else:
- return output
-
- def _RunPipedShellCommand(self, script, **kwargs):
- PIPESTATUS_LEADER = 'PIPESTATUS: '
-
- script += '; echo "%s${PIPESTATUS[@]}"' % PIPESTATUS_LEADER
- kwargs['check_return'] = True
- output = self.RunShellCommand(script, **kwargs)
- pipestatus_line = output[-1]
-
- if not pipestatus_line.startswith(PIPESTATUS_LEADER):
- logging.error('Pipe exit statuses of shell script missing.')
- raise device_errors.AdbShellCommandFailedError(
- script, output, status=None,
- device_serial=self.adb.GetDeviceSerial())
-
- output = output[:-1]
- statuses = [
- int(s) for s in pipestatus_line[len(PIPESTATUS_LEADER):].split()]
- if any(statuses):
- raise device_errors.AdbShellCommandFailedError(
- script, output, status=statuses,
- device_serial=self.adb.GetDeviceSerial())
- return output
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def KillAll(self, process_name, signum=device_signal.SIGKILL, as_root=False,
- blocking=False, quiet=False, timeout=None, retries=None):
- """Kill all processes with the given name on the device.
-
- Args:
- process_name: A string containing the name of the process to kill.
- signum: An integer containing the signal number to send to kill. Defaults
- to SIGKILL (9).
- as_root: A boolean indicating whether the kill should be executed with
- root privileges.
- blocking: A boolean indicating whether we should wait until all processes
- with the given |process_name| are dead.
- quiet: A boolean indicating whether to ignore the fact that no processes
- to kill were found.
- timeout: timeout in seconds
- retries: number of retries
-
- Returns:
- The number of processes attempted to kill.
-
- Raises:
- CommandFailedError if no process was killed and |quiet| is False.
- CommandTimeoutError on timeout.
- DeviceUnreachableError on missing device.
- """
- pids = self.GetPids(process_name)
- if not pids:
- if quiet:
- return 0
- else:
- raise device_errors.CommandFailedError(
- 'No process "%s"' % process_name, str(self))
-
- cmd = ['kill', '-%d' % signum] + pids.values()
- self.RunShellCommand(cmd, as_root=as_root, check_return=True)
-
- if blocking:
- # TODO(perezu): use timeout_retry.WaitFor
- wait_period = 0.1
- while self.GetPids(process_name):
- time.sleep(wait_period)
-
- return len(pids)
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def StartActivity(self, intent_obj, blocking=False, trace_file_name=None,
- force_stop=False, timeout=None, retries=None):
- """Start package's activity on the device.
-
- Args:
- intent_obj: An Intent object to send.
- blocking: A boolean indicating whether we should wait for the activity to
- finish launching.
- trace_file_name: If present, a string that both indicates that we want to
- profile the activity and contains the path to which the
- trace should be saved.
- force_stop: A boolean indicating whether we should stop the activity
- before starting it.
- timeout: timeout in seconds
- retries: number of retries
-
- Raises:
- CommandFailedError if the activity could not be started.
- CommandTimeoutError on timeout.
- DeviceUnreachableError on missing device.
- """
- cmd = ['am', 'start']
- if blocking:
- cmd.append('-W')
- if trace_file_name:
- cmd.extend(['--start-profiler', trace_file_name])
- if force_stop:
- cmd.append('-S')
- cmd.extend(intent_obj.am_args)
- for line in self.RunShellCommand(cmd, check_return=True):
- if line.startswith('Error:'):
- raise device_errors.CommandFailedError(line, str(self))
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def StartInstrumentation(self, component, finish=True, raw=False,
- extras=None, timeout=None, retries=None):
- if extras is None:
- extras = {}
-
- cmd = ['am', 'instrument']
- if finish:
- cmd.append('-w')
- if raw:
- cmd.append('-r')
- for k, v in extras.iteritems():
- cmd.extend(['-e', str(k), str(v)])
- cmd.append(component)
- return self.RunShellCommand(cmd, check_return=True, large_output=True)
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def BroadcastIntent(self, intent_obj, timeout=None, retries=None):
- """Send a broadcast intent.
-
- Args:
- intent: An Intent to broadcast.
- timeout: timeout in seconds
- retries: number of retries
-
- Raises:
- CommandTimeoutError on timeout.
- DeviceUnreachableError on missing device.
- """
- cmd = ['am', 'broadcast'] + intent_obj.am_args
- self.RunShellCommand(cmd, check_return=True)
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def GoHome(self, timeout=None, retries=None):
- """Return to the home screen and obtain launcher focus.
-
- This command launches the home screen and attempts to obtain
- launcher focus until the timeout is reached.
-
- Args:
- timeout: timeout in seconds
- retries: number of retries
-
- Raises:
- CommandTimeoutError on timeout.
- DeviceUnreachableError on missing device.
- """
- def is_launcher_focused():
- output = self.RunShellCommand(['dumpsys', 'window', 'windows'],
- check_return=True, large_output=True)
- return any(self._LAUNCHER_FOCUSED_RE.match(l) for l in output)
-
- def dismiss_popups():
- # There is a dialog present; attempt to get rid of it.
- # Not all dialogs can be dismissed with back.
- self.SendKeyEvent(keyevent.KEYCODE_ENTER)
- self.SendKeyEvent(keyevent.KEYCODE_BACK)
- return is_launcher_focused()
-
- # If Home is already focused, return early to avoid unnecessary work.
- if is_launcher_focused():
- return
-
- self.StartActivity(
- intent.Intent(action='android.intent.action.MAIN',
- category='android.intent.category.HOME'),
- blocking=True)
-
- if not is_launcher_focused():
- timeout_retry.WaitFor(dismiss_popups, wait_period=1)
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def ForceStop(self, package, timeout=None, retries=None):
- """Close the application.
-
- Args:
- package: A string containing the name of the package to stop.
- timeout: timeout in seconds
- retries: number of retries
-
- Raises:
- CommandTimeoutError on timeout.
- DeviceUnreachableError on missing device.
- """
- self.RunShellCommand(['am', 'force-stop', package], check_return=True)
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def ClearApplicationState(self, package, timeout=None, retries=None):
- """Clear all state for the given package.
-
- Args:
- package: A string containing the name of the package to stop.
- timeout: timeout in seconds
- retries: number of retries
-
- Raises:
- CommandTimeoutError on timeout.
- DeviceUnreachableError on missing device.
- """
- # Check that the package exists before clearing it for android builds below
- # JB MR2. Necessary because calling pm clear on a package that doesn't exist
- # may never return.
- if ((self.build_version_sdk >=
- constants.ANDROID_SDK_VERSION_CODES.JELLY_BEAN_MR2)
- or self.GetApplicationPaths(package)):
- self.RunShellCommand(['pm', 'clear', package], check_return=True)
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def SendKeyEvent(self, keycode, timeout=None, retries=None):
- """Sends a keycode to the device.
-
- See the pylib.constants.keyevent module for suitable keycode values.
-
- Args:
- keycode: A integer keycode to send to the device.
- timeout: timeout in seconds
- retries: number of retries
-
- Raises:
- CommandTimeoutError on timeout.
- DeviceUnreachableError on missing device.
- """
- self.RunShellCommand(['input', 'keyevent', format(keycode, 'd')],
- check_return=True)
-
- PUSH_CHANGED_FILES_DEFAULT_TIMEOUT = 10 * _DEFAULT_TIMEOUT
- PUSH_CHANGED_FILES_DEFAULT_RETRIES = _DEFAULT_RETRIES
-
- @decorators.WithTimeoutAndRetriesDefaults(
- PUSH_CHANGED_FILES_DEFAULT_TIMEOUT,
- PUSH_CHANGED_FILES_DEFAULT_RETRIES)
- def PushChangedFiles(self, host_device_tuples, timeout=None,
- retries=None, delete_device_stale=False):
- """Push files to the device, skipping files that don't need updating.
-
- When a directory is pushed, it is traversed recursively on the host and
- all files in it are pushed to the device as needed.
- Additionally, if delete_device_stale option is True,
- files that exist on the device but don't exist on the host are deleted.
-
- Args:
- host_device_tuples: A list of (host_path, device_path) tuples, where
- |host_path| is an absolute path of a file or directory on the host
- that should be minimially pushed to the device, and |device_path| is
- an absolute path of the destination on the device.
- timeout: timeout in seconds
- retries: number of retries
- delete_device_stale: option to delete stale files on device
-
- Raises:
- CommandFailedError on failure.
- CommandTimeoutError on timeout.
- DeviceUnreachableError on missing device.
- """
-
- all_changed_files = []
- all_stale_files = []
- for h, d in host_device_tuples:
- if os.path.isdir(h):
- self.RunShellCommand(['mkdir', '-p', d], check_return=True)
- changed_files, stale_files = (
- self._GetChangedAndStaleFiles(h, d, delete_device_stale))
- all_changed_files += changed_files
- all_stale_files += stale_files
-
- if delete_device_stale:
- self.RunShellCommand(['rm', '-f'] + all_stale_files,
- check_return=True)
-
- if not all_changed_files:
- return
-
- self._PushFilesImpl(host_device_tuples, all_changed_files)
-
- def _GetChangedAndStaleFiles(self, host_path, device_path, track_stale=False):
- """Get files to push and delete
-
- Args:
- host_path: an absolute path of a file or directory on the host
- device_path: an absolute path of a file or directory on the device
- track_stale: whether to bother looking for stale files (slower)
-
- Returns:
- a two-element tuple
- 1st element: a list of (host_files_path, device_files_path) tuples to push
- 2nd element: a list of stale files under device_path, or [] when
- track_stale == False
- """
- real_host_path = os.path.realpath(host_path)
- try:
- real_device_path = self.RunShellCommand(
- ['realpath', device_path], single_line=True, check_return=True)
- except device_errors.CommandFailedError:
- real_device_path = None
- if not real_device_path:
- return ([(host_path, device_path)], [])
-
- try:
- host_checksums = md5sum.CalculateHostMd5Sums([real_host_path])
- interesting_device_paths = [real_device_path]
- if not track_stale and os.path.isdir(real_host_path):
- interesting_device_paths = [
- posixpath.join(real_device_path, os.path.relpath(p, real_host_path))
- for p in host_checksums.keys()]
- device_checksums = md5sum.CalculateDeviceMd5Sums(
- interesting_device_paths, self)
- except EnvironmentError as e:
- logging.warning('Error calculating md5: %s', e)
- return ([(host_path, device_path)], [])
-
- if os.path.isfile(host_path):
- host_checksum = host_checksums.get(real_host_path)
- device_checksum = device_checksums.get(real_device_path)
- if host_checksum != device_checksum:
- return ([(host_path, device_path)], [])
- else:
- return ([], [])
- else:
- to_push = []
- for host_abs_path, host_checksum in host_checksums.iteritems():
- device_abs_path = '%s/%s' % (
- real_device_path, os.path.relpath(host_abs_path, real_host_path))
- device_checksum = device_checksums.pop(device_abs_path, None)
- if device_checksum != host_checksum:
- to_push.append((host_abs_path, device_abs_path))
- to_delete = device_checksums.keys()
- return (to_push, to_delete)
-
- def _PushFilesImpl(self, host_device_tuples, files):
- size = sum(host_utils.GetRecursiveDiskUsage(h) for h, _ in files)
- file_count = len(files)
- dir_size = sum(host_utils.GetRecursiveDiskUsage(h)
- for h, _ in host_device_tuples)
- dir_file_count = 0
- for h, _ in host_device_tuples:
- if os.path.isdir(h):
- dir_file_count += sum(len(f) for _r, _d, f in os.walk(h))
- else:
- dir_file_count += 1
-
- push_duration = self._ApproximateDuration(
- file_count, file_count, size, False)
- dir_push_duration = self._ApproximateDuration(
- len(host_device_tuples), dir_file_count, dir_size, False)
- zip_duration = self._ApproximateDuration(1, 1, size, True)
-
- self._InstallCommands()
-
- if dir_push_duration < push_duration and (
- dir_push_duration < zip_duration or not self._commands_installed):
- self._PushChangedFilesIndividually(host_device_tuples)
- elif push_duration < zip_duration or not self._commands_installed:
- self._PushChangedFilesIndividually(files)
- else:
- self._PushChangedFilesZipped(files)
- self.RunShellCommand(
- ['chmod', '-R', '777'] + [d for _, d in host_device_tuples],
- as_root=True, check_return=True)
-
- def _InstallCommands(self):
- if self._commands_installed is None:
- try:
- if not install_commands.Installed(self):
- install_commands.InstallCommands(self)
- self._commands_installed = True
- except Exception as e:
- logging.warning('unzip not available: %s' % str(e))
- self._commands_installed = False
-
- @staticmethod
- def _ApproximateDuration(adb_calls, file_count, byte_count, is_zipping):
- # We approximate the time to push a set of files to a device as:
- # t = c1 * a + c2 * f + c3 + b / c4 + b / (c5 * c6), where
- # t: total time (sec)
- # c1: adb call time delay (sec)
- # a: number of times adb is called (unitless)
- # c2: push time delay (sec)
- # f: number of files pushed via adb (unitless)
- # c3: zip time delay (sec)
- # c4: zip rate (bytes/sec)
- # b: total number of bytes (bytes)
- # c5: transfer rate (bytes/sec)
- # c6: compression ratio (unitless)
-
- # All of these are approximations.
- ADB_CALL_PENALTY = 0.1 # seconds
- ADB_PUSH_PENALTY = 0.01 # seconds
- ZIP_PENALTY = 2.0 # seconds
- ZIP_RATE = 10000000.0 # bytes / second
- TRANSFER_RATE = 2000000.0 # bytes / second
- COMPRESSION_RATIO = 2.0 # unitless
-
- adb_call_time = ADB_CALL_PENALTY * adb_calls
- adb_push_setup_time = ADB_PUSH_PENALTY * file_count
- if is_zipping:
- zip_time = ZIP_PENALTY + byte_count / ZIP_RATE
- transfer_time = byte_count / (TRANSFER_RATE * COMPRESSION_RATIO)
- else:
- zip_time = 0
- transfer_time = byte_count / TRANSFER_RATE
- return adb_call_time + adb_push_setup_time + zip_time + transfer_time
-
- def _PushChangedFilesIndividually(self, files):
- for h, d in files:
- self.adb.Push(h, d)
-
- def _PushChangedFilesZipped(self, files):
- if not files:
- return
-
- with tempfile.NamedTemporaryFile(suffix='.zip') as zip_file:
- zip_proc = multiprocessing.Process(
- target=DeviceUtils._CreateDeviceZip,
- args=(zip_file.name, files))
- zip_proc.start()
- zip_proc.join()
-
- zip_on_device = '%s/tmp.zip' % self.GetExternalStoragePath()
- try:
- self.adb.Push(zip_file.name, zip_on_device)
- self.RunShellCommand(
- ['unzip', zip_on_device],
- as_root=True,
- env={'PATH': '%s:$PATH' % install_commands.BIN_DIR},
- check_return=True)
- finally:
- if zip_proc.is_alive():
- zip_proc.terminate()
- if self.IsOnline():
- self.RunShellCommand(['rm', zip_on_device], check_return=True)
-
- @staticmethod
- def _CreateDeviceZip(zip_path, host_device_tuples):
- with zipfile.ZipFile(zip_path, 'w') as zip_file:
- for host_path, device_path in host_device_tuples:
- zip_utils.WriteToZipFile(zip_file, host_path, device_path)
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def FileExists(self, device_path, timeout=None, retries=None):
- """Checks whether the given file exists on the device.
-
- Args:
- device_path: A string containing the absolute path to the file on the
- device.
- timeout: timeout in seconds
- retries: number of retries
-
- Returns:
- True if the file exists on the device, False otherwise.
-
- Raises:
- CommandTimeoutError on timeout.
- DeviceUnreachableError on missing device.
- """
- try:
- self.RunShellCommand(['test', '-e', device_path], check_return=True)
- return True
- except device_errors.AdbCommandFailedError:
- return False
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def PullFile(self, device_path, host_path, timeout=None, retries=None):
- """Pull a file from the device.
-
- Args:
- device_path: A string containing the absolute path of the file to pull
- from the device.
- host_path: A string containing the absolute path of the destination on
- the host.
- timeout: timeout in seconds
- retries: number of retries
-
- Raises:
- CommandFailedError on failure.
- CommandTimeoutError on timeout.
- """
- # Create the base dir if it doesn't exist already
- dirname = os.path.dirname(host_path)
- if dirname and not os.path.exists(dirname):
- os.makedirs(dirname)
- self.adb.Pull(device_path, host_path)
-
- def _ReadFileWithPull(self, device_path):
- try:
- d = tempfile.mkdtemp()
- host_temp_path = os.path.join(d, 'tmp_ReadFileWithPull')
- self.adb.Pull(device_path, host_temp_path)
- with open(host_temp_path, 'r') as host_temp:
- return host_temp.read()
- finally:
- if os.path.exists(d):
- shutil.rmtree(d)
-
- _LS_RE = re.compile(
- r'(?P<perms>\S+) +(?P<owner>\S+) +(?P<group>\S+) +(?:(?P<size>\d+) +)?'
- + r'(?P<date>\S+) +(?P<time>\S+) +(?P<name>.+)$')
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def ReadFile(self, device_path, as_root=False, force_pull=False,
- timeout=None, retries=None):
- """Reads the contents of a file from the device.
-
- Args:
- device_path: A string containing the absolute path of the file to read
- from the device.
- as_root: A boolean indicating whether the read should be executed with
- root privileges.
- force_pull: A boolean indicating whether to force the operation to be
- performed by pulling a file from the device. The default is, when the
- contents are short, to retrieve the contents using cat instead.
- timeout: timeout in seconds
- retries: number of retries
-
- Returns:
- The contents of |device_path| as a string. Contents are intepreted using
- universal newlines, so the caller will see them encoded as '\n'. Also,
- all lines will be terminated.
-
- Raises:
- AdbCommandFailedError if the file can't be read.
- CommandTimeoutError on timeout.
- DeviceUnreachableError on missing device.
- """
- def get_size(path):
- # TODO(jbudorick): Implement a generic version of Stat() that handles
- # as_root=True, then switch this implementation to use that.
- ls_out = self.RunShellCommand(['ls', '-l', device_path], as_root=as_root,
- check_return=True)
- for line in ls_out:
- m = self._LS_RE.match(line)
- if m and m.group('name') == posixpath.basename(device_path):
- return int(m.group('size'))
- logging.warning('Could not determine size of %s.', device_path)
- return None
-
- if (not force_pull
- and 0 < get_size(device_path) <= self._MAX_ADB_OUTPUT_LENGTH):
- return _JoinLines(self.RunShellCommand(
- ['cat', device_path], as_root=as_root, check_return=True))
- elif as_root and self.NeedsSU():
- with device_temp_file.DeviceTempFile(self.adb) as device_temp:
- self.RunShellCommand(['cp', device_path, device_temp.name],
- as_root=True, check_return=True)
- return self._ReadFileWithPull(device_temp.name)
- else:
- return self._ReadFileWithPull(device_path)
-
- def _WriteFileWithPush(self, device_path, contents):
- with tempfile.NamedTemporaryFile() as host_temp:
- host_temp.write(contents)
- host_temp.flush()
- self.adb.Push(host_temp.name, device_path)
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def WriteFile(self, device_path, contents, as_root=False, force_push=False,
- timeout=None, retries=None):
- """Writes |contents| to a file on the device.
-
- Args:
- device_path: A string containing the absolute path to the file to write
- on the device.
- contents: A string containing the data to write to the device.
- as_root: A boolean indicating whether the write should be executed with
- root privileges (if available).
- force_push: A boolean indicating whether to force the operation to be
- performed by pushing a file to the device. The default is, when the
- contents are short, to pass the contents using a shell script instead.
- timeout: timeout in seconds
- retries: number of retries
-
- Raises:
- CommandFailedError if the file could not be written on the device.
- CommandTimeoutError on timeout.
- DeviceUnreachableError on missing device.
- """
- if not force_push and len(contents) < self._MAX_ADB_COMMAND_LENGTH:
- # If the contents are small, for efficieny we write the contents with
- # a shell command rather than pushing a file.
- cmd = 'echo -n %s > %s' % (cmd_helper.SingleQuote(contents),
- cmd_helper.SingleQuote(device_path))
- self.RunShellCommand(cmd, as_root=as_root, check_return=True)
- elif as_root and self.NeedsSU():
- # Adb does not allow to "push with su", so we first push to a temp file
- # on a safe location, and then copy it to the desired location with su.
- with device_temp_file.DeviceTempFile(self.adb) as device_temp:
- self._WriteFileWithPush(device_temp.name, contents)
- # Here we need 'cp' rather than 'mv' because the temp and
- # destination files might be on different file systems (e.g.
- # on internal storage and an external sd card).
- self.RunShellCommand(['cp', device_temp.name, device_path],
- as_root=True, check_return=True)
- else:
- # If root is not needed, we can push directly to the desired location.
- self._WriteFileWithPush(device_path, contents)
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def Ls(self, device_path, timeout=None, retries=None):
- """Lists the contents of a directory on the device.
-
- Args:
- device_path: A string containing the path of the directory on the device
- to list.
- timeout: timeout in seconds
- retries: number of retries
-
- Returns:
- A list of pairs (filename, stat) for each file found in the directory,
- where the stat object has the properties: st_mode, st_size, and st_time.
-
- Raises:
- AdbCommandFailedError if |device_path| does not specify a valid and
- accessible directory in the device.
- CommandTimeoutError on timeout.
- DeviceUnreachableError on missing device.
- """
- return self.adb.Ls(device_path)
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def Stat(self, device_path, timeout=None, retries=None):
- """Get the stat attributes of a file or directory on the device.
-
- Args:
- device_path: A string containing the path of from which to get attributes
- on the device.
- timeout: timeout in seconds
- retries: number of retries
-
- Returns:
- A stat object with the properties: st_mode, st_size, and st_time
-
- Raises:
- CommandFailedError if device_path cannot be found on the device.
- CommandTimeoutError on timeout.
- DeviceUnreachableError on missing device.
- """
- dirname, target = device_path.rsplit('/', 1)
- for filename, stat in self.adb.Ls(dirname):
- if filename == target:
- return stat
- raise device_errors.CommandFailedError(
- 'Cannot find file or directory: %r' % device_path, str(self))
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def SetJavaAsserts(self, enabled, timeout=None, retries=None):
- """Enables or disables Java asserts.
-
- Args:
- enabled: A boolean indicating whether Java asserts should be enabled
- or disabled.
- timeout: timeout in seconds
- retries: number of retries
-
- Returns:
- True if the device-side property changed and a restart is required as a
- result, False otherwise.
-
- Raises:
- CommandTimeoutError on timeout.
- """
- def find_property(lines, property_name):
- for index, line in enumerate(lines):
- if line.strip() == '':
- continue
- key, value = (s.strip() for s in line.split('=', 1))
- if key == property_name:
- return index, value
- return None, ''
-
- new_value = 'all' if enabled else ''
-
- # First ensure the desired property is persisted.
- try:
- properties = self.ReadFile(
- constants.DEVICE_LOCAL_PROPERTIES_PATH).splitlines()
- except device_errors.CommandFailedError:
- properties = []
- index, value = find_property(properties, self.JAVA_ASSERT_PROPERTY)
- if new_value != value:
- if new_value:
- new_line = '%s=%s' % (self.JAVA_ASSERT_PROPERTY, new_value)
- if index is None:
- properties.append(new_line)
- else:
- properties[index] = new_line
- else:
- assert index is not None # since new_value == '' and new_value != value
- properties.pop(index)
- self.WriteFile(constants.DEVICE_LOCAL_PROPERTIES_PATH,
- _JoinLines(properties))
-
- # Next, check the current runtime value is what we need, and
- # if not, set it and report that a reboot is required.
- value = self.GetProp(self.JAVA_ASSERT_PROPERTY)
- if new_value != value:
- self.SetProp(self.JAVA_ASSERT_PROPERTY, new_value)
- return True
- else:
- return False
-
- @property
- def language(self):
- """Returns the language setting on the device."""
- return self.GetProp('persist.sys.language', cache=False)
-
- @property
- def country(self):
- """Returns the country setting on the device."""
- return self.GetProp('persist.sys.country', cache=False)
-
- @property
- def screen_density(self):
- """Returns the screen density of the device."""
- DPI_TO_DENSITY = {
- 120: 'ldpi',
- 160: 'mdpi',
- 240: 'hdpi',
- 320: 'xhdpi',
- 480: 'xxhdpi',
- 640: 'xxxhdpi',
- }
- dpi = int(self.GetProp('ro.sf.lcd_density', cache=True))
- return DPI_TO_DENSITY.get(dpi, 'tvdpi')
-
- @property
- def build_description(self):
- """Returns the build description of the system.
-
- For example:
- nakasi-user 4.4.4 KTU84P 1227136 release-keys
- """
- return self.GetProp('ro.build.description', cache=True)
-
- @property
- def build_fingerprint(self):
- """Returns the build fingerprint of the system.
-
- For example:
- google/nakasi/grouper:4.4.4/KTU84P/1227136:user/release-keys
- """
- return self.GetProp('ro.build.fingerprint', cache=True)
-
- @property
- def build_id(self):
- """Returns the build ID of the system (e.g. 'KTU84P')."""
- return self.GetProp('ro.build.id', cache=True)
-
- @property
- def build_product(self):
- """Returns the build product of the system (e.g. 'grouper')."""
- return self.GetProp('ro.build.product', cache=True)
-
- @property
- def build_type(self):
- """Returns the build type of the system (e.g. 'user')."""
- return self.GetProp('ro.build.type', cache=True)
-
- @property
- def build_version_sdk(self):
- """Returns the build version sdk of the system as a number (e.g. 19).
-
- For version code numbers see:
- http://developer.android.com/reference/android/os/Build.VERSION_CODES.html
-
- For named constants see:
- pylib.constants.ANDROID_SDK_VERSION_CODES
-
- Raises:
- CommandFailedError if the build version sdk is not a number.
- """
- value = self.GetProp('ro.build.version.sdk', cache=True)
- try:
- return int(value)
- except ValueError:
- raise device_errors.CommandFailedError(
- 'Invalid build version sdk: %r' % value)
-
- @property
- def product_cpu_abi(self):
- """Returns the product cpu abi of the device (e.g. 'armeabi-v7a')."""
- return self.GetProp('ro.product.cpu.abi', cache=True)
-
- @property
- def product_model(self):
- """Returns the name of the product model (e.g. 'Nexus 7')."""
- return self.GetProp('ro.product.model', cache=True)
-
- @property
- def product_name(self):
- """Returns the product name of the device (e.g. 'nakasi')."""
- return self.GetProp('ro.product.name', cache=True)
-
- def GetProp(self, property_name, cache=False, timeout=DEFAULT,
- retries=DEFAULT):
- """Gets a property from the device.
-
- Args:
- property_name: A string containing the name of the property to get from
- the device.
- cache: A boolean indicating whether to cache the value of this property.
- timeout: timeout in seconds
- retries: number of retries
-
- Returns:
- The value of the device's |property_name| property.
-
- Raises:
- CommandTimeoutError on timeout.
- """
- assert isinstance(property_name, basestring), (
- "property_name is not a string: %r" % property_name)
-
- cache_key = '_prop:' + property_name
- if cache and cache_key in self._cache:
- return self._cache[cache_key]
- else:
- # timeout and retries are handled down at run shell, because we don't
- # want to apply them in the other branch when reading from the cache
- value = self.RunShellCommand(
- ['getprop', property_name], single_line=True, check_return=True,
- timeout=self._default_timeout if timeout is DEFAULT else timeout,
- retries=self._default_retries if retries is DEFAULT else retries)
- if cache or cache_key in self._cache:
- self._cache[cache_key] = value
- return value
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def SetProp(self, property_name, value, check=False, timeout=None,
- retries=None):
- """Sets a property on the device.
-
- Args:
- property_name: A string containing the name of the property to set on
- the device.
- value: A string containing the value to set to the property on the
- device.
- check: A boolean indicating whether to check that the property was
- successfully set on the device.
- timeout: timeout in seconds
- retries: number of retries
-
- Raises:
- CommandFailedError if check is true and the property was not correctly
- set on the device (e.g. because it is not rooted).
- CommandTimeoutError on timeout.
- """
- assert isinstance(property_name, basestring), (
- "property_name is not a string: %r" % property_name)
- assert isinstance(value, basestring), "value is not a string: %r" % value
-
- self.RunShellCommand(['setprop', property_name, value], check_return=True)
- if property_name in self._cache:
- del self._cache[property_name]
- # TODO(perezju) remove the option and make the check mandatory, but using a
- # single shell script to both set- and getprop.
- if check and value != self.GetProp(property_name):
- raise device_errors.CommandFailedError(
- 'Unable to set property %r on the device to %r'
- % (property_name, value), str(self))
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def GetABI(self, timeout=None, retries=None):
- """Gets the device main ABI.
-
- Args:
- timeout: timeout in seconds
- retries: number of retries
-
- Returns:
- The device's main ABI name.
-
- Raises:
- CommandTimeoutError on timeout.
- """
- return self.GetProp('ro.product.cpu.abi')
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def GetPids(self, process_name, timeout=None, retries=None):
- """Returns the PIDs of processes with the given name.
-
- Note that the |process_name| is often the package name.
-
- Args:
- process_name: A string containing the process name to get the PIDs for.
- timeout: timeout in seconds
- retries: number of retries
-
- Returns:
- A dict mapping process name to PID for each process that contained the
- provided |process_name|.
-
- Raises:
- CommandTimeoutError on timeout.
- DeviceUnreachableError on missing device.
- """
- procs_pids = {}
- try:
- ps_output = self._RunPipedShellCommand(
- 'ps | grep -F %s' % cmd_helper.SingleQuote(process_name))
- except device_errors.AdbShellCommandFailedError as e:
- if e.status and isinstance(e.status, list) and not e.status[0]:
- # If ps succeeded but grep failed, there were no processes with the
- # given name.
- return procs_pids
- else:
- raise
-
- for line in ps_output:
- try:
- ps_data = line.split()
- if process_name in ps_data[-1]:
- procs_pids[ps_data[-1]] = ps_data[1]
- except IndexError:
- pass
- return procs_pids
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def TakeScreenshot(self, host_path=None, timeout=None, retries=None):
- """Takes a screenshot of the device.
-
- Args:
- host_path: A string containing the path on the host to save the
- screenshot to. If None, a file name in the current
- directory will be generated.
- timeout: timeout in seconds
- retries: number of retries
-
- Returns:
- The name of the file on the host to which the screenshot was saved.
-
- Raises:
- CommandFailedError on failure.
- CommandTimeoutError on timeout.
- DeviceUnreachableError on missing device.
- """
- if not host_path:
- host_path = os.path.abspath('screenshot-%s.png' % _GetTimeStamp())
- with device_temp_file.DeviceTempFile(self.adb, suffix='.png') as device_tmp:
- self.RunShellCommand(['/system/bin/screencap', '-p', device_tmp.name],
- check_return=True)
- self.PullFile(device_tmp.name, host_path)
- return host_path
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def GetMemoryUsageForPid(self, pid, timeout=None, retries=None):
- """Gets the memory usage for the given PID.
-
- Args:
- pid: PID of the process.
- timeout: timeout in seconds
- retries: number of retries
-
- Returns:
- A dict containing memory usage statistics for the PID. May include:
- Size, Rss, Pss, Shared_Clean, Shared_Dirty, Private_Clean,
- Private_Dirty, VmHWM
-
- Raises:
- CommandTimeoutError on timeout.
- """
- result = collections.defaultdict(int)
-
- try:
- result.update(self._GetMemoryUsageForPidFromSmaps(pid))
- except device_errors.CommandFailedError:
- logging.exception('Error getting memory usage from smaps')
-
- try:
- result.update(self._GetMemoryUsageForPidFromStatus(pid))
- except device_errors.CommandFailedError:
- logging.exception('Error getting memory usage from status')
-
- return result
-
- def _GetMemoryUsageForPidFromSmaps(self, pid):
- SMAPS_COLUMNS = (
- 'Size', 'Rss', 'Pss', 'Shared_Clean', 'Shared_Dirty', 'Private_Clean',
- 'Private_Dirty')
-
- showmap_out = self._RunPipedShellCommand(
- 'showmap %d | grep TOTAL' % int(pid), as_root=True)
-
- split_totals = showmap_out[-1].split()
- if (not split_totals
- or len(split_totals) != 9
- or split_totals[-1] != 'TOTAL'):
- raise device_errors.CommandFailedError(
- 'Invalid output from showmap: %s' % '\n'.join(showmap_out))
-
- return dict(itertools.izip(SMAPS_COLUMNS, (int(n) for n in split_totals)))
-
- def _GetMemoryUsageForPidFromStatus(self, pid):
- for line in self.ReadFile(
- '/proc/%s/status' % str(pid), as_root=True).splitlines():
- if line.startswith('VmHWM:'):
- return {'VmHWM': int(line.split()[1])}
- else:
- raise device_errors.CommandFailedError(
- 'Could not find memory peak value for pid %s', str(pid))
-
- @decorators.WithTimeoutAndRetriesFromInstance()
- def GetLogcatMonitor(self, timeout=None, retries=None, *args, **kwargs):
- """Returns a new LogcatMonitor associated with this device.
-
- Parameters passed to this function are passed directly to
- |logcat_monitor.LogcatMonitor| and are documented there.
-
- Args:
- timeout: timeout in seconds
- retries: number of retries
- """
- return logcat_monitor.LogcatMonitor(self.adb, *args, **kwargs)
-
- def GetClientCache(self, client_name):
- """Returns client cache."""
- if client_name not in self._client_caches:
- self._client_caches[client_name] = {}
- return self._client_caches[client_name]
-
- def _ClearCache(self):
- """Clears all caches."""
- for client in self._client_caches:
- self._client_caches[client].clear()
- self._cache.clear()
-
- @classmethod
- def parallel(cls, devices=None, async=False):
- """Creates a Parallelizer to operate over the provided list of devices.
-
- If |devices| is either |None| or an empty list, the Parallelizer will
- operate over all attached devices that have not been blacklisted.
-
- Args:
- devices: A list of either DeviceUtils instances or objects from
- from which DeviceUtils instances can be constructed. If None,
- all attached devices will be used.
- async: If true, returns a Parallelizer that runs operations
- asynchronously.
-
- Returns:
- A Parallelizer operating over |devices|.
- """
- if not devices:
- devices = cls.HealthyDevices()
- if not devices:
- raise device_errors.NoDevicesError()
-
- devices = [d if isinstance(d, cls) else cls(d) for d in devices]
- if async:
- return parallelizer.Parallelizer(devices)
- else:
- return parallelizer.SyncParallelizer(devices)
-
- @classmethod
- def HealthyDevices(cls):
- blacklist = device_blacklist.ReadBlacklist()
- def blacklisted(adb):
- if adb.GetDeviceSerial() in blacklist:
- logging.warning('Device %s is blacklisted.', adb.GetDeviceSerial())
- return True
- return False
-
- return [cls(adb) for adb in adb_wrapper.AdbWrapper.Devices()
- if not blacklisted(adb)]
diff --git a/build/android/pylib/device/device_utils_device_test.py b/build/android/pylib/device/device_utils_device_test.py
deleted file mode 100755
index daae2b6..0000000
--- a/build/android/pylib/device/device_utils_device_test.py
+++ /dev/null
@@ -1,211 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""
-Unit tests for the contents of device_utils.py (mostly DeviceUtils).
-The test will invoke real devices
-"""
-
-import os
-import tempfile
-import unittest
-
-from pylib import cmd_helper
-from pylib import constants
-from pylib.device import adb_wrapper
-from pylib.device import device_utils
-from pylib.utils import md5sum
-
-_OLD_CONTENTS = "foo"
-_NEW_CONTENTS = "bar"
-_DEVICE_DIR = "/data/local/tmp/device_utils_test"
-_SUB_DIR = "sub"
-_SUB_DIR1 = "sub1"
-_SUB_DIR2 = "sub2"
-
-class DeviceUtilsPushDeleteFilesTest(unittest.TestCase):
-
- def setUp(self):
- devices = adb_wrapper.AdbWrapper.Devices()
- assert devices, 'A device must be attached'
- self.adb = devices[0]
- self.adb.WaitForDevice()
- self.device = device_utils.DeviceUtils(
- self.adb, default_timeout=10, default_retries=0)
- default_build_type = os.environ.get('BUILDTYPE', 'Debug')
- constants.SetBuildType(default_build_type)
-
- @staticmethod
- def _MakeTempFile(contents):
- """Make a temporary file with the given contents.
-
- Args:
- contents: string to write to the temporary file.
-
- Returns:
- the tuple contains the absolute path to the file and the file name
- """
- fi, path = tempfile.mkstemp(text=True)
- with os.fdopen(fi, 'w') as f:
- f.write(contents)
- file_name = os.path.basename(path)
- return (path, file_name)
-
- @staticmethod
- def _MakeTempFileGivenDir(directory, contents):
- """Make a temporary file under the given directory
- with the given contents
-
- Args:
- directory: the temp directory to create the file
- contents: string to write to the temp file
-
- Returns:
- the list contains the absolute path to the file and the file name
- """
- fi, path = tempfile.mkstemp(dir=directory, text=True)
- with os.fdopen(fi, 'w') as f:
- f.write(contents)
- file_name = os.path.basename(path)
- return (path, file_name)
-
- @staticmethod
- def _ChangeTempFile(path, contents):
- with os.open(path, 'w') as f:
- f.write(contents)
-
- @staticmethod
- def _DeleteTempFile(path):
- os.remove(path)
-
- def testPushChangedFiles_noFileChange(self):
- (host_file_path, file_name) = self._MakeTempFile(_OLD_CONTENTS)
- device_file_path = "%s/%s" % (_DEVICE_DIR, file_name)
- self.adb.Push(host_file_path, device_file_path)
- self.device.PushChangedFiles([(host_file_path, device_file_path)])
- result = self.device.RunShellCommand(['cat', device_file_path],
- single_line=True)
- self.assertEqual(_OLD_CONTENTS, result)
-
- cmd_helper.RunCmd(['rm', host_file_path])
- self.device.RunShellCommand(['rm', '-rf', _DEVICE_DIR])
-
- def testPushChangedFiles_singleFileChange(self):
- (host_file_path, file_name) = self._MakeTempFile(_OLD_CONTENTS)
- device_file_path = "%s/%s" % (_DEVICE_DIR, file_name)
- self.adb.Push(host_file_path, device_file_path)
-
- with open(host_file_path, 'w') as f:
- f.write(_NEW_CONTENTS)
- self.device.PushChangedFiles([(host_file_path, device_file_path)])
- result = self.device.RunShellCommand(['cat', device_file_path],
- single_line=True)
- self.assertEqual(_NEW_CONTENTS, result)
-
- cmd_helper.RunCmd(['rm', host_file_path])
- self.device.RunShellCommand(['rm', '-rf', _DEVICE_DIR])
-
- def testDeleteFiles(self):
- host_tmp_dir = tempfile.mkdtemp()
- (host_file_path, file_name) = self._MakeTempFileGivenDir(
- host_tmp_dir, _OLD_CONTENTS)
-
- device_file_path = "%s/%s" % (_DEVICE_DIR, file_name)
- self.adb.Push(host_file_path, device_file_path)
-
- cmd_helper.RunCmd(['rm', host_file_path])
- self.device.PushChangedFiles([(host_tmp_dir, _DEVICE_DIR)],
- delete_device_stale=True)
- result = self.device.RunShellCommand(['ls', _DEVICE_DIR], single_line=True)
- self.assertEqual('', result)
-
- cmd_helper.RunCmd(['rm', '-rf', host_tmp_dir])
- self.device.RunShellCommand(['rm', '-rf', _DEVICE_DIR])
-
- def testPushAndDeleteFiles_noSubDir(self):
- host_tmp_dir = tempfile.mkdtemp()
- (host_file_path1, file_name1) = self._MakeTempFileGivenDir(
- host_tmp_dir, _OLD_CONTENTS)
- (host_file_path2, file_name2) = self._MakeTempFileGivenDir(
- host_tmp_dir, _OLD_CONTENTS)
-
- device_file_path1 = "%s/%s" % (_DEVICE_DIR, file_name1)
- device_file_path2 = "%s/%s" % (_DEVICE_DIR, file_name2)
- self.adb.Push(host_file_path1, device_file_path1)
- self.adb.Push(host_file_path2, device_file_path2)
-
- with open(host_file_path1, 'w') as f:
- f.write(_NEW_CONTENTS)
- cmd_helper.RunCmd(['rm', host_file_path2])
-
- self.device.PushChangedFiles([(host_tmp_dir, _DEVICE_DIR)],
- delete_device_stale=True)
- result = self.device.RunShellCommand(['cat', device_file_path1],
- single_line=True)
- self.assertEqual(_NEW_CONTENTS, result)
- result = self.device.RunShellCommand(['ls', _DEVICE_DIR], single_line=True)
- self.assertEqual(file_name1, result)
-
- self.device.RunShellCommand(['rm', '-rf', _DEVICE_DIR])
- cmd_helper.RunCmd(['rm', '-rf', host_tmp_dir])
-
- def testPushAndDeleteFiles_SubDir(self):
- host_tmp_dir = tempfile.mkdtemp()
- host_sub_dir1 = "%s/%s" % (host_tmp_dir, _SUB_DIR1)
- host_sub_dir2 = "%s/%s/%s" % (host_tmp_dir, _SUB_DIR, _SUB_DIR2)
- cmd_helper.RunCmd(['mkdir', '-p', host_sub_dir1])
- cmd_helper.RunCmd(['mkdir', '-p', host_sub_dir2])
-
- (host_file_path1, file_name1) = self._MakeTempFileGivenDir(
- host_tmp_dir, _OLD_CONTENTS)
- (host_file_path2, file_name2) = self._MakeTempFileGivenDir(
- host_tmp_dir, _OLD_CONTENTS)
- (host_file_path3, file_name3) = self._MakeTempFileGivenDir(
- host_sub_dir1, _OLD_CONTENTS)
- (host_file_path4, file_name4) = self._MakeTempFileGivenDir(
- host_sub_dir2, _OLD_CONTENTS)
-
- device_file_path1 = "%s/%s" % (_DEVICE_DIR, file_name1)
- device_file_path2 = "%s/%s" % (_DEVICE_DIR, file_name2)
- device_file_path3 = "%s/%s/%s" % (_DEVICE_DIR, _SUB_DIR1, file_name3)
- device_file_path4 = "%s/%s/%s/%s" % (_DEVICE_DIR, _SUB_DIR,
- _SUB_DIR2, file_name4)
-
- self.adb.Push(host_file_path1, device_file_path1)
- self.adb.Push(host_file_path2, device_file_path2)
- self.adb.Push(host_file_path3, device_file_path3)
- self.adb.Push(host_file_path4, device_file_path4)
-
- with open(host_file_path1, 'w') as f:
- f.write(_NEW_CONTENTS)
- cmd_helper.RunCmd(['rm', host_file_path2])
- cmd_helper.RunCmd(['rm', host_file_path4])
-
- self.device.PushChangedFiles([(host_tmp_dir, _DEVICE_DIR)],
- delete_device_stale=True)
- result = self.device.RunShellCommand(['cat', device_file_path1],
- single_line=True)
- self.assertEqual(_NEW_CONTENTS, result)
-
- result = self.device.RunShellCommand(['ls', _DEVICE_DIR])
- self.assertIn(file_name1, result)
- self.assertIn(_SUB_DIR1, result)
- self.assertIn(_SUB_DIR, result)
- self.assertEqual(3, len(result))
-
- result = self.device.RunShellCommand(['cat', device_file_path3],
- single_line=True)
- self.assertEqual(_OLD_CONTENTS, result)
-
- result = self.device.RunShellCommand(["ls", "%s/%s/%s"
- % (_DEVICE_DIR, _SUB_DIR, _SUB_DIR2)],
- single_line=True)
- self.assertEqual('', result)
-
- self.device.RunShellCommand(['rm', '-rf', _DEVICE_DIR])
- cmd_helper.RunCmd(['rm', '-rf', host_tmp_dir])
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/build/android/pylib/device/device_utils_test.py b/build/android/pylib/device/device_utils_test.py
deleted file mode 100755
index 6699673..0000000
--- a/build/android/pylib/device/device_utils_test.py
+++ /dev/null
@@ -1,1845 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""
-Unit tests for the contents of device_utils.py (mostly DeviceUtils).
-"""
-
-# pylint: disable=C0321
-# pylint: disable=W0212
-# pylint: disable=W0613
-
-import collections
-import datetime
-import logging
-import os
-import re
-import sys
-import unittest
-
-from pylib import android_commands
-from pylib import cmd_helper
-from pylib import constants
-from pylib import device_signal
-from pylib.device import adb_wrapper
-from pylib.device import device_errors
-from pylib.device import device_utils
-from pylib.device import intent
-from pylib.sdk import split_select
-from pylib.utils import mock_calls
-
-# RunCommand from third_party/android_testrunner/run_command.py is mocked
-# below, so its path needs to be in sys.path.
-sys.path.append(os.path.join(
- constants.DIR_SOURCE_ROOT, 'third_party', 'android_testrunner'))
-
-sys.path.append(os.path.join(
- constants.DIR_SOURCE_ROOT, 'third_party', 'pymock'))
-import mock # pylint: disable=F0401
-
-
-class DeviceUtilsInitTest(unittest.TestCase):
-
- def testInitWithStr(self):
- serial_as_str = str('0123456789abcdef')
- d = device_utils.DeviceUtils('0123456789abcdef')
- self.assertEqual(serial_as_str, d.adb.GetDeviceSerial())
-
- def testInitWithUnicode(self):
- serial_as_unicode = unicode('fedcba9876543210')
- d = device_utils.DeviceUtils(serial_as_unicode)
- self.assertEqual(serial_as_unicode, d.adb.GetDeviceSerial())
-
- def testInitWithAdbWrapper(self):
- serial = '123456789abcdef0'
- a = adb_wrapper.AdbWrapper(serial)
- d = device_utils.DeviceUtils(a)
- self.assertEqual(serial, d.adb.GetDeviceSerial())
-
- def testInitWithAndroidCommands(self):
- serial = '0fedcba987654321'
- a = android_commands.AndroidCommands(device=serial)
- d = device_utils.DeviceUtils(a)
- self.assertEqual(serial, d.adb.GetDeviceSerial())
-
- def testInitWithMissing_fails(self):
- with self.assertRaises(ValueError):
- device_utils.DeviceUtils(None)
- with self.assertRaises(ValueError):
- device_utils.DeviceUtils('')
-
-
-class DeviceUtilsGetAVDsTest(mock_calls.TestCase):
-
- def testGetAVDs(self):
- with self.assertCall(
- mock.call.pylib.cmd_helper.GetCmdOutput([mock.ANY, 'list', 'avd']),
- 'Available Android Virtual Devices:\n'
- ' Name: my_android5.0\n'
- ' Path: /some/path/to/.android/avd/my_android5.0.avd\n'
- ' Target: Android 5.0 (API level 21)\n'
- ' Tag/ABI: default/x86\n'
- ' Skin: WVGA800\n'):
- self.assertEquals(['my_android5.0'],
- device_utils.GetAVDs())
-
-
-class DeviceUtilsRestartServerTest(mock_calls.TestCase):
-
- @mock.patch('time.sleep', mock.Mock())
- def testRestartServer_succeeds(self):
- with self.assertCalls(
- mock.call.pylib.device.adb_wrapper.AdbWrapper.KillServer(),
- (mock.call.pylib.cmd_helper.GetCmdStatusAndOutput(['pgrep', 'adb']),
- (1, '')),
- mock.call.pylib.device.adb_wrapper.AdbWrapper.StartServer(),
- (mock.call.pylib.cmd_helper.GetCmdStatusAndOutput(['pgrep', 'adb']),
- (1, '')),
- (mock.call.pylib.cmd_helper.GetCmdStatusAndOutput(['pgrep', 'adb']),
- (0, '123\n'))):
- device_utils.RestartServer()
-
-
-class MockTempFile(object):
-
- def __init__(self, name='/tmp/some/file'):
- self.file = mock.MagicMock(spec=file)
- self.file.name = name
- self.file.name_quoted = cmd_helper.SingleQuote(name)
-
- def __enter__(self):
- return self.file
-
- def __exit__(self, exc_type, exc_val, exc_tb):
- pass
-
- @property
- def name(self):
- return self.file.name
-
-
-class _PatchedFunction(object):
- def __init__(self, patched=None, mocked=None):
- self.patched = patched
- self.mocked = mocked
-
-
-def _AdbWrapperMock(test_serial):
- adb = mock.Mock(spec=adb_wrapper.AdbWrapper)
- adb.__str__ = mock.Mock(return_value=test_serial)
- adb.GetDeviceSerial.return_value = test_serial
- return adb
-
-
-class DeviceUtilsTest(mock_calls.TestCase):
-
- def setUp(self):
- self.adb = _AdbWrapperMock('0123456789abcdef')
- self.device = device_utils.DeviceUtils(
- self.adb, default_timeout=10, default_retries=0)
- self.watchMethodCalls(self.call.adb, ignore=['GetDeviceSerial'])
-
- def AdbCommandError(self, args=None, output=None, status=None, msg=None):
- if args is None:
- args = ['[unspecified]']
- return mock.Mock(side_effect=device_errors.AdbCommandFailedError(
- args, output, status, msg, str(self.device)))
-
- def CommandError(self, msg=None):
- if msg is None:
- msg = 'Command failed'
- return mock.Mock(side_effect=device_errors.CommandFailedError(
- msg, str(self.device)))
-
- def ShellError(self, output=None, status=1):
- def action(cmd, *args, **kwargs):
- raise device_errors.AdbShellCommandFailedError(
- cmd, output, status, str(self.device))
- if output is None:
- output = 'Permission denied\n'
- return action
-
- def TimeoutError(self, msg=None):
- if msg is None:
- msg = 'Operation timed out'
- return mock.Mock(side_effect=device_errors.CommandTimeoutError(
- msg, str(self.device)))
-
-
-class DeviceUtilsEqTest(DeviceUtilsTest):
-
- def testEq_equal_deviceUtils(self):
- other = device_utils.DeviceUtils(_AdbWrapperMock('0123456789abcdef'))
- self.assertTrue(self.device == other)
- self.assertTrue(other == self.device)
-
- def testEq_equal_adbWrapper(self):
- other = adb_wrapper.AdbWrapper('0123456789abcdef')
- self.assertTrue(self.device == other)
- self.assertTrue(other == self.device)
-
- def testEq_equal_string(self):
- other = '0123456789abcdef'
- self.assertTrue(self.device == other)
- self.assertTrue(other == self.device)
-
- def testEq_devicesNotEqual(self):
- other = device_utils.DeviceUtils(_AdbWrapperMock('0123456789abcdee'))
- self.assertFalse(self.device == other)
- self.assertFalse(other == self.device)
-
- def testEq_identity(self):
- self.assertTrue(self.device == self.device)
-
- def testEq_serialInList(self):
- devices = [self.device]
- self.assertTrue('0123456789abcdef' in devices)
-
-
-class DeviceUtilsLtTest(DeviceUtilsTest):
-
- def testLt_lessThan(self):
- other = device_utils.DeviceUtils(_AdbWrapperMock('ffffffffffffffff'))
- self.assertTrue(self.device < other)
- self.assertTrue(other > self.device)
-
- def testLt_greaterThan_lhs(self):
- other = device_utils.DeviceUtils(_AdbWrapperMock('0000000000000000'))
- self.assertFalse(self.device < other)
- self.assertFalse(other > self.device)
-
- def testLt_equal(self):
- other = device_utils.DeviceUtils(_AdbWrapperMock('0123456789abcdef'))
- self.assertFalse(self.device < other)
- self.assertFalse(other > self.device)
-
- def testLt_sorted(self):
- devices = [
- device_utils.DeviceUtils(_AdbWrapperMock('ffffffffffffffff')),
- device_utils.DeviceUtils(_AdbWrapperMock('0000000000000000')),
- ]
- sorted_devices = sorted(devices)
- self.assertEquals('0000000000000000',
- sorted_devices[0].adb.GetDeviceSerial())
- self.assertEquals('ffffffffffffffff',
- sorted_devices[1].adb.GetDeviceSerial())
-
-
-class DeviceUtilsStrTest(DeviceUtilsTest):
-
- def testStr_returnsSerial(self):
- with self.assertCalls(
- (self.call.adb.GetDeviceSerial(), '0123456789abcdef')):
- self.assertEqual('0123456789abcdef', str(self.device))
-
-
-class DeviceUtilsIsOnlineTest(DeviceUtilsTest):
-
- def testIsOnline_true(self):
- with self.assertCall(self.call.adb.GetState(), 'device'):
- self.assertTrue(self.device.IsOnline())
-
- def testIsOnline_false(self):
- with self.assertCall(self.call.adb.GetState(), 'offline'):
- self.assertFalse(self.device.IsOnline())
-
- def testIsOnline_error(self):
- with self.assertCall(self.call.adb.GetState(), self.CommandError()):
- self.assertFalse(self.device.IsOnline())
-
-
-class DeviceUtilsHasRootTest(DeviceUtilsTest):
-
- def testHasRoot_true(self):
- with self.assertCall(self.call.adb.Shell('ls /root'), 'foo\n'):
- self.assertTrue(self.device.HasRoot())
-
- def testHasRoot_false(self):
- with self.assertCall(self.call.adb.Shell('ls /root'), self.ShellError()):
- self.assertFalse(self.device.HasRoot())
-
-
-class DeviceUtilsEnableRootTest(DeviceUtilsTest):
-
- def testEnableRoot_succeeds(self):
- with self.assertCalls(
- (self.call.device.IsUserBuild(), False),
- self.call.adb.Root(),
- self.call.device.WaitUntilFullyBooted()):
- self.device.EnableRoot()
-
- def testEnableRoot_userBuild(self):
- with self.assertCalls(
- (self.call.device.IsUserBuild(), True)):
- with self.assertRaises(device_errors.CommandFailedError):
- self.device.EnableRoot()
-
- def testEnableRoot_rootFails(self):
- with self.assertCalls(
- (self.call.device.IsUserBuild(), False),
- (self.call.adb.Root(), self.CommandError())):
- with self.assertRaises(device_errors.CommandFailedError):
- self.device.EnableRoot()
-
-
-class DeviceUtilsIsUserBuildTest(DeviceUtilsTest):
-
- def testIsUserBuild_yes(self):
- with self.assertCall(
- self.call.device.GetProp('ro.build.type', cache=True), 'user'):
- self.assertTrue(self.device.IsUserBuild())
-
- def testIsUserBuild_no(self):
- with self.assertCall(
- self.call.device.GetProp('ro.build.type', cache=True), 'userdebug'):
- self.assertFalse(self.device.IsUserBuild())
-
-
-class DeviceUtilsGetExternalStoragePathTest(DeviceUtilsTest):
-
- def testGetExternalStoragePath_succeeds(self):
- with self.assertCall(
- self.call.adb.Shell('echo $EXTERNAL_STORAGE'), '/fake/storage/path\n'):
- self.assertEquals('/fake/storage/path',
- self.device.GetExternalStoragePath())
-
- def testGetExternalStoragePath_fails(self):
- with self.assertCall(self.call.adb.Shell('echo $EXTERNAL_STORAGE'), '\n'):
- with self.assertRaises(device_errors.CommandFailedError):
- self.device.GetExternalStoragePath()
-
-
-class DeviceUtilsGetApplicationPathsTest(DeviceUtilsTest):
-
- def testGetApplicationPaths_exists(self):
- with self.assertCalls(
- (self.call.adb.Shell('getprop ro.build.version.sdk'), '19\n'),
- (self.call.adb.Shell('pm path android'),
- 'package:/path/to/android.apk\n')):
- self.assertEquals(['/path/to/android.apk'],
- self.device.GetApplicationPaths('android'))
-
- def testGetApplicationPaths_notExists(self):
- with self.assertCalls(
- (self.call.adb.Shell('getprop ro.build.version.sdk'), '19\n'),
- (self.call.adb.Shell('pm path not.installed.app'), '')):
- self.assertEquals([],
- self.device.GetApplicationPaths('not.installed.app'))
-
- def testGetApplicationPaths_fails(self):
- with self.assertCalls(
- (self.call.adb.Shell('getprop ro.build.version.sdk'), '19\n'),
- (self.call.adb.Shell('pm path android'),
- self.CommandError('ERROR. Is package manager running?\n'))):
- with self.assertRaises(device_errors.CommandFailedError):
- self.device.GetApplicationPaths('android')
-
-
-class DeviceUtilsGetApplicationDataDirectoryTest(DeviceUtilsTest):
-
- def testGetApplicationDataDirectory_exists(self):
- with self.assertCall(
- self.call.device._RunPipedShellCommand(
- 'pm dump foo.bar.baz | grep dataDir='),
- ['dataDir=/data/data/foo.bar.baz']):
- self.assertEquals(
- '/data/data/foo.bar.baz',
- self.device.GetApplicationDataDirectory('foo.bar.baz'))
-
- def testGetApplicationDataDirectory_notExists(self):
- with self.assertCall(
- self.call.device._RunPipedShellCommand(
- 'pm dump foo.bar.baz | grep dataDir='),
- self.ShellError()):
- self.assertIsNone(self.device.GetApplicationDataDirectory('foo.bar.baz'))
-
-
-@mock.patch('time.sleep', mock.Mock())
-class DeviceUtilsWaitUntilFullyBootedTest(DeviceUtilsTest):
-
- def testWaitUntilFullyBooted_succeedsNoWifi(self):
- with self.assertCalls(
- self.call.adb.WaitForDevice(),
- # sd_card_ready
- (self.call.device.GetExternalStoragePath(), '/fake/storage/path'),
- (self.call.adb.Shell('test -d /fake/storage/path'), ''),
- # pm_ready
- (self.call.device.GetApplicationPaths('android'),
- ['package:/some/fake/path']),
- # boot_completed
- (self.call.device.GetProp('sys.boot_completed'), '1')):
- self.device.WaitUntilFullyBooted(wifi=False)
-
- def testWaitUntilFullyBooted_succeedsWithWifi(self):
- with self.assertCalls(
- self.call.adb.WaitForDevice(),
- # sd_card_ready
- (self.call.device.GetExternalStoragePath(), '/fake/storage/path'),
- (self.call.adb.Shell('test -d /fake/storage/path'), ''),
- # pm_ready
- (self.call.device.GetApplicationPaths('android'),
- ['package:/some/fake/path']),
- # boot_completed
- (self.call.device.GetProp('sys.boot_completed'), '1'),
- # wifi_enabled
- (self.call.adb.Shell('dumpsys wifi'),
- 'stuff\nWi-Fi is enabled\nmore stuff\n')):
- self.device.WaitUntilFullyBooted(wifi=True)
-
- def testWaitUntilFullyBooted_deviceNotInitiallyAvailable(self):
- with self.assertCalls(
- self.call.adb.WaitForDevice(),
- # sd_card_ready
- (self.call.device.GetExternalStoragePath(), self.AdbCommandError()),
- # sd_card_ready
- (self.call.device.GetExternalStoragePath(), self.AdbCommandError()),
- # sd_card_ready
- (self.call.device.GetExternalStoragePath(), self.AdbCommandError()),
- # sd_card_ready
- (self.call.device.GetExternalStoragePath(), self.AdbCommandError()),
- # sd_card_ready
- (self.call.device.GetExternalStoragePath(), '/fake/storage/path'),
- (self.call.adb.Shell('test -d /fake/storage/path'), ''),
- # pm_ready
- (self.call.device.GetApplicationPaths('android'),
- ['package:/some/fake/path']),
- # boot_completed
- (self.call.device.GetProp('sys.boot_completed'), '1')):
- self.device.WaitUntilFullyBooted(wifi=False)
-
- def testWaitUntilFullyBooted_sdCardReadyFails_noPath(self):
- with self.assertCalls(
- self.call.adb.WaitForDevice(),
- # sd_card_ready
- (self.call.device.GetExternalStoragePath(), self.CommandError())):
- with self.assertRaises(device_errors.CommandFailedError):
- self.device.WaitUntilFullyBooted(wifi=False)
-
- def testWaitUntilFullyBooted_sdCardReadyFails_notExists(self):
- with self.assertCalls(
- self.call.adb.WaitForDevice(),
- # sd_card_ready
- (self.call.device.GetExternalStoragePath(), '/fake/storage/path'),
- (self.call.adb.Shell('test -d /fake/storage/path'), self.ShellError()),
- # sd_card_ready
- (self.call.device.GetExternalStoragePath(), '/fake/storage/path'),
- (self.call.adb.Shell('test -d /fake/storage/path'), self.ShellError()),
- # sd_card_ready
- (self.call.device.GetExternalStoragePath(), '/fake/storage/path'),
- (self.call.adb.Shell('test -d /fake/storage/path'),
- self.TimeoutError())):
- with self.assertRaises(device_errors.CommandTimeoutError):
- self.device.WaitUntilFullyBooted(wifi=False)
-
- def testWaitUntilFullyBooted_devicePmFails(self):
- with self.assertCalls(
- self.call.adb.WaitForDevice(),
- # sd_card_ready
- (self.call.device.GetExternalStoragePath(), '/fake/storage/path'),
- (self.call.adb.Shell('test -d /fake/storage/path'), ''),
- # pm_ready
- (self.call.device.GetApplicationPaths('android'), self.CommandError()),
- # pm_ready
- (self.call.device.GetApplicationPaths('android'), self.CommandError()),
- # pm_ready
- (self.call.device.GetApplicationPaths('android'), self.TimeoutError())):
- with self.assertRaises(device_errors.CommandTimeoutError):
- self.device.WaitUntilFullyBooted(wifi=False)
-
- def testWaitUntilFullyBooted_bootFails(self):
- with self.assertCalls(
- self.call.adb.WaitForDevice(),
- # sd_card_ready
- (self.call.device.GetExternalStoragePath(), '/fake/storage/path'),
- (self.call.adb.Shell('test -d /fake/storage/path'), ''),
- # pm_ready
- (self.call.device.GetApplicationPaths('android'),
- ['package:/some/fake/path']),
- # boot_completed
- (self.call.device.GetProp('sys.boot_completed'), '0'),
- # boot_completed
- (self.call.device.GetProp('sys.boot_completed'), '0'),
- # boot_completed
- (self.call.device.GetProp('sys.boot_completed'), self.TimeoutError())):
- with self.assertRaises(device_errors.CommandTimeoutError):
- self.device.WaitUntilFullyBooted(wifi=False)
-
- def testWaitUntilFullyBooted_wifiFails(self):
- with self.assertCalls(
- self.call.adb.WaitForDevice(),
- # sd_card_ready
- (self.call.device.GetExternalStoragePath(), '/fake/storage/path'),
- (self.call.adb.Shell('test -d /fake/storage/path'), ''),
- # pm_ready
- (self.call.device.GetApplicationPaths('android'),
- ['package:/some/fake/path']),
- # boot_completed
- (self.call.device.GetProp('sys.boot_completed'), '1'),
- # wifi_enabled
- (self.call.adb.Shell('dumpsys wifi'), 'stuff\nmore stuff\n'),
- # wifi_enabled
- (self.call.adb.Shell('dumpsys wifi'), 'stuff\nmore stuff\n'),
- # wifi_enabled
- (self.call.adb.Shell('dumpsys wifi'), self.TimeoutError())):
- with self.assertRaises(device_errors.CommandTimeoutError):
- self.device.WaitUntilFullyBooted(wifi=True)
-
-
-@mock.patch('time.sleep', mock.Mock())
-class DeviceUtilsRebootTest(DeviceUtilsTest):
-
- def testReboot_nonBlocking(self):
- with self.assertCalls(
- self.call.adb.Reboot(),
- (self.call.device.IsOnline(), True),
- (self.call.device.IsOnline(), False)):
- self.device.Reboot(block=False)
-
- def testReboot_blocking(self):
- with self.assertCalls(
- self.call.adb.Reboot(),
- (self.call.device.IsOnline(), True),
- (self.call.device.IsOnline(), False),
- self.call.device.WaitUntilFullyBooted(wifi=False)):
- self.device.Reboot(block=True)
-
- def testReboot_blockUntilWifi(self):
- with self.assertCalls(
- self.call.adb.Reboot(),
- (self.call.device.IsOnline(), True),
- (self.call.device.IsOnline(), False),
- self.call.device.WaitUntilFullyBooted(wifi=True)):
- self.device.Reboot(block=True, wifi=True)
-
-
-class DeviceUtilsInstallTest(DeviceUtilsTest):
-
- def testInstall_noPriorInstall(self):
- with self.assertCalls(
- (mock.call.pylib.utils.apk_helper.GetPackageName('/fake/test/app.apk'),
- 'this.is.a.test.package'),
- (self.call.device.GetApplicationPaths('this.is.a.test.package'), []),
- self.call.adb.Install('/fake/test/app.apk', reinstall=False)):
- self.device.Install('/fake/test/app.apk', retries=0)
-
- def testInstall_differentPriorInstall(self):
- with self.assertCalls(
- (mock.call.pylib.utils.apk_helper.GetPackageName('/fake/test/app.apk'),
- 'this.is.a.test.package'),
- (self.call.device.GetApplicationPaths('this.is.a.test.package'),
- ['/fake/data/app/this.is.a.test.package.apk']),
- (self.call.device._GetChangedAndStaleFiles(
- '/fake/test/app.apk', '/fake/data/app/this.is.a.test.package.apk'),
- ([('/fake/test/app.apk', '/fake/data/app/this.is.a.test.package.apk')],
- [])),
- self.call.adb.Uninstall('this.is.a.test.package'),
- self.call.adb.Install('/fake/test/app.apk', reinstall=False)):
- self.device.Install('/fake/test/app.apk', retries=0)
-
- def testInstall_differentPriorInstall_reinstall(self):
- with self.assertCalls(
- (mock.call.pylib.utils.apk_helper.GetPackageName('/fake/test/app.apk'),
- 'this.is.a.test.package'),
- (self.call.device.GetApplicationPaths('this.is.a.test.package'),
- ['/fake/data/app/this.is.a.test.package.apk']),
- (self.call.device._GetChangedAndStaleFiles(
- '/fake/test/app.apk', '/fake/data/app/this.is.a.test.package.apk'),
- ([('/fake/test/app.apk', '/fake/data/app/this.is.a.test.package.apk')],
- [])),
- self.call.adb.Install('/fake/test/app.apk', reinstall=True)):
- self.device.Install('/fake/test/app.apk', reinstall=True, retries=0)
-
- def testInstall_identicalPriorInstall(self):
- with self.assertCalls(
- (mock.call.pylib.utils.apk_helper.GetPackageName('/fake/test/app.apk'),
- 'this.is.a.test.package'),
- (self.call.device.GetApplicationPaths('this.is.a.test.package'),
- ['/fake/data/app/this.is.a.test.package.apk']),
- (self.call.device._GetChangedAndStaleFiles(
- '/fake/test/app.apk', '/fake/data/app/this.is.a.test.package.apk'),
- ([], []))):
- self.device.Install('/fake/test/app.apk', retries=0)
-
- def testInstall_fails(self):
- with self.assertCalls(
- (mock.call.pylib.utils.apk_helper.GetPackageName('/fake/test/app.apk'),
- 'this.is.a.test.package'),
- (self.call.device.GetApplicationPaths('this.is.a.test.package'), []),
- (self.call.adb.Install('/fake/test/app.apk', reinstall=False),
- self.CommandError('Failure\r\n'))):
- with self.assertRaises(device_errors.CommandFailedError):
- self.device.Install('/fake/test/app.apk', retries=0)
-
-class DeviceUtilsInstallSplitApkTest(DeviceUtilsTest):
-
- def testInstallSplitApk_noPriorInstall(self):
- with self.assertCalls(
- (self.call.device._CheckSdkLevel(21)),
- (mock.call.pylib.sdk.split_select.SelectSplits(
- self.device, 'base.apk',
- ['split1.apk', 'split2.apk', 'split3.apk']),
- ['split2.apk']),
- (mock.call.pylib.utils.apk_helper.GetPackageName('base.apk'),
- 'this.is.a.test.package'),
- (self.call.device.GetApplicationPaths('this.is.a.test.package'), []),
- (self.call.adb.InstallMultiple(
- ['base.apk', 'split2.apk'], partial=None, reinstall=False))):
- self.device.InstallSplitApk('base.apk',
- ['split1.apk', 'split2.apk', 'split3.apk'], retries=0)
-
- def testInstallSplitApk_partialInstall(self):
- with self.assertCalls(
- (self.call.device._CheckSdkLevel(21)),
- (mock.call.pylib.sdk.split_select.SelectSplits(
- self.device, 'base.apk',
- ['split1.apk', 'split2.apk', 'split3.apk']),
- ['split2.apk']),
- (mock.call.pylib.utils.apk_helper.GetPackageName('base.apk'),
- 'test.package'),
- (self.call.device.GetApplicationPaths('test.package'),
- ['base-on-device.apk', 'split2-on-device.apk']),
- (mock.call.pylib.utils.md5sum.CalculateDeviceMd5Sums(
- ['base-on-device.apk', 'split2-on-device.apk'], self.device),
- {'base-on-device.apk': 'AAA', 'split2-on-device.apk': 'BBB'}),
- (mock.call.pylib.utils.md5sum.CalculateHostMd5Sums(
- ['base.apk', 'split2.apk']),
- {'base.apk': 'AAA', 'split2.apk': 'CCC'}),
- (self.call.adb.InstallMultiple(
- ['split2.apk'], partial='test.package', reinstall=True))):
- self.device.InstallSplitApk('base.apk',
- ['split1.apk', 'split2.apk', 'split3.apk'], reinstall=True, retries=0)
-
-
-class DeviceUtilsRunShellCommandTest(DeviceUtilsTest):
-
- def setUp(self):
- super(DeviceUtilsRunShellCommandTest, self).setUp()
- self.device.NeedsSU = mock.Mock(return_value=False)
-
- def testRunShellCommand_commandAsList(self):
- with self.assertCall(self.call.adb.Shell('pm list packages'), ''):
- self.device.RunShellCommand(['pm', 'list', 'packages'])
-
- def testRunShellCommand_commandAsListQuoted(self):
- with self.assertCall(self.call.adb.Shell("echo 'hello world' '$10'"), ''):
- self.device.RunShellCommand(['echo', 'hello world', '$10'])
-
- def testRunShellCommand_commandAsString(self):
- with self.assertCall(self.call.adb.Shell('echo "$VAR"'), ''):
- self.device.RunShellCommand('echo "$VAR"')
-
- def testNewRunShellImpl_withEnv(self):
- with self.assertCall(
- self.call.adb.Shell('VAR=some_string echo "$VAR"'), ''):
- self.device.RunShellCommand('echo "$VAR"', env={'VAR': 'some_string'})
-
- def testNewRunShellImpl_withEnvQuoted(self):
- with self.assertCall(
- self.call.adb.Shell('PATH="$PATH:/other/path" run_this'), ''):
- self.device.RunShellCommand('run_this', env={'PATH': '$PATH:/other/path'})
-
- def testNewRunShellImpl_withEnv_failure(self):
- with self.assertRaises(KeyError):
- self.device.RunShellCommand('some_cmd', env={'INVALID NAME': 'value'})
-
- def testNewRunShellImpl_withCwd(self):
- with self.assertCall(self.call.adb.Shell('cd /some/test/path && ls'), ''):
- self.device.RunShellCommand('ls', cwd='/some/test/path')
-
- def testNewRunShellImpl_withCwdQuoted(self):
- with self.assertCall(
- self.call.adb.Shell("cd '/some test/path with/spaces' && ls"), ''):
- self.device.RunShellCommand('ls', cwd='/some test/path with/spaces')
-
- def testRunShellCommand_withHugeCmd(self):
- payload = 'hi! ' * 1024
- expected_cmd = "echo '%s'" % payload
- with self.assertCalls(
- (mock.call.pylib.utils.device_temp_file.DeviceTempFile(
- self.adb, suffix='.sh'), MockTempFile('/sdcard/temp-123.sh')),
- self.call.device._WriteFileWithPush('/sdcard/temp-123.sh', expected_cmd),
- (self.call.adb.Shell('sh /sdcard/temp-123.sh'), payload + '\n')):
- self.assertEquals([payload],
- self.device.RunShellCommand(['echo', payload]))
-
- def testRunShellCommand_withHugeCmdAmdSU(self):
- payload = 'hi! ' * 1024
- expected_cmd = """su -c sh -c 'echo '"'"'%s'"'"''""" % payload
- with self.assertCalls(
- (self.call.device.NeedsSU(), True),
- (mock.call.pylib.utils.device_temp_file.DeviceTempFile(
- self.adb, suffix='.sh'), MockTempFile('/sdcard/temp-123.sh')),
- self.call.device._WriteFileWithPush('/sdcard/temp-123.sh', expected_cmd),
- (self.call.adb.Shell('sh /sdcard/temp-123.sh'), payload + '\n')):
- self.assertEquals(
- [payload],
- self.device.RunShellCommand(['echo', payload], as_root=True))
-
- def testRunShellCommand_withSu(self):
- with self.assertCalls(
- (self.call.device.NeedsSU(), True),
- (self.call.adb.Shell("su -c sh -c 'setprop service.adb.root 0'"), '')):
- self.device.RunShellCommand('setprop service.adb.root 0', as_root=True)
-
- def testRunShellCommand_manyLines(self):
- cmd = 'ls /some/path'
- with self.assertCall(self.call.adb.Shell(cmd), 'file1\nfile2\nfile3\n'):
- self.assertEquals(['file1', 'file2', 'file3'],
- self.device.RunShellCommand(cmd))
-
- def testRunShellCommand_singleLine_success(self):
- cmd = 'echo $VALUE'
- with self.assertCall(self.call.adb.Shell(cmd), 'some value\n'):
- self.assertEquals('some value',
- self.device.RunShellCommand(cmd, single_line=True))
-
- def testRunShellCommand_singleLine_successEmptyLine(self):
- cmd = 'echo $VALUE'
- with self.assertCall(self.call.adb.Shell(cmd), '\n'):
- self.assertEquals('',
- self.device.RunShellCommand(cmd, single_line=True))
-
- def testRunShellCommand_singleLine_successWithoutEndLine(self):
- cmd = 'echo -n $VALUE'
- with self.assertCall(self.call.adb.Shell(cmd), 'some value'):
- self.assertEquals('some value',
- self.device.RunShellCommand(cmd, single_line=True))
-
- def testRunShellCommand_singleLine_successNoOutput(self):
- cmd = 'echo -n $VALUE'
- with self.assertCall(self.call.adb.Shell(cmd), ''):
- self.assertEquals('',
- self.device.RunShellCommand(cmd, single_line=True))
-
- def testRunShellCommand_singleLine_failTooManyLines(self):
- cmd = 'echo $VALUE'
- with self.assertCall(self.call.adb.Shell(cmd),
- 'some value\nanother value\n'):
- with self.assertRaises(device_errors.CommandFailedError):
- self.device.RunShellCommand(cmd, single_line=True)
-
- def testRunShellCommand_checkReturn_success(self):
- cmd = 'echo $ANDROID_DATA'
- output = '/data\n'
- with self.assertCall(self.call.adb.Shell(cmd), output):
- self.assertEquals([output.rstrip()],
- self.device.RunShellCommand(cmd, check_return=True))
-
- def testRunShellCommand_checkReturn_failure(self):
- cmd = 'ls /root'
- output = 'opendir failed, Permission denied\n'
- with self.assertCall(self.call.adb.Shell(cmd), self.ShellError(output)):
- with self.assertRaises(device_errors.AdbCommandFailedError):
- self.device.RunShellCommand(cmd, check_return=True)
-
- def testRunShellCommand_checkReturn_disabled(self):
- cmd = 'ls /root'
- output = 'opendir failed, Permission denied\n'
- with self.assertCall(self.call.adb.Shell(cmd), self.ShellError(output)):
- self.assertEquals([output.rstrip()],
- self.device.RunShellCommand(cmd, check_return=False))
-
- def testRunShellCommand_largeOutput_enabled(self):
- cmd = 'echo $VALUE'
- temp_file = MockTempFile('/sdcard/temp-123')
- cmd_redirect = '%s > %s' % (cmd, temp_file.name)
- with self.assertCalls(
- (mock.call.pylib.utils.device_temp_file.DeviceTempFile(self.adb),
- temp_file),
- (self.call.adb.Shell(cmd_redirect)),
- (self.call.device.ReadFile(temp_file.name, force_pull=True),
- 'something')):
- self.assertEquals(
- ['something'],
- self.device.RunShellCommand(
- cmd, large_output=True, check_return=True))
-
- def testRunShellCommand_largeOutput_disabledNoTrigger(self):
- cmd = 'something'
- with self.assertCall(self.call.adb.Shell(cmd), self.ShellError('')):
- with self.assertRaises(device_errors.AdbCommandFailedError):
- self.device.RunShellCommand(cmd, check_return=True)
-
- def testRunShellCommand_largeOutput_disabledTrigger(self):
- cmd = 'echo $VALUE'
- temp_file = MockTempFile('/sdcard/temp-123')
- cmd_redirect = '%s > %s' % (cmd, temp_file.name)
- with self.assertCalls(
- (self.call.adb.Shell(cmd), self.ShellError('', None)),
- (mock.call.pylib.utils.device_temp_file.DeviceTempFile(self.adb),
- temp_file),
- (self.call.adb.Shell(cmd_redirect)),
- (self.call.device.ReadFile(mock.ANY, force_pull=True),
- 'something')):
- self.assertEquals(['something'],
- self.device.RunShellCommand(cmd, check_return=True))
-
-
-class DeviceUtilsRunPipedShellCommandTest(DeviceUtilsTest):
-
- def testRunPipedShellCommand_success(self):
- with self.assertCall(
- self.call.device.RunShellCommand(
- 'ps | grep foo; echo "PIPESTATUS: ${PIPESTATUS[@]}"',
- check_return=True),
- ['This line contains foo', 'PIPESTATUS: 0 0']):
- self.assertEquals(['This line contains foo'],
- self.device._RunPipedShellCommand('ps | grep foo'))
-
- def testRunPipedShellCommand_firstCommandFails(self):
- with self.assertCall(
- self.call.device.RunShellCommand(
- 'ps | grep foo; echo "PIPESTATUS: ${PIPESTATUS[@]}"',
- check_return=True),
- ['PIPESTATUS: 1 0']):
- with self.assertRaises(device_errors.AdbShellCommandFailedError) as ec:
- self.device._RunPipedShellCommand('ps | grep foo')
- self.assertEquals([1, 0], ec.exception.status)
-
- def testRunPipedShellCommand_secondCommandFails(self):
- with self.assertCall(
- self.call.device.RunShellCommand(
- 'ps | grep foo; echo "PIPESTATUS: ${PIPESTATUS[@]}"',
- check_return=True),
- ['PIPESTATUS: 0 1']):
- with self.assertRaises(device_errors.AdbShellCommandFailedError) as ec:
- self.device._RunPipedShellCommand('ps | grep foo')
- self.assertEquals([0, 1], ec.exception.status)
-
- def testRunPipedShellCommand_outputCutOff(self):
- with self.assertCall(
- self.call.device.RunShellCommand(
- 'ps | grep foo; echo "PIPESTATUS: ${PIPESTATUS[@]}"',
- check_return=True),
- ['foo.bar'] * 256 + ['foo.ba']):
- with self.assertRaises(device_errors.AdbShellCommandFailedError) as ec:
- self.device._RunPipedShellCommand('ps | grep foo')
- self.assertIs(None, ec.exception.status)
-
-
-@mock.patch('time.sleep', mock.Mock())
-class DeviceUtilsKillAllTest(DeviceUtilsTest):
-
- def testKillAll_noMatchingProcessesFailure(self):
- with self.assertCall(self.call.device.GetPids('test_process'), {}):
- with self.assertRaises(device_errors.CommandFailedError):
- self.device.KillAll('test_process')
-
- def testKillAll_noMatchingProcessesQuiet(self):
- with self.assertCall(self.call.device.GetPids('test_process'), {}):
- self.assertEqual(0, self.device.KillAll('test_process', quiet=True))
-
- def testKillAll_nonblocking(self):
- with self.assertCalls(
- (self.call.device.GetPids('some.process'), {'some.process': '1234'}),
- (self.call.adb.Shell('kill -9 1234'), '')):
- self.assertEquals(
- 1, self.device.KillAll('some.process', blocking=False))
-
- def testKillAll_blocking(self):
- with self.assertCalls(
- (self.call.device.GetPids('some.process'), {'some.process': '1234'}),
- (self.call.adb.Shell('kill -9 1234'), ''),
- (self.call.device.GetPids('some.process'), {'some.process': '1234'}),
- (self.call.device.GetPids('some.process'), [])):
- self.assertEquals(
- 1, self.device.KillAll('some.process', blocking=True))
-
- def testKillAll_root(self):
- with self.assertCalls(
- (self.call.device.GetPids('some.process'), {'some.process': '1234'}),
- (self.call.device.NeedsSU(), True),
- (self.call.adb.Shell("su -c sh -c 'kill -9 1234'"), '')):
- self.assertEquals(
- 1, self.device.KillAll('some.process', as_root=True))
-
- def testKillAll_sigterm(self):
- with self.assertCalls(
- (self.call.device.GetPids('some.process'), {'some.process': '1234'}),
- (self.call.adb.Shell('kill -15 1234'), '')):
- self.assertEquals(
- 1, self.device.KillAll('some.process', signum=device_signal.SIGTERM))
-
-
-class DeviceUtilsStartActivityTest(DeviceUtilsTest):
-
- def testStartActivity_actionOnly(self):
- test_intent = intent.Intent(action='android.intent.action.VIEW')
- with self.assertCall(
- self.call.adb.Shell('am start '
- '-a android.intent.action.VIEW'),
- 'Starting: Intent { act=android.intent.action.VIEW }'):
- self.device.StartActivity(test_intent)
-
- def testStartActivity_success(self):
- test_intent = intent.Intent(action='android.intent.action.VIEW',
- package='this.is.a.test.package',
- activity='.Main')
- with self.assertCall(
- self.call.adb.Shell('am start '
- '-a android.intent.action.VIEW '
- '-n this.is.a.test.package/.Main'),
- 'Starting: Intent { act=android.intent.action.VIEW }'):
- self.device.StartActivity(test_intent)
-
- def testStartActivity_failure(self):
- test_intent = intent.Intent(action='android.intent.action.VIEW',
- package='this.is.a.test.package',
- activity='.Main')
- with self.assertCall(
- self.call.adb.Shell('am start '
- '-a android.intent.action.VIEW '
- '-n this.is.a.test.package/.Main'),
- 'Error: Failed to start test activity'):
- with self.assertRaises(device_errors.CommandFailedError):
- self.device.StartActivity(test_intent)
-
- def testStartActivity_blocking(self):
- test_intent = intent.Intent(action='android.intent.action.VIEW',
- package='this.is.a.test.package',
- activity='.Main')
- with self.assertCall(
- self.call.adb.Shell('am start '
- '-W '
- '-a android.intent.action.VIEW '
- '-n this.is.a.test.package/.Main'),
- 'Starting: Intent { act=android.intent.action.VIEW }'):
- self.device.StartActivity(test_intent, blocking=True)
-
- def testStartActivity_withCategory(self):
- test_intent = intent.Intent(action='android.intent.action.VIEW',
- package='this.is.a.test.package',
- activity='.Main',
- category='android.intent.category.HOME')
- with self.assertCall(
- self.call.adb.Shell('am start '
- '-a android.intent.action.VIEW '
- '-c android.intent.category.HOME '
- '-n this.is.a.test.package/.Main'),
- 'Starting: Intent { act=android.intent.action.VIEW }'):
- self.device.StartActivity(test_intent)
-
- def testStartActivity_withMultipleCategories(self):
- test_intent = intent.Intent(action='android.intent.action.VIEW',
- package='this.is.a.test.package',
- activity='.Main',
- category=['android.intent.category.HOME',
- 'android.intent.category.BROWSABLE'])
- with self.assertCall(
- self.call.adb.Shell('am start '
- '-a android.intent.action.VIEW '
- '-c android.intent.category.HOME '
- '-c android.intent.category.BROWSABLE '
- '-n this.is.a.test.package/.Main'),
- 'Starting: Intent { act=android.intent.action.VIEW }'):
- self.device.StartActivity(test_intent)
-
- def testStartActivity_withData(self):
- test_intent = intent.Intent(action='android.intent.action.VIEW',
- package='this.is.a.test.package',
- activity='.Main',
- data='http://www.google.com/')
- with self.assertCall(
- self.call.adb.Shell('am start '
- '-a android.intent.action.VIEW '
- '-d http://www.google.com/ '
- '-n this.is.a.test.package/.Main'),
- 'Starting: Intent { act=android.intent.action.VIEW }'):
- self.device.StartActivity(test_intent)
-
- def testStartActivity_withStringExtra(self):
- test_intent = intent.Intent(action='android.intent.action.VIEW',
- package='this.is.a.test.package',
- activity='.Main',
- extras={'foo': 'test'})
- with self.assertCall(
- self.call.adb.Shell('am start '
- '-a android.intent.action.VIEW '
- '-n this.is.a.test.package/.Main '
- '--es foo test'),
- 'Starting: Intent { act=android.intent.action.VIEW }'):
- self.device.StartActivity(test_intent)
-
- def testStartActivity_withBoolExtra(self):
- test_intent = intent.Intent(action='android.intent.action.VIEW',
- package='this.is.a.test.package',
- activity='.Main',
- extras={'foo': True})
- with self.assertCall(
- self.call.adb.Shell('am start '
- '-a android.intent.action.VIEW '
- '-n this.is.a.test.package/.Main '
- '--ez foo True'),
- 'Starting: Intent { act=android.intent.action.VIEW }'):
- self.device.StartActivity(test_intent)
-
- def testStartActivity_withIntExtra(self):
- test_intent = intent.Intent(action='android.intent.action.VIEW',
- package='this.is.a.test.package',
- activity='.Main',
- extras={'foo': 123})
- with self.assertCall(
- self.call.adb.Shell('am start '
- '-a android.intent.action.VIEW '
- '-n this.is.a.test.package/.Main '
- '--ei foo 123'),
- 'Starting: Intent { act=android.intent.action.VIEW }'):
- self.device.StartActivity(test_intent)
-
- def testStartActivity_withTraceFile(self):
- test_intent = intent.Intent(action='android.intent.action.VIEW',
- package='this.is.a.test.package',
- activity='.Main')
- with self.assertCall(
- self.call.adb.Shell('am start '
- '--start-profiler test_trace_file.out '
- '-a android.intent.action.VIEW '
- '-n this.is.a.test.package/.Main'),
- 'Starting: Intent { act=android.intent.action.VIEW }'):
- self.device.StartActivity(test_intent,
- trace_file_name='test_trace_file.out')
-
- def testStartActivity_withForceStop(self):
- test_intent = intent.Intent(action='android.intent.action.VIEW',
- package='this.is.a.test.package',
- activity='.Main')
- with self.assertCall(
- self.call.adb.Shell('am start '
- '-S '
- '-a android.intent.action.VIEW '
- '-n this.is.a.test.package/.Main'),
- 'Starting: Intent { act=android.intent.action.VIEW }'):
- self.device.StartActivity(test_intent, force_stop=True)
-
- def testStartActivity_withFlags(self):
- test_intent = intent.Intent(action='android.intent.action.VIEW',
- package='this.is.a.test.package',
- activity='.Main',
- flags='0x10000000')
- with self.assertCall(
- self.call.adb.Shell('am start '
- '-a android.intent.action.VIEW '
- '-n this.is.a.test.package/.Main '
- '-f 0x10000000'),
- 'Starting: Intent { act=android.intent.action.VIEW }'):
- self.device.StartActivity(test_intent)
-
-
-class DeviceUtilsStartInstrumentationTest(DeviceUtilsTest):
-
- def testStartInstrumentation_nothing(self):
- with self.assertCalls(
- self.call.device.RunShellCommand(
- ['am', 'instrument', 'test.package/.TestInstrumentation'],
- check_return=True, large_output=True)):
- self.device.StartInstrumentation(
- 'test.package/.TestInstrumentation',
- finish=False, raw=False, extras=None)
-
- def testStartInstrumentation_finish(self):
- with self.assertCalls(
- (self.call.device.RunShellCommand(
- ['am', 'instrument', '-w', 'test.package/.TestInstrumentation'],
- check_return=True, large_output=True),
- ['OK (1 test)'])):
- output = self.device.StartInstrumentation(
- 'test.package/.TestInstrumentation',
- finish=True, raw=False, extras=None)
- self.assertEquals(['OK (1 test)'], output)
-
- def testStartInstrumentation_raw(self):
- with self.assertCalls(
- self.call.device.RunShellCommand(
- ['am', 'instrument', '-r', 'test.package/.TestInstrumentation'],
- check_return=True, large_output=True)):
- self.device.StartInstrumentation(
- 'test.package/.TestInstrumentation',
- finish=False, raw=True, extras=None)
-
- def testStartInstrumentation_extras(self):
- with self.assertCalls(
- self.call.device.RunShellCommand(
- ['am', 'instrument', '-e', 'foo', 'Foo', '-e', 'bar', 'Bar',
- 'test.package/.TestInstrumentation'],
- check_return=True, large_output=True)):
- self.device.StartInstrumentation(
- 'test.package/.TestInstrumentation',
- finish=False, raw=False, extras={'foo': 'Foo', 'bar': 'Bar'})
-
-
-class DeviceUtilsBroadcastIntentTest(DeviceUtilsTest):
-
- def testBroadcastIntent_noExtras(self):
- test_intent = intent.Intent(action='test.package.with.an.INTENT')
- with self.assertCall(
- self.call.adb.Shell('am broadcast -a test.package.with.an.INTENT'),
- 'Broadcasting: Intent { act=test.package.with.an.INTENT } '):
- self.device.BroadcastIntent(test_intent)
-
- def testBroadcastIntent_withExtra(self):
- test_intent = intent.Intent(action='test.package.with.an.INTENT',
- extras={'foo': 'bar value'})
- with self.assertCall(
- self.call.adb.Shell(
- "am broadcast -a test.package.with.an.INTENT --es foo 'bar value'"),
- 'Broadcasting: Intent { act=test.package.with.an.INTENT } '):
- self.device.BroadcastIntent(test_intent)
-
- def testBroadcastIntent_withExtra_noValue(self):
- test_intent = intent.Intent(action='test.package.with.an.INTENT',
- extras={'foo': None})
- with self.assertCall(
- self.call.adb.Shell(
- 'am broadcast -a test.package.with.an.INTENT --esn foo'),
- 'Broadcasting: Intent { act=test.package.with.an.INTENT } '):
- self.device.BroadcastIntent(test_intent)
-
-
-class DeviceUtilsGoHomeTest(DeviceUtilsTest):
-
- def testGoHome_popupsExist(self):
- with self.assertCalls(
- (self.call.device.RunShellCommand(
- ['dumpsys', 'window', 'windows'], check_return=True,
- large_output=True), []),
- (self.call.device.RunShellCommand(
- ['am', 'start', '-W', '-a', 'android.intent.action.MAIN',
- '-c', 'android.intent.category.HOME'], check_return=True),
- 'Starting: Intent { act=android.intent.action.MAIN }\r\n'''),
- (self.call.device.RunShellCommand(
- ['dumpsys', 'window', 'windows'], check_return=True,
- large_output=True), []),
- (self.call.device.RunShellCommand(
- ['input', 'keyevent', '66'], check_return=True)),
- (self.call.device.RunShellCommand(
- ['input', 'keyevent', '4'], check_return=True)),
- (self.call.device.RunShellCommand(
- ['dumpsys', 'window', 'windows'], check_return=True,
- large_output=True),
- ['mCurrentFocus Launcher'])):
- self.device.GoHome()
-
- def testGoHome_willRetry(self):
- with self.assertCalls(
- (self.call.device.RunShellCommand(
- ['dumpsys', 'window', 'windows'], check_return=True,
- large_output=True), []),
- (self.call.device.RunShellCommand(
- ['am', 'start', '-W', '-a', 'android.intent.action.MAIN',
- '-c', 'android.intent.category.HOME'], check_return=True),
- 'Starting: Intent { act=android.intent.action.MAIN }\r\n'''),
- (self.call.device.RunShellCommand(
- ['dumpsys', 'window', 'windows'], check_return=True,
- large_output=True), []),
- (self.call.device.RunShellCommand(
- ['input', 'keyevent', '66'], check_return=True,)),
- (self.call.device.RunShellCommand(
- ['input', 'keyevent', '4'], check_return=True)),
- (self.call.device.RunShellCommand(
- ['dumpsys', 'window', 'windows'], check_return=True,
- large_output=True), []),
- (self.call.device.RunShellCommand(
- ['input', 'keyevent', '66'], check_return=True)),
- (self.call.device.RunShellCommand(
- ['input', 'keyevent', '4'], check_return=True)),
- (self.call.device.RunShellCommand(
- ['dumpsys', 'window', 'windows'], check_return=True,
- large_output=True),
- self.TimeoutError())):
- with self.assertRaises(device_errors.CommandTimeoutError):
- self.device.GoHome()
-
- def testGoHome_alreadyFocused(self):
- with self.assertCall(
- self.call.device.RunShellCommand(
- ['dumpsys', 'window', 'windows'], check_return=True,
- large_output=True),
- ['mCurrentFocus Launcher']):
- self.device.GoHome()
-
- def testGoHome_alreadyFocusedAlternateCase(self):
- with self.assertCall(
- self.call.device.RunShellCommand(
- ['dumpsys', 'window', 'windows'], check_return=True,
- large_output=True),
- [' mCurrentFocus .launcher/.']):
- self.device.GoHome()
-
- def testGoHome_obtainsFocusAfterGoingHome(self):
- with self.assertCalls(
- (self.call.device.RunShellCommand(
- ['dumpsys', 'window', 'windows'], check_return=True,
- large_output=True), []),
- (self.call.device.RunShellCommand(
- ['am', 'start', '-W', '-a', 'android.intent.action.MAIN',
- '-c', 'android.intent.category.HOME'], check_return=True),
- 'Starting: Intent { act=android.intent.action.MAIN }\r\n'''),
- (self.call.device.RunShellCommand(
- ['dumpsys', 'window', 'windows'], check_return=True,
- large_output=True),
- ['mCurrentFocus Launcher'])):
- self.device.GoHome()
-
-class DeviceUtilsForceStopTest(DeviceUtilsTest):
-
- def testForceStop(self):
- with self.assertCall(
- self.call.adb.Shell('am force-stop this.is.a.test.package'),
- ''):
- self.device.ForceStop('this.is.a.test.package')
-
-
-class DeviceUtilsClearApplicationStateTest(DeviceUtilsTest):
-
- def testClearApplicationState_packageDoesntExist(self):
- with self.assertCalls(
- (self.call.adb.Shell('getprop ro.build.version.sdk'), '17\n'),
- (self.call.device.GetApplicationPaths('this.package.does.not.exist'),
- [])):
- self.device.ClearApplicationState('this.package.does.not.exist')
-
- def testClearApplicationState_packageDoesntExistOnAndroidJBMR2OrAbove(self):
- with self.assertCalls(
- (self.call.adb.Shell('getprop ro.build.version.sdk'), '18\n'),
- (self.call.adb.Shell('pm clear this.package.does.not.exist'),
- 'Failed\r\n')):
- self.device.ClearApplicationState('this.package.does.not.exist')
-
- def testClearApplicationState_packageExists(self):
- with self.assertCalls(
- (self.call.adb.Shell('getprop ro.build.version.sdk'), '17\n'),
- (self.call.device.GetApplicationPaths('this.package.exists'),
- ['/data/app/this.package.exists.apk']),
- (self.call.adb.Shell('pm clear this.package.exists'),
- 'Success\r\n')):
- self.device.ClearApplicationState('this.package.exists')
-
- def testClearApplicationState_packageExistsOnAndroidJBMR2OrAbove(self):
- with self.assertCalls(
- (self.call.adb.Shell('getprop ro.build.version.sdk'), '18\n'),
- (self.call.adb.Shell('pm clear this.package.exists'),
- 'Success\r\n')):
- self.device.ClearApplicationState('this.package.exists')
-
-
-class DeviceUtilsSendKeyEventTest(DeviceUtilsTest):
-
- def testSendKeyEvent(self):
- with self.assertCall(self.call.adb.Shell('input keyevent 66'), ''):
- self.device.SendKeyEvent(66)
-
-
-class DeviceUtilsPushChangedFilesIndividuallyTest(DeviceUtilsTest):
-
- def testPushChangedFilesIndividually_empty(self):
- test_files = []
- with self.assertCalls():
- self.device._PushChangedFilesIndividually(test_files)
-
- def testPushChangedFilesIndividually_single(self):
- test_files = [('/test/host/path', '/test/device/path')]
- with self.assertCalls(self.call.adb.Push(*test_files[0])):
- self.device._PushChangedFilesIndividually(test_files)
-
- def testPushChangedFilesIndividually_multiple(self):
- test_files = [
- ('/test/host/path/file1', '/test/device/path/file1'),
- ('/test/host/path/file2', '/test/device/path/file2')]
- with self.assertCalls(
- self.call.adb.Push(*test_files[0]),
- self.call.adb.Push(*test_files[1])):
- self.device._PushChangedFilesIndividually(test_files)
-
-
-class DeviceUtilsPushChangedFilesZippedTest(DeviceUtilsTest):
-
- def testPushChangedFilesZipped_empty(self):
- test_files = []
- with self.assertCalls():
- self.device._PushChangedFilesZipped(test_files)
-
- def _testPushChangedFilesZipped_spec(self, test_files):
- mock_zip_temp = mock.mock_open()
- mock_zip_temp.return_value.name = '/test/temp/file/tmp.zip'
- with self.assertCalls(
- (mock.call.tempfile.NamedTemporaryFile(suffix='.zip'), mock_zip_temp),
- (mock.call.multiprocessing.Process(
- target=device_utils.DeviceUtils._CreateDeviceZip,
- args=('/test/temp/file/tmp.zip', test_files)), mock.Mock()),
- (self.call.device.GetExternalStoragePath(),
- '/test/device/external_dir'),
- self.call.adb.Push(
- '/test/temp/file/tmp.zip', '/test/device/external_dir/tmp.zip'),
- self.call.device.RunShellCommand(
- ['unzip', '/test/device/external_dir/tmp.zip'],
- as_root=True,
- env={'PATH': '/data/local/tmp/bin:$PATH'},
- check_return=True),
- (self.call.device.IsOnline(), True),
- self.call.device.RunShellCommand(
- ['rm', '/test/device/external_dir/tmp.zip'], check_return=True)):
- self.device._PushChangedFilesZipped(test_files)
-
- def testPushChangedFilesZipped_single(self):
- self._testPushChangedFilesZipped_spec(
- [('/test/host/path/file1', '/test/device/path/file1')])
-
- def testPushChangedFilesZipped_multiple(self):
- self._testPushChangedFilesZipped_spec(
- [('/test/host/path/file1', '/test/device/path/file1'),
- ('/test/host/path/file2', '/test/device/path/file2')])
-
-
-class DeviceUtilsFileExistsTest(DeviceUtilsTest):
-
- def testFileExists_usingTest_fileExists(self):
- with self.assertCall(
- self.call.device.RunShellCommand(
- ['test', '-e', '/path/file.exists'], check_return=True), ''):
- self.assertTrue(self.device.FileExists('/path/file.exists'))
-
- def testFileExists_usingTest_fileDoesntExist(self):
- with self.assertCall(
- self.call.device.RunShellCommand(
- ['test', '-e', '/does/not/exist'], check_return=True),
- self.ShellError('', 1)):
- self.assertFalse(self.device.FileExists('/does/not/exist'))
-
-
-class DeviceUtilsPullFileTest(DeviceUtilsTest):
-
- def testPullFile_existsOnDevice(self):
- with mock.patch('os.path.exists', return_value=True):
- with self.assertCall(
- self.call.adb.Pull('/data/app/test.file.exists',
- '/test/file/host/path')):
- self.device.PullFile('/data/app/test.file.exists',
- '/test/file/host/path')
-
- def testPullFile_doesntExistOnDevice(self):
- with mock.patch('os.path.exists', return_value=True):
- with self.assertCall(
- self.call.adb.Pull('/data/app/test.file.does.not.exist',
- '/test/file/host/path'),
- self.CommandError('remote object does not exist')):
- with self.assertRaises(device_errors.CommandFailedError):
- self.device.PullFile('/data/app/test.file.does.not.exist',
- '/test/file/host/path')
-
-
-class DeviceUtilsReadFileTest(DeviceUtilsTest):
-
- def testReadFileWithPull_success(self):
- tmp_host_dir = '/tmp/dir/on.host/'
- tmp_host = MockTempFile('/tmp/dir/on.host/tmp_ReadFileWithPull')
- tmp_host.file.read.return_value = 'some interesting contents'
- with self.assertCalls(
- (mock.call.tempfile.mkdtemp(), tmp_host_dir),
- (self.call.adb.Pull('/path/to/device/file', mock.ANY)),
- (mock.call.__builtin__.open(mock.ANY, 'r'), tmp_host),
- (mock.call.os.path.exists(tmp_host_dir), True),
- (mock.call.shutil.rmtree(tmp_host_dir), None)):
- self.assertEquals('some interesting contents',
- self.device._ReadFileWithPull('/path/to/device/file'))
- tmp_host.file.read.assert_called_once_with()
-
- def testReadFileWithPull_rejected(self):
- tmp_host_dir = '/tmp/dir/on.host/'
- with self.assertCalls(
- (mock.call.tempfile.mkdtemp(), tmp_host_dir),
- (self.call.adb.Pull('/path/to/device/file', mock.ANY),
- self.CommandError()),
- (mock.call.os.path.exists(tmp_host_dir), True),
- (mock.call.shutil.rmtree(tmp_host_dir), None)):
- with self.assertRaises(device_errors.CommandFailedError):
- self.device._ReadFileWithPull('/path/to/device/file')
-
- def testReadFile_exists(self):
- with self.assertCalls(
- (self.call.device.RunShellCommand(
- ['ls', '-l', '/read/this/test/file'],
- as_root=False, check_return=True),
- ['-rw-rw---- root foo 256 1970-01-01 00:00 file']),
- (self.call.device.RunShellCommand(
- ['cat', '/read/this/test/file'],
- as_root=False, check_return=True),
- ['this is a test file'])):
- self.assertEqual('this is a test file\n',
- self.device.ReadFile('/read/this/test/file'))
-
- def testReadFile_doesNotExist(self):
- with self.assertCall(
- self.call.device.RunShellCommand(
- ['ls', '-l', '/this/file/does.not.exist'],
- as_root=False, check_return=True),
- self.CommandError('File does not exist')):
- with self.assertRaises(device_errors.CommandFailedError):
- self.device.ReadFile('/this/file/does.not.exist')
-
- def testReadFile_zeroSize(self):
- with self.assertCalls(
- (self.call.device.RunShellCommand(
- ['ls', '-l', '/this/file/has/zero/size'],
- as_root=False, check_return=True),
- ['-r--r--r-- root foo 0 1970-01-01 00:00 zero_size_file']),
- (self.call.device._ReadFileWithPull('/this/file/has/zero/size'),
- 'but it has contents\n')):
- self.assertEqual('but it has contents\n',
- self.device.ReadFile('/this/file/has/zero/size'))
-
- def testReadFile_withSU(self):
- with self.assertCalls(
- (self.call.device.RunShellCommand(
- ['ls', '-l', '/this/file/can.be.read.with.su'],
- as_root=True, check_return=True),
- ['-rw------- root root 256 1970-01-01 00:00 can.be.read.with.su']),
- (self.call.device.RunShellCommand(
- ['cat', '/this/file/can.be.read.with.su'],
- as_root=True, check_return=True),
- ['this is a test file', 'read with su'])):
- self.assertEqual(
- 'this is a test file\nread with su\n',
- self.device.ReadFile('/this/file/can.be.read.with.su',
- as_root=True))
-
- def testReadFile_withPull(self):
- contents = 'a' * 123456
- with self.assertCalls(
- (self.call.device.RunShellCommand(
- ['ls', '-l', '/read/this/big/test/file'],
- as_root=False, check_return=True),
- ['-rw-rw---- root foo 123456 1970-01-01 00:00 file']),
- (self.call.device._ReadFileWithPull('/read/this/big/test/file'),
- contents)):
- self.assertEqual(
- contents, self.device.ReadFile('/read/this/big/test/file'))
-
- def testReadFile_withPullAndSU(self):
- contents = 'b' * 123456
- with self.assertCalls(
- (self.call.device.RunShellCommand(
- ['ls', '-l', '/this/big/file/can.be.read.with.su'],
- as_root=True, check_return=True),
- ['-rw------- root root 123456 1970-01-01 00:00 can.be.read.with.su']),
- (self.call.device.NeedsSU(), True),
- (mock.call.pylib.utils.device_temp_file.DeviceTempFile(self.adb),
- MockTempFile('/sdcard/tmp/on.device')),
- self.call.device.RunShellCommand(
- ['cp', '/this/big/file/can.be.read.with.su',
- '/sdcard/tmp/on.device'],
- as_root=True, check_return=True),
- (self.call.device._ReadFileWithPull('/sdcard/tmp/on.device'),
- contents)):
- self.assertEqual(
- contents,
- self.device.ReadFile('/this/big/file/can.be.read.with.su',
- as_root=True))
-
- def testReadFile_forcePull(self):
- contents = 'a' * 123456
- with self.assertCall(
- self.call.device._ReadFileWithPull('/read/this/big/test/file'),
- contents):
- self.assertEqual(
- contents,
- self.device.ReadFile('/read/this/big/test/file', force_pull=True))
-
-
-class DeviceUtilsWriteFileTest(DeviceUtilsTest):
-
- def testWriteFileWithPush_success(self):
- tmp_host = MockTempFile('/tmp/file/on.host')
- contents = 'some interesting contents'
- with self.assertCalls(
- (mock.call.tempfile.NamedTemporaryFile(), tmp_host),
- self.call.adb.Push('/tmp/file/on.host', '/path/to/device/file')):
- self.device._WriteFileWithPush('/path/to/device/file', contents)
- tmp_host.file.write.assert_called_once_with(contents)
-
- def testWriteFileWithPush_rejected(self):
- tmp_host = MockTempFile('/tmp/file/on.host')
- contents = 'some interesting contents'
- with self.assertCalls(
- (mock.call.tempfile.NamedTemporaryFile(), tmp_host),
- (self.call.adb.Push('/tmp/file/on.host', '/path/to/device/file'),
- self.CommandError())):
- with self.assertRaises(device_errors.CommandFailedError):
- self.device._WriteFileWithPush('/path/to/device/file', contents)
-
- def testWriteFile_withPush(self):
- contents = 'some large contents ' * 26 # 20 * 26 = 520 chars
- with self.assertCalls(
- self.call.device._WriteFileWithPush('/path/to/device/file', contents)):
- self.device.WriteFile('/path/to/device/file', contents)
-
- def testWriteFile_withPushForced(self):
- contents = 'tiny contents'
- with self.assertCalls(
- self.call.device._WriteFileWithPush('/path/to/device/file', contents)):
- self.device.WriteFile('/path/to/device/file', contents, force_push=True)
-
- def testWriteFile_withPushAndSU(self):
- contents = 'some large contents ' * 26 # 20 * 26 = 520 chars
- with self.assertCalls(
- (self.call.device.NeedsSU(), True),
- (mock.call.pylib.utils.device_temp_file.DeviceTempFile(self.adb),
- MockTempFile('/sdcard/tmp/on.device')),
- self.call.device._WriteFileWithPush('/sdcard/tmp/on.device', contents),
- self.call.device.RunShellCommand(
- ['cp', '/sdcard/tmp/on.device', '/path/to/device/file'],
- as_root=True, check_return=True)):
- self.device.WriteFile('/path/to/device/file', contents, as_root=True)
-
- def testWriteFile_withEcho(self):
- with self.assertCall(self.call.adb.Shell(
- "echo -n the.contents > /test/file/to.write"), ''):
- self.device.WriteFile('/test/file/to.write', 'the.contents')
-
- def testWriteFile_withEchoAndQuotes(self):
- with self.assertCall(self.call.adb.Shell(
- "echo -n 'the contents' > '/test/file/to write'"), ''):
- self.device.WriteFile('/test/file/to write', 'the contents')
-
- def testWriteFile_withEchoAndSU(self):
- with self.assertCalls(
- (self.call.device.NeedsSU(), True),
- (self.call.adb.Shell("su -c sh -c 'echo -n contents > /test/file'"),
- '')):
- self.device.WriteFile('/test/file', 'contents', as_root=True)
-
-
-class DeviceUtilsLsTest(DeviceUtilsTest):
-
- def testLs_directory(self):
- result = [('.', adb_wrapper.DeviceStat(16889, 4096, 1417436123)),
- ('..', adb_wrapper.DeviceStat(16873, 4096, 12382237)),
- ('testfile.txt', adb_wrapper.DeviceStat(33206, 3, 1417436122))]
- with self.assertCalls(
- (self.call.adb.Ls('/data/local/tmp'), result)):
- self.assertEquals(result,
- self.device.Ls('/data/local/tmp'))
-
- def testLs_nothing(self):
- with self.assertCalls(
- (self.call.adb.Ls('/data/local/tmp/testfile.txt'), [])):
- self.assertEquals([],
- self.device.Ls('/data/local/tmp/testfile.txt'))
-
-
-class DeviceUtilsStatTest(DeviceUtilsTest):
-
- def testStat_file(self):
- result = [('.', adb_wrapper.DeviceStat(16889, 4096, 1417436123)),
- ('..', adb_wrapper.DeviceStat(16873, 4096, 12382237)),
- ('testfile.txt', adb_wrapper.DeviceStat(33206, 3, 1417436122))]
- with self.assertCalls(
- (self.call.adb.Ls('/data/local/tmp'), result)):
- self.assertEquals(adb_wrapper.DeviceStat(33206, 3, 1417436122),
- self.device.Stat('/data/local/tmp/testfile.txt'))
-
- def testStat_directory(self):
- result = [('.', adb_wrapper.DeviceStat(16873, 4096, 12382237)),
- ('..', adb_wrapper.DeviceStat(16873, 4096, 12382237)),
- ('tmp', adb_wrapper.DeviceStat(16889, 4096, 1417436123))]
- with self.assertCalls(
- (self.call.adb.Ls('/data/local'), result)):
- self.assertEquals(adb_wrapper.DeviceStat(16889, 4096, 1417436123),
- self.device.Stat('/data/local/tmp'))
-
- def testStat_doesNotExist(self):
- result = [('.', adb_wrapper.DeviceStat(16889, 4096, 1417436123)),
- ('..', adb_wrapper.DeviceStat(16873, 4096, 12382237)),
- ('testfile.txt', adb_wrapper.DeviceStat(33206, 3, 1417436122))]
- with self.assertCalls(
- (self.call.adb.Ls('/data/local/tmp'), result)):
- with self.assertRaises(device_errors.CommandFailedError):
- self.device.Stat('/data/local/tmp/does.not.exist.txt')
-
-
-class DeviceUtilsSetJavaAssertsTest(DeviceUtilsTest):
-
- def testSetJavaAsserts_enable(self):
- with self.assertCalls(
- (self.call.device.ReadFile(constants.DEVICE_LOCAL_PROPERTIES_PATH),
- 'some.example.prop=with an example value\n'
- 'some.other.prop=value_ok\n'),
- self.call.device.WriteFile(
- constants.DEVICE_LOCAL_PROPERTIES_PATH,
- 'some.example.prop=with an example value\n'
- 'some.other.prop=value_ok\n'
- 'dalvik.vm.enableassertions=all\n'),
- (self.call.device.GetProp('dalvik.vm.enableassertions'), ''),
- self.call.device.SetProp('dalvik.vm.enableassertions', 'all')):
- self.assertTrue(self.device.SetJavaAsserts(True))
-
- def testSetJavaAsserts_disable(self):
- with self.assertCalls(
- (self.call.device.ReadFile(constants.DEVICE_LOCAL_PROPERTIES_PATH),
- 'some.example.prop=with an example value\n'
- 'dalvik.vm.enableassertions=all\n'
- 'some.other.prop=value_ok\n'),
- self.call.device.WriteFile(
- constants.DEVICE_LOCAL_PROPERTIES_PATH,
- 'some.example.prop=with an example value\n'
- 'some.other.prop=value_ok\n'),
- (self.call.device.GetProp('dalvik.vm.enableassertions'), 'all'),
- self.call.device.SetProp('dalvik.vm.enableassertions', '')):
- self.assertTrue(self.device.SetJavaAsserts(False))
-
- def testSetJavaAsserts_alreadyEnabled(self):
- with self.assertCalls(
- (self.call.device.ReadFile(constants.DEVICE_LOCAL_PROPERTIES_PATH),
- 'some.example.prop=with an example value\n'
- 'dalvik.vm.enableassertions=all\n'
- 'some.other.prop=value_ok\n'),
- (self.call.device.GetProp('dalvik.vm.enableassertions'), 'all')):
- self.assertFalse(self.device.SetJavaAsserts(True))
-
-
-class DeviceUtilsGetPropTest(DeviceUtilsTest):
-
- def testGetProp_exists(self):
- with self.assertCall(
- self.call.adb.Shell('getprop test.property'), 'property_value\n'):
- self.assertEqual('property_value',
- self.device.GetProp('test.property'))
-
- def testGetProp_doesNotExist(self):
- with self.assertCall(
- self.call.adb.Shell('getprop property.does.not.exist'), '\n'):
- self.assertEqual('', self.device.GetProp('property.does.not.exist'))
-
- def testGetProp_cachedRoProp(self):
- with self.assertCall(
- self.call.adb.Shell('getprop ro.build.type'), 'userdebug\n'):
- self.assertEqual('userdebug',
- self.device.GetProp('ro.build.type', cache=True))
- self.assertEqual('userdebug',
- self.device.GetProp('ro.build.type', cache=True))
-
- def testGetProp_retryAndCache(self):
- with self.assertCalls(
- (self.call.adb.Shell('getprop ro.build.type'), self.ShellError()),
- (self.call.adb.Shell('getprop ro.build.type'), self.ShellError()),
- (self.call.adb.Shell('getprop ro.build.type'), 'userdebug\n')):
- self.assertEqual('userdebug',
- self.device.GetProp('ro.build.type',
- cache=True, retries=3))
- self.assertEqual('userdebug',
- self.device.GetProp('ro.build.type',
- cache=True, retries=3))
-
-
-class DeviceUtilsSetPropTest(DeviceUtilsTest):
-
- def testSetProp(self):
- with self.assertCall(
- self.call.adb.Shell("setprop test.property 'test value'"), ''):
- self.device.SetProp('test.property', 'test value')
-
- def testSetProp_check_succeeds(self):
- with self.assertCalls(
- (self.call.adb.Shell('setprop test.property new_value'), ''),
- (self.call.adb.Shell('getprop test.property'), 'new_value')):
- self.device.SetProp('test.property', 'new_value', check=True)
-
- def testSetProp_check_fails(self):
- with self.assertCalls(
- (self.call.adb.Shell('setprop test.property new_value'), ''),
- (self.call.adb.Shell('getprop test.property'), 'old_value')):
- with self.assertRaises(device_errors.CommandFailedError):
- self.device.SetProp('test.property', 'new_value', check=True)
-
-
-class DeviceUtilsGetPidsTest(DeviceUtilsTest):
-
- def testGetPids_noMatches(self):
- with self.assertCall(
- self.call.device._RunPipedShellCommand('ps | grep -F does.not.match'),
- []):
- self.assertEqual({}, self.device.GetPids('does.not.match'))
-
- def testGetPids_oneMatch(self):
- with self.assertCall(
- self.call.device._RunPipedShellCommand('ps | grep -F one.match'),
- ['user 1001 100 1024 1024 ffffffff 00000000 one.match']):
- self.assertEqual({'one.match': '1001'}, self.device.GetPids('one.match'))
-
- def testGetPids_mutlipleMatches(self):
- with self.assertCall(
- self.call.device._RunPipedShellCommand('ps | grep -F match'),
- ['user 1001 100 1024 1024 ffffffff 00000000 one.match',
- 'user 1002 100 1024 1024 ffffffff 00000000 two.match',
- 'user 1003 100 1024 1024 ffffffff 00000000 three.match']):
- self.assertEqual(
- {'one.match': '1001', 'two.match': '1002', 'three.match': '1003'},
- self.device.GetPids('match'))
-
- def testGetPids_exactMatch(self):
- with self.assertCall(
- self.call.device._RunPipedShellCommand('ps | grep -F exact.match'),
- ['user 1000 100 1024 1024 ffffffff 00000000 not.exact.match',
- 'user 1234 100 1024 1024 ffffffff 00000000 exact.match']):
- self.assertEqual(
- {'not.exact.match': '1000', 'exact.match': '1234'},
- self.device.GetPids('exact.match'))
-
- def testGetPids_quotable(self):
- with self.assertCall(
- self.call.device._RunPipedShellCommand("ps | grep -F 'my$process'"),
- ['user 1234 100 1024 1024 ffffffff 00000000 my$process']):
- self.assertEqual(
- {'my$process': '1234'}, self.device.GetPids('my$process'))
-
-
-class DeviceUtilsTakeScreenshotTest(DeviceUtilsTest):
-
- def testTakeScreenshot_fileNameProvided(self):
- with self.assertCalls(
- (mock.call.pylib.utils.device_temp_file.DeviceTempFile(
- self.adb, suffix='.png'),
- MockTempFile('/tmp/path/temp-123.png')),
- (self.call.adb.Shell('/system/bin/screencap -p /tmp/path/temp-123.png'),
- ''),
- self.call.device.PullFile('/tmp/path/temp-123.png',
- '/test/host/screenshot.png')):
- self.device.TakeScreenshot('/test/host/screenshot.png')
-
-
-class DeviceUtilsGetMemoryUsageForPidTest(DeviceUtilsTest):
-
- def setUp(self):
- super(DeviceUtilsGetMemoryUsageForPidTest, self).setUp()
-
- def testGetMemoryUsageForPid_validPid(self):
- with self.assertCalls(
- (self.call.device._RunPipedShellCommand(
- 'showmap 1234 | grep TOTAL', as_root=True),
- ['100 101 102 103 104 105 106 107 TOTAL']),
- (self.call.device.ReadFile('/proc/1234/status', as_root=True),
- 'VmHWM: 1024 kB\n')):
- self.assertEqual(
- {
- 'Size': 100,
- 'Rss': 101,
- 'Pss': 102,
- 'Shared_Clean': 103,
- 'Shared_Dirty': 104,
- 'Private_Clean': 105,
- 'Private_Dirty': 106,
- 'VmHWM': 1024
- },
- self.device.GetMemoryUsageForPid(1234))
-
- def testGetMemoryUsageForPid_noSmaps(self):
- with self.assertCalls(
- (self.call.device._RunPipedShellCommand(
- 'showmap 4321 | grep TOTAL', as_root=True),
- ['cannot open /proc/4321/smaps: No such file or directory']),
- (self.call.device.ReadFile('/proc/4321/status', as_root=True),
- 'VmHWM: 1024 kb\n')):
- self.assertEquals({'VmHWM': 1024}, self.device.GetMemoryUsageForPid(4321))
-
- def testGetMemoryUsageForPid_noStatus(self):
- with self.assertCalls(
- (self.call.device._RunPipedShellCommand(
- 'showmap 4321 | grep TOTAL', as_root=True),
- ['100 101 102 103 104 105 106 107 TOTAL']),
- (self.call.device.ReadFile('/proc/4321/status', as_root=True),
- self.CommandError())):
- self.assertEquals(
- {
- 'Size': 100,
- 'Rss': 101,
- 'Pss': 102,
- 'Shared_Clean': 103,
- 'Shared_Dirty': 104,
- 'Private_Clean': 105,
- 'Private_Dirty': 106,
- },
- self.device.GetMemoryUsageForPid(4321))
-
-
-class DeviceUtilsClientCache(DeviceUtilsTest):
-
- def testClientCache_twoCaches(self):
- self.device._cache['test'] = 0
- client_cache_one = self.device.GetClientCache('ClientOne')
- client_cache_one['test'] = 1
- client_cache_two = self.device.GetClientCache('ClientTwo')
- client_cache_two['test'] = 2
- self.assertEqual(self.device._cache, {'test': 0})
- self.assertEqual(client_cache_one, {'test': 1})
- self.assertEqual(client_cache_two, {'test': 2})
- self.device._ClearCache()
- self.assertEqual(self.device._cache, {})
- self.assertEqual(client_cache_one, {})
- self.assertEqual(client_cache_two, {})
-
- def testClientCache_multipleInstances(self):
- client_cache_one = self.device.GetClientCache('ClientOne')
- client_cache_one['test'] = 1
- client_cache_two = self.device.GetClientCache('ClientOne')
- self.assertEqual(client_cache_one, {'test': 1})
- self.assertEqual(client_cache_two, {'test': 1})
- self.device._ClearCache()
- self.assertEqual(client_cache_one, {})
- self.assertEqual(client_cache_two, {})
-
-
-class DeviceUtilsParallelTest(mock_calls.TestCase):
-
- def testParallel_default(self):
- test_serials = ['0123456789abcdef', 'fedcba9876543210']
- with self.assertCall(
- mock.call.pylib.device.device_utils.DeviceUtils.HealthyDevices(),
- [device_utils.DeviceUtils(s) for s in test_serials]):
- parallel_devices = device_utils.DeviceUtils.parallel()
- for serial, device in zip(test_serials, parallel_devices.pGet(None)):
- self.assertTrue(isinstance(device, device_utils.DeviceUtils))
- self.assertEquals(serial, device.adb.GetDeviceSerial())
-
- def testParallel_noDevices(self):
- with self.assertCall(
- mock.call.pylib.device.device_utils.DeviceUtils.HealthyDevices(), []):
- with self.assertRaises(device_errors.NoDevicesError):
- device_utils.DeviceUtils.parallel()
-
-
-class DeviceUtilsHealthyDevicesTest(mock_calls.TestCase):
-
- def _createAdbWrapperMock(self, serial, is_ready=True):
- adb = _AdbWrapperMock(serial)
- adb.is_ready = is_ready
- return adb
-
- def testHealthyDevices_default(self):
- test_serials = ['0123456789abcdef', 'fedcba9876543210']
- with self.assertCalls(
- (mock.call.pylib.device.device_blacklist.ReadBlacklist(), []),
- (mock.call.pylib.device.adb_wrapper.AdbWrapper.Devices(),
- [self._createAdbWrapperMock(s) for s in test_serials])):
- devices = device_utils.DeviceUtils.HealthyDevices()
- for serial, device in zip(test_serials, devices):
- self.assertTrue(isinstance(device, device_utils.DeviceUtils))
- self.assertEquals(serial, device.adb.GetDeviceSerial())
-
- def testHealthyDevices_blacklisted(self):
- test_serials = ['0123456789abcdef', 'fedcba9876543210']
- with self.assertCalls(
- (mock.call.pylib.device.device_blacklist.ReadBlacklist(),
- ['fedcba9876543210']),
- (mock.call.pylib.device.adb_wrapper.AdbWrapper.Devices(),
- [self._createAdbWrapperMock(s) for s in test_serials])):
- devices = device_utils.DeviceUtils.HealthyDevices()
- self.assertEquals(1, len(devices))
- self.assertTrue(isinstance(devices[0], device_utils.DeviceUtils))
- self.assertEquals('0123456789abcdef', devices[0].adb.GetDeviceSerial())
-
-
-if __name__ == '__main__':
- logging.getLogger().setLevel(logging.DEBUG)
- unittest.main(verbosity=2)
-
diff --git a/build/android/pylib/device/intent.py b/build/android/pylib/device/intent.py
deleted file mode 100644
index 333b9f1..0000000
--- a/build/android/pylib/device/intent.py
+++ /dev/null
@@ -1,113 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Manages intents and associated information.
-
-This is generally intended to be used with functions that calls Android's
-Am command.
-"""
-
-class Intent(object):
-
- def __init__(self, action='android.intent.action.VIEW', activity=None,
- category=None, component=None, data=None, extras=None,
- flags=None, package=None):
- """Creates an Intent.
-
- Args:
- action: A string containing the action.
- activity: A string that, with |package|, can be used to specify the
- component.
- category: A string or list containing any categories.
- component: A string that specifies the component to send the intent to.
- data: A string containing a data URI.
- extras: A dict containing extra parameters to be passed along with the
- intent.
- flags: A string containing flags to pass.
- package: A string that, with activity, can be used to specify the
- component.
- """
- self._action = action
- self._activity = activity
- if isinstance(category, list) or category is None:
- self._category = category
- else:
- self._category = [category]
- self._component = component
- self._data = data
- self._extras = extras
- self._flags = flags
- self._package = package
-
- if self._component and '/' in component:
- self._package, self._activity = component.split('/', 1)
- elif self._package and self._activity:
- self._component = '%s/%s' % (package, activity)
-
- @property
- def action(self):
- return self._action
-
- @property
- def activity(self):
- return self._activity
-
- @property
- def category(self):
- return self._category
-
- @property
- def component(self):
- return self._component
-
- @property
- def data(self):
- return self._data
-
- @property
- def extras(self):
- return self._extras
-
- @property
- def flags(self):
- return self._flags
-
- @property
- def package(self):
- return self._package
-
- @property
- def am_args(self):
- """Returns the intent as a list of arguments for the activity manager.
-
- For details refer to the specification at:
- - http://developer.android.com/tools/help/adb.html#IntentSpec
- """
- args = []
- if self.action:
- args.extend(['-a', self.action])
- if self.data:
- args.extend(['-d', self.data])
- if self.category:
- args.extend(arg for cat in self.category for arg in ('-c', cat))
- if self.component:
- args.extend(['-n', self.component])
- if self.flags:
- args.extend(['-f', self.flags])
- if self.extras:
- for key, value in self.extras.iteritems():
- if value is None:
- args.extend(['--esn', key])
- elif isinstance(value, str):
- args.extend(['--es', key, value])
- elif isinstance(value, bool):
- args.extend(['--ez', key, str(value)])
- elif isinstance(value, int):
- args.extend(['--ei', key, str(value)])
- elif isinstance(value, float):
- args.extend(['--ef', key, str(value)])
- else:
- raise NotImplementedError(
- 'Intent does not know how to pass %s extras' % type(value))
- return args
diff --git a/build/android/pylib/device/logcat_monitor.py b/build/android/pylib/device/logcat_monitor.py
deleted file mode 100644
index 2eebc2d..0000000
--- a/build/android/pylib/device/logcat_monitor.py
+++ /dev/null
@@ -1,139 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# pylint: disable=unused-argument
-
-import collections
-import itertools
-import logging
-import subprocess
-import tempfile
-import time
-import re
-
-from pylib.device import adb_wrapper
-from pylib.device import decorators
-from pylib.device import device_errors
-
-
-class LogcatMonitor(object):
-
- _THREADTIME_RE_FORMAT = (
- r'(?P<date>\S*) +(?P<time>\S*) +(?P<proc_id>%s) +(?P<thread_id>%s) +'
- r'(?P<log_level>%s) +(?P<component>%s) *: +(?P<message>%s)$')
-
- def __init__(self, adb, clear=True, filter_specs=None):
- """Create a LogcatMonitor instance.
-
- Args:
- adb: An instance of adb_wrapper.AdbWrapper.
- clear: If True, clear the logcat when monitoring starts.
- filter_specs: An optional list of '<tag>[:priority]' strings.
- """
- if isinstance(adb, adb_wrapper.AdbWrapper):
- self._adb = adb
- else:
- raise ValueError('Unsupported type passed for argument "device"')
- self._clear = clear
- self._filter_specs = filter_specs
- self._logcat_out = None
- self._logcat_out_file = None
- self._logcat_proc = None
-
- @decorators.WithTimeoutAndRetriesDefaults(10, 0)
- def WaitFor(self, success_regex, failure_regex=None, timeout=None,
- retries=None):
- """Wait for a matching logcat line or until a timeout occurs.
-
- This will attempt to match lines in the logcat against both |success_regex|
- and |failure_regex| (if provided). Note that this calls re.search on each
- logcat line, not re.match, so the provided regular expressions don't have
- to match an entire line.
-
- Args:
- success_regex: The regular expression to search for.
- failure_regex: An optional regular expression that, if hit, causes this
- to stop looking for a match. Can be None.
- timeout: timeout in seconds
- retries: number of retries
-
- Returns:
- A match object if |success_regex| matches a part of a logcat line, or
- None if |failure_regex| matches a part of a logcat line.
- Raises:
- CommandFailedError on logcat failure (NOT on a |failure_regex| match).
- CommandTimeoutError if no logcat line matching either |success_regex| or
- |failure_regex| is found in |timeout| seconds.
- DeviceUnreachableError if the device becomes unreachable.
- """
- if isinstance(success_regex, basestring):
- success_regex = re.compile(success_regex)
- if isinstance(failure_regex, basestring):
- failure_regex = re.compile(failure_regex)
-
- logging.debug('Waiting %d seconds for "%s"', timeout, success_regex.pattern)
-
- # NOTE This will continue looping until:
- # - success_regex matches a line, in which case the match object is
- # returned.
- # - failure_regex matches a line, in which case None is returned
- # - the timeout is hit, in which case a CommandTimeoutError is raised.
- for l in self._adb.Logcat(filter_specs=self._filter_specs):
- m = success_regex.search(l)
- if m:
- return m
- if failure_regex and failure_regex.search(l):
- return None
-
- def FindAll(self, message_regex, proc_id=None, thread_id=None, log_level=None,
- component=None):
- """Finds all lines in the logcat that match the provided constraints.
-
- Args:
- message_regex: The regular expression that the <message> section must
- match.
- proc_id: The process ID to match. If None, matches any process ID.
- thread_id: The thread ID to match. If None, matches any thread ID.
- log_level: The log level to match. If None, matches any log level.
- component: The component to match. If None, matches any component.
-
- Yields:
- A match object for each matching line in the logcat. The match object
- will always contain, in addition to groups defined in |message_regex|,
- the following named groups: 'date', 'time', 'proc_id', 'thread_id',
- 'log_level', 'component', and 'message'.
- """
- if proc_id is None:
- proc_id = r'\d+'
- if thread_id is None:
- thread_id = r'\d+'
- if log_level is None:
- log_level = r'[VDIWEF]'
- if component is None:
- component = r'[^\s:]+'
- threadtime_re = re.compile(
- type(self)._THREADTIME_RE_FORMAT % (
- proc_id, thread_id, log_level, component, message_regex))
-
- for line in self._adb.Logcat(dump=True, logcat_format='threadtime'):
- m = re.match(threadtime_re, line)
- if m:
- yield m
-
- def Start(self):
- """Starts the logcat monitor.
-
- Clears the logcat if |clear| was set in |__init__|.
- """
- if self._clear:
- self._adb.Logcat(clear=True)
-
- def __enter__(self):
- """Starts the logcat monitor."""
- self.Start()
- return self
-
- def __exit__(self, exc_type, exc_val, exc_tb):
- """Stops the logcat monitor."""
- pass
diff --git a/build/android/pylib/device/logcat_monitor_test.py b/build/android/pylib/device/logcat_monitor_test.py
deleted file mode 100755
index db397e57..0000000
--- a/build/android/pylib/device/logcat_monitor_test.py
+++ /dev/null
@@ -1,164 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import itertools
-import os
-import sys
-import unittest
-
-from pylib import constants
-from pylib.device import adb_wrapper
-from pylib.device import decorators
-from pylib.device import logcat_monitor
-
-sys.path.append(os.path.join(
- constants.DIR_SOURCE_ROOT, 'third_party', 'pymock'))
-import mock # pylint: disable=F0401
-
-
-class LogcatMonitorTest(unittest.TestCase):
-
- _TEST_THREADTIME_LOGCAT_DATA = [
- '01-01 01:02:03.456 7890 0987 V LogcatMonitorTest: '
- 'verbose logcat monitor test message 1',
- '01-01 01:02:03.457 8901 1098 D LogcatMonitorTest: '
- 'debug logcat monitor test message 2',
- '01-01 01:02:03.458 9012 2109 I LogcatMonitorTest: '
- 'info logcat monitor test message 3',
- '01-01 01:02:03.459 0123 3210 W LogcatMonitorTest: '
- 'warning logcat monitor test message 4',
- '01-01 01:02:03.460 1234 4321 E LogcatMonitorTest: '
- 'error logcat monitor test message 5',
- '01-01 01:02:03.461 2345 5432 F LogcatMonitorTest: '
- 'fatal logcat monitor test message 6',
- '01-01 01:02:03.462 3456 6543 D LogcatMonitorTest: '
- 'ignore me',]
-
- def _createTestLog(self, raw_logcat=None):
- test_adb = adb_wrapper.AdbWrapper('0123456789abcdef')
- test_adb.Logcat = mock.Mock(return_value=(l for l in raw_logcat))
- test_log = logcat_monitor.LogcatMonitor(test_adb, clear=False)
- return test_log
-
- def assertIterEqual(self, expected_iter, actual_iter):
- for expected, actual in itertools.izip_longest(expected_iter, actual_iter):
- self.assertIsNotNone(
- expected,
- msg='actual has unexpected elements starting with %s' % str(actual))
- self.assertIsNotNone(
- actual,
- msg='actual is missing elements starting with %s' % str(expected))
- self.assertEqual(actual.group('proc_id'), expected[0])
- self.assertEqual(actual.group('thread_id'), expected[1])
- self.assertEqual(actual.group('log_level'), expected[2])
- self.assertEqual(actual.group('component'), expected[3])
- self.assertEqual(actual.group('message'), expected[4])
-
- with self.assertRaises(StopIteration):
- next(actual_iter)
- with self.assertRaises(StopIteration):
- next(expected_iter)
-
- def testWaitFor_success(self):
- test_log = self._createTestLog(
- raw_logcat=type(self)._TEST_THREADTIME_LOGCAT_DATA)
- actual_match = test_log.WaitFor(r'.*(fatal|error) logcat monitor.*', None)
- self.assertTrue(actual_match)
- self.assertEqual(
- '01-01 01:02:03.460 1234 4321 E LogcatMonitorTest: '
- 'error logcat monitor test message 5',
- actual_match.group(0))
- self.assertEqual('error', actual_match.group(1))
-
- def testWaitFor_failure(self):
- test_log = self._createTestLog(
- raw_logcat=type(self)._TEST_THREADTIME_LOGCAT_DATA)
- actual_match = test_log.WaitFor(
- r'.*My Success Regex.*', r'.*(fatal|error) logcat monitor.*')
- self.assertIsNone(actual_match)
-
- def testFindAll_defaults(self):
- test_log = self._createTestLog(
- raw_logcat=type(self)._TEST_THREADTIME_LOGCAT_DATA)
- expected_results = [
- ('7890', '0987', 'V', 'LogcatMonitorTest',
- 'verbose logcat monitor test message 1'),
- ('8901', '1098', 'D', 'LogcatMonitorTest',
- 'debug logcat monitor test message 2'),
- ('9012', '2109', 'I', 'LogcatMonitorTest',
- 'info logcat monitor test message 3'),
- ('0123', '3210', 'W', 'LogcatMonitorTest',
- 'warning logcat monitor test message 4'),
- ('1234', '4321', 'E', 'LogcatMonitorTest',
- 'error logcat monitor test message 5'),
- ('2345', '5432', 'F', 'LogcatMonitorTest',
- 'fatal logcat monitor test message 6')]
- actual_results = test_log.FindAll(r'\S* logcat monitor test message \d')
- self.assertIterEqual(iter(expected_results), actual_results)
-
- def testFindAll_defaults_miss(self):
- test_log = self._createTestLog(
- raw_logcat=type(self)._TEST_THREADTIME_LOGCAT_DATA)
- expected_results = []
- actual_results = test_log.FindAll(r'\S* nothing should match this \d')
- self.assertIterEqual(iter(expected_results), actual_results)
-
- def testFindAll_filterProcId(self):
- test_log = self._createTestLog(
- raw_logcat=type(self)._TEST_THREADTIME_LOGCAT_DATA)
- actual_results = test_log.FindAll(
- r'\S* logcat monitor test message \d', proc_id=1234)
- expected_results = [
- ('1234', '4321', 'E', 'LogcatMonitorTest',
- 'error logcat monitor test message 5')]
- self.assertIterEqual(iter(expected_results), actual_results)
-
- def testFindAll_filterThreadId(self):
- test_log = self._createTestLog(
- raw_logcat=type(self)._TEST_THREADTIME_LOGCAT_DATA)
- actual_results = test_log.FindAll(
- r'\S* logcat monitor test message \d', thread_id=2109)
- expected_results = [
- ('9012', '2109', 'I', 'LogcatMonitorTest',
- 'info logcat monitor test message 3')]
- self.assertIterEqual(iter(expected_results), actual_results)
-
- def testFindAll_filterLogLevel(self):
- test_log = self._createTestLog(
- raw_logcat=type(self)._TEST_THREADTIME_LOGCAT_DATA)
- actual_results = test_log.FindAll(
- r'\S* logcat monitor test message \d', log_level=r'[DW]')
- expected_results = [
- ('8901', '1098', 'D', 'LogcatMonitorTest',
- 'debug logcat monitor test message 2'),
- ('0123', '3210', 'W', 'LogcatMonitorTest',
- 'warning logcat monitor test message 4'),]
- self.assertIterEqual(iter(expected_results), actual_results)
-
- def testFindAll_filterComponent(self):
- test_log = self._createTestLog(
- raw_logcat=type(self)._TEST_THREADTIME_LOGCAT_DATA)
- actual_results = test_log.FindAll(r'.*', component='LogcatMonitorTest')
- expected_results = [
- ('7890', '0987', 'V', 'LogcatMonitorTest',
- 'verbose logcat monitor test message 1'),
- ('8901', '1098', 'D', 'LogcatMonitorTest',
- 'debug logcat monitor test message 2'),
- ('9012', '2109', 'I', 'LogcatMonitorTest',
- 'info logcat monitor test message 3'),
- ('0123', '3210', 'W', 'LogcatMonitorTest',
- 'warning logcat monitor test message 4'),
- ('1234', '4321', 'E', 'LogcatMonitorTest',
- 'error logcat monitor test message 5'),
- ('2345', '5432', 'F', 'LogcatMonitorTest',
- 'fatal logcat monitor test message 6'),
- ('3456', '6543', 'D', 'LogcatMonitorTest',
- 'ignore me'),]
- self.assertIterEqual(iter(expected_results), actual_results)
-
-
-if __name__ == '__main__':
- unittest.main(verbosity=2)
-
diff --git a/build/android/pylib/device/shared_prefs.py b/build/android/pylib/device/shared_prefs.py
deleted file mode 100644
index 32cef4b..0000000
--- a/build/android/pylib/device/shared_prefs.py
+++ /dev/null
@@ -1,391 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Helper object to read and modify Shared Preferences from Android apps.
-
-See e.g.:
- http://developer.android.com/reference/android/content/SharedPreferences.html
-"""
-
-import collections
-import logging
-import posixpath
-
-from xml.etree import ElementTree
-
-
-_XML_DECLARATION = "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
-
-
-class BasePref(object):
- """Base class for getting/setting the value of a specific preference type.
-
- Should not be instantiated directly. The SharedPrefs collection will
- instantiate the appropriate subclasses, which directly manipulate the
- underlying xml document, to parse and serialize values according to their
- type.
-
- Args:
- elem: An xml ElementTree object holding the preference data.
-
- Properties:
- tag_name: A string with the tag that must be used for this preference type.
- """
- tag_name = None
-
- def __init__(self, elem):
- if elem.tag != type(self).tag_name:
- raise TypeError('Property %r has type %r, but trying to access as %r' %
- (elem.get('name'), elem.tag, type(self).tag_name))
- self._elem = elem
-
- def __str__(self):
- """Get the underlying xml element as a string."""
- return ElementTree.tostring(self._elem)
-
- def get(self):
- """Get the value of this preference."""
- return self._elem.get('value')
-
- def set(self, value):
- """Set from a value casted as a string."""
- self._elem.set('value', str(value))
-
- @property
- def has_value(self):
- """Check whether the element has a value."""
- return self._elem.get('value') is not None
-
-
-class BooleanPref(BasePref):
- """Class for getting/setting a preference with a boolean value.
-
- The underlying xml element has the form, e.g.:
- <boolean name="featureEnabled" value="false" />
- """
- tag_name = 'boolean'
- VALUES = {'true': True, 'false': False}
-
- def get(self):
- """Get the value as a Python bool."""
- return type(self).VALUES[super(BooleanPref, self).get()]
-
- def set(self, value):
- """Set from a value casted as a bool."""
- super(BooleanPref, self).set('true' if value else 'false')
-
-
-class FloatPref(BasePref):
- """Class for getting/setting a preference with a float value.
-
- The underlying xml element has the form, e.g.:
- <float name="someMetric" value="4.7" />
- """
- tag_name = 'float'
-
- def get(self):
- """Get the value as a Python float."""
- return float(super(FloatPref, self).get())
-
-
-class IntPref(BasePref):
- """Class for getting/setting a preference with an int value.
-
- The underlying xml element has the form, e.g.:
- <int name="aCounter" value="1234" />
- """
- tag_name = 'int'
-
- def get(self):
- """Get the value as a Python int."""
- return int(super(IntPref, self).get())
-
-
-class LongPref(IntPref):
- """Class for getting/setting a preference with a long value.
-
- The underlying xml element has the form, e.g.:
- <long name="aLongCounter" value="1234" />
-
- We use the same implementation from IntPref.
- """
- tag_name = 'long'
-
-
-class StringPref(BasePref):
- """Class for getting/setting a preference with a string value.
-
- The underlying xml element has the form, e.g.:
- <string name="someHashValue">249b3e5af13d4db2</string>
- """
- tag_name = 'string'
-
- def get(self):
- """Get the value as a Python string."""
- return self._elem.text
-
- def set(self, value):
- """Set from a value casted as a string."""
- self._elem.text = str(value)
-
-
-class StringSetPref(StringPref):
- """Class for getting/setting a preference with a set of string values.
-
- The underlying xml element has the form, e.g.:
- <set name="managed_apps">
- <string>com.mine.app1</string>
- <string>com.mine.app2</string>
- <string>com.mine.app3</string>
- </set>
- """
- tag_name = 'set'
-
- def get(self):
- """Get a list with the string values contained."""
- value = []
- for child in self._elem:
- assert child.tag == 'string'
- value.append(child.text)
- return value
-
- def set(self, value):
- """Set from a sequence of values, each casted as a string."""
- for child in list(self._elem):
- self._elem.remove(child)
- for item in value:
- ElementTree.SubElement(self._elem, 'string').text = str(item)
-
-
-_PREF_TYPES = {c.tag_name: c for c in [BooleanPref, FloatPref, IntPref,
- LongPref, StringPref, StringSetPref]}
-
-
-class SharedPrefs(object):
- def __init__(self, device, package, filename):
- """Helper object to read and update "Shared Prefs" of Android apps.
-
- Such files typically look like, e.g.:
-
- <?xml version='1.0' encoding='utf-8' standalone='yes' ?>
- <map>
- <int name="databaseVersion" value="107" />
- <boolean name="featureEnabled" value="false" />
- <string name="someHashValue">249b3e5af13d4db2</string>
- </map>
-
- Example usage:
-
- prefs = shared_prefs.SharedPrefs(device, 'com.my.app', 'my_prefs.xml')
- prefs.Load()
- prefs.GetString('someHashValue') # => '249b3e5af13d4db2'
- prefs.SetInt('databaseVersion', 42)
- prefs.Remove('featureEnabled')
- prefs.Commit()
-
- The object may also be used as a context manager to automatically load and
- commit, respectively, upon entering and leaving the context.
-
- Args:
- device: A DeviceUtils object.
- package: A string with the package name of the app that owns the shared
- preferences file.
- filename: A string with the name of the preferences file to read/write.
- """
- self._device = device
- self._xml = None
- self._package = package
- self._filename = filename
- self._path = '/data/data/%s/shared_prefs/%s' % (package, filename)
- self._changed = False
-
- def __repr__(self):
- """Get a useful printable representation of the object."""
- return '<{cls} file {filename} for {package} on {device}>'.format(
- cls=type(self).__name__, filename=self.filename, package=self.package,
- device=str(self._device))
-
- def __str__(self):
- """Get the underlying xml document as a string."""
- return _XML_DECLARATION + ElementTree.tostring(self.xml)
-
- @property
- def package(self):
- """Get the package name of the app that owns the shared preferences."""
- return self._package
-
- @property
- def filename(self):
- """Get the filename of the shared preferences file."""
- return self._filename
-
- @property
- def path(self):
- """Get the full path to the shared preferences file on the device."""
- return self._path
-
- @property
- def changed(self):
- """True if properties have changed and a commit would be needed."""
- return self._changed
-
- @property
- def xml(self):
- """Get the underlying xml document as an ElementTree object."""
- if self._xml is None:
- self._xml = ElementTree.Element('map')
- return self._xml
-
- def Load(self):
- """Load the shared preferences file from the device.
-
- A empty xml document, which may be modified and saved on |commit|, is
- created if the file does not already exist.
- """
- if self._device.FileExists(self.path):
- self._xml = ElementTree.fromstring(
- self._device.ReadFile(self.path, as_root=True))
- assert self._xml.tag == 'map'
- else:
- self._xml = None
- self._changed = False
-
- def Clear(self):
- """Clear all of the preferences contained in this object."""
- if self._xml is not None and len(self): # only clear if not already empty
- self._xml = None
- self._changed = True
-
- def Commit(self):
- """Save the current set of preferences to the device.
-
- Only actually saves if some preferences have been modified.
- """
- if not self.changed:
- return
- self._device.RunShellCommand(
- ['mkdir', '-p', posixpath.dirname(self.path)],
- as_root=True, check_return=True)
- self._device.WriteFile(self.path, str(self), as_root=True)
- self._device.KillAll(self.package, as_root=True, quiet=True)
- self._changed = False
-
- def __len__(self):
- """Get the number of preferences in this collection."""
- return len(self.xml)
-
- def PropertyType(self, key):
- """Get the type (i.e. tag name) of a property in the collection."""
- return self._GetChild(key).tag
-
- def HasProperty(self, key):
- try:
- self._GetChild(key)
- return True
- except KeyError:
- return False
-
- def GetBoolean(self, key):
- """Get a boolean property."""
- return BooleanPref(self._GetChild(key)).get()
-
- def SetBoolean(self, key, value):
- """Set a boolean property."""
- self._SetPrefValue(key, value, BooleanPref)
-
- def GetFloat(self, key):
- """Get a float property."""
- return FloatPref(self._GetChild(key)).get()
-
- def SetFloat(self, key, value):
- """Set a float property."""
- self._SetPrefValue(key, value, FloatPref)
-
- def GetInt(self, key):
- """Get an int property."""
- return IntPref(self._GetChild(key)).get()
-
- def SetInt(self, key, value):
- """Set an int property."""
- self._SetPrefValue(key, value, IntPref)
-
- def GetLong(self, key):
- """Get a long property."""
- return LongPref(self._GetChild(key)).get()
-
- def SetLong(self, key, value):
- """Set a long property."""
- self._SetPrefValue(key, value, LongPref)
-
- def GetString(self, key):
- """Get a string property."""
- return StringPref(self._GetChild(key)).get()
-
- def SetString(self, key, value):
- """Set a string property."""
- self._SetPrefValue(key, value, StringPref)
-
- def GetStringSet(self, key):
- """Get a string set property."""
- return StringSetPref(self._GetChild(key)).get()
-
- def SetStringSet(self, key, value):
- """Set a string set property."""
- self._SetPrefValue(key, value, StringSetPref)
-
- def Remove(self, key):
- """Remove a preference from the collection."""
- self.xml.remove(self._GetChild(key))
-
- def AsDict(self):
- """Return the properties and their values as a dictionary."""
- d = {}
- for child in self.xml:
- pref = _PREF_TYPES[child.tag](child)
- d[child.get('name')] = pref.get()
- return d
-
- def __enter__(self):
- """Load preferences file from the device when entering a context."""
- self.Load()
- return self
-
- def __exit__(self, exc_type, _exc_value, _traceback):
- """Save preferences file to the device when leaving a context."""
- if not exc_type:
- self.Commit()
-
- def _GetChild(self, key):
- """Get the underlying xml node that holds the property of a given key.
-
- Raises:
- KeyError when the key is not found in the collection.
- """
- for child in self.xml:
- if child.get('name') == key:
- return child
- raise KeyError(key)
-
- def _SetPrefValue(self, key, value, pref_cls):
- """Set the value of a property.
-
- Args:
- key: The key of the property to set.
- value: The new value of the property.
- pref_cls: A subclass of BasePref used to access the property.
-
- Raises:
- TypeError when the key already exists but with a different type.
- """
- try:
- pref = pref_cls(self._GetChild(key))
- old_value = pref.get()
- except KeyError:
- pref = pref_cls(ElementTree.SubElement(
- self.xml, pref_cls.tag_name, {'name': key}))
- old_value = None
- if old_value != value:
- pref.set(value)
- self._changed = True
- logging.info('Setting property: %s', pref)
diff --git a/build/android/pylib/device/shared_prefs_test.py b/build/android/pylib/device/shared_prefs_test.py
deleted file mode 100755
index c5f0ec3..0000000
--- a/build/android/pylib/device/shared_prefs_test.py
+++ /dev/null
@@ -1,169 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""
-Unit tests for the contents of shared_prefs.py (mostly SharedPrefs).
-"""
-
-import logging
-import os
-import sys
-import unittest
-
-from pylib import constants
-from pylib.device import device_utils
-from pylib.device import shared_prefs
-
-sys.path.append(os.path.join(
- constants.DIR_SOURCE_ROOT, 'third_party', 'pymock'))
-import mock
-
-
-def MockDeviceWithFiles(files=None):
- if files is None:
- files = {}
-
- def file_exists(path):
- return path in files
-
- def write_file(path, contents, **_kwargs):
- files[path] = contents
-
- def read_file(path, **_kwargs):
- return files[path]
-
- device = mock.MagicMock(spec=device_utils.DeviceUtils)
- device.FileExists = mock.Mock(side_effect=file_exists)
- device.WriteFile = mock.Mock(side_effect=write_file)
- device.ReadFile = mock.Mock(side_effect=read_file)
- return device
-
-
-class SharedPrefsTest(unittest.TestCase):
-
- def setUp(self):
- self.device = MockDeviceWithFiles({
- '/data/data/com.some.package/shared_prefs/prefs.xml':
- "<?xml version='1.0' encoding='utf-8' standalone='yes' ?>\n"
- '<map>\n'
- ' <int name="databaseVersion" value="107" />\n'
- ' <boolean name="featureEnabled" value="false" />\n'
- ' <string name="someHashValue">249b3e5af13d4db2</string>\n'
- '</map>'})
- self.expected_data = {'databaseVersion': 107,
- 'featureEnabled': False,
- 'someHashValue': '249b3e5af13d4db2'}
-
- def testPropertyLifetime(self):
- prefs = shared_prefs.SharedPrefs(
- self.device, 'com.some.package', 'prefs.xml')
- self.assertEquals(len(prefs), 0) # collection is empty before loading
- prefs.SetInt('myValue', 444)
- self.assertEquals(len(prefs), 1)
- self.assertEquals(prefs.GetInt('myValue'), 444)
- self.assertTrue(prefs.HasProperty('myValue'))
- prefs.Remove('myValue')
- self.assertEquals(len(prefs), 0)
- self.assertFalse(prefs.HasProperty('myValue'))
- with self.assertRaises(KeyError):
- prefs.GetInt('myValue')
-
- def testPropertyType(self):
- prefs = shared_prefs.SharedPrefs(
- self.device, 'com.some.package', 'prefs.xml')
- prefs.SetInt('myValue', 444)
- self.assertEquals(prefs.PropertyType('myValue'), 'int')
- with self.assertRaises(TypeError):
- prefs.GetString('myValue')
- with self.assertRaises(TypeError):
- prefs.SetString('myValue', 'hello')
-
- def testLoad(self):
- prefs = shared_prefs.SharedPrefs(
- self.device, 'com.some.package', 'prefs.xml')
- self.assertEquals(len(prefs), 0) # collection is empty before loading
- prefs.Load()
- self.assertEquals(len(prefs), len(self.expected_data))
- self.assertEquals(prefs.AsDict(), self.expected_data)
- self.assertFalse(prefs.changed)
-
- def testClear(self):
- prefs = shared_prefs.SharedPrefs(
- self.device, 'com.some.package', 'prefs.xml')
- prefs.Load()
- self.assertEquals(prefs.AsDict(), self.expected_data)
- self.assertFalse(prefs.changed)
- prefs.Clear()
- self.assertEquals(len(prefs), 0) # collection is empty now
- self.assertTrue(prefs.changed)
-
- def testCommit(self):
- prefs = shared_prefs.SharedPrefs(
- self.device, 'com.some.package', 'other_prefs.xml')
- self.assertFalse(self.device.FileExists(prefs.path)) # file does not exist
- prefs.Load()
- self.assertEquals(len(prefs), 0) # file did not exist, collection is empty
- prefs.SetInt('magicNumber', 42)
- prefs.SetFloat('myMetric', 3.14)
- prefs.SetLong('bigNumner', 6000000000)
- prefs.SetStringSet('apps', ['gmail', 'chrome', 'music'])
- self.assertFalse(self.device.FileExists(prefs.path)) # still does not exist
- self.assertTrue(prefs.changed)
- prefs.Commit()
- self.assertTrue(self.device.FileExists(prefs.path)) # should exist now
- self.device.KillAll.assert_called_once_with(prefs.package, as_root=True,
- quiet=True)
- self.assertFalse(prefs.changed)
-
- prefs = shared_prefs.SharedPrefs(
- self.device, 'com.some.package', 'other_prefs.xml')
- self.assertEquals(len(prefs), 0) # collection is empty before loading
- prefs.Load()
- self.assertEquals(prefs.AsDict(), {
- 'magicNumber': 42,
- 'myMetric': 3.14,
- 'bigNumner': 6000000000,
- 'apps': ['gmail', 'chrome', 'music']}) # data survived roundtrip
-
- def testAsContextManager_onlyReads(self):
- with shared_prefs.SharedPrefs(
- self.device, 'com.some.package', 'prefs.xml') as prefs:
- self.assertEquals(prefs.AsDict(), self.expected_data) # loaded and ready
- self.assertEquals(self.device.WriteFile.call_args_list, []) # did not write
-
- def testAsContextManager_readAndWrite(self):
- with shared_prefs.SharedPrefs(
- self.device, 'com.some.package', 'prefs.xml') as prefs:
- prefs.SetBoolean('featureEnabled', True)
- prefs.Remove('someHashValue')
- prefs.SetString('newString', 'hello')
-
- self.assertTrue(self.device.WriteFile.called) # did write
- with shared_prefs.SharedPrefs(
- self.device, 'com.some.package', 'prefs.xml') as prefs:
- # changes persisted
- self.assertTrue(prefs.GetBoolean('featureEnabled'))
- self.assertFalse(prefs.HasProperty('someHashValue'))
- self.assertEquals(prefs.GetString('newString'), 'hello')
- self.assertTrue(prefs.HasProperty('databaseVersion')) # still there
-
- def testAsContextManager_commitAborted(self):
- with self.assertRaises(TypeError):
- with shared_prefs.SharedPrefs(
- self.device, 'com.some.package', 'prefs.xml') as prefs:
- prefs.SetBoolean('featureEnabled', True)
- prefs.Remove('someHashValue')
- prefs.SetString('newString', 'hello')
- prefs.SetInt('newString', 123) # oops!
-
- self.assertEquals(self.device.WriteFile.call_args_list, []) # did not write
- with shared_prefs.SharedPrefs(
- self.device, 'com.some.package', 'prefs.xml') as prefs:
- # contents were not modified
- self.assertEquals(prefs.AsDict(), self.expected_data)
-
-if __name__ == '__main__':
- logging.getLogger().setLevel(logging.DEBUG)
- unittest.main(verbosity=2)
diff --git a/build/android/pylib/device_settings.py b/build/android/pylib/device_settings.py
deleted file mode 100644
index beabcff..0000000
--- a/build/android/pylib/device_settings.py
+++ /dev/null
@@ -1,198 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-
-from pylib import constants
-from pylib import content_settings
-from pylib.device import device_errors
-
-_LOCK_SCREEN_SETTINGS_PATH = '/data/system/locksettings.db'
-_ALTERNATE_LOCK_SCREEN_SETTINGS_PATH = (
- '/data/data/com.android.providers.settings/databases/settings.db')
-PASSWORD_QUALITY_UNSPECIFIED = '0'
-
-
-def ConfigureContentSettings(device, desired_settings):
- """Configures device content setings from a list.
-
- Many settings are documented at:
- http://developer.android.com/reference/android/provider/Settings.Global.html
- http://developer.android.com/reference/android/provider/Settings.Secure.html
- http://developer.android.com/reference/android/provider/Settings.System.html
-
- Many others are undocumented.
-
- Args:
- device: A DeviceUtils instance for the device to configure.
- desired_settings: A list of (table, [(key: value), ...]) for all
- settings to configure.
- """
- if device.build_type == 'userdebug':
- for table, key_value in desired_settings:
- settings = content_settings.ContentSettings(table, device)
- for key, value in key_value:
- settings[key] = value
- logging.info('\n%s %s', table, (80 - len(table)) * '-')
- for key, value in sorted(settings.iteritems()):
- logging.info('\t%s: %s', key, value)
-
-
-def SetLockScreenSettings(device):
- """Sets lock screen settings on the device.
-
- On certain device/Android configurations we need to disable the lock screen in
- a different database. Additionally, the password type must be set to
- DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED.
- Lock screen settings are stored in sqlite on the device in:
- /data/system/locksettings.db
-
- IMPORTANT: The first column is used as a primary key so that all rows with the
- same value for that column are removed from the table prior to inserting the
- new values.
-
- Args:
- device: A DeviceUtils instance for the device to configure.
-
- Raises:
- Exception if the setting was not properly set.
- """
- if device.build_type != 'userdebug':
- logging.warning('Unable to disable lockscreen on user builds.')
- return
-
- def get_lock_settings(table):
- return [(table, 'lockscreen.disabled', '1'),
- (table, 'lockscreen.password_type', PASSWORD_QUALITY_UNSPECIFIED),
- (table, 'lockscreen.password_type_alternate',
- PASSWORD_QUALITY_UNSPECIFIED)]
-
- if device.FileExists(_LOCK_SCREEN_SETTINGS_PATH):
- db = _LOCK_SCREEN_SETTINGS_PATH
- locksettings = get_lock_settings('locksettings')
- columns = ['name', 'user', 'value']
- generate_values = lambda k, v: [k, '0', v]
- elif device.FileExists(_ALTERNATE_LOCK_SCREEN_SETTINGS_PATH):
- db = _ALTERNATE_LOCK_SCREEN_SETTINGS_PATH
- locksettings = get_lock_settings('secure') + get_lock_settings('system')
- columns = ['name', 'value']
- generate_values = lambda k, v: [k, v]
- else:
- logging.warning('Unable to find database file to set lock screen settings.')
- return
-
- for table, key, value in locksettings:
- # Set the lockscreen setting for default user '0'
- values = generate_values(key, value)
-
- cmd = """begin transaction;
-delete from '%(table)s' where %(primary_key)s='%(primary_value)s';
-insert into '%(table)s' (%(columns)s) values (%(values)s);
-commit transaction;""" % {
- 'table': table,
- 'primary_key': columns[0],
- 'primary_value': values[0],
- 'columns': ', '.join(columns),
- 'values': ', '.join(["'%s'" % value for value in values])
- }
- output_msg = device.RunShellCommand('sqlite3 %s "%s"' % (db, cmd),
- as_root=True)
- if output_msg:
- logging.info(' '.join(output_msg))
-
-
-ENABLE_LOCATION_SETTINGS = [
- # Note that setting these in this order is required in order for all of
- # them to take and stick through a reboot.
- ('com.google.settings/partner', [
- ('use_location_for_services', 1),
- ]),
- ('settings/secure', [
- # Ensure Geolocation is enabled and allowed for tests.
- ('location_providers_allowed', 'gps,network'),
- ]),
- ('com.google.settings/partner', [
- ('network_location_opt_in', 1),
- ])
-]
-
-DISABLE_LOCATION_SETTINGS = [
- ('com.google.settings/partner', [
- ('use_location_for_services', 0),
- ]),
- ('settings/secure', [
- # Ensure Geolocation is disabled.
- ('location_providers_allowed', ''),
- ]),
-]
-
-ENABLE_MOCK_LOCATION_SETTINGS = [
- ('settings/secure', [
- ('mock_location', 1),
- ]),
-]
-
-DISABLE_MOCK_LOCATION_SETTINGS = [
- ('settings/secure', [
- ('mock_location', 0),
- ]),
-]
-
-DETERMINISTIC_DEVICE_SETTINGS = [
- ('settings/global', [
- ('assisted_gps_enabled', 0),
-
- # Disable "auto time" and "auto time zone" to avoid network-provided time
- # to overwrite the device's datetime and timezone synchronized from host
- # when running tests later. See b/6569849.
- ('auto_time', 0),
- ('auto_time_zone', 0),
-
- ('development_settings_enabled', 1),
-
- # Flag for allowing ActivityManagerService to send ACTION_APP_ERROR intents
- # on application crashes and ANRs. If this is disabled, the crash/ANR dialog
- # will never display the "Report" button.
- # Type: int ( 0 = disallow, 1 = allow )
- ('send_action_app_error', 0),
-
- ('stay_on_while_plugged_in', 3),
-
- ('verifier_verify_adb_installs', 0),
- ]),
- ('settings/secure', [
- ('allowed_geolocation_origins',
- 'http://www.google.co.uk http://www.google.com'),
-
- # Ensure that we never get random dialogs like "Unfortunately the process
- # android.process.acore has stopped", which steal the focus, and make our
- # automation fail (because the dialog steals the focus then mistakenly
- # receives the injected user input events).
- ('anr_show_background', 0),
-
- ('lockscreen.disabled', 1),
-
- ('screensaver_enabled', 0),
- ]),
- ('settings/system', [
- # Don't want devices to accidentally rotate the screen as that could
- # affect performance measurements.
- ('accelerometer_rotation', 0),
-
- ('lockscreen.disabled', 1),
-
- # Turn down brightness and disable auto-adjust so that devices run cooler.
- ('screen_brightness', 5),
- ('screen_brightness_mode', 0),
-
- ('user_rotation', 0),
- ]),
-]
-
-NETWORK_DISABLED_SETTINGS = [
- ('settings/global', [
- ('airplane_mode_on', 1),
- ('wifi_on', 0),
- ]),
-]
diff --git a/build/android/pylib/device_signal.py b/build/android/pylib/device_signal.py
deleted file mode 100644
index 6a5b709..0000000
--- a/build/android/pylib/device_signal.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Defines constants for signals that should be supported on devices.
-
-Note: Obtained by running `kill -l` on a user device.
-"""
-
-
-SIGHUP = 1 # Hangup
-SIGINT = 2 # Interrupt
-SIGQUIT = 3 # Quit
-SIGILL = 4 # Illegal instruction
-SIGTRAP = 5 # Trap
-SIGABRT = 6 # Aborted
-SIGBUS = 7 # Bus error
-SIGFPE = 8 # Floating point exception
-SIGKILL = 9 # Killed
-SIGUSR1 = 10 # User signal 1
-SIGSEGV = 11 # Segmentation fault
-SIGUSR2 = 12 # User signal 2
-SIGPIPE = 13 # Broken pipe
-SIGALRM = 14 # Alarm clock
-SIGTERM = 15 # Terminated
-SIGSTKFLT = 16 # Stack fault
-SIGCHLD = 17 # Child exited
-SIGCONT = 18 # Continue
-SIGSTOP = 19 # Stopped (signal)
-SIGTSTP = 20 # Stopped
-SIGTTIN = 21 # Stopped (tty input)
-SIGTTOU = 22 # Stopped (tty output)
-SIGURG = 23 # Urgent I/O condition
-SIGXCPU = 24 # CPU time limit exceeded
-SIGXFSZ = 25 # File size limit exceeded
-SIGVTALRM = 26 # Virtual timer expired
-SIGPROF = 27 # Profiling timer expired
-SIGWINCH = 28 # Window size changed
-SIGIO = 29 # I/O possible
-SIGPWR = 30 # Power failure
-SIGSYS = 31 # Bad system call
diff --git a/build/android/pylib/efficient_android_directory_copy.sh b/build/android/pylib/efficient_android_directory_copy.sh
deleted file mode 100755
index 7021109..0000000
--- a/build/android/pylib/efficient_android_directory_copy.sh
+++ /dev/null
@@ -1,78 +0,0 @@
-#!/system/bin/sh
-
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# Android shell script to make the destination directory identical with the
-# source directory, without doing unnecessary copies. This assumes that the
-# the destination directory was originally a copy of the source directory, and
-# has since been modified.
-
-source=$1
-dest=$2
-echo copying $source to $dest
-
-delete_extra() {
- # Don't delete symbolic links, since doing so deletes the vital lib link.
- if [ ! -L "$1" ]
- then
- if [ ! -e "$source/$1" ]
- then
- echo rm -rf "$dest/$1"
- rm -rf "$dest/$1"
- elif [ -d "$1" ]
- then
- for f in "$1"/*
- do
- delete_extra "$f"
- done
- fi
- fi
-}
-
-copy_if_older() {
- if [ -d "$1" ] && [ -e "$dest/$1" ]
- then
- if [ ! -e "$dest/$1" ]
- then
- echo cp -a "$1" "$dest/$1"
- cp -a "$1" "$dest/$1"
- else
- for f in "$1"/*
- do
- copy_if_older "$f"
- done
- fi
- elif [ ! -e "$dest/$1" ] || [ "$1" -ot "$dest/$1" ] || [ "$1" -nt "$dest/$1" ]
- then
- # dates are different, so either the destination of the source has changed.
- echo cp -a "$1" "$dest/$1"
- cp -a "$1" "$dest/$1"
- fi
-}
-
-if [ -e "$dest" ]
-then
- echo cd "$dest"
- cd "$dest"
- for f in ./*
- do
- if [ -e "$f" ]
- then
- delete_extra "$f"
- fi
- done
-else
- echo mkdir "$dest"
- mkdir "$dest"
-fi
-echo cd "$source"
-cd "$source"
-for f in ./*
-do
- if [ -e "$f" ]
- then
- copy_if_older "$f"
- fi
-done
diff --git a/build/android/pylib/flag_changer.py b/build/android/pylib/flag_changer.py
deleted file mode 100644
index 718bc39..0000000
--- a/build/android/pylib/flag_changer.py
+++ /dev/null
@@ -1,166 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-
-import pylib.android_commands
-import pylib.device.device_utils
-
-from pylib.device import device_errors
-
-
-class FlagChanger(object):
- """Changes the flags Chrome runs with.
-
- There are two different use cases for this file:
- * Flags are permanently set by calling Set().
- * Flags can be temporarily set for a particular set of unit tests. These
- tests should call Restore() to revert the flags to their original state
- once the tests have completed.
- """
-
- def __init__(self, device, cmdline_file):
- """Initializes the FlagChanger and records the original arguments.
-
- Args:
- device: A DeviceUtils instance.
- cmdline_file: Path to the command line file on the device.
- """
- # TODO(jbudorick) Remove once telemetry switches over.
- if isinstance(device, pylib.android_commands.AndroidCommands):
- device = pylib.device.device_utils.DeviceUtils(device)
- self._device = device
- self._cmdline_file = cmdline_file
-
- # Save the original flags.
- try:
- self._orig_line = self._device.ReadFile(self._cmdline_file).strip()
- except device_errors.CommandFailedError:
- self._orig_line = ''
-
- # Parse out the flags into a list to facilitate adding and removing flags.
- self._current_flags = self._TokenizeFlags(self._orig_line)
-
- def Get(self):
- """Returns list of current flags."""
- return self._current_flags
-
- def Set(self, flags):
- """Replaces all flags on the current command line with the flags given.
-
- Args:
- flags: A list of flags to set, eg. ['--single-process'].
- """
- if flags:
- assert flags[0] != 'chrome'
-
- self._current_flags = flags
- self._UpdateCommandLineFile()
-
- def AddFlags(self, flags):
- """Appends flags to the command line if they aren't already there.
-
- Args:
- flags: A list of flags to add on, eg. ['--single-process'].
- """
- if flags:
- assert flags[0] != 'chrome'
-
- # Avoid appending flags that are already present.
- for flag in flags:
- if flag not in self._current_flags:
- self._current_flags.append(flag)
- self._UpdateCommandLineFile()
-
- def RemoveFlags(self, flags):
- """Removes flags from the command line, if they exist.
-
- Args:
- flags: A list of flags to remove, eg. ['--single-process']. Note that we
- expect a complete match when removing flags; if you want to remove
- a switch with a value, you must use the exact string used to add
- it in the first place.
- """
- if flags:
- assert flags[0] != 'chrome'
-
- for flag in flags:
- if flag in self._current_flags:
- self._current_flags.remove(flag)
- self._UpdateCommandLineFile()
-
- def Restore(self):
- """Restores the flags to their original state."""
- self._current_flags = self._TokenizeFlags(self._orig_line)
- self._UpdateCommandLineFile()
-
- def _UpdateCommandLineFile(self):
- """Writes out the command line to the file, or removes it if empty."""
- logging.info('Current flags: %s', self._current_flags)
- # Root is not required to write to /data/local/tmp/.
- use_root = '/data/local/tmp/' not in self._cmdline_file
- if self._current_flags:
- # The first command line argument doesn't matter as we are not actually
- # launching the chrome executable using this command line.
- cmd_line = ' '.join(['_'] + self._current_flags)
- self._device.WriteFile(
- self._cmdline_file, cmd_line, as_root=use_root)
- file_contents = self._device.ReadFile(
- self._cmdline_file, as_root=use_root).rstrip()
- assert file_contents == cmd_line, (
- 'Failed to set the command line file at %s' % self._cmdline_file)
- else:
- self._device.RunShellCommand('rm ' + self._cmdline_file,
- as_root=use_root)
- assert not self._device.FileExists(self._cmdline_file), (
- 'Failed to remove the command line file at %s' % self._cmdline_file)
-
- @staticmethod
- def _TokenizeFlags(line):
- """Changes the string containing the command line into a list of flags.
-
- Follows similar logic to CommandLine.java::tokenizeQuotedArguments:
- * Flags are split using whitespace, unless the whitespace is within a
- pair of quotation marks.
- * Unlike the Java version, we keep the quotation marks around switch
- values since we need them to re-create the file when new flags are
- appended.
-
- Args:
- line: A string containing the entire command line. The first token is
- assumed to be the program name.
- """
- if not line:
- return []
-
- tokenized_flags = []
- current_flag = ""
- within_quotations = False
-
- # Move through the string character by character and build up each flag
- # along the way.
- for c in line.strip():
- if c is '"':
- if len(current_flag) > 0 and current_flag[-1] == '\\':
- # Last char was a backslash; pop it, and treat this " as a literal.
- current_flag = current_flag[0:-1] + '"'
- else:
- within_quotations = not within_quotations
- current_flag += c
- elif not within_quotations and (c is ' ' or c is '\t'):
- if current_flag is not "":
- tokenized_flags.append(current_flag)
- current_flag = ""
- else:
- current_flag += c
-
- # Tack on the last flag.
- if not current_flag:
- if within_quotations:
- logging.warn('Unterminated quoted argument: ' + line)
- else:
- tokenized_flags.append(current_flag)
-
- # Return everything but the program name.
- return tokenized_flags[1:]
diff --git a/build/android/pylib/forwarder.py b/build/android/pylib/forwarder.py
deleted file mode 100644
index c8c47d6..0000000
--- a/build/android/pylib/forwarder.py
+++ /dev/null
@@ -1,331 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# pylint: disable=W0212
-
-import fcntl
-import logging
-import os
-import psutil
-
-from pylib import cmd_helper
-from pylib import constants
-from pylib import valgrind_tools
-
-# TODO(jbudorick) Remove once telemetry gets switched over.
-import pylib.android_commands
-import pylib.device.device_utils
-
-
-def _GetProcessStartTime(pid):
- return psutil.Process(pid).create_time
-
-
-class _FileLock(object):
- """With statement-aware implementation of a file lock.
-
- File locks are needed for cross-process synchronization when the
- multiprocessing Python module is used.
- """
- def __init__(self, path):
- self._fd = -1
- self._path = path
-
- def __enter__(self):
- self._fd = os.open(self._path, os.O_RDONLY | os.O_CREAT)
- if self._fd < 0:
- raise Exception('Could not open file %s for reading' % self._path)
- fcntl.flock(self._fd, fcntl.LOCK_EX)
-
- def __exit__(self, _exception_type, _exception_value, traceback):
- fcntl.flock(self._fd, fcntl.LOCK_UN)
- os.close(self._fd)
-
-
-class Forwarder(object):
- """Thread-safe class to manage port forwards from the device to the host."""
-
- _DEVICE_FORWARDER_FOLDER = (constants.TEST_EXECUTABLE_DIR +
- '/forwarder/')
- _DEVICE_FORWARDER_PATH = (constants.TEST_EXECUTABLE_DIR +
- '/forwarder/device_forwarder')
- _LOCK_PATH = '/tmp/chrome.forwarder.lock'
- # Defined in host_forwarder_main.cc
- _HOST_FORWARDER_LOG = '/tmp/host_forwarder_log'
-
- _instance = None
-
- @staticmethod
- def Map(port_pairs, device, tool=None):
- """Runs the forwarder.
-
- Args:
- port_pairs: A list of tuples (device_port, host_port) to forward. Note
- that you can specify 0 as a device_port, in which case a
- port will by dynamically assigned on the device. You can
- get the number of the assigned port using the
- DevicePortForHostPort method.
- device: A DeviceUtils instance.
- tool: Tool class to use to get wrapper, if necessary, for executing the
- forwarder (see valgrind_tools.py).
-
- Raises:
- Exception on failure to forward the port.
- """
- # TODO(jbudorick) Remove once telemetry gets switched over.
- if isinstance(device, pylib.android_commands.AndroidCommands):
- device = pylib.device.device_utils.DeviceUtils(device)
- if not tool:
- tool = valgrind_tools.CreateTool(None, device)
- with _FileLock(Forwarder._LOCK_PATH):
- instance = Forwarder._GetInstanceLocked(tool)
- instance._InitDeviceLocked(device, tool)
-
- device_serial = str(device)
- redirection_commands = [
- ['--adb=' + constants.GetAdbPath(),
- '--serial-id=' + device_serial,
- '--map', str(device_port), str(host_port)]
- for device_port, host_port in port_pairs]
- logging.info('Forwarding using commands: %s', redirection_commands)
-
- for redirection_command in redirection_commands:
- try:
- (exit_code, output) = cmd_helper.GetCmdStatusAndOutput(
- [instance._host_forwarder_path] + redirection_command)
- except OSError as e:
- if e.errno == 2:
- raise Exception('Unable to start host forwarder. Make sure you have'
- ' built host_forwarder.')
- else: raise
- if exit_code != 0:
- Forwarder._KillDeviceLocked(device, tool)
- raise Exception('%s exited with %d:\n%s' % (
- instance._host_forwarder_path, exit_code, '\n'.join(output)))
- tokens = output.split(':')
- if len(tokens) != 2:
- raise Exception('Unexpected host forwarder output "%s", '
- 'expected "device_port:host_port"' % output)
- device_port = int(tokens[0])
- host_port = int(tokens[1])
- serial_with_port = (device_serial, device_port)
- instance._device_to_host_port_map[serial_with_port] = host_port
- instance._host_to_device_port_map[host_port] = serial_with_port
- logging.info('Forwarding device port: %d to host port: %d.',
- device_port, host_port)
-
- @staticmethod
- def UnmapDevicePort(device_port, device):
- """Unmaps a previously forwarded device port.
-
- Args:
- device: A DeviceUtils instance.
- device_port: A previously forwarded port (through Map()).
- """
- # TODO(jbudorick) Remove once telemetry gets switched over.
- if isinstance(device, pylib.android_commands.AndroidCommands):
- device = pylib.device.device_utils.DeviceUtils(device)
- with _FileLock(Forwarder._LOCK_PATH):
- Forwarder._UnmapDevicePortLocked(device_port, device)
-
- @staticmethod
- def UnmapAllDevicePorts(device):
- """Unmaps all the previously forwarded ports for the provided device.
-
- Args:
- device: A DeviceUtils instance.
- port_pairs: A list of tuples (device_port, host_port) to unmap.
- """
- # TODO(jbudorick) Remove once telemetry gets switched over.
- if isinstance(device, pylib.android_commands.AndroidCommands):
- device = pylib.device.device_utils.DeviceUtils(device)
- with _FileLock(Forwarder._LOCK_PATH):
- if not Forwarder._instance:
- return
- adb_serial = str(device)
- if adb_serial not in Forwarder._instance._initialized_devices:
- return
- port_map = Forwarder._GetInstanceLocked(
- None)._device_to_host_port_map
- for (device_serial, device_port) in port_map.keys():
- if adb_serial == device_serial:
- Forwarder._UnmapDevicePortLocked(device_port, device)
- # There are no more ports mapped, kill the device_forwarder.
- tool = valgrind_tools.CreateTool(None, device)
- Forwarder._KillDeviceLocked(device, tool)
-
- @staticmethod
- def DevicePortForHostPort(host_port):
- """Returns the device port that corresponds to a given host port."""
- with _FileLock(Forwarder._LOCK_PATH):
- (_device_serial, device_port) = Forwarder._GetInstanceLocked(
- None)._host_to_device_port_map.get(host_port)
- return device_port
-
- @staticmethod
- def RemoveHostLog():
- if os.path.exists(Forwarder._HOST_FORWARDER_LOG):
- os.unlink(Forwarder._HOST_FORWARDER_LOG)
-
- @staticmethod
- def GetHostLog():
- if not os.path.exists(Forwarder._HOST_FORWARDER_LOG):
- return ''
- with file(Forwarder._HOST_FORWARDER_LOG, 'r') as f:
- return f.read()
-
- @staticmethod
- def _GetInstanceLocked(tool):
- """Returns the singleton instance.
-
- Note that the global lock must be acquired before calling this method.
-
- Args:
- tool: Tool class to use to get wrapper, if necessary, for executing the
- forwarder (see valgrind_tools.py).
- """
- if not Forwarder._instance:
- Forwarder._instance = Forwarder(tool)
- return Forwarder._instance
-
- def __init__(self, tool):
- """Constructs a new instance of Forwarder.
-
- Note that Forwarder is a singleton therefore this constructor should be
- called only once.
-
- Args:
- tool: Tool class to use to get wrapper, if necessary, for executing the
- forwarder (see valgrind_tools.py).
- """
- assert not Forwarder._instance
- self._tool = tool
- self._initialized_devices = set()
- self._device_to_host_port_map = dict()
- self._host_to_device_port_map = dict()
- self._host_forwarder_path = os.path.join(
- constants.GetOutDirectory(), 'host_forwarder')
- assert os.path.exists(self._host_forwarder_path), 'Please build forwarder2'
- self._device_forwarder_path_on_host = os.path.join(
- constants.GetOutDirectory(), 'forwarder_dist')
- self._InitHostLocked()
-
- @staticmethod
- def _UnmapDevicePortLocked(device_port, device):
- """Internal method used by UnmapDevicePort().
-
- Note that the global lock must be acquired before calling this method.
- """
- instance = Forwarder._GetInstanceLocked(None)
- serial = str(device)
- serial_with_port = (serial, device_port)
- if not serial_with_port in instance._device_to_host_port_map:
- logging.error('Trying to unmap non-forwarded port %d' % device_port)
- return
- redirection_command = ['--adb=' + constants.GetAdbPath(),
- '--serial-id=' + serial,
- '--unmap', str(device_port)]
- (exit_code, output) = cmd_helper.GetCmdStatusAndOutput(
- [instance._host_forwarder_path] + redirection_command)
- if exit_code != 0:
- logging.error('%s exited with %d:\n%s' % (
- instance._host_forwarder_path, exit_code, '\n'.join(output)))
- host_port = instance._device_to_host_port_map[serial_with_port]
- del instance._device_to_host_port_map[serial_with_port]
- del instance._host_to_device_port_map[host_port]
-
- @staticmethod
- def _GetPidForLock():
- """Returns the PID used for host_forwarder initialization.
-
- The PID of the "sharder" is used to handle multiprocessing. The "sharder"
- is the initial process that forks that is the parent process.
- """
- return os.getpgrp()
-
- def _InitHostLocked(self):
- """Initializes the host forwarder daemon.
-
- Note that the global lock must be acquired before calling this method. This
- method kills any existing host_forwarder process that could be stale.
- """
- # See if the host_forwarder daemon was already initialized by a concurrent
- # process or thread (in case multi-process sharding is not used).
- pid_for_lock = Forwarder._GetPidForLock()
- fd = os.open(Forwarder._LOCK_PATH, os.O_RDWR | os.O_CREAT)
- with os.fdopen(fd, 'r+') as pid_file:
- pid_with_start_time = pid_file.readline()
- if pid_with_start_time:
- (pid, process_start_time) = pid_with_start_time.split(':')
- if pid == str(pid_for_lock):
- if process_start_time == str(_GetProcessStartTime(pid_for_lock)):
- return
- self._KillHostLocked()
- pid_file.seek(0)
- pid_file.write(
- '%s:%s' % (pid_for_lock, str(_GetProcessStartTime(pid_for_lock))))
- pid_file.truncate()
-
- def _InitDeviceLocked(self, device, tool):
- """Initializes the device_forwarder daemon for a specific device (once).
-
- Note that the global lock must be acquired before calling this method. This
- method kills any existing device_forwarder daemon on the device that could
- be stale, pushes the latest version of the daemon (to the device) and starts
- it.
-
- Args:
- device: A DeviceUtils instance.
- tool: Tool class to use to get wrapper, if necessary, for executing the
- forwarder (see valgrind_tools.py).
- """
- device_serial = str(device)
- if device_serial in self._initialized_devices:
- return
- Forwarder._KillDeviceLocked(device, tool)
- device.PushChangedFiles([(
- self._device_forwarder_path_on_host,
- Forwarder._DEVICE_FORWARDER_FOLDER)])
- cmd = '%s %s' % (tool.GetUtilWrapper(), Forwarder._DEVICE_FORWARDER_PATH)
- device.RunShellCommand(
- cmd, env={'LD_LIBRARY_PATH': Forwarder._DEVICE_FORWARDER_FOLDER},
- check_return=True)
- self._initialized_devices.add(device_serial)
-
- def _KillHostLocked(self):
- """Kills the forwarder process running on the host.
-
- Note that the global lock must be acquired before calling this method.
- """
- logging.info('Killing host_forwarder.')
- (exit_code, output) = cmd_helper.GetCmdStatusAndOutput(
- [self._host_forwarder_path, '--kill-server'])
- if exit_code != 0:
- (exit_code, output) = cmd_helper.GetCmdStatusAndOutput(
- ['pkill', '-9', 'host_forwarder'])
- if exit_code != 0:
- raise Exception('%s exited with %d:\n%s' % (
- self._host_forwarder_path, exit_code, '\n'.join(output)))
-
- @staticmethod
- def _KillDeviceLocked(device, tool):
- """Kills the forwarder process running on the device.
-
- Note that the global lock must be acquired before calling this method.
-
- Args:
- device: Instance of DeviceUtils for talking to the device.
- tool: Wrapper tool (e.g. valgrind) that can be used to execute the device
- forwarder (see valgrind_tools.py).
- """
- logging.info('Killing device_forwarder.')
- Forwarder._instance._initialized_devices.discard(str(device))
- if not device.FileExists(Forwarder._DEVICE_FORWARDER_PATH):
- return
-
- cmd = '%s %s --kill-server' % (tool.GetUtilWrapper(),
- Forwarder._DEVICE_FORWARDER_PATH)
- device.RunShellCommand(
- cmd, env={'LD_LIBRARY_PATH': Forwarder._DEVICE_FORWARDER_FOLDER},
- check_return=True)
diff --git a/build/android/pylib/gtest/__init__.py b/build/android/pylib/gtest/__init__.py
deleted file mode 100644
index 727e987..0000000
--- a/build/android/pylib/gtest/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
diff --git a/build/android/pylib/gtest/filter/OWNERS b/build/android/pylib/gtest/filter/OWNERS
deleted file mode 100644
index 72e8ffc..0000000
--- a/build/android/pylib/gtest/filter/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-*
diff --git a/build/android/pylib/gtest/filter/base_unittests_disabled b/build/android/pylib/gtest/filter/base_unittests_disabled
deleted file mode 100644
index bf2311d..0000000
--- a/build/android/pylib/gtest/filter/base_unittests_disabled
+++ /dev/null
@@ -1,28 +0,0 @@
-# List of suppressions
-
-# Android will not support StackTrace.
-StackTrace.*
-#
-# Sometimes this is automatically generated by run_tests.py
-VerifyPathControlledByUserTest.Symlinks
-
-# http://crbug.com/138845
-MessagePumpLibeventTest.TestWatchingFromBadThread
-
-StringPrintfTest.StringPrintfMisc
-StringPrintfTest.StringAppendfString
-StringPrintfTest.StringAppendfInt
-StringPrintfTest.StringPrintfBounds
-ProcessUtilTest.GetAppOutputRestrictedSIGPIPE
-# TODO(jrg): Fails on bots. Works locally. Figure out why. 2/6/12
-FieldTrialTest.*
-# Flaky?
-ScopedJavaRefTest.RefCounts
-# Death tests are not supported with apks.
-*DeathTest*
-FileTest.MemoryCorruption
-MessagePumpLibeventTest.QuitOutsideOfRun
-ScopedFD.ScopedFDCrashesOnCloseFailure
-
-# http://crbug.com/245043
-StackContainer.BufferAlignment
diff --git a/build/android/pylib/gtest/filter/base_unittests_emulator_additional_disabled b/build/android/pylib/gtest/filter/base_unittests_emulator_additional_disabled
deleted file mode 100644
index 85e8fd6..0000000
--- a/build/android/pylib/gtest/filter/base_unittests_emulator_additional_disabled
+++ /dev/null
@@ -1,10 +0,0 @@
-# Addtional list of suppressions from emulator
-#
-# Automatically generated by run_tests.py
-PathServiceTest.Get
-SharedMemoryTest.OpenClose
-StringPrintfTest.StringAppendfInt
-StringPrintfTest.StringAppendfString
-StringPrintfTest.StringPrintfBounds
-StringPrintfTest.StringPrintfMisc
-VerifyPathControlledByUserTest.Symlinks
diff --git a/build/android/pylib/gtest/filter/blink_heap_unittests_disabled b/build/android/pylib/gtest/filter/blink_heap_unittests_disabled
deleted file mode 100644
index 7a43fb1..0000000
--- a/build/android/pylib/gtest/filter/blink_heap_unittests_disabled
+++ /dev/null
@@ -1,2 +0,0 @@
-# List of suppressions
-
diff --git a/build/android/pylib/gtest/filter/breakpad_unittests_disabled b/build/android/pylib/gtest/filter/breakpad_unittests_disabled
deleted file mode 100644
index cefc64f..0000000
--- a/build/android/pylib/gtest/filter/breakpad_unittests_disabled
+++ /dev/null
@@ -1,9 +0,0 @@
-FileIDStripTest.StripSelf
-# crbug.com/303960
-ExceptionHandlerTest.InstructionPointerMemoryNullPointer
-# crbug.com/171419
-MinidumpWriterTest.MappingInfoContained
-# crbug.com/310088
-MinidumpWriterTest.MinidumpSizeLimit
-# crbug.com/375838
-ElfCoreDumpTest.ValidCoreFile
diff --git a/build/android/pylib/gtest/filter/cc_unittests_disabled b/build/android/pylib/gtest/filter/cc_unittests_disabled
deleted file mode 100644
index b49d2c6..0000000
--- a/build/android/pylib/gtest/filter/cc_unittests_disabled
+++ /dev/null
@@ -1,5 +0,0 @@
-# Death tests are not supported with apks.
-BeginFrameObserverBaseTest.OnBeginFrameImplementation
-BeginFrameSourceBaseTest.ObserverManipulation
-BeginFrameSourceMultiplexerTest.SourcesManipulation
-BeginFrameSourceMultiplexerTest.MinimumIntervalNegativeFails
diff --git a/build/android/pylib/gtest/filter/content_browsertests_disabled b/build/android/pylib/gtest/filter/content_browsertests_disabled
deleted file mode 100644
index dcad240..0000000
--- a/build/android/pylib/gtest/filter/content_browsertests_disabled
+++ /dev/null
@@ -1,62 +0,0 @@
-# List of suppressions
-# Timeouts
-Http/MediaTest.*
-File/MediaTest.*
-MediaTest.*
-DatabaseTest.*
-
-# Crashes
-RenderFrameHostManagerTest.IgnoreRendererDebugURLsWhenCrashed
-
-# Plugins are not supported.
-BrowserPluginThreadedCompositorPixelTest.*
-BrowserPluginHostTest.*
-BrowserPluginTest.*
-PluginTest.*
-
-# http://crbug.com/463740
-CrossPlatformAccessibilityBrowserTest.SelectedEditableTextAccessibility
-
-# http://crbug.com/297230
-DumpAccessibilityTreeTest.AccessibilityAriaLevel
-DumpAccessibilityTreeTest.AccessibilityAriaProgressbar
-DumpAccessibilityTreeTest.AccessibilityListMarkers
-DumpAccessibilityTreeTest.AccessibilityUl
-DumpAccessibilityTreeTest.AccessibilityCanvas
-RendererAccessibilityTest.DetachAccessibilityObject
-DumpAccessibilityTreeTest.AccessibilityDialog
-DumpAccessibilityTreeTest.AccessibilityModalDialogClosed
-DumpAccessibilityTreeTest.AccessibilityModalDialogInIframeOpened
-RendererAccessibilityTest.EventOnObjectNotInTree
-
-# http://crbug.com/187500
-RenderViewImplTest.*
-RendererAccessibilityTest.SendFullAccessibilityTreeOnReload
-RendererAccessibilityTest.HideAccessibilityObject
-RendererAccessibilityTest.ShowAccessibilityObject
-
-# http://crbug.com/215894
-DownloadContentTest.CancelInterruptedDownload
-DownloadContentTest.CancelResumingDownload
-DownloadContentTest.RemoveDownload
-DownloadContentTest.RemoveResumingDownload
-DownloadContentTest.ResumeInterruptedDownload
-DownloadContentTest.ResumeInterruptedDownloadNoRange
-DownloadContentTest.ResumeInterruptedDownloadNoVerifiers
-DownloadContentTest.ResumeInterruptedDownloadBadPrecondition
-DownloadContentTest.ResumeWithDeletedFile
-
-# http://crbug.com/386227
-IndexedDBBrowserTest.VersionChangeCrashResilience
-
-# http://crbug.com/233118
-IndexedDBBrowserTest.NullKeyPathPersistence
-
-# http://crbug.com/342525
-IndexedDBBrowserTestSingleProcess.RenderThreadShutdownTest
-
-# http://crbug.com/338421
-GinBrowserTest.GinAndGarbageCollection
-
-# http://crbug.com/343604
-MSE_ClearKey/EncryptedMediaTest.ConfigChangeVideo/0
diff --git a/build/android/pylib/gtest/filter/content_unittests_disabled b/build/android/pylib/gtest/filter/content_unittests_disabled
deleted file mode 100644
index 925a7d1..0000000
--- a/build/android/pylib/gtest/filter/content_unittests_disabled
+++ /dev/null
@@ -1,13 +0,0 @@
-# List of suppressions
-
-# crbug.com/139095
-RenderWidgetTest.OnMsgPaintAtSize
-# crbug.com/147549
-GamepadProviderTest.PollingAccess
-PepperGamepadHostTest.WaitForReply
-# crbug.com/159234
-WebContentsVideoCaptureDeviceTest.*
-# crbug.com/167045
-ContentViewPopupZoomerTest.testPopupZoomerShowsUp
-# crbug.com/254034
-PageStateSerializationTest.BackwardsCompat_v11
diff --git a/build/android/pylib/gtest/filter/gfx_unittests_disabled b/build/android/pylib/gtest/filter/gfx_unittests_disabled
deleted file mode 100644
index b9aec9e..0000000
--- a/build/android/pylib/gtest/filter/gfx_unittests_disabled
+++ /dev/null
@@ -1,10 +0,0 @@
-CanvasTest.StringSizeEmptyString
-CanvasTest.StringWidth
-FontTest.Ascent
-FontTest.AvgWidths
-FontTest.CapHeight
-FontTest.GetActualFontNameForTesting
-FontTest.Height
-FontTest.LoadArial
-FontTest.LoadArialBold
-TextUtilsTest.GetStringWidth
diff --git a/build/android/pylib/gtest/filter/ipc_tests_disabled b/build/android/pylib/gtest/filter/ipc_tests_disabled
deleted file mode 100644
index e8d0691..0000000
--- a/build/android/pylib/gtest/filter/ipc_tests_disabled
+++ /dev/null
@@ -1,18 +0,0 @@
-# Times out
-IPCSyncChannelTest.ChattyServer
-
-# MultiProcessTest related failures. These tests fail if DCHECK is enabled.
-IPCChannelPosixTest.AdvancedConnected
-IPCChannelPosixTest.ResetState
-IPCChannelPosixTest.MultiConnection
-IPCFuzzingTest.SanityTest
-IPCFuzzingTest.MsgBadPayloadArgs
-IPCFuzzingTest.MsgBadPayloadShort
-IPCSendFdsTest.DescriptorTest
-IPCChannelProxyTest.MessageClassFilters
-IPCChannelProxyTest.GlobalAndMessageClassFilters
-IPCChannelProxyTest.FilterRemoval
-IPCChannelTest.ChannelTest
-IPCChannelTest.ChannelProxyTest
-IPCChannelTest.SendMessageInChannelConnected
-SyncSocketTest.SanityTest
diff --git a/build/android/pylib/gtest/filter/media_unittests_disabled b/build/android/pylib/gtest/filter/media_unittests_disabled
deleted file mode 100644
index ed3b9aa..0000000
--- a/build/android/pylib/gtest/filter/media_unittests_disabled
+++ /dev/null
@@ -1,8 +0,0 @@
-# List of suppressions
-
-# Death tests are not supported on APK
-# http://crbug.com/138855
-CompositeFilterDeathTest.*
-
-# http://crbug.com/138833
-AesDecryptorTest.*
diff --git a/build/android/pylib/gtest/filter/net_unittests_disabled b/build/android/pylib/gtest/filter/net_unittests_disabled
deleted file mode 100644
index 75a1c86..0000000
--- a/build/android/pylib/gtest/filter/net_unittests_disabled
+++ /dev/null
@@ -1,41 +0,0 @@
-# List of suppressions.
-
-PythonUtils.PythonRunTime
-VerifyEndEntity/CertVerifyProcWeakDigestTest.Verify/0
-VerifyEndEntity/CertVerifyProcWeakDigestTest.Verify/1
-VerifyEndEntity/CertVerifyProcWeakDigestTest.Verify/2
-VerifyIncompleteEndEntity/CertVerifyProcWeakDigestTest.Verify/0
-VerifyIncompleteEndEntity/CertVerifyProcWeakDigestTest.Verify/1
-VerifyIncompleteEndEntity/CertVerifyProcWeakDigestTest.Verify/2
-VerifyIncompleteIntermediate/CertVerifyProcWeakDigestTest.Verify/0
-VerifyIncompleteIntermediate/CertVerifyProcWeakDigestTest.Verify/1
-VerifyIncompleteIntermediate/CertVerifyProcWeakDigestTest.Verify/2
-VerifyIntermediate/CertVerifyProcWeakDigestTest.Verify/0
-VerifyIntermediate/CertVerifyProcWeakDigestTest.Verify/1
-VerifyIntermediate/CertVerifyProcWeakDigestTest.Verify/2
-VerifyMixed/CertVerifyProcWeakDigestTest.Verify/0
-VerifyMixed/CertVerifyProcWeakDigestTest.Verify/1
-VerifyMixed/CertVerifyProcWeakDigestTest.Verify/2
-VerifyRoot/CertVerifyProcWeakDigestTest.Verify/0
-VerifyRoot/CertVerifyProcWeakDigestTest.Verify/1
-VerifyRoot/CertVerifyProcWeakDigestTest.Verify/2
-
-# Can't spin up more than one SpawnedTestServer on Android.
-URLRequestTestReferrerPolicy.HTTPToCrossOriginHTTP
-URLRequestTestReferrerPolicy.HTTPSToCrossOriginHTTPS
-URLRequestTestReferrerPolicy.HTTPToHTTPS
-URLRequestTestReferrerPolicy.HTTPSToHTTP
-
-# Fail only on bots.
-HttpCache.RangeGET_Cancel
-HttpCache.RangeGET_Cancel2
-HttpCache.RangeGET_OK
-HttpCache.RangeGET_Previous200
-HttpCache.RangeGET_Revalidate2
-HttpCache.RangeGET_SyncOK
-HttpCache.TypicalGET_ConditionalRequest
-# Death tests are not supported with apks.
-*DeathTest*
-# These are death tests and thus also disabled.
-PrioritizedDispatcherTest.CancelNull
-PrioritizedDispatcherTest.CancelMissing
diff --git a/build/android/pylib/gtest/filter/sync_unit_tests_disabled b/build/android/pylib/gtest/filter/sync_unit_tests_disabled
deleted file mode 100644
index cc4b72d..0000000
--- a/build/android/pylib/gtest/filter/sync_unit_tests_disabled
+++ /dev/null
@@ -1,4 +0,0 @@
-SyncHttpBridgeTest.*
-
-# crbug.com/144422
-OnDiskSyncableDirectory.FailInitialWrite
diff --git a/build/android/pylib/gtest/filter/unit_tests_disabled b/build/android/pylib/gtest/filter/unit_tests_disabled
deleted file mode 100644
index c7851fd..0000000
--- a/build/android/pylib/gtest/filter/unit_tests_disabled
+++ /dev/null
@@ -1,119 +0,0 @@
-# List of suppressions
-
-# The UDP related tests currently do not work on Android because
-# we lack a UDP forwarder tool.
-NetworkStatsTestUDP.*
-
-# Missing test resource of 16MB.
-HistoryProfileTest.TypicalProfileVersion
-
-# crbug.com/139408
-SQLitePersistentCookieStoreTest.TestDontLoadOldSessionCookies
-SQLitePersistentCookieStoreTest.PersistIsPersistent
-
-# crbug.com/139433
-AutofillTableTest.AutofillProfile*
-AutofillTableTest.UpdateAutofillProfile
-
-# crbug.com/139400
-AutofillProfileTest.*
-CreditCardTest.SetInfoExpirationMonth
-
-# crbug.com/139398
-DownloadItemModelTest.InterruptTooltip
-
-# Tests crashing in the APK
-# l10n_util.cc(655)] Check failed: std::string::npos != pos
-DownloadItemModelTest.InterruptStatus
-# l10n_util.cc(655)] Check failed: std::string::npos != pos
-WebsiteSettingsTest.OnSiteDataAccessed
-
-# crbug.com/139423
-ValueStoreFrontendTest.GetExistingData
-
-# crbug.com/139421
-ChromeSelectFilePolicyTest.ExpectAsynchronousListenerCall
-
-# http://crbug.com/139033
-ChromeDownloadManagerDelegateTest.StartDownload_PromptAlways
-
-# Extension support is limited on Android.
-# Some of these can be enabled if we register extension related prefs in
-# browser_prefs.cc
-ExtensionTest.*
-ExtensionAPI.*
-ExtensionFileUtilTest.*
-ExtensionPermissionsTest.*
-ExtensionUnpackerTest.*
-ActiveTabTest.*
-ExtensionAppsPromo.*
-ComponentLoaderTest.*
-ExtensionFromUserScript.*
-ExtensionFromWebApp.*
-ExtensionIconManagerTest.*
-ExtensionServiceTest.*
-ExtensionServiceTestSimple.*
-ExtensionSourcePriorityTest.*
-ExtensionSpecialStoragePolicyTest.*
-ExternalPolicyProviderTest.*
-ExternalProviderImplTest.*
-MenuManagerTest.*
-PageActionControllerTest.*
-PermissionsUpdaterTest.*
-ImageLoaderTest.*
-ImageLoadingTrackerTest.*
-ExtensionSettingsFrontendTest.*
-ExtensionSettingsSyncTest.*
-ExtensionUpdaterTest.*
-UserScriptListenerTest.*
-WebApplicationTest.GetShortcutInfoForTab
-ExtensionActionIconFactoryTest.*
-
-# crbug.com/139411
-AutocompleteProviderTest.*
-HistoryContentsProviderBodyOnlyTest.*
-HistoryContentsProviderTest.*
-HQPOrderingTest.*
-SearchProviderTest.*
-
-ProtocolHandlerRegistryTest.TestOSRegistrationFailure
-
-# crbug.com/139418
-SQLiteServerBoundCertStoreTest.TestUpgradeV1
-SQLiteServerBoundCertStoreTest.TestUpgradeV2
-
-ProfileSyncComponentsFactoryImplTest.*
-PermissionsTest.GetWarningMessages_Plugins
-ImageOperations.ResizeShouldAverageColors
-
-# crbug.com/138275
-PrerenderTest.*
-RenderWidgetTest.OnMsgPaintAtSize
-
-# crbug.com/139643
-VariationsUtilTest.DisableAfterInitialization
-VariationsUtilTest.AssociateGoogleVariationID
-VariationsUtilTest.NoAssociation
-
-# crbug.com/141473
-AutofillManagerTest.UpdatePasswordSyncState
-AutofillManagerTest.UpdatePasswordGenerationState
-
-# crbug.com/144227
-ExtensionIconImageTest.*
-
-# crbug.com/145843
-EntropyProviderTest.UseOneTimeRandomizationSHA1
-EntropyProviderTest.UseOneTimeRandomizationPermuted
-
-# crbug.com/147500
-ManifestTest.RestrictedKeys
-
-# crbug.com/152599
-SyncSearchEngineDataTypeControllerTest.*
-
-# crbug.com/256259
-DiagnosticsModelTest.RunAll
-
-# Death tests are not supported with apks.
-*DeathTest*
diff --git a/build/android/pylib/gtest/filter/webkit_unit_tests_disabled b/build/android/pylib/gtest/filter/webkit_unit_tests_disabled
deleted file mode 100644
index 1ffa325..0000000
--- a/build/android/pylib/gtest/filter/webkit_unit_tests_disabled
+++ /dev/null
@@ -1,25 +0,0 @@
-# List of suppressions
-
-# crbug.com/159935
-WebCompositorInputHandlerImplTest.gestureFlingAnimates
-WebCompositorInputHandlerImplTest.gestureFlingTransferResets
-WebPageSerializerTest.HTMLNodes
-
-# crbug.com/241730
-ScrollAnimatorNoneTest.CurveMathQuartic
-ScrollAnimatorNoneTest.ScrollDownToBumper
-ScrollAnimatorNoneTest.ScrollQuadraticSmoothed
-ScrollAnimatorNoneTest.ScrollTwiceCubic
-ScrollAnimatorNoneTest.VaryingInputsEquivalencyCoastSteep
-WebViewTest.VisitedLinkCrash
-
-# Disabled until blink roll r151682
-DeferredImageDecoderTest.drawScaledIntoSkPicture
-
-# Disabled until blink roll r173540
-DeferredImageDecoderTest.decodeOnOtherThread
-DeferredImageDecoderTest.drawIntoSkPicture
-DeferredImageDecoderTest.drawIntoSkPictureProgressive
-
-# crbug.com/320005
-CoreAnimationCompositorAnimationsTest.ConvertTimingForCompositorIterationCount
diff --git a/build/android/pylib/gtest/gtest_config.py b/build/android/pylib/gtest/gtest_config.py
deleted file mode 100644
index 76e0f50..0000000
--- a/build/android/pylib/gtest/gtest_config.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# Copyright (c) 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Configuration file for android gtest suites."""
-
-# Add new suites here before upgrading them to the stable list below.
-EXPERIMENTAL_TEST_SUITES = [
- 'components_browsertests',
- 'content_gl_tests',
- 'heap_profiler_unittests',
- 'devtools_bridge_tests',
-]
-
-TELEMETRY_EXPERIMENTAL_TEST_SUITES = [
- 'telemetry_unittests',
-]
-
-# Do not modify this list without approval of an android owner.
-# This list determines which suites are run by default, both for local
-# testing and on android trybots running on commit-queue.
-STABLE_TEST_SUITES = [
- 'android_webview_unittests',
- 'base_unittests',
- 'breakpad_unittests',
- 'cc_unittests',
- 'components_unittests',
- 'content_browsertests',
- 'content_unittests',
- 'events_unittests',
- 'gl_tests',
- 'gl_unittests',
- 'gpu_unittests',
- 'ipc_tests',
- 'media_unittests',
- 'midi_unittests',
- 'net_unittests',
- 'sandbox_linux_unittests',
- 'skia_unittests',
- 'sql_unittests',
- 'sync_unit_tests',
- 'ui_android_unittests',
- 'ui_base_unittests',
- 'ui_touch_selection_unittests',
- 'unit_tests',
- 'webkit_unit_tests',
-]
-
-# Tests fail in component=shared_library build, which is required for ASan.
-# http://crbug.com/344868
-ASAN_EXCLUDED_TEST_SUITES = [
- 'breakpad_unittests',
- 'sandbox_linux_unittests'
-]
diff --git a/build/android/pylib/gtest/gtest_test_instance.py b/build/android/pylib/gtest/gtest_test_instance.py
deleted file mode 100644
index 3285e0b..0000000
--- a/build/android/pylib/gtest/gtest_test_instance.py
+++ /dev/null
@@ -1,329 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import os
-import re
-import shutil
-import sys
-import tempfile
-
-from pylib import constants
-from pylib.base import base_test_result
-from pylib.base import test_instance
-from pylib.utils import apk_helper
-
-sys.path.append(os.path.join(
- constants.DIR_SOURCE_ROOT, 'build', 'util', 'lib', 'common'))
-import unittest_util
-
-
-BROWSER_TEST_SUITES = [
- 'components_browsertests',
- 'content_browsertests',
-]
-
-
-_DEFAULT_ISOLATE_FILE_PATHS = {
- 'base_unittests': 'base/base_unittests.isolate',
- 'blink_heap_unittests':
- 'third_party/WebKit/Source/platform/heap/BlinkHeapUnitTests.isolate',
- 'breakpad_unittests': 'breakpad/breakpad_unittests.isolate',
- 'cc_perftests': 'cc/cc_perftests.isolate',
- 'components_browsertests': 'components/components_browsertests.isolate',
- 'components_unittests': 'components/components_unittests.isolate',
- 'content_browsertests': 'content/content_browsertests.isolate',
- 'content_unittests': 'content/content_unittests.isolate',
- 'media_perftests': 'media/media_perftests.isolate',
- 'media_unittests': 'media/media_unittests.isolate',
- 'midi_unittests': 'media/midi/midi_unittests.isolate',
- 'net_unittests': 'net/net_unittests.isolate',
- 'sql_unittests': 'sql/sql_unittests.isolate',
- 'sync_unit_tests': 'sync/sync_unit_tests.isolate',
- 'ui_base_unittests': 'ui/base/ui_base_tests.isolate',
- 'unit_tests': 'chrome/unit_tests.isolate',
- 'webkit_unit_tests':
- 'third_party/WebKit/Source/web/WebKitUnitTests.isolate',
-}
-
-
-# Used for filtering large data deps at a finer grain than what's allowed in
-# isolate files since pushing deps to devices is expensive.
-# Wildcards are allowed.
-_DEPS_EXCLUSION_LIST = [
- 'chrome/test/data/extensions/api_test',
- 'chrome/test/data/extensions/secure_shell',
- 'chrome/test/data/firefox*',
- 'chrome/test/data/gpu',
- 'chrome/test/data/image_decoding',
- 'chrome/test/data/import',
- 'chrome/test/data/page_cycler',
- 'chrome/test/data/perf',
- 'chrome/test/data/pyauto_private',
- 'chrome/test/data/safari_import',
- 'chrome/test/data/scroll',
- 'chrome/test/data/third_party',
- 'third_party/hunspell_dictionaries/*.dic',
- # crbug.com/258690
- 'webkit/data/bmp_decoder',
- 'webkit/data/ico_decoder',
-]
-
-
-_EXTRA_NATIVE_TEST_ACTIVITY = (
- 'org.chromium.native_test.NativeTestInstrumentationTestRunner.'
- 'NativeTestActivity')
-_EXTRA_SHARD_SIZE_LIMIT =(
- 'org.chromium.native_test.NativeTestInstrumentationTestRunner.'
- 'ShardSizeLimit')
-
-# TODO(jbudorick): Remove these once we're no longer parsing stdout to generate
-# results.
-_RE_TEST_STATUS = re.compile(
- r'\[ +((?:RUN)|(?:FAILED)|(?:OK)) +\] ?([^ ]+)(?: \((\d+) ms\))?$')
-_RE_TEST_RUN_STATUS = re.compile(
- r'\[ +(PASSED|RUNNER_FAILED|CRASHED) \] ?[^ ]+')
-
-
-# TODO(jbudorick): Make this a class method of GtestTestInstance once
-# test_package_apk and test_package_exe are gone.
-def ParseGTestListTests(raw_list):
- """Parses a raw test list as provided by --gtest_list_tests.
-
- Args:
- raw_list: The raw test listing with the following format:
-
- IPCChannelTest.
- SendMessageInChannelConnected
- IPCSyncChannelTest.
- Simple
- DISABLED_SendWithTimeoutMixedOKAndTimeout
-
- Returns:
- A list of all tests. For the above raw listing:
-
- [IPCChannelTest.SendMessageInChannelConnected, IPCSyncChannelTest.Simple,
- IPCSyncChannelTest.DISABLED_SendWithTimeoutMixedOKAndTimeout]
- """
- ret = []
- current = ''
- for test in raw_list:
- if not test:
- continue
- if test[0] != ' ':
- test_case = test.split()[0]
- if test_case.endswith('.'):
- current = test_case
- elif not 'YOU HAVE' in test:
- test_name = test.split()[0]
- ret += [current + test_name]
- return ret
-
-
-class GtestTestInstance(test_instance.TestInstance):
-
- def __init__(self, args, isolate_delegate, error_func):
- super(GtestTestInstance, self).__init__()
- # TODO(jbudorick): Support multiple test suites.
- if len(args.suite_name) > 1:
- raise ValueError('Platform mode currently supports only 1 gtest suite')
- self._suite = args.suite_name[0]
-
- self._apk_path = os.path.join(
- constants.GetOutDirectory(), '%s_apk' % self._suite,
- '%s-debug.apk' % self._suite)
- self._exe_path = os.path.join(constants.GetOutDirectory(),
- self._suite)
- if not os.path.exists(self._apk_path):
- self._apk_path = None
- self._activity = None
- self._package = None
- self._runner = None
- else:
- helper = apk_helper.ApkHelper(self._apk_path)
- self._activity = helper.GetActivityName()
- self._package = helper.GetPackageName()
- self._runner = helper.GetInstrumentationName()
- self._extras = {
- _EXTRA_NATIVE_TEST_ACTIVITY: self._activity,
- }
- if self._suite in BROWSER_TEST_SUITES:
- self._extras[_EXTRA_SHARD_SIZE_LIMIT] = 1
-
- if not os.path.exists(self._exe_path):
- self._exe_path = None
- if not self._apk_path and not self._exe_path:
- error_func('Could not find apk or executable for %s' % self._suite)
-
- self._data_deps = []
- if args.test_filter:
- self._gtest_filter = args.test_filter
- elif args.test_filter_file:
- with open(args.test_filter_file, 'r') as f:
- self._gtest_filter = ':'.join(l.strip() for l in f)
- else:
- self._gtest_filter = None
-
- if not args.isolate_file_path:
- default_isolate_file_path = _DEFAULT_ISOLATE_FILE_PATHS.get(self._suite)
- if default_isolate_file_path:
- args.isolate_file_path = os.path.join(
- constants.DIR_SOURCE_ROOT, default_isolate_file_path)
-
- if args.isolate_file_path:
- self._isolate_abs_path = os.path.abspath(args.isolate_file_path)
- self._isolate_delegate = isolate_delegate
- self._isolated_abs_path = os.path.join(
- constants.GetOutDirectory(), '%s.isolated' % self._suite)
- else:
- logging.warning('No isolate file provided. No data deps will be pushed.');
- self._isolate_delegate = None
-
- if args.app_data_files:
- self._app_data_files = args.app_data_files
- if args.app_data_file_dir:
- self._app_data_file_dir = args.app_data_file_dir
- else:
- self._app_data_file_dir = tempfile.mkdtemp()
- logging.critical('Saving app files to %s', self._app_data_file_dir)
- else:
- self._app_data_files = None
- self._app_data_file_dir = None
-
- #override
- def TestType(self):
- return 'gtest'
-
- #override
- def SetUp(self):
- """Map data dependencies via isolate."""
- if self._isolate_delegate:
- self._isolate_delegate.Remap(
- self._isolate_abs_path, self._isolated_abs_path)
- self._isolate_delegate.PurgeExcluded(_DEPS_EXCLUSION_LIST)
- self._isolate_delegate.MoveOutputDeps()
- dest_dir = None
- if self._suite == 'breakpad_unittests':
- dest_dir = '/data/local/tmp/'
- self._data_deps.extend([(constants.ISOLATE_DEPS_DIR, dest_dir)])
-
-
- def GetDataDependencies(self):
- """Returns the test suite's data dependencies.
-
- Returns:
- A list of (host_path, device_path) tuples to push. If device_path is
- None, the client is responsible for determining where to push the file.
- """
- return self._data_deps
-
- def FilterTests(self, test_list, disabled_prefixes=None):
- """Filters |test_list| based on prefixes and, if present, a filter string.
-
- Args:
- test_list: The list of tests to filter.
- disabled_prefixes: A list of test prefixes to filter. Defaults to
- DISABLED_, FLAKY_, FAILS_, PRE_, and MANUAL_
- Returns:
- A filtered list of tests to run.
- """
- gtest_filter_strings = [
- self._GenerateDisabledFilterString(disabled_prefixes)]
- if self._gtest_filter:
- gtest_filter_strings.append(self._gtest_filter)
-
- filtered_test_list = test_list
- for gtest_filter_string in gtest_filter_strings:
- logging.debug('Filtering tests using: %s', gtest_filter_string)
- filtered_test_list = unittest_util.FilterTestNames(
- filtered_test_list, gtest_filter_string)
- return filtered_test_list
-
- def _GenerateDisabledFilterString(self, disabled_prefixes):
- disabled_filter_items = []
-
- if disabled_prefixes is None:
- disabled_prefixes = ['DISABLED_', 'FLAKY_', 'FAILS_', 'PRE_', 'MANUAL_']
- disabled_filter_items += ['%s*' % dp for dp in disabled_prefixes]
- disabled_filter_items += ['*.%s*' % dp for dp in disabled_prefixes]
-
- disabled_tests_file_path = os.path.join(
- constants.DIR_SOURCE_ROOT, 'build', 'android', 'pylib', 'gtest',
- 'filter', '%s_disabled' % self._suite)
- if disabled_tests_file_path and os.path.exists(disabled_tests_file_path):
- with open(disabled_tests_file_path) as disabled_tests_file:
- disabled_filter_items += [
- '%s' % l for l in (line.strip() for line in disabled_tests_file)
- if l and not l.startswith('#')]
-
- return '*-%s' % ':'.join(disabled_filter_items)
-
- def ParseGTestOutput(self, output):
- """Parses raw gtest output and returns a list of results.
-
- Args:
- output: A list of output lines.
- Returns:
- A list of base_test_result.BaseTestResults.
- """
- results = []
- for l in output:
- matcher = _RE_TEST_STATUS.match(l)
- if matcher:
- result_type = None
- if matcher.group(1) == 'OK':
- result_type = base_test_result.ResultType.PASS
- elif matcher.group(1) == 'FAILED':
- result_type = base_test_result.ResultType.FAIL
-
- if result_type:
- test_name = matcher.group(2)
- duration = matcher.group(3) if matcher.group(3) else 0
- results.append(base_test_result.BaseTestResult(
- test_name, result_type, duration))
- logging.info(l)
- return results
-
- #override
- def TearDown(self):
- """Clear the mappings created by SetUp."""
- if self._isolate_delegate:
- self._isolate_delegate.Clear()
-
- @property
- def activity(self):
- return self._activity
-
- @property
- def apk(self):
- return self._apk_path
-
- @property
- def app_file_dir(self):
- return self._app_data_file_dir
-
- @property
- def app_files(self):
- return self._app_data_files
-
- @property
- def exe(self):
- return self._exe_path
-
- @property
- def extras(self):
- return self._extras
-
- @property
- def package(self):
- return self._package
-
- @property
- def runner(self):
- return self._runner
-
- @property
- def suite(self):
- return self._suite
-
diff --git a/build/android/pylib/gtest/gtest_test_instance_test.py b/build/android/pylib/gtest/gtest_test_instance_test.py
deleted file mode 100755
index c52b235..0000000
--- a/build/android/pylib/gtest/gtest_test_instance_test.py
+++ /dev/null
@@ -1,86 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from pylib.gtest import gtest_test_instance
-
-
-class GtestTestInstanceTests(unittest.TestCase):
-
- def testParseGTestListTests_simple(self):
- raw_output = [
- 'TestCaseOne.',
- ' testOne',
- ' testTwo',
- 'TestCaseTwo.',
- ' testThree',
- ' testFour',
- ]
- actual = gtest_test_instance.ParseGTestListTests(raw_output)
- expected = [
- 'TestCaseOne.testOne',
- 'TestCaseOne.testTwo',
- 'TestCaseTwo.testThree',
- 'TestCaseTwo.testFour',
- ]
- self.assertEqual(expected, actual)
-
- def testParseGTestListTests_typeParameterized_old(self):
- raw_output = [
- 'TPTestCase/WithTypeParam/0.',
- ' testOne',
- ' testTwo',
- ]
- actual = gtest_test_instance.ParseGTestListTests(raw_output)
- expected = [
- 'TPTestCase/WithTypeParam/0.testOne',
- 'TPTestCase/WithTypeParam/0.testTwo',
- ]
- self.assertEqual(expected, actual)
-
- def testParseGTestListTests_typeParameterized_new(self):
- raw_output = [
- 'TPTestCase/WithTypeParam/0. # TypeParam = TypeParam0',
- ' testOne',
- ' testTwo',
- ]
- actual = gtest_test_instance.ParseGTestListTests(raw_output)
- expected = [
- 'TPTestCase/WithTypeParam/0.testOne',
- 'TPTestCase/WithTypeParam/0.testTwo',
- ]
- self.assertEqual(expected, actual)
-
- def testParseGTestListTests_valueParameterized_old(self):
- raw_output = [
- 'VPTestCase.',
- ' testWithValueParam/0',
- ' testWithValueParam/1',
- ]
- actual = gtest_test_instance.ParseGTestListTests(raw_output)
- expected = [
- 'VPTestCase.testWithValueParam/0',
- 'VPTestCase.testWithValueParam/1',
- ]
- self.assertEqual(expected, actual)
-
- def testParseGTestListTests_valueParameterized_new(self):
- raw_output = [
- 'VPTestCase.',
- ' testWithValueParam/0 # GetParam() = 0',
- ' testWithValueParam/1 # GetParam() = 1',
- ]
- actual = gtest_test_instance.ParseGTestListTests(raw_output)
- expected = [
- 'VPTestCase.testWithValueParam/0',
- 'VPTestCase.testWithValueParam/1',
- ]
- self.assertEqual(expected, actual)
-
-
-if __name__ == '__main__':
- unittest.main(verbosity=2)
-
diff --git a/build/android/pylib/gtest/local_device_gtest_run.py b/build/android/pylib/gtest/local_device_gtest_run.py
deleted file mode 100644
index f1cea4e..0000000
--- a/build/android/pylib/gtest/local_device_gtest_run.py
+++ /dev/null
@@ -1,241 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import itertools
-import logging
-import os
-import posixpath
-
-from pylib import constants
-from pylib import ports
-from pylib.base import test_run
-from pylib.device import device_errors
-from pylib.gtest import gtest_test_instance
-
-from pylib.local import local_test_server_spawner
-from pylib.local.device import local_device_environment
-from pylib.local.device import local_device_test_run
-from pylib.utils import device_temp_file
-
-_COMMAND_LINE_FLAGS_SUPPORTED = True
-
-_EXTRA_COMMAND_LINE_FILE = (
- 'org.chromium.native_test.NativeTestActivity.CommandLineFile')
-_EXTRA_COMMAND_LINE_FLAGS = (
- 'org.chromium.native_test.NativeTestActivity.CommandLineFlags')
-_EXTRA_TEST_LIST = (
- 'org.chromium.native_test.NativeTestInstrumentationTestRunner'
- '.TestList')
-
-_MAX_SHARD_SIZE = 256
-
-# TODO(jbudorick): Move this up to the test instance if the net test server is
-# handled outside of the APK for the remote_device environment.
-_SUITE_REQUIRES_TEST_SERVER_SPAWNER = [
- 'components_browsertests', 'content_unittests', 'content_browsertests',
- 'net_unittests', 'unit_tests'
-]
-
-# TODO(jbudorick): Move this inside _ApkDelegate once TestPackageApk is gone.
-def PullAppFilesImpl(device, package, files, directory):
- device_dir = device.GetApplicationDataDirectory(package)
- host_dir = os.path.join(directory, str(device))
- for f in files:
- device_file = posixpath.join(device_dir, f)
- host_file = os.path.join(host_dir, *f.split(posixpath.sep))
- host_file_base, ext = os.path.splitext(host_file)
- for i in itertools.count():
- host_file = '%s_%d%s' % (host_file_base, i, ext)
- if not os.path.exists(host_file):
- break
- device.PullFile(device_file, host_file)
-
-class _ApkDelegate(object):
- def __init__(self, test_instance):
- self._activity = test_instance.activity
- self._apk = test_instance.apk
- self._package = test_instance.package
- self._runner = test_instance.runner
-
- self._component = '%s/%s' % (self._package, self._runner)
- self._extras = test_instance.extras
-
- def Install(self, device):
- device.Install(self._apk)
-
- def Run(self, test, device, flags=None, **kwargs):
- extras = dict(self._extras)
-
- with device_temp_file.DeviceTempFile(device.adb) as command_line_file:
- device.WriteFile(command_line_file.name, '_ %s' % flags if flags else '_')
- extras[_EXTRA_COMMAND_LINE_FILE] = command_line_file.name
-
- with device_temp_file.DeviceTempFile(device.adb) as test_list_file:
- if test:
- device.WriteFile(test_list_file.name, '\n'.join(test))
- extras[_EXTRA_TEST_LIST] = test_list_file.name
-
- return device.StartInstrumentation(
- self._component, extras=extras, raw=False, **kwargs)
-
- def PullAppFiles(self, device, files, directory):
- PullAppFilesImpl(device, self._package, files, directory)
-
- def Clear(self, device):
- device.ClearApplicationState(self._package)
-
-
-class _ExeDelegate(object):
- def __init__(self, tr, exe):
- self._exe_host_path = exe
- self._exe_file_name = os.path.split(exe)[-1]
- self._exe_device_path = '%s/%s' % (
- constants.TEST_EXECUTABLE_DIR, self._exe_file_name)
- deps_host_path = self._exe_host_path + '_deps'
- if os.path.exists(deps_host_path):
- self._deps_host_path = deps_host_path
- self._deps_device_path = self._exe_device_path + '_deps'
- else:
- self._deps_host_path = None
- self._test_run = tr
-
- def Install(self, device):
- # TODO(jbudorick): Look into merging this with normal data deps pushing if
- # executables become supported on nonlocal environments.
- host_device_tuples = [(self._exe_host_path, self._exe_device_path)]
- if self._deps_host_path:
- host_device_tuples.append((self._deps_host_path, self._deps_device_path))
- device.PushChangedFiles(host_device_tuples)
-
- def Run(self, test, device, flags=None, **kwargs):
- cmd = [
- self._test_run.GetTool(device).GetTestWrapper(),
- self._exe_device_path,
- ]
- if test:
- cmd.append('--gtest_filter=%s' % ':'.join(test))
- if flags:
- cmd.append(flags)
- cwd = constants.TEST_EXECUTABLE_DIR
-
- env = {
- 'LD_LIBRARY_PATH':
- '%s/%s_deps' % (constants.TEST_EXECUTABLE_DIR, self._exe_file_name),
- }
- try:
- gcov_strip_depth = os.environ['NATIVE_COVERAGE_DEPTH_STRIP']
- external = device.GetExternalStoragePath()
- env['GCOV_PREFIX'] = '%s/gcov' % external
- env['GCOV_PREFIX_STRIP'] = gcov_strip_depth
- except (device_errors.CommandFailedError, KeyError):
- pass
-
- # TODO(jbudorick): Switch to just RunShellCommand once perezju@'s CL
- # for long shell commands lands.
- with device_temp_file.DeviceTempFile(device.adb) as script_file:
- script_contents = ' '.join(cmd)
- logging.info('script contents: %r' % script_contents)
- device.WriteFile(script_file.name, script_contents)
- output = device.RunShellCommand(['sh', script_file.name], cwd=cwd,
- env=env, **kwargs)
- return output
-
- def PullAppFiles(self, device, files, directory):
- pass
-
- def Clear(self, device):
- device.KillAll(self._exe_file_name, blocking=True, timeout=30, quiet=True)
-
-
-class LocalDeviceGtestRun(local_device_test_run.LocalDeviceTestRun):
-
- def __init__(self, env, test_instance):
- assert isinstance(env, local_device_environment.LocalDeviceEnvironment)
- assert isinstance(test_instance, gtest_test_instance.GtestTestInstance)
- super(LocalDeviceGtestRun, self).__init__(env, test_instance)
-
- if self._test_instance.apk:
- self._delegate = _ApkDelegate(self._test_instance)
- elif self._test_instance.exe:
- self._delegate = _ExeDelegate(self, self._test_instance.exe)
-
- self._servers = {}
-
- #override
- def TestPackage(self):
- return self._test_instance.suite
-
- #override
- def SetUp(self):
-
- def individual_device_set_up(dev, host_device_tuples):
- # Install test APK.
- self._delegate.Install(dev)
-
- # Push data dependencies.
- external_storage = dev.GetExternalStoragePath()
- host_device_tuples = [
- (h, d if d is not None else external_storage)
- for h, d in host_device_tuples]
- dev.PushChangedFiles(host_device_tuples)
-
- self._servers[str(dev)] = []
- if self.TestPackage() in _SUITE_REQUIRES_TEST_SERVER_SPAWNER:
- self._servers[str(dev)].append(
- local_test_server_spawner.LocalTestServerSpawner(
- ports.AllocateTestServerPort(), dev, self.GetTool(dev)))
-
- for s in self._servers[str(dev)]:
- s.SetUp()
-
- self._env.parallel_devices.pMap(individual_device_set_up,
- self._test_instance.GetDataDependencies())
-
- #override
- def _ShouldShard(self):
- return True
-
- #override
- def _CreateShards(self, tests):
- device_count = len(self._env.devices)
- shards = []
- for i in xrange(0, device_count):
- unbounded_shard = tests[i::device_count]
- shards += [unbounded_shard[j:j+_MAX_SHARD_SIZE]
- for j in xrange(0, len(unbounded_shard), _MAX_SHARD_SIZE)]
- return shards
-
- #override
- def _GetTests(self):
- tests = self._delegate.Run(
- None, self._env.devices[0], flags='--gtest_list_tests')
- tests = gtest_test_instance.ParseGTestListTests(tests)
- tests = self._test_instance.FilterTests(tests)
- return tests
-
- #override
- def _RunTest(self, device, test):
- # Run the test.
- output = self._delegate.Run(
- test, device, timeout=900, retries=0)
- for s in self._servers[str(device)]:
- s.Reset()
- if self._test_instance.app_files:
- self._delegate.PullAppFiles(device, self._test_instance.app_files,
- self._test_instance.app_file_dir)
- self._delegate.Clear(device)
-
- # Parse the output.
- # TODO(jbudorick): Transition test scripts away from parsing stdout.
- results = self._test_instance.ParseGTestOutput(output)
- return results
-
- #override
- def TearDown(self):
- def individual_device_tear_down(dev):
- for s in self._servers[str(dev)]:
- s.TearDown()
-
- self._env.parallel_devices.pMap(individual_device_tear_down)
-
diff --git a/build/android/pylib/gtest/setup.py b/build/android/pylib/gtest/setup.py
deleted file mode 100644
index f563ccf..0000000
--- a/build/android/pylib/gtest/setup.py
+++ /dev/null
@@ -1,230 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Generates test runner factory and tests for GTests."""
-# pylint: disable=W0212
-
-import logging
-import os
-import sys
-
-from pylib import constants
-
-from pylib.base import base_setup
-from pylib.base import base_test_result
-from pylib.base import test_dispatcher
-from pylib.device import device_utils
-from pylib.gtest import gtest_test_instance
-from pylib.gtest import test_package_apk
-from pylib.gtest import test_package_exe
-from pylib.gtest import test_runner
-
-sys.path.insert(0,
- os.path.join(constants.DIR_SOURCE_ROOT, 'build', 'util', 'lib',
- 'common'))
-import unittest_util # pylint: disable=F0401
-
-
-ISOLATE_FILE_PATHS = gtest_test_instance._DEFAULT_ISOLATE_FILE_PATHS
-
-
-# Used for filtering large data deps at a finer grain than what's allowed in
-# isolate files since pushing deps to devices is expensive.
-# Wildcards are allowed.
-DEPS_EXCLUSION_LIST = [
- 'chrome/test/data/extensions/api_test',
- 'chrome/test/data/extensions/secure_shell',
- 'chrome/test/data/firefox*',
- 'chrome/test/data/gpu',
- 'chrome/test/data/image_decoding',
- 'chrome/test/data/import',
- 'chrome/test/data/page_cycler',
- 'chrome/test/data/perf',
- 'chrome/test/data/pyauto_private',
- 'chrome/test/data/safari_import',
- 'chrome/test/data/scroll',
- 'chrome/test/data/third_party',
- 'third_party/hunspell_dictionaries/*.dic',
- # crbug.com/258690
- 'webkit/data/bmp_decoder',
- 'webkit/data/ico_decoder',
-]
-
-
-def _GetDisabledTestsFilterFromFile(suite_name):
- """Returns a gtest filter based on the *_disabled file.
-
- Args:
- suite_name: Name of the test suite (e.g. base_unittests).
-
- Returns:
- A gtest filter which excludes disabled tests.
- Example: '*-StackTrace.*:StringPrintfTest.StringPrintfMisc'
- """
- filter_file_path = os.path.join(
- os.path.abspath(os.path.dirname(__file__)),
- 'filter', '%s_disabled' % suite_name)
-
- if not filter_file_path or not os.path.exists(filter_file_path):
- logging.info('No filter file found at %s', filter_file_path)
- return '*'
-
- filters = [x for x in [x.strip() for x in file(filter_file_path).readlines()]
- if x and x[0] != '#']
- disabled_filter = '*-%s' % ':'.join(filters)
- logging.info('Applying filter "%s" obtained from %s',
- disabled_filter, filter_file_path)
- return disabled_filter
-
-
-def _GetTests(test_options, test_package, devices):
- """Get a list of tests.
-
- Args:
- test_options: A GTestOptions object.
- test_package: A TestPackageApk object.
- devices: A list of attached devices.
-
- Returns:
- A list of all the tests in the test suite.
- """
- class TestListResult(base_test_result.BaseTestResult):
- def __init__(self):
- super(TestListResult, self).__init__(
- 'gtest_list_tests', base_test_result.ResultType.PASS)
- self.test_list = []
-
- def TestListerRunnerFactory(device, _shard_index):
- class TestListerRunner(test_runner.TestRunner):
- def RunTest(self, _test):
- result = TestListResult()
- self.test_package.Install(self.device)
- result.test_list = self.test_package.GetAllTests(self.device)
- results = base_test_result.TestRunResults()
- results.AddResult(result)
- return results, None
- return TestListerRunner(test_options, device, test_package)
-
- results, _no_retry = test_dispatcher.RunTests(
- ['gtest_list_tests'], TestListerRunnerFactory, devices)
- tests = []
- for r in results.GetAll():
- tests.extend(r.test_list)
- return tests
-
-
-def _FilterTestsUsingPrefixes(all_tests, pre=False, manual=False):
- """Removes tests with disabled prefixes.
-
- Args:
- all_tests: List of tests to filter.
- pre: If True, include tests with PRE_ prefix.
- manual: If True, include tests with MANUAL_ prefix.
-
- Returns:
- List of tests remaining.
- """
- filtered_tests = []
- filter_prefixes = ['DISABLED_', 'FLAKY_', 'FAILS_']
-
- if not pre:
- filter_prefixes.append('PRE_')
-
- if not manual:
- filter_prefixes.append('MANUAL_')
-
- for t in all_tests:
- test_case, test = t.split('.', 1)
- if not any([test_case.startswith(prefix) or test.startswith(prefix) for
- prefix in filter_prefixes]):
- filtered_tests.append(t)
- return filtered_tests
-
-
-def _FilterDisabledTests(tests, suite_name, has_gtest_filter):
- """Removes disabled tests from |tests|.
-
- Applies the following filters in order:
- 1. Remove tests with disabled prefixes.
- 2. Remove tests specified in the *_disabled files in the 'filter' dir
-
- Args:
- tests: List of tests.
- suite_name: Name of the test suite (e.g. base_unittests).
- has_gtest_filter: Whether a gtest_filter is provided.
-
- Returns:
- List of tests remaining.
- """
- tests = _FilterTestsUsingPrefixes(
- tests, has_gtest_filter, has_gtest_filter)
- tests = unittest_util.FilterTestNames(
- tests, _GetDisabledTestsFilterFromFile(suite_name))
-
- return tests
-
-
-def Setup(test_options, devices):
- """Create the test runner factory and tests.
-
- Args:
- test_options: A GTestOptions object.
- devices: A list of attached devices.
-
- Returns:
- A tuple of (TestRunnerFactory, tests).
- """
- test_package = test_package_apk.TestPackageApk(test_options.suite_name)
- if not os.path.exists(test_package.suite_path):
- exe_test_package = test_package_exe.TestPackageExecutable(
- test_options.suite_name)
- if not os.path.exists(exe_test_package.suite_path):
- raise Exception(
- 'Did not find %s target. Ensure it has been built.\n'
- '(not found at %s or %s)'
- % (test_options.suite_name,
- test_package.suite_path,
- exe_test_package.suite_path))
- test_package = exe_test_package
- logging.warning('Found target %s', test_package.suite_path)
-
- i = base_setup.GenerateDepsDirUsingIsolate(test_options.suite_name,
- test_options.isolate_file_path,
- ISOLATE_FILE_PATHS,
- DEPS_EXCLUSION_LIST)
- def push_data_deps_to_device_dir(device):
- device_dir = (constants.TEST_EXECUTABLE_DIR
- if test_package.suite_name == 'breakpad_unittests'
- else device.GetExternalStoragePath())
- base_setup.PushDataDeps(device, device_dir, test_options)
- device_utils.DeviceUtils.parallel(devices).pMap(push_data_deps_to_device_dir)
- if i:
- i.Clear()
-
- tests = _GetTests(test_options, test_package, devices)
-
- # Constructs a new TestRunner with the current options.
- def TestRunnerFactory(device, _shard_index):
- return test_runner.TestRunner(
- test_options,
- device,
- test_package)
-
- if test_options.run_disabled:
- test_options = test_options._replace(
- test_arguments=('%s --gtest_also_run_disabled_tests' %
- test_options.test_arguments))
- else:
- tests = _FilterDisabledTests(tests, test_options.suite_name,
- bool(test_options.gtest_filter))
- if test_options.gtest_filter:
- tests = unittest_util.FilterTestNames(tests, test_options.gtest_filter)
-
- # Coalesce unit tests into a single test per device
- if test_options.suite_name not in gtest_test_instance.BROWSER_TEST_SUITES:
- num_devices = len(devices)
- tests = [':'.join(tests[i::num_devices]) for i in xrange(num_devices)]
- tests = [t for t in tests if t]
-
- return (TestRunnerFactory, tests)
diff --git a/build/android/pylib/gtest/test_options.py b/build/android/pylib/gtest/test_options.py
deleted file mode 100644
index 8bc6996..0000000
--- a/build/android/pylib/gtest/test_options.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Defines the GTestOptions named tuple."""
-
-import collections
-
-GTestOptions = collections.namedtuple('GTestOptions', [
- 'tool',
- 'gtest_filter',
- 'run_disabled',
- 'test_arguments',
- 'timeout',
- 'isolate_file_path',
- 'suite_name',
- 'app_data_files',
- 'app_data_file_dir',
- 'delete_stale_data'])
diff --git a/build/android/pylib/gtest/test_package.py b/build/android/pylib/gtest/test_package.py
deleted file mode 100644
index 4042a98..0000000
--- a/build/android/pylib/gtest/test_package.py
+++ /dev/null
@@ -1,76 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Base class representing GTest test packages."""
-# pylint: disable=R0201
-
-
-class TestPackage(object):
-
- """A helper base class for both APK and stand-alone executables.
-
- Args:
- suite_name: Name of the test suite (e.g. base_unittests).
- """
- def __init__(self, suite_name):
- self.suite_name = suite_name
-
- def ClearApplicationState(self, device):
- """Clears the application state.
-
- Args:
- device: Instance of DeviceUtils.
- """
- raise NotImplementedError('Method must be overridden.')
-
- def CreateCommandLineFileOnDevice(self, device, test_filter, test_arguments):
- """Creates a test runner script and pushes to the device.
-
- Args:
- device: Instance of DeviceUtils.
- test_filter: A test_filter flag.
- test_arguments: Additional arguments to pass to the test binary.
- """
- raise NotImplementedError('Method must be overridden.')
-
- def GetAllTests(self, device):
- """Returns a list of all tests available in the test suite.
-
- Args:
- device: Instance of DeviceUtils.
- """
- raise NotImplementedError('Method must be overridden.')
-
- def GetGTestReturnCode(self, _device):
- return None
-
- def SpawnTestProcess(self, device):
- """Spawn the test process.
-
- Args:
- device: Instance of DeviceUtils.
-
- Returns:
- An instance of pexpect spawn class.
- """
- raise NotImplementedError('Method must be overridden.')
-
- def Install(self, device):
- """Install the test package to the device.
-
- Args:
- device: Instance of DeviceUtils.
- """
- raise NotImplementedError('Method must be overridden.')
-
- def PullAppFiles(self, device, files, directory):
- """Pull application data from the device.
-
- Args:
- device: Instance of DeviceUtils.
- files: A list of paths relative to the application data directory to
- retrieve from the device.
- directory: The host directory to which files should be pulled.
- """
- raise NotImplementedError('Method must be overridden.')
diff --git a/build/android/pylib/gtest/test_package_apk.py b/build/android/pylib/gtest/test_package_apk.py
deleted file mode 100644
index a679b03..0000000
--- a/build/android/pylib/gtest/test_package_apk.py
+++ /dev/null
@@ -1,157 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Defines TestPackageApk to help run APK-based native tests."""
-# pylint: disable=W0212
-
-import itertools
-import logging
-import os
-import posixpath
-import shlex
-import sys
-import tempfile
-import time
-
-from pylib import android_commands
-from pylib import constants
-from pylib import pexpect
-from pylib.device import device_errors
-from pylib.device import intent
-from pylib.gtest import gtest_test_instance
-from pylib.gtest import local_device_gtest_run
-from pylib.gtest.test_package import TestPackage
-
-
-class TestPackageApk(TestPackage):
- """A helper class for running APK-based native tests."""
-
- def __init__(self, suite_name):
- """
- Args:
- suite_name: Name of the test suite (e.g. base_unittests).
- """
- TestPackage.__init__(self, suite_name)
- self.suite_path = os.path.join(
- constants.GetOutDirectory(), '%s_apk' % suite_name,
- '%s-debug.apk' % suite_name)
- if suite_name == 'content_browsertests':
- self._package_info = constants.PACKAGE_INFO['content_browsertests']
- elif suite_name == 'components_browsertests':
- self._package_info = constants.PACKAGE_INFO['components_browsertests']
- else:
- self._package_info = constants.PACKAGE_INFO['gtest']
-
- if suite_name == 'net_unittests':
- self._extras = {'RunInSubThread': ''}
- else:
- self._extras = []
-
- def _CreateCommandLineFileOnDevice(self, device, options):
- device.WriteFile(self._package_info.cmdline_file,
- self.suite_name + ' ' + options)
-
- def _GetFifo(self):
- # The test.fifo path is determined by:
- # testing/android/native_test/java/src/org/chromium/native_test/
- # NativeTestActivity.java and
- # testing/android/native_test_launcher.cc
- return '/data/data/' + self._package_info.package + '/files/test.fifo'
-
- def _ClearFifo(self, device):
- device.RunShellCommand('rm -f ' + self._GetFifo())
-
- def _WatchFifo(self, device, timeout, logfile=None):
- for i in range(100):
- if device.FileExists(self._GetFifo()):
- logging.info('Fifo created. Slept for %f secs' % (i * 0.5))
- break
- time.sleep(0.5)
- else:
- raise device_errors.DeviceUnreachableError(
- 'Unable to find fifo on device %s ' % self._GetFifo())
- args = shlex.split(device.old_interface.Adb()._target_arg)
- args += ['shell', 'cat', self._GetFifo()]
- return pexpect.spawn('adb', args, timeout=timeout, logfile=logfile)
-
- def _StartActivity(self, device, force_stop=True):
- device.StartActivity(
- intent.Intent(package=self._package_info.package,
- activity=self._package_info.activity,
- action='android.intent.action.MAIN',
- extras=self._extras),
- # No wait since the runner waits for FIFO creation anyway.
- blocking=False,
- force_stop=force_stop)
-
- #override
- def ClearApplicationState(self, device):
- device.ClearApplicationState(self._package_info.package)
- # Content shell creates a profile on the sdscard which accumulates cache
- # files over time.
- if self.suite_name == 'content_browsertests':
- try:
- device.RunShellCommand(
- 'rm -r %s/content_shell' % device.GetExternalStoragePath(),
- timeout=60 * 2)
- except device_errors.CommandFailedError:
- # TODO(jbudorick) Handle this exception appropriately once the
- # conversions are done.
- pass
- elif self.suite_name == 'components_browsertests':
- try:
- device.RunShellCommand(
- 'rm -r %s/components_shell' % device.GetExternalStoragePath(),
- timeout=60 * 2)
- except device_errors.CommandFailedError:
- # TODO(jbudorick) Handle this exception appropriately once the
- # conversions are done.
- pass
-
- #override
- def CreateCommandLineFileOnDevice(self, device, test_filter, test_arguments):
- self._CreateCommandLineFileOnDevice(
- device, '--gtest_filter=%s %s' % (test_filter, test_arguments))
-
- #override
- def GetAllTests(self, device):
- self._CreateCommandLineFileOnDevice(device, '--gtest_list_tests')
- try:
- self.tool.SetupEnvironment()
- # Clear and start monitoring logcat.
- self._ClearFifo(device)
- self._StartActivity(device)
- # Wait for native test to complete.
- p = self._WatchFifo(device, timeout=30 * self.tool.GetTimeoutScale())
- p.expect('<<ScopedMainEntryLogger')
- p.close()
- finally:
- self.tool.CleanUpEnvironment()
- # We need to strip the trailing newline.
- content = [line.rstrip() for line in p.before.splitlines()]
- return gtest_test_instance.ParseGTestListTests(content)
-
- #override
- def SpawnTestProcess(self, device):
- try:
- self.tool.SetupEnvironment()
- self._ClearFifo(device)
- # Doesn't need to stop an Activity because ClearApplicationState() is
- # always called before this call and so it is already stopped at this
- # point.
- self._StartActivity(device, force_stop=False)
- finally:
- self.tool.CleanUpEnvironment()
- logfile = android_commands.NewLineNormalizer(sys.stdout)
- return self._WatchFifo(device, timeout=10, logfile=logfile)
-
- #override
- def Install(self, device):
- self.tool.CopyFiles(device)
- device.Install(self.suite_path)
-
- #override
- def PullAppFiles(self, device, files, directory):
- local_device_gtest_run.PullAppFilesImpl(
- device, self._package_info.package, files, directory)
diff --git a/build/android/pylib/gtest/test_package_exe.py b/build/android/pylib/gtest/test_package_exe.py
deleted file mode 100644
index 87071b5..0000000
--- a/build/android/pylib/gtest/test_package_exe.py
+++ /dev/null
@@ -1,163 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Defines TestPackageExecutable to help run stand-alone executables."""
-
-import logging
-import os
-import posixpath
-import sys
-import tempfile
-
-from pylib import cmd_helper
-from pylib import constants
-from pylib import pexpect
-from pylib.device import device_errors
-from pylib.gtest import gtest_test_instance
-from pylib.gtest.test_package import TestPackage
-
-
-class TestPackageExecutable(TestPackage):
- """A helper class for running stand-alone executables."""
-
- _TEST_RUNNER_RET_VAL_FILE = 'gtest_retval'
-
- def __init__(self, suite_name):
- """
- Args:
- suite_name: Name of the test suite (e.g. base_unittests).
- """
- TestPackage.__init__(self, suite_name)
- self.suite_path = os.path.join(constants.GetOutDirectory(), suite_name)
- self._symbols_dir = os.path.join(constants.GetOutDirectory(),
- 'lib.target')
-
- #override
- def GetGTestReturnCode(self, device):
- ret = None
- ret_code = 1 # Assume failure if we can't find it
- ret_code_file = tempfile.NamedTemporaryFile()
- try:
- if not device.PullFile(
- constants.TEST_EXECUTABLE_DIR + '/' +
- TestPackageExecutable._TEST_RUNNER_RET_VAL_FILE,
- ret_code_file.name):
- logging.critical('Unable to pull gtest ret val file %s',
- ret_code_file.name)
- raise ValueError
- ret_code = file(ret_code_file.name).read()
- ret = int(ret_code)
- except ValueError:
- logging.critical('Error reading gtest ret val file %s [%s]',
- ret_code_file.name, ret_code)
- ret = 1
- return ret
-
- @staticmethod
- def _AddNativeCoverageExports(device):
- # export GCOV_PREFIX set the path for native coverage results
- # export GCOV_PREFIX_STRIP indicates how many initial directory
- # names to strip off the hardwired absolute paths.
- # This value is calculated in buildbot.sh and
- # depends on where the tree is built.
- # Ex: /usr/local/google/code/chrome will become
- # /code/chrome if GCOV_PREFIX_STRIP=3
- try:
- depth = os.environ['NATIVE_COVERAGE_DEPTH_STRIP']
- export_string = ('export GCOV_PREFIX="%s/gcov"\n' %
- device.GetExternalStoragePath())
- export_string += 'export GCOV_PREFIX_STRIP=%s\n' % depth
- return export_string
- except KeyError:
- logging.info('NATIVE_COVERAGE_DEPTH_STRIP is not defined: '
- 'No native coverage.')
- return ''
- except device_errors.CommandFailedError:
- logging.info('No external storage found: No native coverage.')
- return ''
-
- #override
- def ClearApplicationState(self, device):
- device.KillAll(self.suite_name, blocking=True, timeout=30, quiet=True)
-
- #override
- def CreateCommandLineFileOnDevice(self, device, test_filter, test_arguments):
- tool_wrapper = self.tool.GetTestWrapper()
- sh_script_file = tempfile.NamedTemporaryFile()
- # We need to capture the exit status from the script since adb shell won't
- # propagate to us.
- sh_script_file.write(
- 'cd %s\n'
- '%s'
- '%s LD_LIBRARY_PATH=%s/%s_deps %s/%s --gtest_filter=%s %s\n'
- 'echo $? > %s' %
- (constants.TEST_EXECUTABLE_DIR,
- self._AddNativeCoverageExports(device),
- tool_wrapper,
- constants.TEST_EXECUTABLE_DIR,
- self.suite_name,
- constants.TEST_EXECUTABLE_DIR,
- self.suite_name,
- test_filter, test_arguments,
- TestPackageExecutable._TEST_RUNNER_RET_VAL_FILE))
- sh_script_file.flush()
- cmd_helper.RunCmd(['chmod', '+x', sh_script_file.name])
- device.PushChangedFiles([(
- sh_script_file.name,
- constants.TEST_EXECUTABLE_DIR + '/chrome_test_runner.sh')])
- logging.info('Conents of the test runner script: ')
- for line in open(sh_script_file.name).readlines():
- logging.info(' ' + line.rstrip())
-
- #override
- def GetAllTests(self, device):
- lib_path = posixpath.join(
- constants.TEST_EXECUTABLE_DIR, '%s_deps' % self.suite_name)
-
- cmd = []
- if self.tool.GetTestWrapper():
- cmd.append(self.tool.GetTestWrapper())
- cmd.extend([
- posixpath.join(constants.TEST_EXECUTABLE_DIR, self.suite_name),
- '--gtest_list_tests'])
-
- output = device.RunShellCommand(
- cmd, check_return=True, env={'LD_LIBRARY_PATH': lib_path})
- return gtest_test_instance.ParseGTestListTests(output)
-
- #override
- def SpawnTestProcess(self, device):
- args = ['adb', '-s', str(device), 'shell', 'sh',
- constants.TEST_EXECUTABLE_DIR + '/chrome_test_runner.sh']
- logging.info(args)
- return pexpect.spawn(args[0], args[1:], logfile=sys.stdout)
-
- #override
- def Install(self, device):
- if self.tool.NeedsDebugInfo():
- target_name = self.suite_path
- else:
- target_name = self.suite_path + '_stripped'
- if not os.path.isfile(target_name):
- raise Exception('Did not find %s, build target %s' %
- (target_name, self.suite_name + '_stripped'))
-
- target_mtime = os.stat(target_name).st_mtime
- source_mtime = os.stat(self.suite_path).st_mtime
- if target_mtime < source_mtime:
- raise Exception(
- 'stripped binary (%s, timestamp %d) older than '
- 'source binary (%s, timestamp %d), build target %s' %
- (target_name, target_mtime, self.suite_path, source_mtime,
- self.suite_name + '_stripped'))
-
- test_binary_path = constants.TEST_EXECUTABLE_DIR + '/' + self.suite_name
- device.PushChangedFiles([(target_name, test_binary_path)])
- deps_path = self.suite_path + '_deps'
- if os.path.isdir(deps_path):
- device.PushChangedFiles([(deps_path, test_binary_path + '_deps')])
-
- #override
- def PullAppFiles(self, device, files, directory):
- pass
diff --git a/build/android/pylib/gtest/test_runner.py b/build/android/pylib/gtest/test_runner.py
deleted file mode 100644
index a48f18a..0000000
--- a/build/android/pylib/gtest/test_runner.py
+++ /dev/null
@@ -1,217 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import os
-import re
-import tempfile
-
-from pylib import pexpect
-from pylib import ports
-from pylib.base import base_test_result
-from pylib.base import base_test_runner
-from pylib.device import device_errors
-from pylib.gtest import gtest_test_instance
-from pylib.local import local_test_server_spawner
-from pylib.perf import perf_control
-
-# Test case statuses.
-RE_RUN = re.compile('\\[ RUN \\] ?(.*)\r\n')
-RE_FAIL = re.compile('\\[ FAILED \\] ?(.*?)( \\((\\d+) ms\\))?\r\r\n')
-RE_OK = re.compile('\\[ OK \\] ?(.*?)( \\((\\d+) ms\\))?\r\r\n')
-
-# Test run statuses.
-RE_PASSED = re.compile('\\[ PASSED \\] ?(.*)\r\n')
-RE_RUNNER_FAIL = re.compile('\\[ RUNNER_FAILED \\] ?(.*)\r\n')
-# Signal handlers are installed before starting tests
-# to output the CRASHED marker when a crash happens.
-RE_CRASH = re.compile('\\[ CRASHED \\](.*)\r\n')
-
-# Bots that don't output anything for 20 minutes get timed out, so that's our
-# hard cap.
-_INFRA_STDOUT_TIMEOUT = 20 * 60
-
-
-def _TestSuiteRequiresMockTestServer(suite_name):
- """Returns True if the test suite requires mock test server."""
- tests_require_net_test_server = ['unit_tests', 'net_unittests',
- 'components_browsertests',
- 'content_unittests',
- 'content_browsertests']
- return (suite_name in
- tests_require_net_test_server)
-
-def _TestSuiteRequiresHighPerfMode(suite_name):
- """Returns True if the test suite requires high performance mode."""
- return 'perftests' in suite_name
-
-class TestRunner(base_test_runner.BaseTestRunner):
- def __init__(self, test_options, device, test_package):
- """Single test suite attached to a single device.
-
- Args:
- test_options: A GTestOptions object.
- device: Device to run the tests.
- test_package: An instance of TestPackage class.
- """
-
- super(TestRunner, self).__init__(device, test_options.tool)
-
- self.test_package = test_package
- self.test_package.tool = self.tool
- self._test_arguments = test_options.test_arguments
-
- timeout = test_options.timeout
- if timeout == 0:
- timeout = 60
- # On a VM (e.g. chromium buildbots), this timeout is way too small.
- if os.environ.get('BUILDBOT_SLAVENAME'):
- timeout = timeout * 2
-
- self._timeout = min(timeout * self.tool.GetTimeoutScale(),
- _INFRA_STDOUT_TIMEOUT)
- if _TestSuiteRequiresHighPerfMode(self.test_package.suite_name):
- self._perf_controller = perf_control.PerfControl(self.device)
-
- if _TestSuiteRequiresMockTestServer(self.test_package.suite_name):
- self._servers = [
- local_test_server_spawner.LocalTestServerSpawner(
- ports.AllocateTestServerPort(), self.device, self.tool)]
- else:
- self._servers = []
-
- if test_options.app_data_files:
- self._app_data_files = test_options.app_data_files
- if test_options.app_data_file_dir:
- self._app_data_file_dir = test_options.app_data_file_dir
- else:
- self._app_data_file_dir = tempfile.mkdtemp()
- logging.critical('Saving app files to %s', self._app_data_file_dir)
- else:
- self._app_data_files = None
- self._app_data_file_dir = None
-
- #override
- def InstallTestPackage(self):
- self.test_package.Install(self.device)
-
- def _ParseTestOutput(self, p):
- """Process the test output.
-
- Args:
- p: An instance of pexpect spawn class.
-
- Returns:
- A TestRunResults object.
- """
- results = base_test_result.TestRunResults()
-
- log = ''
- try:
- while True:
- full_test_name = None
-
- found = p.expect([RE_RUN, RE_PASSED, RE_RUNNER_FAIL],
- timeout=self._timeout)
- if found == 1: # RE_PASSED
- break
- elif found == 2: # RE_RUNNER_FAIL
- break
- else: # RE_RUN
- full_test_name = p.match.group(1).replace('\r', '')
- found = p.expect([RE_OK, RE_FAIL, RE_CRASH], timeout=self._timeout)
- log = p.before.replace('\r', '')
- if found == 0: # RE_OK
- if full_test_name == p.match.group(1).replace('\r', ''):
- duration_ms = int(p.match.group(3)) if p.match.group(3) else 0
- results.AddResult(base_test_result.BaseTestResult(
- full_test_name, base_test_result.ResultType.PASS,
- duration=duration_ms, log=log))
- elif found == 2: # RE_CRASH
- results.AddResult(base_test_result.BaseTestResult(
- full_test_name, base_test_result.ResultType.CRASH,
- log=log))
- break
- else: # RE_FAIL
- duration_ms = int(p.match.group(3)) if p.match.group(3) else 0
- results.AddResult(base_test_result.BaseTestResult(
- full_test_name, base_test_result.ResultType.FAIL,
- duration=duration_ms, log=log))
- except pexpect.EOF:
- logging.error('Test terminated - EOF')
- # We're here because either the device went offline, or the test harness
- # crashed without outputting the CRASHED marker (crbug.com/175538).
- if not self.device.IsOnline():
- raise device_errors.DeviceUnreachableError(
- 'Device %s went offline.' % str(self.device))
- if full_test_name:
- results.AddResult(base_test_result.BaseTestResult(
- full_test_name, base_test_result.ResultType.CRASH,
- log=p.before.replace('\r', '')))
- except pexpect.TIMEOUT:
- logging.error('Test terminated after %d second timeout.',
- self._timeout)
- if full_test_name:
- results.AddResult(base_test_result.BaseTestResult(
- full_test_name, base_test_result.ResultType.TIMEOUT,
- log=p.before.replace('\r', '')))
- finally:
- p.close()
-
- ret_code = self.test_package.GetGTestReturnCode(self.device)
- if ret_code:
- logging.critical(
- 'gtest exit code: %d\npexpect.before: %s\npexpect.after: %s',
- ret_code, p.before, p.after)
-
- return results
-
- #override
- def RunTest(self, test):
- test_results = base_test_result.TestRunResults()
- if not test:
- return test_results, None
-
- try:
- self.test_package.ClearApplicationState(self.device)
- self.test_package.CreateCommandLineFileOnDevice(
- self.device, test, self._test_arguments)
- test_results = self._ParseTestOutput(
- self.test_package.SpawnTestProcess(self.device))
- if self._app_data_files:
- self.test_package.PullAppFiles(self.device, self._app_data_files,
- self._app_data_file_dir)
- finally:
- for s in self._servers:
- s.Reset()
- # Calculate unknown test results.
- all_tests = set(test.split(':'))
- all_tests_ran = set([t.GetName() for t in test_results.GetAll()])
- unknown_tests = all_tests - all_tests_ran
- test_results.AddResults(
- [base_test_result.BaseTestResult(t, base_test_result.ResultType.UNKNOWN)
- for t in unknown_tests])
- retry = ':'.join([t.GetName() for t in test_results.GetNotPass()])
- return test_results, retry
-
- #override
- def SetUp(self):
- """Sets up necessary test enviroment for the test suite."""
- super(TestRunner, self).SetUp()
- for s in self._servers:
- s.SetUp()
- if _TestSuiteRequiresHighPerfMode(self.test_package.suite_name):
- self._perf_controller.SetHighPerfMode()
- self.tool.SetupEnvironment()
-
- #override
- def TearDown(self):
- """Cleans up the test enviroment for the test suite."""
- for s in self._servers:
- s.TearDown()
- if _TestSuiteRequiresHighPerfMode(self.test_package.suite_name):
- self._perf_controller.SetDefaultPerfMode()
- self.test_package.ClearApplicationState(self.device)
- self.tool.CleanUpEnvironment()
- super(TestRunner, self).TearDown()
diff --git a/build/android/pylib/host_driven/__init__.py b/build/android/pylib/host_driven/__init__.py
deleted file mode 100644
index 727e987..0000000
--- a/build/android/pylib/host_driven/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
diff --git a/build/android/pylib/host_driven/setup.py b/build/android/pylib/host_driven/setup.py
deleted file mode 100644
index b2ed348..0000000
--- a/build/android/pylib/host_driven/setup.py
+++ /dev/null
@@ -1,200 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Setup for instrumentation host-driven tests."""
-
-import logging
-import os
-import sys
-import types
-
-from pylib.host_driven import test_case
-from pylib.host_driven import test_info_collection
-from pylib.host_driven import test_runner
-
-
-def _GetPythonFiles(root, files):
- """Returns all files from |files| that end in 'Test.py'.
-
- Args:
- root: A directory name with python files.
- files: A list of file names.
-
- Returns:
- A list with all python files that match the testing naming scheme.
- """
- return [os.path.join(root, f) for f in files if f.endswith('Test.py')]
-
-
-def _InferImportNameFromFile(python_file):
- """Given a file, infer the import name for that file.
-
- Example: /usr/foo/bar/baz.py -> baz.
-
- Args:
- python_file: Path to the Python file, ostensibly to import later.
-
- Returns:
- The module name for the given file.
- """
- return os.path.splitext(os.path.basename(python_file))[0]
-
-
-def _GetTestModules(host_driven_test_root, is_official_build):
- """Retrieve a list of python modules that match the testing naming scheme.
-
- Walks the location of host-driven tests, imports them, and provides the list
- of imported modules to the caller.
-
- Args:
- host_driven_test_root: The path to walk, looking for the
- pythonDrivenTests or host_driven_tests directory
- is_official_build: Whether to run only those tests marked 'official'
-
- Returns:
- A list of python modules under |host_driven_test_root| which match the
- testing naming scheme. Each module should define one or more classes that
- derive from HostDrivenTestCase.
- """
- # By default run all host-driven tests under pythonDrivenTests or
- # host_driven_tests.
- host_driven_test_file_list = []
- for root, _, files in os.walk(host_driven_test_root):
- if (root.endswith('host_driven_tests') or
- root.endswith('pythonDrivenTests') or
- (is_official_build and (root.endswith('pythonDrivenTests/official') or
- root.endswith('host_driven_tests/official')))):
- host_driven_test_file_list += _GetPythonFiles(root, files)
- host_driven_test_file_list.sort()
-
- test_module_list = [_GetModuleFromFile(test_file)
- for test_file in host_driven_test_file_list]
- return test_module_list
-
-
-def _GetModuleFromFile(python_file):
- """Gets the python module associated with a file by importing it.
-
- Args:
- python_file: File to import.
-
- Returns:
- The module object.
- """
- sys.path.append(os.path.dirname(python_file))
- import_name = _InferImportNameFromFile(python_file)
- return __import__(import_name)
-
-
-def _GetTestsFromClass(test_case_class, **kwargs):
- """Returns one test object for each test method in |test_case_class|.
-
- Test methods are methods on the class which begin with 'test'.
-
- Args:
- test_case_class: Class derived from HostDrivenTestCase which contains zero
- or more test methods.
- kwargs: Keyword args to pass into the constructor of test cases.
-
- Returns:
- A list of test case objects, each initialized for a particular test method.
- """
- test_names = [m for m in dir(test_case_class)
- if _IsTestMethod(m, test_case_class)]
- return [test_case_class(name, **kwargs) for name in test_names]
-
-
-def _GetTestsFromModule(test_module, **kwargs):
- """Gets a list of test objects from |test_module|.
-
- Args:
- test_module: Module from which to get the set of test methods.
- kwargs: Keyword args to pass into the constructor of test cases.
-
- Returns:
- A list of test case objects each initialized for a particular test method
- defined in |test_module|.
- """
-
- tests = []
- for name in dir(test_module):
- attr = getattr(test_module, name)
- if _IsTestCaseClass(attr):
- tests.extend(_GetTestsFromClass(attr, **kwargs))
- return tests
-
-
-def _IsTestCaseClass(test_class):
- return (type(test_class) is types.TypeType and
- issubclass(test_class, test_case.HostDrivenTestCase) and
- test_class is not test_case.HostDrivenTestCase)
-
-
-def _IsTestMethod(attrname, test_case_class):
- """Checks whether this is a valid test method.
-
- Args:
- attrname: The method name.
- test_case_class: The test case class.
-
- Returns:
- True if test_case_class.'attrname' is callable and it starts with 'test';
- False otherwise.
- """
- attr = getattr(test_case_class, attrname)
- return callable(attr) and attrname.startswith('test')
-
-
-def _GetAllTests(test_root, is_official_build, **kwargs):
- """Retrieve a list of host-driven tests defined under |test_root|.
-
- Args:
- test_root: Path which contains host-driven test files.
- is_official_build: Whether this is an official build.
- kwargs: Keyword args to pass into the constructor of test cases.
-
- Returns:
- List of test case objects, one for each available test method.
- """
- if not test_root:
- return []
- all_tests = []
- test_module_list = _GetTestModules(test_root, is_official_build)
- for module in test_module_list:
- all_tests.extend(_GetTestsFromModule(module, **kwargs))
- return all_tests
-
-
-def InstrumentationSetup(host_driven_test_root, official_build,
- instrumentation_options):
- """Creates a list of host-driven instrumentation tests and a runner factory.
-
- Args:
- host_driven_test_root: Directory where the host-driven tests are.
- official_build: True if this is an official build.
- instrumentation_options: An InstrumentationOptions object.
-
- Returns:
- A tuple of (TestRunnerFactory, tests).
- """
-
- test_collection = test_info_collection.TestInfoCollection()
- all_tests = _GetAllTests(
- host_driven_test_root, official_build,
- instrumentation_options=instrumentation_options)
- test_collection.AddTests(all_tests)
-
- available_tests = test_collection.GetAvailableTests(
- instrumentation_options.annotations,
- instrumentation_options.exclude_annotations,
- instrumentation_options.test_filter)
- logging.debug('All available tests: ' + str(
- [t.tagged_name for t in available_tests]))
-
- def TestRunnerFactory(device, shard_index):
- return test_runner.HostDrivenTestRunner(
- device, shard_index,
- instrumentation_options.tool)
-
- return (TestRunnerFactory, available_tests)
diff --git a/build/android/pylib/host_driven/test_case.py b/build/android/pylib/host_driven/test_case.py
deleted file mode 100644
index 6ff4c5f..0000000
--- a/build/android/pylib/host_driven/test_case.py
+++ /dev/null
@@ -1,189 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Base class for host-driven test cases.
-
-This test case is intended to serve as the base class for any host-driven
-test cases. It is similar to the Python unitttest module in that test cases
-inherit from this class and add methods which will be run as tests.
-
-When a HostDrivenTestCase object is instantiated, its purpose is to run only one
-test method in the derived class. The test runner gives it the name of the test
-method the instance will run. The test runner calls SetUp with the device ID
-which the test method will run against. The test runner runs the test method
-itself, collecting the result, and calls TearDown.
-
-Tests can perform arbitrary Python commands and asserts in test methods. Tests
-that run instrumentation tests can make use of the _RunJavaTestFilters helper
-function to trigger Java tests and convert results into a single host-driven
-test result.
-"""
-
-import logging
-import os
-import time
-
-from pylib import constants
-from pylib import forwarder
-from pylib import valgrind_tools
-from pylib.base import base_test_result
-from pylib.device import device_utils
-from pylib.instrumentation import test_package
-from pylib.instrumentation import test_result
-from pylib.instrumentation import test_runner
-
-# aka the parent of com.google.android
-BASE_ROOT = 'src' + os.sep
-
-
-class HostDrivenTestCase(object):
- """Base class for host-driven test cases."""
-
- _HOST_DRIVEN_TAG = 'HostDriven'
-
- def __init__(self, test_name, instrumentation_options=None):
- """Create a test case initialized to run |test_name|.
-
- Args:
- test_name: The name of the method to run as the test.
- instrumentation_options: An InstrumentationOptions object.
- """
- class_name = self.__class__.__name__
- self.device = None
- self.device_id = ''
- self.has_forwarded_ports = False
- self.instrumentation_options = instrumentation_options
- self.ports_to_forward = []
- self.shard_index = 0
-
- # Use tagged_name when creating results, so that we can identify host-driven
- # tests in the overall results.
- self.test_name = test_name
- self.qualified_name = '%s.%s' % (class_name, self.test_name)
- self.tagged_name = '%s_%s' % (self._HOST_DRIVEN_TAG, self.qualified_name)
-
- # TODO(bulach): make ports_to_forward not optional and move the Forwarder
- # mapping here.
- def SetUp(self, device, shard_index, ports_to_forward=None):
- if not ports_to_forward:
- ports_to_forward = []
- self.device = device
- self.shard_index = shard_index
- self.device_id = str(self.device)
- if ports_to_forward:
- self.ports_to_forward = ports_to_forward
-
- def TearDown(self):
- pass
-
- # TODO(craigdh): Remove GetOutDir once references have been removed
- # downstream.
- @staticmethod
- def GetOutDir():
- return constants.GetOutDirectory()
-
- def Run(self):
- logging.info('Running host-driven test: %s', self.tagged_name)
- # Get the test method on the derived class and execute it
- return getattr(self, self.test_name)()
-
- @staticmethod
- def __GetHostForwarderLog():
- return ('-- Begin Full HostForwarder log\n'
- '%s\n'
- '--End Full HostForwarder log\n' % forwarder.Forwarder.GetHostLog())
-
- def __StartForwarder(self):
- logging.warning('Forwarding %s %s', self.ports_to_forward,
- self.has_forwarded_ports)
- if self.ports_to_forward and not self.has_forwarded_ports:
- self.has_forwarded_ports = True
- tool = valgrind_tools.CreateTool(None, self.device)
- forwarder.Forwarder.Map([(port, port) for port in self.ports_to_forward],
- self.device, tool)
-
- def __RunJavaTest(self, test, test_pkg, additional_flags=None):
- """Runs a single Java test in a Java TestRunner.
-
- Args:
- test: Fully qualified test name (ex. foo.bar.TestClass#testMethod)
- test_pkg: TestPackage object.
- additional_flags: A list of additional flags to add to the command line.
-
- Returns:
- TestRunResults object with a single test result.
- """
- # TODO(bulach): move this to SetUp() stage.
- self.__StartForwarder()
-
- java_test_runner = test_runner.TestRunner(
- self.instrumentation_options, self.device, self.shard_index,
- test_pkg, additional_flags=additional_flags)
- try:
- java_test_runner.SetUp()
- return java_test_runner.RunTest(test)[0]
- finally:
- java_test_runner.TearDown()
-
- def _RunJavaTestFilters(self, test_filters, additional_flags=None):
- """Calls a list of tests and stops at the first test failure.
-
- This method iterates until either it encounters a non-passing test or it
- exhausts the list of tests. Then it returns the appropriate overall result.
-
- Test cases may make use of this method internally to assist in running
- instrumentation tests. This function relies on instrumentation_options
- being defined.
-
- Args:
- test_filters: A list of Java test filters.
- additional_flags: A list of addition flags to add to the command line.
-
- Returns:
- A TestRunResults object containing an overall result for this set of Java
- tests. If any Java tests do not pass, this is a fail overall.
- """
- test_type = base_test_result.ResultType.PASS
- log = ''
-
- test_pkg = test_package.TestPackage(
- self.instrumentation_options.test_apk_path,
- self.instrumentation_options.test_apk_jar_path,
- self.instrumentation_options.test_support_apk_path)
-
- start_ms = int(time.time()) * 1000
- done = False
- for test_filter in test_filters:
- tests = test_pkg.GetAllMatchingTests(None, None, test_filter)
- # Filters should always result in >= 1 test.
- if len(tests) == 0:
- raise Exception('Java test filter "%s" returned no tests.'
- % test_filter)
- for test in tests:
- # We're only running one test at a time, so this TestRunResults object
- # will hold only one result.
- java_result = self.__RunJavaTest(test, test_pkg, additional_flags)
- assert len(java_result.GetAll()) == 1
- if not java_result.DidRunPass():
- result = java_result.GetNotPass().pop()
- log = result.GetLog()
- log += self.__GetHostForwarderLog()
- test_type = result.GetType()
- done = True
- break
- if done:
- break
- duration_ms = int(time.time()) * 1000 - start_ms
-
- overall_result = base_test_result.TestRunResults()
- overall_result.AddResult(
- test_result.InstrumentationTestResult(
- self.tagged_name, test_type, start_ms, duration_ms, log=log))
- return overall_result
-
- def __str__(self):
- return self.tagged_name
-
- def __repr__(self):
- return self.tagged_name
diff --git a/build/android/pylib/host_driven/test_info_collection.py b/build/android/pylib/host_driven/test_info_collection.py
deleted file mode 100644
index c65d417..0000000
--- a/build/android/pylib/host_driven/test_info_collection.py
+++ /dev/null
@@ -1,144 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Module containing information about the host-driven tests."""
-
-import logging
-import os
-import sys
-
-from pylib.host_driven import tests_annotations
-
-from pylib import constants
-
-sys.path.insert(0,
- os.path.join(constants.DIR_SOURCE_ROOT,
- 'build', 'util', 'lib', 'common'))
-
-import unittest_util # pylint: disable=F0401
-
-class TestInfo(object):
- """An object containing and representing a test function, plus metadata."""
-
- def __init__(self, runnable, set_up=None, tear_down=None):
- # The actual test function/method.
- self.runnable = runnable
- # Qualified name of test function/method (e.g. FooModule.testBar).
- self.qualified_name = self._GetQualifiedName(runnable)
- # setUp and teardown functions, if any.
- self.set_up = set_up
- self.tear_down = tear_down
-
- @staticmethod
- def _GetQualifiedName(runnable):
- """Helper method to infer a runnable's name and module name.
-
- Many filters and lists presuppose a format of module_name.testMethodName.
- To make this easy on everyone, we use some reflection magic to infer this
- name automatically.
-
- Args:
- runnable: the test method to get the qualified name for
-
- Returns:
- qualified name for this runnable, incl. module name and method name.
- """
- runnable_name = runnable.__name__
- # See also tests_annotations.
- module_name = os.path.splitext(
- os.path.basename(runnable.__globals__['__file__']))[0]
- return '.'.join([module_name, runnable_name])
-
- def __str__(self):
- return self.qualified_name
-
-
-class TestInfoCollection(object):
- """A collection of TestInfo objects which facilitates filtering."""
-
- def __init__(self):
- """Initialize a new TestInfoCollection."""
- # Master list of all valid tests.
- self.all_tests = []
-
- def AddTests(self, test_infos):
- """Adds a set of tests to this collection.
-
- The user may then retrieve them, optionally according to criteria, via
- GetAvailableTests().
-
- Args:
- test_infos: a list of TestInfos representing test functions/methods.
- """
- self.all_tests = test_infos
-
- def GetAvailableTests(self, annotations, exclude_annotations, name_filter):
- """Get a collection of TestInfos which match the supplied criteria.
-
- Args:
- annotations: List of annotations. Each test in the returned list is
- annotated with atleast one of these annotations.
- exclude_annotations: List of annotations. The tests in the returned
- list are not annotated with any of these annotations.
- name_filter: name filter which tests must match, if any
-
- Returns:
- List of available tests.
- """
- available_tests = self.all_tests
-
- # Filter out tests which match neither the requested annotation, nor the
- # requested name filter, if any.
- available_tests = [t for t in available_tests if
- self._AnnotationIncludesTest(t, annotations)]
- if annotations and len(annotations) == 1 and annotations[0] == 'SmallTest':
- tests_without_annotation = [
- t for t in self.all_tests if
- not tests_annotations.AnnotatedFunctions.GetTestAnnotations(
- t.qualified_name)]
- test_names = [t.qualified_name for t in tests_without_annotation]
- logging.warning('The following tests do not contain any annotation. '
- 'Assuming "SmallTest":\n%s',
- '\n'.join(test_names))
- available_tests += tests_without_annotation
- if exclude_annotations:
- excluded_tests = [t for t in available_tests if
- self._AnnotationIncludesTest(t, exclude_annotations)]
- available_tests = list(set(available_tests) - set(excluded_tests))
-
- if name_filter:
- available_test_names = unittest_util.FilterTestNames(
- [t.qualified_name for t in available_tests], name_filter)
- available_tests = [
- t for t in available_tests if
- t.qualified_name in available_test_names]
- return available_tests
-
- @staticmethod
- def _AnnotationIncludesTest(test_info, annotation_filter_list):
- """Checks whether a given test represented by test_info matches annotation.
-
- Args:
- test_info: TestInfo object representing the test
- annotation_filter_list: list of annotation filters to match (e.g. Smoke)
-
- Returns:
- True if no annotation was supplied or the test matches; false otherwise.
- """
- if not annotation_filter_list:
- return True
- for annotation_filter in annotation_filter_list:
- filters = annotation_filter.split('=')
- if len(filters) == 2:
- key = filters[0]
- value_list = filters[1].split(',')
- for value in value_list:
- if tests_annotations.AnnotatedFunctions.IsAnnotated(
- key + ':' + value, test_info.qualified_name):
- return True
- elif tests_annotations.AnnotatedFunctions.IsAnnotated(
- annotation_filter, test_info.qualified_name):
- return True
- return False
-
diff --git a/build/android/pylib/host_driven/test_runner.py b/build/android/pylib/host_driven/test_runner.py
deleted file mode 100644
index 8620aa1..0000000
--- a/build/android/pylib/host_driven/test_runner.py
+++ /dev/null
@@ -1,133 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Runs host-driven tests on a particular device."""
-
-import logging
-import sys
-import time
-import traceback
-
-from pylib.base import base_test_result
-from pylib.base import base_test_runner
-from pylib.host_driven import test_case
-from pylib.instrumentation import test_result
-
-
-class HostDrivenExceptionTestResult(test_result.InstrumentationTestResult):
- """Test result corresponding to a python exception in a host-driven test."""
-
- def __init__(self, test_name, start_date_ms, exc_info):
- """Constructs a HostDrivenExceptionTestResult object.
-
- Args:
- test_name: name of the test which raised an exception.
- start_date_ms: the starting time for the test.
- exc_info: exception info, ostensibly from sys.exc_info().
- """
- exc_type, exc_value, exc_traceback = exc_info
- trace_info = ''.join(traceback.format_exception(exc_type, exc_value,
- exc_traceback))
- log_msg = 'Exception:\n' + trace_info
- duration_ms = (int(time.time()) * 1000) - start_date_ms
-
- super(HostDrivenExceptionTestResult, self).__init__(
- test_name,
- base_test_result.ResultType.FAIL,
- start_date_ms,
- duration_ms,
- log=str(exc_type) + ' ' + log_msg)
-
-
-class HostDrivenTestRunner(base_test_runner.BaseTestRunner):
- """Orchestrates running a set of host-driven tests.
-
- Any Python exceptions in the tests are caught and translated into a failed
- result, rather than being re-raised on the main thread.
- """
-
- # TODO(jbudorick): Remove cleanup_test_files once it's no longer used.
- # pylint: disable=unused-argument
- #override
- def __init__(self, device, shard_index, tool, cleanup_test_files=None):
- """Creates a new HostDrivenTestRunner.
-
- Args:
- device: Attached android device.
- shard_index: Shard index.
- tool: Name of the Valgrind tool.
- cleanup_test_files: Deprecated.
- """
-
- super(HostDrivenTestRunner, self).__init__(device, tool)
-
- # The shard index affords the ability to create unique port numbers (e.g.
- # DEFAULT_PORT + shard_index) if the test so wishes.
- self.shard_index = shard_index
-
- # pylint: enable=unused-argument
-
- #override
- def RunTest(self, test):
- """Sets up and runs a test case.
-
- Args:
- test: An object which is ostensibly a subclass of HostDrivenTestCase.
-
- Returns:
- A TestRunResults object which contains the result produced by the test
- and, in the case of a failure, the test that should be retried.
- """
-
- assert isinstance(test, test_case.HostDrivenTestCase)
-
- start_date_ms = int(time.time()) * 1000
- exception_raised = False
-
- try:
- test.SetUp(self.device, self.shard_index)
- except Exception:
- logging.exception(
- 'Caught exception while trying to run SetUp() for test: ' +
- test.tagged_name)
- # Tests whose SetUp() method has failed are likely to fail, or at least
- # yield invalid results.
- exc_info = sys.exc_info()
- results = base_test_result.TestRunResults()
- results.AddResult(HostDrivenExceptionTestResult(
- test.tagged_name, start_date_ms, exc_info))
- return results, test
-
- try:
- results = test.Run()
- except Exception:
- # Setting this lets TearDown() avoid stomping on our stack trace from
- # Run() should TearDown() also raise an exception.
- exception_raised = True
- logging.exception('Caught exception while trying to run test: ' +
- test.tagged_name)
- exc_info = sys.exc_info()
- results = base_test_result.TestRunResults()
- results.AddResult(HostDrivenExceptionTestResult(
- test.tagged_name, start_date_ms, exc_info))
-
- try:
- test.TearDown()
- except Exception:
- logging.exception(
- 'Caught exception while trying run TearDown() for test: ' +
- test.tagged_name)
- if not exception_raised:
- # Don't stomp the error during the test if TearDown blows up. This is a
- # trade-off: if the test fails, this will mask any problem with TearDown
- # until the test is fixed.
- exc_info = sys.exc_info()
- results = base_test_result.TestRunResults()
- results.AddResult(HostDrivenExceptionTestResult(
- test.tagged_name, start_date_ms, exc_info))
-
- if not results.DidRunPass():
- return results, test
- else:
- return results, None
diff --git a/build/android/pylib/host_driven/test_server.py b/build/android/pylib/host_driven/test_server.py
deleted file mode 100644
index 0783500..0000000
--- a/build/android/pylib/host_driven/test_server.py
+++ /dev/null
@@ -1,130 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Host driven test server controller.
-
-This class controls the startup and shutdown of a python driven test server that
-runs in a separate process.
-
-The server starts up automatically when the object is created.
-
-After it starts up, it is possible to retreive the hostname it started on
-through accessing the member field |host| and the port name through |port|.
-
-For shutting down the server, call TearDown().
-"""
-
-import logging
-import subprocess
-import os
-import os.path
-import time
-import urllib2
-
-from pylib import constants
-
-# NOTE: when adding or modifying these lines, omit any leading slashes!
-# Otherwise os.path.join() will (correctly) treat them as absolute paths
-# instead of relative paths, and will do nothing.
-_PYTHONPATH_DIRS = [
- 'net/tools/testserver/',
- 'third_party/',
- 'third_party/pyftpdlib/src/',
- 'third_party/pywebsocket/src',
- 'third_party/tlslite/',
-]
-
-# Python files in these directories are generated as part of the build.
-# These dirs are located in out/(Debug|Release) directory.
-# The correct path is determined based on the build type. E.g. out/Debug for
-# debug builds and out/Release for release builds.
-_GENERATED_PYTHONPATH_DIRS = [
- 'pyproto/policy/proto/',
- 'pyproto/sync/protocol/',
- 'pyproto/'
-]
-
-_TEST_SERVER_HOST = '127.0.0.1'
-# Paths for supported test server executables.
-TEST_NET_SERVER_PATH = 'net/tools/testserver/testserver.py'
-TEST_SYNC_SERVER_PATH = 'sync/tools/testserver/sync_testserver.py'
-TEST_POLICY_SERVER_PATH = 'chrome/browser/policy/test/policy_testserver.py'
-# Parameters to check that the server is up and running.
-TEST_SERVER_CHECK_PARAMS = {
- TEST_NET_SERVER_PATH: {
- 'url_path': '/',
- 'response': 'Default response given for path'
- },
- TEST_SYNC_SERVER_PATH: {
- 'url_path': 'chromiumsync/time',
- 'response': '0123456789'
- },
- TEST_POLICY_SERVER_PATH: {
- 'url_path': 'test/ping',
- 'response': 'Policy server is up.'
- },
-}
-
-class TestServer(object):
- """Sets up a host driven test server on the host machine.
-
- For shutting down the server, call TearDown().
- """
-
- def __init__(self, shard_index, test_server_port, test_server_path,
- test_server_flags=None):
- """Sets up a Python driven test server on the host machine.
-
- Args:
- shard_index: Index of the current shard.
- test_server_port: Port to run the test server on. This is multiplexed with
- the shard index. To retrieve the real port access the
- member variable |port|.
- test_server_path: The path (relative to the root src dir) of the server
- test_server_flags: Optional list of additional flags to the test server
- """
- self.host = _TEST_SERVER_HOST
- self.port = test_server_port + shard_index
-
- src_dir = constants.DIR_SOURCE_ROOT
- # Make dirs into a list of absolute paths.
- abs_dirs = [os.path.join(src_dir, d) for d in _PYTHONPATH_DIRS]
- # Add the generated python files to the path
- abs_dirs.extend([os.path.join(src_dir, constants.GetOutDirectory(), d)
- for d in _GENERATED_PYTHONPATH_DIRS])
- current_python_path = os.environ.get('PYTHONPATH')
- extra_python_path = ':'.join(abs_dirs)
- if current_python_path:
- python_path = current_python_path + ':' + extra_python_path
- else:
- python_path = extra_python_path
-
- # NOTE: A separate python process is used to simplify getting the right
- # system path for finding includes.
- test_server_flags = test_server_flags or []
- cmd = ['python', os.path.join(src_dir, test_server_path),
- '--log-to-console',
- ('--host=%s' % self.host),
- ('--port=%d' % self.port),
- '--on-remote-server'] + test_server_flags
- self._test_server_process = subprocess.Popen(
- cmd, env={'PYTHONPATH': python_path})
- test_url = 'http://%s:%d/%s' % (self.host, self.port,
- TEST_SERVER_CHECK_PARAMS[test_server_path]['url_path'])
- expected_response = TEST_SERVER_CHECK_PARAMS[test_server_path]['response']
- retries = 0
- while retries < 5:
- try:
- d = urllib2.urlopen(test_url).read()
- logging.info('URL %s GOT: %s' % (test_url, d))
- if d.startswith(expected_response):
- break
- except Exception as e:
- logging.info('URL %s GOT: %s' % (test_url, e))
- time.sleep(retries * 0.1)
- retries += 1
-
- def TearDown(self):
- self._test_server_process.kill()
- self._test_server_process.wait()
diff --git a/build/android/pylib/host_driven/tests_annotations.py b/build/android/pylib/host_driven/tests_annotations.py
deleted file mode 100644
index 5331140..0000000
--- a/build/android/pylib/host_driven/tests_annotations.py
+++ /dev/null
@@ -1,94 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Annotations for host-driven tests."""
-# pylint: disable=W0212
-
-import os
-
-
-class AnnotatedFunctions(object):
- """A container for annotated methods."""
- _ANNOTATED = {}
-
- @staticmethod
- def _AddFunction(annotation, function):
- """Adds an annotated function to our container.
-
- Args:
- annotation: the annotation string.
- function: the function.
- Returns:
- The function passed in.
- """
- module_name = os.path.splitext(os.path.basename(
- function.__globals__['__file__']))[0]
- qualified_function_name = '.'.join([module_name, function.func_name])
- function_list = AnnotatedFunctions._ANNOTATED.get(annotation, [])
- function_list.append(qualified_function_name)
- AnnotatedFunctions._ANNOTATED[annotation] = function_list
- return function
-
- @staticmethod
- def IsAnnotated(annotation, qualified_function_name):
- """True if function name (module.function) contains the annotation.
-
- Args:
- annotation: the annotation string.
- qualified_function_name: the qualified function name.
- Returns:
- True if module.function contains the annotation.
- """
- return qualified_function_name in AnnotatedFunctions._ANNOTATED.get(
- annotation, [])
-
- @staticmethod
- def GetTestAnnotations(qualified_function_name):
- """Returns a list containing all annotations for the given function.
-
- Args:
- qualified_function_name: the qualified function name.
- Returns:
- List of all annotations for this function.
- """
- return [annotation
- for annotation, tests in AnnotatedFunctions._ANNOTATED.iteritems()
- if qualified_function_name in tests]
-
-
-# The following functions are annotations used for the host-driven tests.
-def Smoke(function):
- return AnnotatedFunctions._AddFunction('Smoke', function)
-
-
-def SmallTest(function):
- return AnnotatedFunctions._AddFunction('SmallTest', function)
-
-
-def MediumTest(function):
- return AnnotatedFunctions._AddFunction('MediumTest', function)
-
-
-def LargeTest(function):
- return AnnotatedFunctions._AddFunction('LargeTest', function)
-
-
-def EnormousTest(function):
- return AnnotatedFunctions._AddFunction('EnormousTest', function)
-
-
-def FlakyTest(function):
- return AnnotatedFunctions._AddFunction('FlakyTest', function)
-
-
-def DisabledTest(function):
- return AnnotatedFunctions._AddFunction('DisabledTest', function)
-
-
-def Feature(feature_list):
- def _AddFeatures(function):
- for feature in feature_list:
- AnnotatedFunctions._AddFunction('Feature:%s' % feature, function)
- return AnnotatedFunctions._AddFunction('Feature', function)
- return _AddFeatures
diff --git a/build/android/pylib/instrumentation/__init__.py b/build/android/pylib/instrumentation/__init__.py
deleted file mode 100644
index 727e987..0000000
--- a/build/android/pylib/instrumentation/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
diff --git a/build/android/pylib/instrumentation/instrumentation_parser.py b/build/android/pylib/instrumentation/instrumentation_parser.py
deleted file mode 100644
index 1859f14..0000000
--- a/build/android/pylib/instrumentation/instrumentation_parser.py
+++ /dev/null
@@ -1,96 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import re
-
-# http://developer.android.com/reference/android/test/InstrumentationTestRunner.html
-STATUS_CODE_START = 1
-STATUS_CODE_OK = 0
-STATUS_CODE_ERROR = -1
-STATUS_CODE_FAILURE = -2
-
-# http://developer.android.com/reference/android/app/Activity.html
-RESULT_CODE_OK = -1
-RESULT_CODE_CANCELED = 0
-
-_INSTR_LINE_RE = re.compile('^\s*INSTRUMENTATION_([A-Z_]+): (.*)$')
-
-
-class InstrumentationParser(object):
-
- def __init__(self, stream):
- """An incremental parser for the output of Android instrumentation tests.
-
- Example:
-
- stream = adb.IterShell('am instrument -r ...')
- parser = InstrumentationParser(stream)
-
- for code, bundle in parser.IterStatus():
- # do something with each instrumentation status
- print 'status:', code, bundle
-
- # do something with the final instrumentation result
- code, bundle = parser.GetResult()
- print 'result:', code, bundle
-
- Args:
- stream: a sequence of lines as produced by the raw output of an
- instrumentation test (e.g. by |am instrument -r| or |uiautomator|).
- """
- self._stream = stream
- self._code = None
- self._bundle = None
-
- def IterStatus(self):
- """Iterate over statuses as they are produced by the instrumentation test.
-
- Yields:
- A tuple (code, bundle) for each instrumentation status found in the
- output.
- """
- def join_bundle_values(bundle):
- for key in bundle:
- bundle[key] = '\n'.join(bundle[key])
- return bundle
-
- bundle = {'STATUS': {}, 'RESULT': {}}
- header = None
- key = None
- for line in self._stream:
- m = _INSTR_LINE_RE.match(line)
- if m:
- header, value = m.groups()
- key = None
- if header in ['STATUS', 'RESULT'] and '=' in value:
- key, value = value.split('=', 1)
- bundle[header][key] = [value]
- elif header == 'STATUS_CODE':
- yield int(value), join_bundle_values(bundle['STATUS'])
- bundle['STATUS'] = {}
- elif header == 'CODE':
- self._code = int(value)
- else:
- logging.warning('Unknown INSTRUMENTATION_%s line: %s', header, value)
- elif key is not None:
- bundle[header][key].append(line)
-
- self._bundle = join_bundle_values(bundle['RESULT'])
-
- def GetResult(self):
- """Return the final instrumentation result.
-
- Returns:
- A pair (code, bundle) with the final instrumentation result. The |code|
- may be None if no instrumentation result was found in the output.
-
- Raises:
- AssertionError if attempting to get the instrumentation result before
- exhausting |IterStatus| first.
- """
- assert self._bundle is not None, (
- 'The IterStatus generator must be exhausted before reading the final'
- ' instrumentation result.')
- return self._code, self._bundle
diff --git a/build/android/pylib/instrumentation/instrumentation_parser_test.py b/build/android/pylib/instrumentation/instrumentation_parser_test.py
deleted file mode 100755
index 092d10f..0000000
--- a/build/android/pylib/instrumentation/instrumentation_parser_test.py
+++ /dev/null
@@ -1,134 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-
-"""Unit tests for instrumentation.InstrumentationParser."""
-
-import unittest
-
-from pylib.instrumentation import instrumentation_parser
-
-
-class InstrumentationParserTest(unittest.TestCase):
-
- def testInstrumentationParser_nothing(self):
- parser = instrumentation_parser.InstrumentationParser([''])
- statuses = list(parser.IterStatus())
- code, bundle = parser.GetResult()
- self.assertEqual(None, code)
- self.assertEqual({}, bundle)
- self.assertEqual([], statuses)
-
- def testInstrumentationParser_noMatchingStarts(self):
- raw_output = [
- '',
- 'this.is.a.test.package.TestClass:.',
- 'Test result for =.',
- 'Time: 1.234',
- '',
- 'OK (1 test)',
- ]
-
- parser = instrumentation_parser.InstrumentationParser(raw_output)
- statuses = list(parser.IterStatus())
- code, bundle = parser.GetResult()
- self.assertEqual(None, code)
- self.assertEqual({}, bundle)
- self.assertEqual([], statuses)
-
- def testInstrumentationParser_resultAndCode(self):
- raw_output = [
- 'INSTRUMENTATION_RESULT: shortMsg=foo bar',
- 'INSTRUMENTATION_RESULT: longMsg=a foo',
- 'walked into',
- 'a bar',
- 'INSTRUMENTATION_CODE: -1',
- ]
-
- parser = instrumentation_parser.InstrumentationParser(raw_output)
- statuses = list(parser.IterStatus())
- code, bundle = parser.GetResult()
- self.assertEqual(-1, code)
- self.assertEqual(
- {'shortMsg': 'foo bar', 'longMsg': 'a foo\nwalked into\na bar'}, bundle)
- self.assertEqual([], statuses)
-
- def testInstrumentationParser_oneStatus(self):
- raw_output = [
- 'INSTRUMENTATION_STATUS: foo=1',
- 'INSTRUMENTATION_STATUS: bar=hello',
- 'INSTRUMENTATION_STATUS: world=false',
- 'INSTRUMENTATION_STATUS: class=this.is.a.test.package.TestClass',
- 'INSTRUMENTATION_STATUS: test=testMethod',
- 'INSTRUMENTATION_STATUS_CODE: 0',
- ]
-
- parser = instrumentation_parser.InstrumentationParser(raw_output)
- statuses = list(parser.IterStatus())
-
- expected = [
- (0, {
- 'foo': '1',
- 'bar': 'hello',
- 'world': 'false',
- 'class': 'this.is.a.test.package.TestClass',
- 'test': 'testMethod',
- })
- ]
- self.assertEqual(expected, statuses)
-
- def testInstrumentationParser_multiStatus(self):
- raw_output = [
- 'INSTRUMENTATION_STATUS: class=foo',
- 'INSTRUMENTATION_STATUS: test=bar',
- 'INSTRUMENTATION_STATUS_CODE: 1',
- 'INSTRUMENTATION_STATUS: test_skipped=true',
- 'INSTRUMENTATION_STATUS_CODE: 0',
- 'INSTRUMENTATION_STATUS: class=hello',
- 'INSTRUMENTATION_STATUS: test=world',
- 'INSTRUMENTATION_STATUS: stack=',
- 'foo/bar.py (27)',
- 'hello/world.py (42)',
- 'test/file.py (1)',
- 'INSTRUMENTATION_STATUS_CODE: -1',
- ]
-
- parser = instrumentation_parser.InstrumentationParser(raw_output)
- statuses = list(parser.IterStatus())
-
- expected = [
- (1, {'class': 'foo', 'test': 'bar',}),
- (0, {'test_skipped': 'true'}),
- (-1, {
- 'class': 'hello',
- 'test': 'world',
- 'stack': '\nfoo/bar.py (27)\nhello/world.py (42)\ntest/file.py (1)',
- }),
- ]
- self.assertEqual(expected, statuses)
-
- def testInstrumentationParser_statusResultAndCode(self):
- raw_output = [
- 'INSTRUMENTATION_STATUS: class=foo',
- 'INSTRUMENTATION_STATUS: test=bar',
- 'INSTRUMENTATION_STATUS_CODE: 1',
- 'INSTRUMENTATION_RESULT: result=hello',
- 'world',
- '',
- '',
- 'INSTRUMENTATION_CODE: 0',
- ]
-
- parser = instrumentation_parser.InstrumentationParser(raw_output)
- statuses = list(parser.IterStatus())
- code, bundle = parser.GetResult()
-
- self.assertEqual(0, code)
- self.assertEqual({'result': 'hello\nworld\n\n'}, bundle)
- self.assertEqual([(1, {'class': 'foo', 'test': 'bar'})], statuses)
-
-
-if __name__ == '__main__':
- unittest.main(verbosity=2)
diff --git a/build/android/pylib/instrumentation/instrumentation_test_instance.py b/build/android/pylib/instrumentation/instrumentation_test_instance.py
deleted file mode 100644
index f9957b0..0000000
--- a/build/android/pylib/instrumentation/instrumentation_test_instance.py
+++ /dev/null
@@ -1,525 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import os
-import pickle
-import re
-import sys
-
-from pylib import cmd_helper
-from pylib import constants
-from pylib import flag_changer
-from pylib.base import base_test_result
-from pylib.base import test_instance
-from pylib.instrumentation import test_result
-from pylib.instrumentation import instrumentation_parser
-from pylib.utils import apk_helper
-from pylib.utils import md5sum
-from pylib.utils import proguard
-
-sys.path.append(
- os.path.join(constants.DIR_SOURCE_ROOT, 'build', 'util', 'lib', 'common'))
-import unittest_util
-
-# Ref: http://developer.android.com/reference/android/app/Activity.html
-_ACTIVITY_RESULT_CANCELED = 0
-_ACTIVITY_RESULT_OK = -1
-
-_DEFAULT_ANNOTATIONS = [
- 'Smoke', 'SmallTest', 'MediumTest', 'LargeTest',
- 'EnormousTest', 'IntegrationTest']
-_EXTRA_ENABLE_HTTP_SERVER = (
- 'org.chromium.chrome.test.ChromeInstrumentationTestRunner.'
- + 'EnableTestHttpServer')
-_EXTRA_DRIVER_TEST_LIST = (
- 'org.chromium.test.driver.OnDeviceInstrumentationDriver.TestList')
-_EXTRA_DRIVER_TEST_LIST_FILE = (
- 'org.chromium.test.driver.OnDeviceInstrumentationDriver.TestListFile')
-_EXTRA_DRIVER_TARGET_PACKAGE = (
- 'org.chromium.test.driver.OnDeviceInstrumentationDriver.TargetPackage')
-_EXTRA_DRIVER_TARGET_CLASS = (
- 'org.chromium.test.driver.OnDeviceInstrumentationDriver.TargetClass')
-_NATIVE_CRASH_RE = re.compile('native crash', re.IGNORECASE)
-_PICKLE_FORMAT_VERSION = 10
-
-
-# TODO(jbudorick): Make these private class methods of
-# InstrumentationTestInstance once the instrumentation test_runner is
-# deprecated.
-def ParseAmInstrumentRawOutput(raw_output):
- """Parses the output of an |am instrument -r| call.
-
- Args:
- raw_output: the output of an |am instrument -r| call as a list of lines
- Returns:
- A 3-tuple containing:
- - the instrumentation code as an integer
- - the instrumentation result as a list of lines
- - the instrumentation statuses received as a list of 2-tuples
- containing:
- - the status code as an integer
- - the bundle dump as a dict mapping string keys to a list of
- strings, one for each line.
- """
- parser = instrumentation_parser.InstrumentationParser(raw_output)
- statuses = list(parser.IterStatus())
- code, bundle = parser.GetResult()
- return (code, bundle, statuses)
-
-
-def GenerateTestResults(
- result_code, result_bundle, statuses, start_ms, duration_ms):
- """Generate test results from |statuses|.
-
- Args:
- result_code: The overall status code as an integer.
- result_bundle: The summary bundle dump as a dict.
- statuses: A list of 2-tuples containing:
- - the status code as an integer
- - the bundle dump as a dict mapping string keys to string values
- Note that this is the same as the third item in the 3-tuple returned by
- |_ParseAmInstrumentRawOutput|.
- start_ms: The start time of the test in milliseconds.
- duration_ms: The duration of the test in milliseconds.
-
- Returns:
- A list containing an instance of InstrumentationTestResult for each test
- parsed.
- """
-
- results = []
-
- current_result = None
-
- for status_code, bundle in statuses:
- test_class = bundle.get('class', '')
- test_method = bundle.get('test', '')
- if test_class and test_method:
- test_name = '%s#%s' % (test_class, test_method)
- else:
- continue
-
- if status_code == instrumentation_parser.STATUS_CODE_START:
- if current_result:
- results.append(current_result)
- current_result = test_result.InstrumentationTestResult(
- test_name, base_test_result.ResultType.UNKNOWN, start_ms, duration_ms)
- else:
- if status_code == instrumentation_parser.STATUS_CODE_OK:
- if bundle.get('test_skipped', '').lower() in ('true', '1', 'yes'):
- current_result.SetType(base_test_result.ResultType.SKIP)
- elif current_result.GetType() == base_test_result.ResultType.UNKNOWN:
- current_result.SetType(base_test_result.ResultType.PASS)
- else:
- if status_code not in (instrumentation_parser.STATUS_CODE_ERROR,
- instrumentation_parser.STATUS_CODE_FAILURE):
- logging.error('Unrecognized status code %d. Handling as an error.',
- status_code)
- current_result.SetType(base_test_result.ResultType.FAIL)
- if 'stack' in bundle:
- current_result.SetLog(bundle['stack'])
-
- if current_result:
- if current_result.GetType() == base_test_result.ResultType.UNKNOWN:
- crashed = (result_code == _ACTIVITY_RESULT_CANCELED
- and any(_NATIVE_CRASH_RE.search(l)
- for l in result_bundle.itervalues()))
- if crashed:
- current_result.SetType(base_test_result.ResultType.CRASH)
-
- results.append(current_result)
-
- return results
-
-
-class InstrumentationTestInstance(test_instance.TestInstance):
-
- def __init__(self, args, isolate_delegate, error_func):
- super(InstrumentationTestInstance, self).__init__()
-
- self._apk_under_test = None
- self._package_info = None
- self._suite = None
- self._test_apk = None
- self._test_jar = None
- self._test_package = None
- self._test_runner = None
- self._test_support_apk = None
- self._initializeApkAttributes(args, error_func)
-
- self._data_deps = None
- self._isolate_abs_path = None
- self._isolate_delegate = None
- self._isolated_abs_path = None
- self._test_data = None
- self._initializeDataDependencyAttributes(args, isolate_delegate)
-
- self._annotations = None
- self._excluded_annotations = None
- self._test_filter = None
- self._initializeTestFilterAttributes(args)
-
- self._flags = None
- self._initializeFlagAttributes(args)
-
- self._driver_apk = None
- self._driver_package = None
- self._driver_name = None
- self._initializeDriverAttributes()
-
- def _initializeApkAttributes(self, args, error_func):
- if args.apk_under_test.endswith('.apk'):
- self._apk_under_test = args.apk_under_test
- else:
- self._apk_under_test = os.path.join(
- constants.GetOutDirectory(), constants.SDK_BUILD_APKS_DIR,
- '%s.apk' % args.apk_under_test)
-
- if not os.path.exists(self._apk_under_test):
- error_func('Unable to find APK under test: %s' % self._apk_under_test)
-
- if args.test_apk.endswith('.apk'):
- self._suite = os.path.splitext(os.path.basename(args.test_apk))[0]
- self._test_apk = args.test_apk
- else:
- self._suite = args.test_apk
- self._test_apk = os.path.join(
- constants.GetOutDirectory(), constants.SDK_BUILD_APKS_DIR,
- '%s.apk' % args.test_apk)
-
- self._test_jar = os.path.join(
- constants.GetOutDirectory(), constants.SDK_BUILD_TEST_JAVALIB_DIR,
- '%s.jar' % self._suite)
- self._test_support_apk = os.path.join(
- constants.GetOutDirectory(), constants.SDK_BUILD_TEST_JAVALIB_DIR,
- '%sSupport.apk' % self._suite)
-
- if not os.path.exists(self._test_apk):
- error_func('Unable to find test APK: %s' % self._test_apk)
- if not os.path.exists(self._test_jar):
- error_func('Unable to find test JAR: %s' % self._test_jar)
-
- apk = apk_helper.ApkHelper(self.test_apk)
- self._test_package = apk.GetPackageName()
- self._test_runner = apk.GetInstrumentationName()
-
- self._package_info = None
- for package_info in constants.PACKAGE_INFO.itervalues():
- if self._test_package == package_info.test_package:
- self._package_info = package_info
- if not self._package_info:
- logging.warning('Unable to find package info for %s', self._test_package)
-
- def _initializeDataDependencyAttributes(self, args, isolate_delegate):
- self._data_deps = []
- if args.isolate_file_path:
- self._isolate_abs_path = os.path.abspath(args.isolate_file_path)
- self._isolate_delegate = isolate_delegate
- self._isolated_abs_path = os.path.join(
- constants.GetOutDirectory(), '%s.isolated' % self._test_package)
- else:
- self._isolate_delegate = None
-
- # TODO(jbudorick): Deprecate and remove --test-data once data dependencies
- # are fully converted to isolate.
- if args.test_data:
- logging.info('Data dependencies specified via --test-data')
- self._test_data = args.test_data
- else:
- self._test_data = None
-
- if not self._isolate_delegate and not self._test_data:
- logging.warning('No data dependencies will be pushed.')
-
- def _initializeTestFilterAttributes(self, args):
- self._test_filter = args.test_filter
-
- def annotation_dict_element(a):
- a = a.split('=')
- return (a[0], a[1] if len(a) == 2 else None)
-
- if args.annotation_str:
- self._annotations = dict(
- annotation_dict_element(a)
- for a in args.annotation_str.split(','))
- elif not self._test_filter:
- self._annotations = dict(
- annotation_dict_element(a)
- for a in _DEFAULT_ANNOTATIONS)
- else:
- self._annotations = {}
-
- if args.exclude_annotation_str:
- self._excluded_annotations = dict(
- annotation_dict_element(a)
- for a in args.exclude_annotation_str.split(','))
- else:
- self._excluded_annotations = {}
-
- def _initializeFlagAttributes(self, args):
- self._flags = ['--disable-fre', '--enable-test-intents']
- # TODO(jbudorick): Transition "--device-flags" to "--device-flags-file"
- if hasattr(args, 'device_flags') and args.device_flags:
- with open(args.device_flags) as device_flags_file:
- stripped_lines = (l.strip() for l in device_flags_file)
- self._flags.extend([flag for flag in stripped_lines if flag])
- if hasattr(args, 'device_flags_file') and args.device_flags_file:
- with open(args.device_flags_file) as device_flags_file:
- stripped_lines = (l.strip() for l in device_flags_file)
- self._flags.extend([flag for flag in stripped_lines if flag])
-
- def _initializeDriverAttributes(self):
- self._driver_apk = os.path.join(
- constants.GetOutDirectory(), constants.SDK_BUILD_APKS_DIR,
- 'OnDeviceInstrumentationDriver.apk')
- if os.path.exists(self._driver_apk):
- driver_apk = apk_helper.ApkHelper(self._driver_apk)
- self._driver_package = driver_apk.GetPackageName()
- self._driver_name = driver_apk.GetInstrumentationName()
- else:
- self._driver_apk = None
-
- @property
- def apk_under_test(self):
- return self._apk_under_test
-
- @property
- def flags(self):
- return self._flags
-
- @property
- def driver_apk(self):
- return self._driver_apk
-
- @property
- def driver_package(self):
- return self._driver_package
-
- @property
- def driver_name(self):
- return self._driver_name
-
- @property
- def package_info(self):
- return self._package_info
-
- @property
- def suite(self):
- return self._suite
-
- @property
- def test_apk(self):
- return self._test_apk
-
- @property
- def test_jar(self):
- return self._test_jar
-
- @property
- def test_support_apk(self):
- return self._test_support_apk
-
- @property
- def test_package(self):
- return self._test_package
-
- @property
- def test_runner(self):
- return self._test_runner
-
- #override
- def TestType(self):
- return 'instrumentation'
-
- #override
- def SetUp(self):
- if self._isolate_delegate:
- self._isolate_delegate.Remap(
- self._isolate_abs_path, self._isolated_abs_path)
- self._isolate_delegate.MoveOutputDeps()
- self._data_deps.extend([(constants.ISOLATE_DEPS_DIR, None)])
-
- # TODO(jbudorick): Convert existing tests that depend on the --test-data
- # mechanism to isolate, then remove this.
- if self._test_data:
- for t in self._test_data:
- device_rel_path, host_rel_path = t.split(':')
- host_abs_path = os.path.join(constants.DIR_SOURCE_ROOT, host_rel_path)
- self._data_deps.extend(
- [(host_abs_path,
- [None, 'chrome', 'test', 'data', device_rel_path])])
-
- def GetDataDependencies(self):
- return self._data_deps
-
- def GetTests(self):
- pickle_path = '%s-proguard.pickle' % self.test_jar
- try:
- tests = self._GetTestsFromPickle(pickle_path, self.test_jar)
- except self.ProguardPickleException as e:
- logging.info('Getting tests from JAR via proguard. (%s)' % str(e))
- tests = self._GetTestsFromProguard(self.test_jar)
- self._SaveTestsToPickle(pickle_path, self.test_jar, tests)
- return self._InflateTests(self._FilterTests(tests))
-
- class ProguardPickleException(Exception):
- pass
-
- def _GetTestsFromPickle(self, pickle_path, jar_path):
- if not os.path.exists(pickle_path):
- raise self.ProguardPickleException('%s does not exist.' % pickle_path)
- if os.path.getmtime(pickle_path) <= os.path.getmtime(jar_path):
- raise self.ProguardPickleException(
- '%s newer than %s.' % (jar_path, pickle_path))
-
- with open(pickle_path, 'r') as pickle_file:
- pickle_data = pickle.loads(pickle_file.read())
- jar_md5 = md5sum.CalculateHostMd5Sums(jar_path)[jar_path]
-
- try:
- if pickle_data['VERSION'] != _PICKLE_FORMAT_VERSION:
- raise self.ProguardPickleException('PICKLE_FORMAT_VERSION has changed.')
- if pickle_data['JAR_MD5SUM'] != jar_md5:
- raise self.ProguardPickleException('JAR file MD5 sum differs.')
- return pickle_data['TEST_METHODS']
- except TypeError as e:
- logging.error(pickle_data)
- raise self.ProguardPickleException(str(e))
-
- def _GetTestsFromProguard(self, jar_path):
- p = proguard.Dump(jar_path)
-
- def is_test_class(c):
- return c['class'].endswith('Test')
-
- def is_test_method(m):
- return m['method'].startswith('test')
-
- class_lookup = dict((c['class'], c) for c in p['classes'])
- def recursive_get_class_annotations(c):
- s = c['superclass']
- if s in class_lookup:
- a = recursive_get_class_annotations(class_lookup[s])
- else:
- a = {}
- a.update(c['annotations'])
- return a
-
- def stripped_test_class(c):
- return {
- 'class': c['class'],
- 'annotations': recursive_get_class_annotations(c),
- 'methods': [m for m in c['methods'] if is_test_method(m)],
- }
-
- return [stripped_test_class(c) for c in p['classes']
- if is_test_class(c)]
-
- def _SaveTestsToPickle(self, pickle_path, jar_path, tests):
- jar_md5 = md5sum.CalculateHostMd5Sums(jar_path)[jar_path]
- pickle_data = {
- 'VERSION': _PICKLE_FORMAT_VERSION,
- 'JAR_MD5SUM': jar_md5,
- 'TEST_METHODS': tests,
- }
- with open(pickle_path, 'w') as pickle_file:
- pickle.dump(pickle_data, pickle_file)
-
- def _FilterTests(self, tests):
-
- def gtest_filter(c, m):
- t = ['%s.%s' % (c['class'].split('.')[-1], m['method'])]
- return (not self._test_filter
- or unittest_util.FilterTestNames(t, self._test_filter))
-
- def annotation_filter(all_annotations):
- if not self._annotations:
- return True
- return any_annotation_matches(self._annotations, all_annotations)
-
- def excluded_annotation_filter(all_annotations):
- if not self._excluded_annotations:
- return True
- return not any_annotation_matches(self._excluded_annotations,
- all_annotations)
-
- def any_annotation_matches(annotations, all_annotations):
- return any(
- ak in all_annotations and (av is None or av == all_annotations[ak])
- for ak, av in annotations.iteritems())
-
- filtered_classes = []
- for c in tests:
- filtered_methods = []
- for m in c['methods']:
- # Gtest filtering
- if not gtest_filter(c, m):
- continue
-
- all_annotations = dict(c['annotations'])
- all_annotations.update(m['annotations'])
- if (not annotation_filter(all_annotations)
- or not excluded_annotation_filter(all_annotations)):
- continue
-
- filtered_methods.append(m)
-
- if filtered_methods:
- filtered_class = dict(c)
- filtered_class['methods'] = filtered_methods
- filtered_classes.append(filtered_class)
-
- return filtered_classes
-
- def _InflateTests(self, tests):
- inflated_tests = []
- for c in tests:
- for m in c['methods']:
- a = dict(c['annotations'])
- a.update(m['annotations'])
- inflated_tests.append({
- 'class': c['class'],
- 'method': m['method'],
- 'annotations': a,
- })
- return inflated_tests
-
- @staticmethod
- def GetHttpServerEnvironmentVars():
- return {
- _EXTRA_ENABLE_HTTP_SERVER: None,
- }
-
- def GetDriverEnvironmentVars(
- self, test_list=None, test_list_file_path=None):
- env = {
- _EXTRA_DRIVER_TARGET_PACKAGE: self.test_package,
- _EXTRA_DRIVER_TARGET_CLASS: self.test_runner,
- }
-
- if test_list:
- env[_EXTRA_DRIVER_TEST_LIST] = ','.join(test_list)
-
- if test_list_file_path:
- env[_EXTRA_DRIVER_TEST_LIST_FILE] = (
- os.path.basename(test_list_file_path))
-
- return env
-
- @staticmethod
- def ParseAmInstrumentRawOutput(raw_output):
- return ParseAmInstrumentRawOutput(raw_output)
-
- @staticmethod
- def GenerateTestResults(
- result_code, result_bundle, statuses, start_ms, duration_ms):
- return GenerateTestResults(result_code, result_bundle, statuses,
- start_ms, duration_ms)
-
- #override
- def TearDown(self):
- if self._isolate_delegate:
- self._isolate_delegate.Clear()
-
diff --git a/build/android/pylib/instrumentation/instrumentation_test_instance_test.py b/build/android/pylib/instrumentation/instrumentation_test_instance_test.py
deleted file mode 100755
index 752e4d3..0000000
--- a/build/android/pylib/instrumentation/instrumentation_test_instance_test.py
+++ /dev/null
@@ -1,109 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-
-"""Unit tests for instrumentation.TestRunner."""
-
-# pylint: disable=W0212
-
-import os
-import sys
-import unittest
-
-from pylib import constants
-from pylib.base import base_test_result
-from pylib.instrumentation import instrumentation_test_instance
-
-sys.path.append(os.path.join(
- constants.DIR_SOURCE_ROOT, 'third_party', 'pymock'))
-import mock # pylint: disable=F0401
-
-
-class InstrumentationTestInstanceTest(unittest.TestCase):
-
- def setUp(self):
- options = mock.Mock()
- options.tool = ''
-
- def testGenerateTestResults_noStatus(self):
- results = instrumentation_test_instance.GenerateTestResults(
- None, None, [], 0, 1000)
- self.assertEqual([], results)
-
- def testGenerateTestResults_testPassed(self):
- statuses = [
- (1, {
- 'class': 'test.package.TestClass',
- 'test': 'testMethod',
- }),
- (0, {
- 'class': 'test.package.TestClass',
- 'test': 'testMethod',
- }),
- ]
- results = instrumentation_test_instance.GenerateTestResults(
- None, None, statuses, 0, 1000)
- self.assertEqual(1, len(results))
- self.assertEqual(base_test_result.ResultType.PASS, results[0].GetType())
-
- def testGenerateTestResults_testSkipped_true(self):
- statuses = [
- (1, {
- 'class': 'test.package.TestClass',
- 'test': 'testMethod',
- }),
- (0, {
- 'test_skipped': 'true',
- 'class': 'test.package.TestClass',
- 'test': 'testMethod',
- }),
- (0, {
- 'class': 'test.package.TestClass',
- 'test': 'testMethod',
- }),
- ]
- results = instrumentation_test_instance.GenerateTestResults(
- None, None, statuses, 0, 1000)
- self.assertEqual(1, len(results))
- self.assertEqual(base_test_result.ResultType.SKIP, results[0].GetType())
-
- def testGenerateTestResults_testSkipped_false(self):
- statuses = [
- (1, {
- 'class': 'test.package.TestClass',
- 'test': 'testMethod',
- }),
- (0, {
- 'test_skipped': 'false',
- }),
- (0, {
- 'class': 'test.package.TestClass',
- 'test': 'testMethod',
- }),
- ]
- results = instrumentation_test_instance.GenerateTestResults(
- None, None, statuses, 0, 1000)
- self.assertEqual(1, len(results))
- self.assertEqual(base_test_result.ResultType.PASS, results[0].GetType())
-
- def testGenerateTestResults_testFailed(self):
- statuses = [
- (1, {
- 'class': 'test.package.TestClass',
- 'test': 'testMethod',
- }),
- (-2, {
- 'class': 'test.package.TestClass',
- 'test': 'testMethod',
- }),
- ]
- results = instrumentation_test_instance.GenerateTestResults(
- None, None, statuses, 0, 1000)
- self.assertEqual(1, len(results))
- self.assertEqual(base_test_result.ResultType.FAIL, results[0].GetType())
-
-
-if __name__ == '__main__':
- unittest.main(verbosity=2)
diff --git a/build/android/pylib/instrumentation/json_perf_parser.py b/build/android/pylib/instrumentation/json_perf_parser.py
deleted file mode 100644
index ffdfbe7..0000000
--- a/build/android/pylib/instrumentation/json_perf_parser.py
+++ /dev/null
@@ -1,161 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-
-"""A helper module for parsing JSON objects from perf tests results."""
-
-import json
-
-
-def GetAverageRunInfo(json_data, name):
- """Summarizes TraceEvent JSON data for performance metrics.
-
- Example JSON Inputs (More tags can be added but these are required):
- Measuring Duration:
- [
- { "cat": "Java",
- "ts": 10000000000,
- "ph": "S",
- "name": "TestTrace"
- },
- { "cat": "Java",
- "ts": 10000004000,
- "ph": "F",
- "name": "TestTrace"
- },
- ...
- ]
-
- Measuring Call Frequency (FPS):
- [
- { "cat": "Java",
- "ts": 10000000000,
- "ph": "I",
- "name": "TestTraceFPS"
- },
- { "cat": "Java",
- "ts": 10000004000,
- "ph": "I",
- "name": "TestTraceFPS"
- },
- ...
- ]
-
- Args:
- json_data: A list of dictonaries each representing a JSON object.
- name: The 'name' tag to filter on in the JSON file.
-
- Returns:
- A dictionary of result data with the following tags:
- min: The minimum value tracked.
- max: The maximum value tracked.
- average: The average of all the values tracked.
- count: The number of times the category/name pair was tracked.
- type: The type of tracking ('Instant' for instant tags and 'Span' for
- begin/end tags.
- category: The passed in category filter.
- name: The passed in name filter.
- data_points: A list of all of the times used to generate this data.
- units: The units for the values being reported.
-
- Raises:
- Exception: if entry contains invalid data.
- """
-
- def EntryFilter(entry):
- return entry['cat'] == 'Java' and entry['name'] == name
- filtered_entries = filter(EntryFilter, json_data)
-
- result = {}
-
- result['min'] = -1
- result['max'] = -1
- result['average'] = 0
- result['count'] = 0
- result['type'] = 'Unknown'
- result['category'] = 'Java'
- result['name'] = name
- result['data_points'] = []
- result['units'] = ''
-
- total_sum = 0
-
- last_val = 0
- val_type = None
- for entry in filtered_entries:
- if not val_type:
- if 'mem' in entry:
- val_type = 'mem'
-
- def GetVal(entry):
- return entry['mem']
-
- result['units'] = 'kb'
- elif 'ts' in entry:
- val_type = 'ts'
-
- def GetVal(entry):
- return float(entry['ts']) / 1000.0
-
- result['units'] = 'ms'
- else:
- raise Exception('Entry did not contain valid value info: %s' % entry)
-
- if not val_type in entry:
- raise Exception('Entry did not contain expected value type "%s" '
- 'information: %s' % (val_type, entry))
- val = GetVal(entry)
- if (entry['ph'] == 'S' and
- (result['type'] == 'Unknown' or result['type'] == 'Span')):
- result['type'] = 'Span'
- last_val = val
- elif ((entry['ph'] == 'F' and result['type'] == 'Span') or
- (entry['ph'] == 'I' and (result['type'] == 'Unknown' or
- result['type'] == 'Instant'))):
- if last_val > 0:
- delta = val - last_val
- if result['min'] == -1 or result['min'] > delta:
- result['min'] = delta
- if result['max'] == -1 or result['max'] < delta:
- result['max'] = delta
- total_sum += delta
- result['count'] += 1
- result['data_points'].append(delta)
- if entry['ph'] == 'I':
- result['type'] = 'Instant'
- last_val = val
- if result['count'] > 0:
- result['average'] = total_sum / result['count']
-
- return result
-
-
-def GetAverageRunInfoFromJSONString(json_string, name):
- """Returns the results from GetAverageRunInfo using a JSON string.
-
- Args:
- json_string: The string containing JSON.
- name: The 'name' tag to filter on in the JSON file.
-
- Returns:
- See GetAverageRunInfo Returns section.
- """
- return GetAverageRunInfo(json.loads(json_string), name)
-
-
-def GetAverageRunInfoFromFile(json_file, name):
- """Returns the results from GetAverageRunInfo using a JSON file.
-
- Args:
- json_file: The path to a JSON file.
- name: The 'name' tag to filter on in the JSON file.
-
- Returns:
- See GetAverageRunInfo Returns section.
- """
- with open(json_file, 'r') as f:
- data = f.read()
- perf = json.loads(data)
-
- return GetAverageRunInfo(perf, name)
diff --git a/build/android/pylib/instrumentation/setup.py b/build/android/pylib/instrumentation/setup.py
deleted file mode 100644
index 7a0501e..0000000
--- a/build/android/pylib/instrumentation/setup.py
+++ /dev/null
@@ -1,113 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Generates test runner factory and tests for instrumentation tests."""
-
-import logging
-import os
-
-from pylib import constants
-from pylib import valgrind_tools
-
-from pylib.base import base_setup
-from pylib.device import device_utils
-from pylib.instrumentation import test_package
-from pylib.instrumentation import test_runner
-
-DEVICE_DATA_DIR = 'chrome/test/data'
-
-ISOLATE_FILE_PATHS = {
- 'AndroidWebViewTest': 'android_webview/android_webview_test_apk.isolate',
- 'ChromeShellTest': 'chrome/chrome_shell_test_apk.isolate',
- 'ContentShellTest': 'content/content_shell_test_apk.isolate',
-}
-
-DEPS_EXCLUSION_LIST = []
-
-# TODO(mikecase): Remove this function and the constant DEVICE_DATA_DIR
-# once all data deps are pushed to the same location on the device.
-def _PushExtraSuiteDataDeps(device, test_apk):
- """Pushes some extra data files/dirs needed by some test suite.
-
- Args:
- test_apk: The test suite basename for which to return file paths.
- """
- if test_apk in ['ChromeTest', 'ContentShellTest']:
- test_files = 'net/data/ssl/certificates'
- host_device_file_tuple = [
- (os.path.join(constants.DIR_SOURCE_ROOT, test_files),
- os.path.join(device.GetExternalStoragePath(), test_files))]
- device.PushChangedFiles(host_device_file_tuple)
-
-
-# TODO(mikecase): Remove this function once everything uses
-# base_setup.PushDataDeps to push data deps to the device.
-def _PushDataDeps(device, test_options):
- valgrind_tools.PushFilesForTool(test_options.tool, device)
-
- host_device_file_tuples = []
- for dest_host_pair in test_options.test_data:
- dst_src = dest_host_pair.split(':', 1)
- dst_layer = dst_src[0]
- host_src = dst_src[1]
- host_test_files_path = os.path.join(constants.DIR_SOURCE_ROOT, host_src)
- if os.path.exists(host_test_files_path):
- host_device_file_tuples += [(
- host_test_files_path,
- '%s/%s/%s' % (
- device.GetExternalStoragePath(),
- DEVICE_DATA_DIR,
- dst_layer))]
- if host_device_file_tuples:
- device.PushChangedFiles(host_device_file_tuples)
-
-
-def Setup(test_options, devices):
- """Create and return the test runner factory and tests.
-
- Args:
- test_options: An InstrumentationOptions object.
-
- Returns:
- A tuple of (TestRunnerFactory, tests).
- """
- if (test_options.coverage_dir and not
- os.path.exists(test_options.coverage_dir)):
- os.makedirs(test_options.coverage_dir)
-
- test_pkg = test_package.TestPackage(test_options.test_apk_path,
- test_options.test_apk_jar_path,
- test_options.test_support_apk_path)
- tests = test_pkg.GetAllMatchingTests(
- test_options.annotations,
- test_options.exclude_annotations,
- test_options.test_filter)
- if not tests:
- logging.error('No instrumentation tests to run with current args.')
-
- if test_options.test_data:
- device_utils.DeviceUtils.parallel(devices).pMap(
- _PushDataDeps, test_options)
-
- if test_options.isolate_file_path:
- i = base_setup.GenerateDepsDirUsingIsolate(test_options.test_apk,
- test_options.isolate_file_path,
- ISOLATE_FILE_PATHS,
- DEPS_EXCLUSION_LIST)
- def push_data_deps_to_device_dir(device):
- base_setup.PushDataDeps(device, device.GetExternalStoragePath(),
- test_options)
- device_utils.DeviceUtils.parallel(devices).pMap(
- push_data_deps_to_device_dir)
- if i:
- i.Clear()
-
- device_utils.DeviceUtils.parallel(devices).pMap(
- _PushExtraSuiteDataDeps, test_options.test_apk)
-
- def TestRunnerFactory(device, shard_index):
- return test_runner.TestRunner(test_options, device, shard_index,
- test_pkg)
-
- return (TestRunnerFactory, tests)
diff --git a/build/android/pylib/instrumentation/test_jar.py b/build/android/pylib/instrumentation/test_jar.py
deleted file mode 100644
index 7ad8997..0000000
--- a/build/android/pylib/instrumentation/test_jar.py
+++ /dev/null
@@ -1,230 +0,0 @@
-# Copyright (c) 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Helper class for instrumenation test jar."""
-# pylint: disable=W0702
-
-import logging
-import os
-import pickle
-import re
-import sys
-
-from pylib import cmd_helper
-from pylib import constants
-from pylib.device import device_utils
-from pylib.utils import md5sum
-from pylib.utils import proguard
-
-sys.path.insert(0,
- os.path.join(constants.DIR_SOURCE_ROOT,
- 'build', 'util', 'lib', 'common'))
-
-import unittest_util # pylint: disable=F0401
-
-# If you change the cached output of proguard, increment this number
-PICKLE_FORMAT_VERSION = 4
-
-
-class TestJar(object):
- _ANNOTATIONS = frozenset(
- ['Smoke', 'SmallTest', 'MediumTest', 'LargeTest', 'EnormousTest',
- 'FlakyTest', 'DisabledTest', 'Manual', 'PerfTest', 'HostDrivenTest',
- 'IntegrationTest'])
- _DEFAULT_ANNOTATION = 'SmallTest'
- _PROGUARD_CLASS_RE = re.compile(r'\s*?- Program class:\s*([\S]+)$')
- _PROGUARD_SUPERCLASS_RE = re.compile(r'\s*? Superclass:\s*([\S]+)$')
- _PROGUARD_METHOD_RE = re.compile(r'\s*?- Method:\s*(\S*)[(].*$')
- _PROGUARD_ANNOTATION_RE = re.compile(r'\s*?- Annotation \[L(\S*);\]:$')
- _PROGUARD_ANNOTATION_CONST_RE = (
- re.compile(r'\s*?- Constant element value.*$'))
- _PROGUARD_ANNOTATION_VALUE_RE = re.compile(r'\s*?- \S+? \[(.*)\]$')
-
- def __init__(self, jar_path):
- if not os.path.exists(jar_path):
- raise Exception('%s not found, please build it' % jar_path)
-
- self._PROGUARD_PATH = os.path.join(constants.ANDROID_SDK_ROOT,
- 'tools/proguard/lib/proguard.jar')
- if not os.path.exists(self._PROGUARD_PATH):
- self._PROGUARD_PATH = os.path.join(os.environ['ANDROID_BUILD_TOP'],
- 'external/proguard/lib/proguard.jar')
- self._jar_path = jar_path
- self._pickled_proguard_name = self._jar_path + '-proguard.pickle'
- self._test_methods = {}
- if not self._GetCachedProguardData():
- self._GetProguardData()
-
- def _GetCachedProguardData(self):
- if (os.path.exists(self._pickled_proguard_name) and
- (os.path.getmtime(self._pickled_proguard_name) >
- os.path.getmtime(self._jar_path))):
- logging.info('Loading cached proguard output from %s',
- self._pickled_proguard_name)
- try:
- with open(self._pickled_proguard_name, 'r') as r:
- d = pickle.loads(r.read())
- jar_md5 = md5sum.CalculateHostMd5Sums(
- self._jar_path)[os.path.realpath(self._jar_path)]
- if (d['JAR_MD5SUM'] == jar_md5 and
- d['VERSION'] == PICKLE_FORMAT_VERSION):
- self._test_methods = d['TEST_METHODS']
- return True
- except:
- logging.warning('PICKLE_FORMAT_VERSION has changed, ignoring cache')
- return False
-
- def _GetProguardData(self):
- logging.info('Retrieving test methods via proguard.')
-
- p = proguard.Dump(self._jar_path)
-
- class_lookup = dict((c['class'], c) for c in p['classes'])
- def recursive_get_annotations(c):
- s = c['superclass']
- if s in class_lookup:
- a = recursive_get_annotations(class_lookup[s])
- else:
- a = {}
- a.update(c['annotations'])
- return a
-
- test_classes = (c for c in p['classes']
- if c['class'].endswith('Test'))
- for c in test_classes:
- class_annotations = recursive_get_annotations(c)
- test_methods = (m for m in c['methods']
- if m['method'].startswith('test'))
- for m in test_methods:
- qualified_method = '%s#%s' % (c['class'], m['method'])
- annotations = dict(class_annotations)
- annotations.update(m['annotations'])
- self._test_methods[qualified_method] = m
- self._test_methods[qualified_method]['annotations'] = annotations
-
- logging.info('Storing proguard output to %s', self._pickled_proguard_name)
- d = {'VERSION': PICKLE_FORMAT_VERSION,
- 'TEST_METHODS': self._test_methods,
- 'JAR_MD5SUM':
- md5sum.CalculateHostMd5Sums(
- self._jar_path)[os.path.realpath(self._jar_path)]}
- with open(self._pickled_proguard_name, 'w') as f:
- f.write(pickle.dumps(d))
-
- @staticmethod
- def _IsTestMethod(test):
- class_name, method = test.split('#')
- return class_name.endswith('Test') and method.startswith('test')
-
- def GetTestAnnotations(self, test):
- """Returns a list of all annotations for the given |test|. May be empty."""
- if not self._IsTestMethod(test) or not test in self._test_methods:
- return []
- return self._test_methods[test]['annotations']
-
- @staticmethod
- def _AnnotationsMatchFilters(annotation_filter_list, annotations):
- """Checks if annotations match any of the filters."""
- if not annotation_filter_list:
- return True
- for annotation_filter in annotation_filter_list:
- filters = annotation_filter.split('=')
- if len(filters) == 2:
- key = filters[0]
- value_list = filters[1].split(',')
- for value in value_list:
- if key in annotations and value == annotations[key]:
- return True
- elif annotation_filter in annotations:
- return True
- return False
-
- def GetAnnotatedTests(self, annotation_filter_list):
- """Returns a list of all tests that match the given annotation filters."""
- return [test for test in self.GetTestMethods()
- if self._IsTestMethod(test) and self._AnnotationsMatchFilters(
- annotation_filter_list, self.GetTestAnnotations(test))]
-
- def GetTestMethods(self):
- """Returns a dict of all test methods and relevant attributes.
-
- Test methods are retrieved as Class#testMethod.
- """
- return self._test_methods
-
- def _GetTestsMissingAnnotation(self):
- """Get a list of test methods with no known annotations."""
- tests_missing_annotations = []
- for test_method in self.GetTestMethods().iterkeys():
- annotations_ = frozenset(self.GetTestAnnotations(test_method).iterkeys())
- if (annotations_.isdisjoint(self._ANNOTATIONS) and
- not self.IsHostDrivenTest(test_method)):
- tests_missing_annotations.append(test_method)
- return sorted(tests_missing_annotations)
-
- def _IsTestValidForSdkRange(self, test_name, attached_min_sdk_level):
- required_min_sdk_level = int(
- self.GetTestAnnotations(test_name).get('MinAndroidSdkLevel', 0))
- return (required_min_sdk_level is None or
- attached_min_sdk_level >= required_min_sdk_level)
-
- def GetAllMatchingTests(self, annotation_filter_list,
- exclude_annotation_list, test_filter):
- """Get a list of tests matching any of the annotations and the filter.
-
- Args:
- annotation_filter_list: List of test annotations. A test must have at
- least one of these annotations. A test without any annotations is
- considered to be SmallTest.
- exclude_annotation_list: List of test annotations. A test must not have
- any of these annotations.
- test_filter: Filter used for partial matching on the test method names.
-
- Returns:
- List of all matching tests.
- """
- if annotation_filter_list:
- available_tests = self.GetAnnotatedTests(annotation_filter_list)
- # Include un-annotated tests in SmallTest.
- if annotation_filter_list.count(self._DEFAULT_ANNOTATION) > 0:
- for test in self._GetTestsMissingAnnotation():
- logging.warning(
- '%s has no annotations. Assuming "%s".', test,
- self._DEFAULT_ANNOTATION)
- available_tests.append(test)
- else:
- available_tests = [m for m in self.GetTestMethods()
- if not self.IsHostDrivenTest(m)]
-
- if exclude_annotation_list:
- excluded_tests = self.GetAnnotatedTests(exclude_annotation_list)
- available_tests = list(set(available_tests) - set(excluded_tests))
-
- tests = []
- if test_filter:
- # |available_tests| are in adb instrument format: package.path.class#test.
-
- # Maps a 'class.test' name to each 'package.path.class#test' name.
- sanitized_test_names = dict([
- (t.split('.')[-1].replace('#', '.'), t) for t in available_tests])
- # Filters 'class.test' names and populates |tests| with the corresponding
- # 'package.path.class#test' names.
- tests = [
- sanitized_test_names[t] for t in unittest_util.FilterTestNames(
- sanitized_test_names.keys(), test_filter.replace('#', '.'))]
- else:
- tests = available_tests
-
- # Filter out any tests with SDK level requirements that don't match the set
- # of attached devices.
- devices = device_utils.DeviceUtils.parallel()
- min_sdk_version = min(devices.build_version_sdk.pGet(None))
- tests = [t for t in tests
- if self._IsTestValidForSdkRange(t, min_sdk_version)]
-
- return tests
-
- @staticmethod
- def IsHostDrivenTest(test):
- return 'pythonDrivenTests' in test
diff --git a/build/android/pylib/instrumentation/test_options.py b/build/android/pylib/instrumentation/test_options.py
deleted file mode 100644
index e7b7a9f..0000000
--- a/build/android/pylib/instrumentation/test_options.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Defines the InstrumentationOptions named tuple."""
-
-import collections
-
-InstrumentationOptions = collections.namedtuple('InstrumentationOptions', [
- 'tool',
- 'annotations',
- 'exclude_annotations',
- 'test_filter',
- 'test_data',
- 'save_perf_json',
- 'screenshot_failures',
- 'wait_for_debugger',
- 'coverage_dir',
- 'test_apk',
- 'test_apk_path',
- 'test_apk_jar_path',
- 'test_runner',
- 'test_support_apk_path',
- 'device_flags',
- 'isolate_file_path',
- 'set_asserts',
- 'delete_stale_data'])
diff --git a/build/android/pylib/instrumentation/test_package.py b/build/android/pylib/instrumentation/test_package.py
deleted file mode 100644
index 5be061d..0000000
--- a/build/android/pylib/instrumentation/test_package.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# Copyright (c) 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Class representing instrumentation test apk and jar."""
-
-import os
-
-from pylib.instrumentation import test_jar
-from pylib.utils import apk_helper
-
-
-class TestPackage(test_jar.TestJar):
- def __init__(self, apk_path, jar_path, test_support_apk_path):
- test_jar.TestJar.__init__(self, jar_path)
-
- if not os.path.exists(apk_path):
- raise Exception('%s not found, please build it' % apk_path)
- if test_support_apk_path and not os.path.exists(test_support_apk_path):
- raise Exception('%s not found, please build it' % test_support_apk_path)
- self._apk_path = apk_path
- self._apk_name = os.path.splitext(os.path.basename(apk_path))[0]
- self._package_name = apk_helper.GetPackageName(self._apk_path)
- self._test_support_apk_path = test_support_apk_path
-
- def GetApkPath(self):
- """Returns the absolute path to the APK."""
- return self._apk_path
-
- def GetApkName(self):
- """Returns the name of the apk without the suffix."""
- return self._apk_name
-
- def GetPackageName(self):
- """Returns the package name of this APK."""
- return self._package_name
-
- # Override.
- def Install(self, device):
- device.Install(self.GetApkPath())
- if (self._test_support_apk_path and
- os.path.exists(self._test_support_apk_path)):
- device.Install(self._test_support_apk_path)
-
diff --git a/build/android/pylib/instrumentation/test_result.py b/build/android/pylib/instrumentation/test_result.py
deleted file mode 100644
index 24e80a8..0000000
--- a/build/android/pylib/instrumentation/test_result.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from pylib.base import base_test_result
-
-
-class InstrumentationTestResult(base_test_result.BaseTestResult):
- """Result information for a single instrumentation test."""
-
- def __init__(self, full_name, test_type, start_date, dur, log=''):
- """Construct an InstrumentationTestResult object.
-
- Args:
- full_name: Full name of the test.
- test_type: Type of the test result as defined in ResultType.
- start_date: Date in milliseconds when the test began running.
- dur: Duration of the test run in milliseconds.
- log: A string listing any errors.
- """
- super(InstrumentationTestResult, self).__init__(
- full_name, test_type, dur, log)
- name_pieces = full_name.rsplit('#')
- if len(name_pieces) > 1:
- self._test_name = name_pieces[1]
- self._class_name = name_pieces[0]
- else:
- self._class_name = full_name
- self._test_name = full_name
- self._start_date = start_date
diff --git a/build/android/pylib/instrumentation/test_runner.py b/build/android/pylib/instrumentation/test_runner.py
deleted file mode 100644
index 0f2e53f..0000000
--- a/build/android/pylib/instrumentation/test_runner.py
+++ /dev/null
@@ -1,374 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Class for running instrumentation tests on a single device."""
-
-import logging
-import os
-import re
-import sys
-import time
-
-from pylib import constants
-from pylib import flag_changer
-from pylib import valgrind_tools
-from pylib.base import base_test_result
-from pylib.base import base_test_runner
-from pylib.device import device_errors
-from pylib.instrumentation import instrumentation_test_instance
-from pylib.instrumentation import json_perf_parser
-from pylib.instrumentation import test_result
-from pylib.local.device import local_device_instrumentation_test_run
-
-sys.path.append(os.path.join(constants.DIR_SOURCE_ROOT, 'build', 'util', 'lib',
- 'common'))
-import perf_tests_results_helper # pylint: disable=F0401
-
-
-_PERF_TEST_ANNOTATION = 'PerfTest'
-
-
-class TestRunner(base_test_runner.BaseTestRunner):
- """Responsible for running a series of tests connected to a single device."""
-
- _DEVICE_COVERAGE_DIR = 'chrome/test/coverage'
- _HOSTMACHINE_PERF_OUTPUT_FILE = '/tmp/chrome-profile'
- _DEVICE_PERF_OUTPUT_SEARCH_PREFIX = (constants.DEVICE_PERF_OUTPUT_DIR +
- '/chrome-profile*')
-
- def __init__(self, test_options, device, shard_index, test_pkg,
- additional_flags=None):
- """Create a new TestRunner.
-
- Args:
- test_options: An InstrumentationOptions object.
- device: Attached android device.
- shard_index: Shard index.
- test_pkg: A TestPackage object.
- additional_flags: A list of additional flags to add to the command line.
- """
- super(TestRunner, self).__init__(device, test_options.tool)
- self._lighttp_port = constants.LIGHTTPD_RANDOM_PORT_FIRST + shard_index
- self._logcat_monitor = None
-
- self.coverage_device_file = None
- self.coverage_dir = test_options.coverage_dir
- self.coverage_host_file = None
- self.options = test_options
- self.test_pkg = test_pkg
- # Use the correct command line file for the package under test.
- cmdline_file = [a.cmdline_file for a in constants.PACKAGE_INFO.itervalues()
- if a.test_package == self.test_pkg.GetPackageName()]
- assert len(cmdline_file) < 2, 'Multiple packages have the same test package'
- if len(cmdline_file) and cmdline_file[0]:
- self.flags = flag_changer.FlagChanger(self.device, cmdline_file[0])
- if additional_flags:
- self.flags.AddFlags(additional_flags)
- else:
- self.flags = None
-
- #override
- def InstallTestPackage(self):
- self.test_pkg.Install(self.device)
-
- def _GetInstrumentationArgs(self):
- ret = {}
- if self.options.wait_for_debugger:
- ret['debug'] = 'true'
- if self.coverage_dir:
- ret['coverage'] = 'true'
- ret['coverageFile'] = self.coverage_device_file
-
- return ret
-
- def _TakeScreenshot(self, test):
- """Takes a screenshot from the device."""
- screenshot_name = os.path.join(constants.SCREENSHOTS_DIR, '%s.png' % test)
- logging.info('Taking screenshot named %s', screenshot_name)
- self.device.TakeScreenshot(screenshot_name)
-
- def SetUp(self):
- """Sets up the test harness and device before all tests are run."""
- super(TestRunner, self).SetUp()
- if not self.device.HasRoot():
- logging.warning('Unable to enable java asserts for %s, non rooted device',
- str(self.device))
- else:
- if self.device.SetJavaAsserts(self.options.set_asserts):
- # TODO(jbudorick) How to best do shell restart after the
- # android_commands refactor?
- self.device.RunShellCommand('stop')
- self.device.RunShellCommand('start')
- self.device.WaitUntilFullyBooted()
-
- # We give different default value to launch HTTP server based on shard index
- # because it may have race condition when multiple processes are trying to
- # launch lighttpd with same port at same time.
- self.LaunchTestHttpServer(
- os.path.join(constants.DIR_SOURCE_ROOT), self._lighttp_port)
- if self.flags:
- self.flags.AddFlags(['--disable-fre', '--enable-test-intents'])
- if self.options.device_flags:
- with open(self.options.device_flags) as device_flags_file:
- stripped_flags = (l.strip() for l in device_flags_file)
- self.flags.AddFlags([flag for flag in stripped_flags if flag])
-
- def TearDown(self):
- """Cleans up the test harness and saves outstanding data from test run."""
- if self.flags:
- self.flags.Restore()
- super(TestRunner, self).TearDown()
-
- def TestSetup(self, test):
- """Sets up the test harness for running a particular test.
-
- Args:
- test: The name of the test that will be run.
- """
- self.SetupPerfMonitoringIfNeeded(test)
- self._SetupIndividualTestTimeoutScale(test)
- self.tool.SetupEnvironment()
-
- if self.flags and self._IsFreTest(test):
- self.flags.RemoveFlags(['--disable-fre'])
-
- # Make sure the forwarder is still running.
- self._RestartHttpServerForwarderIfNecessary()
-
- if self.coverage_dir:
- coverage_basename = '%s.ec' % test
- self.coverage_device_file = '%s/%s/%s' % (
- self.device.GetExternalStoragePath(),
- TestRunner._DEVICE_COVERAGE_DIR, coverage_basename)
- self.coverage_host_file = os.path.join(
- self.coverage_dir, coverage_basename)
-
- def _IsFreTest(self, test):
- """Determines whether a test is a first run experience test.
-
- Args:
- test: The name of the test to be checked.
-
- Returns:
- Whether the feature being tested is FirstRunExperience.
- """
- annotations = self.test_pkg.GetTestAnnotations(test)
- return 'FirstRunExperience' == annotations.get('Feature', None)
-
- def _IsPerfTest(self, test):
- """Determines whether a test is a performance test.
-
- Args:
- test: The name of the test to be checked.
-
- Returns:
- Whether the test is annotated as a performance test.
- """
- return _PERF_TEST_ANNOTATION in self.test_pkg.GetTestAnnotations(test)
-
- def SetupPerfMonitoringIfNeeded(self, test):
- """Sets up performance monitoring if the specified test requires it.
-
- Args:
- test: The name of the test to be run.
- """
- if not self._IsPerfTest(test):
- return
- self.device.RunShellCommand(
- ['rm', TestRunner._DEVICE_PERF_OUTPUT_SEARCH_PREFIX])
- self._logcat_monitor = self.device.GetLogcatMonitor()
- self._logcat_monitor.Start()
-
- def TestTeardown(self, test, result):
- """Cleans up the test harness after running a particular test.
-
- Depending on the options of this TestRunner this might handle performance
- tracking. This method will only be called if the test passed.
-
- Args:
- test: The name of the test that was just run.
- result: result for this test.
- """
-
- self.tool.CleanUpEnvironment()
-
- # The logic below relies on the test passing.
- if not result or not result.DidRunPass():
- return
-
- self.TearDownPerfMonitoring(test)
-
- if self.flags and self._IsFreTest(test):
- self.flags.AddFlags(['--disable-fre'])
-
- if self.coverage_dir:
- self.device.PullFile(
- self.coverage_device_file, self.coverage_host_file)
- self.device.RunShellCommand(
- 'rm -f %s' % self.coverage_device_file)
-
- def TearDownPerfMonitoring(self, test):
- """Cleans up performance monitoring if the specified test required it.
-
- Args:
- test: The name of the test that was just run.
- Raises:
- Exception: if there's anything wrong with the perf data.
- """
- if not self._IsPerfTest(test):
- return
- raw_test_name = test.split('#')[1]
-
- # Wait and grab annotation data so we can figure out which traces to parse
- regex = self._logcat_monitor.WaitFor(
- re.compile(r'\*\*PERFANNOTATION\(' + raw_test_name + r'\)\:(.*)'))
-
- # If the test is set to run on a specific device type only (IE: only
- # tablet or phone) and it is being run on the wrong device, the test
- # just quits and does not do anything. The java test harness will still
- # print the appropriate annotation for us, but will add --NORUN-- for
- # us so we know to ignore the results.
- # The --NORUN-- tag is managed by ChromeTabbedActivityTestBase.java
- if regex.group(1) != '--NORUN--':
-
- # Obtain the relevant perf data. The data is dumped to a
- # JSON formatted file.
- json_string = self.device.ReadFile(
- '/data/data/com.google.android.apps.chrome/files/PerfTestData.txt',
- as_root=True)
-
- if not json_string:
- raise Exception('Perf file is empty')
-
- if self.options.save_perf_json:
- json_local_file = '/tmp/chromium-android-perf-json-' + raw_test_name
- with open(json_local_file, 'w') as f:
- f.write(json_string)
- logging.info('Saving Perf UI JSON from test ' +
- test + ' to ' + json_local_file)
-
- raw_perf_data = regex.group(1).split(';')
-
- for raw_perf_set in raw_perf_data:
- if raw_perf_set:
- perf_set = raw_perf_set.split(',')
- if len(perf_set) != 3:
- raise Exception('Unexpected number of tokens in perf annotation '
- 'string: ' + raw_perf_set)
-
- # Process the performance data
- result = json_perf_parser.GetAverageRunInfoFromJSONString(json_string,
- perf_set[0])
- perf_tests_results_helper.PrintPerfResult(perf_set[1], perf_set[2],
- [result['average']],
- result['units'])
-
- def _SetupIndividualTestTimeoutScale(self, test):
- timeout_scale = self._GetIndividualTestTimeoutScale(test)
- valgrind_tools.SetChromeTimeoutScale(self.device, timeout_scale)
-
- def _GetIndividualTestTimeoutScale(self, test):
- """Returns the timeout scale for the given |test|."""
- annotations = self.test_pkg.GetTestAnnotations(test)
- timeout_scale = 1
- if 'TimeoutScale' in annotations:
- try:
- timeout_scale = int(annotations['TimeoutScale'])
- except ValueError:
- logging.warning('Non-integer value of TimeoutScale ignored. (%s)'
- % annotations['TimeoutScale'])
- if self.options.wait_for_debugger:
- timeout_scale *= 100
- return timeout_scale
-
- def _GetIndividualTestTimeoutSecs(self, test):
- """Returns the timeout in seconds for the given |test|."""
- annotations = self.test_pkg.GetTestAnnotations(test)
- if 'Manual' in annotations:
- return 10 * 60 * 60
- if 'IntegrationTest' in annotations:
- return 30 * 60
- if 'External' in annotations:
- return 10 * 60
- if 'EnormousTest' in annotations:
- return 10 * 60
- if 'LargeTest' in annotations or _PERF_TEST_ANNOTATION in annotations:
- return 5 * 60
- if 'MediumTest' in annotations:
- return 3 * 60
- if 'SmallTest' in annotations:
- return 1 * 60
-
- logging.warn(("Test size not found in annotations for test '%s', using " +
- "1 minute for timeout.") % test)
- return 1 * 60
-
- def _RunTest(self, test, timeout):
- """Runs a single instrumentation test.
-
- Args:
- test: Test class/method.
- timeout: Timeout time in seconds.
-
- Returns:
- The raw output of am instrument as a list of lines.
- """
- extras = self._GetInstrumentationArgs()
- extras['class'] = test
- return self.device.StartInstrumentation(
- '%s/%s' % (self.test_pkg.GetPackageName(), self.options.test_runner),
- raw=True, extras=extras, timeout=timeout, retries=3)
-
- def _GenerateTestResult(self, test, instr_result_code, instr_result_bundle,
- statuses, start_ms, duration_ms):
- results = instrumentation_test_instance.GenerateTestResults(
- instr_result_code, instr_result_bundle, statuses, start_ms, duration_ms)
- for r in results:
- if r.GetName() == test:
- return r
- logging.error('Could not find result for test: %s', test)
- return test_result.InstrumentationTestResult(
- test, base_test_result.ResultType.UNKNOWN, start_ms, duration_ms)
-
- #override
- def RunTest(self, test):
- results = base_test_result.TestRunResults()
- timeout = (self._GetIndividualTestTimeoutSecs(test) *
- self._GetIndividualTestTimeoutScale(test) *
- self.tool.GetTimeoutScale())
-
- start_ms = 0
- duration_ms = 0
- try:
- self.TestSetup(test)
-
- try:
- self.device.GoHome()
- except device_errors.CommandTimeoutError:
- logging.exception('Failed to focus the launcher.')
-
- time_ms = lambda: int(time.time() * 1000)
- start_ms = time_ms()
- raw_output = self._RunTest(test, timeout)
- duration_ms = time_ms() - start_ms
-
- # Parse the test output
- result_code, result_bundle, statuses = (
- instrumentation_test_instance.ParseAmInstrumentRawOutput(raw_output))
- result = self._GenerateTestResult(
- test, result_code, result_bundle, statuses, start_ms, duration_ms)
- if local_device_instrumentation_test_run.DidPackageCrashOnDevice(
- self.test_pkg.GetPackageName(), self.device):
- result.SetType(base_test_result.ResultType.CRASH)
- results.AddResult(result)
- except device_errors.CommandTimeoutError as e:
- results.AddResult(test_result.InstrumentationTestResult(
- test, base_test_result.ResultType.TIMEOUT, start_ms, duration_ms,
- log=str(e) or 'No information'))
- except device_errors.DeviceUnreachableError as e:
- results.AddResult(test_result.InstrumentationTestResult(
- test, base_test_result.ResultType.CRASH, start_ms, duration_ms,
- log=str(e) or 'No information'))
- self.TestTeardown(test, results)
- return (results, None if results.DidRunPass() else test)
diff --git a/build/android/pylib/junit/__init__.py b/build/android/pylib/junit/__init__.py
deleted file mode 100644
index 5cac026..0000000
--- a/build/android/pylib/junit/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
diff --git a/build/android/pylib/junit/setup.py b/build/android/pylib/junit/setup.py
deleted file mode 100644
index 94d4277..0000000
--- a/build/android/pylib/junit/setup.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from pylib.junit import test_runner
-
-def Setup(args):
- """Creates a test runner factory for junit tests.
-
- Args:
- args: an argparse.Namespace object.
- Return:
- A (runner_factory, tests) tuple.
- """
-
- def TestRunnerFactory(_unused_device, _unused_shard_index):
- return test_runner.JavaTestRunner(args)
-
- return (TestRunnerFactory, ['JUnit tests'])
-
diff --git a/build/android/pylib/junit/test_dispatcher.py b/build/android/pylib/junit/test_dispatcher.py
deleted file mode 100644
index 6e0d865..0000000
--- a/build/android/pylib/junit/test_dispatcher.py
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from pylib import constants
-from pylib.base import base_test_result
-
-def RunTests(tests, runner_factory):
- """Runs a set of java tests on the host.
-
- Return:
- A tuple containing the results & the exit code.
- """
- def run(t):
- runner = runner_factory(None, None)
- runner.SetUp()
- results_list, return_code = runner.RunTest(t)
- runner.TearDown()
- return (results_list, return_code == 0)
-
- test_run_results = base_test_result.TestRunResults()
- exit_code = 0
- for t in tests:
- results_list, passed = run(t)
- test_run_results.AddResults(results_list)
- if not passed:
- exit_code = constants.ERROR_EXIT_CODE
- return (test_run_results, exit_code)
\ No newline at end of file
diff --git a/build/android/pylib/junit/test_runner.py b/build/android/pylib/junit/test_runner.py
deleted file mode 100644
index a6d3bf9..0000000
--- a/build/android/pylib/junit/test_runner.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import json
-import os
-import tempfile
-
-from pylib import cmd_helper
-from pylib import constants
-from pylib.base import base_test_result
-from pylib.results import json_results
-
-class JavaTestRunner(object):
- """Runs java tests on the host."""
-
- def __init__(self, args):
- self._package_filter = args.package_filter
- self._runner_filter = args.runner_filter
- self._sdk_version = args.sdk_version
- self._test_filter = args.test_filter
- self._test_suite = args.test_suite
-
- def SetUp(self):
- pass
-
- def RunTest(self, _test):
- """Runs junit tests from |self._test_suite|."""
- with tempfile.NamedTemporaryFile() as json_file:
- java_script = os.path.join(
- constants.GetOutDirectory(), 'bin', self._test_suite)
- command = [java_script,
- '-test-jars', self._test_suite + '.jar',
- '-json-results-file', json_file.name]
- if self._test_filter:
- command.extend(['-gtest-filter', self._test_filter])
- if self._package_filter:
- command.extend(['-package-filter', self._package_filter])
- if self._runner_filter:
- command.extend(['-runner-filter', self._runner_filter])
- if self._sdk_version:
- command.extend(['-sdk-version', self._sdk_version])
- return_code = cmd_helper.RunCmd(command)
- results_list = json_results.ParseResultsFromJson(
- json.loads(json_file.read()))
- return (results_list, return_code)
-
- def TearDown(self):
- pass
-
diff --git a/build/android/pylib/linker/__init__.py b/build/android/pylib/linker/__init__.py
deleted file mode 100644
index af99437..0000000
--- a/build/android/pylib/linker/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
diff --git a/build/android/pylib/linker/setup.py b/build/android/pylib/linker/setup.py
deleted file mode 100644
index 5776f5a..0000000
--- a/build/android/pylib/linker/setup.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Setup for linker tests."""
-
-import os
-import sys
-
-from pylib import constants
-from pylib.linker import test_case
-from pylib.linker import test_runner
-
-sys.path.insert(0,
- os.path.join(constants.DIR_SOURCE_ROOT, 'build', 'util', 'lib',
- 'common'))
-import unittest_util # pylint: disable=F0401
-
-def Setup(args, _devices):
- """Creates a list of test cases and a runner factory.
-
- Args:
- args: an argparse.Namespace object.
- Returns:
- A tuple of (TestRunnerFactory, tests).
- """
- test_cases = [
- test_case.LinkerLibraryAddressTest,
- test_case.LinkerSharedRelroTest,
- test_case.LinkerRandomizationTest]
-
- low_memory_modes = [False, True]
- all_tests = [t(is_low_memory=m) for t in test_cases for m in low_memory_modes]
-
- if args.test_filter:
- all_test_names = [test.qualified_name for test in all_tests]
- filtered_test_names = unittest_util.FilterTestNames(all_test_names,
- args.test_filter)
- all_tests = [t for t in all_tests \
- if t.qualified_name in filtered_test_names]
-
- def TestRunnerFactory(device, _shard_index):
- return test_runner.LinkerTestRunner(device, args.tool)
-
- return (TestRunnerFactory, all_tests)
diff --git a/build/android/pylib/linker/test_case.py b/build/android/pylib/linker/test_case.py
deleted file mode 100644
index c7b0f50..0000000
--- a/build/android/pylib/linker/test_case.py
+++ /dev/null
@@ -1,496 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Base class for linker-specific test cases.
-
- The custom dynamic linker can only be tested through a custom test case
- for various technical reasons:
-
- - It's an 'invisible feature', i.e. it doesn't expose a new API or
- behaviour, all it does is save RAM when loading native libraries.
-
- - Checking that it works correctly requires several things that do not
- fit the existing GTest-based and instrumentation-based tests:
-
- - Native test code needs to be run in both the browser and renderer
- process at the same time just after loading native libraries, in
- a completely asynchronous way.
-
- - Each test case requires restarting a whole new application process
- with a different command-line.
-
- - Enabling test support in the Linker code requires building a special
- APK with a flag to activate special test-only support code in the
- Linker code itself.
-
- Host-driven tests have also been tried, but since they're really
- sub-classes of instrumentation tests, they didn't work well either.
-
- To build and run the linker tests, do the following:
-
- ninja -C out/Debug chromium_linker_test_apk
- build/android/test_runner.py linker
-
-"""
-# pylint: disable=R0201
-
-import logging
-import os
-import re
-import time
-
-from pylib import constants
-from pylib.base import base_test_result
-from pylib.device import device_errors
-from pylib.device import intent
-
-
-ResultType = base_test_result.ResultType
-
-_PACKAGE_NAME = 'org.chromium.chromium_linker_test_apk'
-_ACTIVITY_NAME = '.ChromiumLinkerTestActivity'
-_COMMAND_LINE_FILE = '/data/local/tmp/chromium-linker-test-command-line'
-
-# Path to the Linker.java source file.
-_LINKER_JAVA_SOURCE_PATH = (
- 'base/android/java/src/org/chromium/base/library_loader/Linker.java')
-
-# A regular expression used to extract the browser shared RELRO configuration
-# from the Java source file above.
-_RE_LINKER_BROWSER_CONFIG = re.compile(
- r'.*BROWSER_SHARED_RELRO_CONFIG\s+=\s+' +
- r'BROWSER_SHARED_RELRO_CONFIG_(\S+)\s*;.*',
- re.MULTILINE | re.DOTALL)
-
-# Logcat filters used during each test. Only the 'chromium' one is really
-# needed, but the logs are added to the TestResult in case of error, and
-# it is handy to have the 'chromium_android_linker' ones as well when
-# troubleshooting.
-_LOGCAT_FILTERS = ['*:s', 'chromium:v', 'chromium_android_linker:v']
-#_LOGCAT_FILTERS = ['*:v'] ## DEBUG
-
-# Regular expression used to match status lines in logcat.
-_RE_BROWSER_STATUS_LINE = re.compile(r' BROWSER_LINKER_TEST: (FAIL|SUCCESS)$')
-_RE_RENDERER_STATUS_LINE = re.compile(r' RENDERER_LINKER_TEST: (FAIL|SUCCESS)$')
-
-# Regular expression used to mach library load addresses in logcat.
-_RE_LIBRARY_ADDRESS = re.compile(
- r'(BROWSER|RENDERER)_LIBRARY_ADDRESS: (\S+) ([0-9A-Fa-f]+)')
-
-
-def _GetBrowserSharedRelroConfig():
- """Returns a string corresponding to the Linker's configuration of shared
- RELRO sections in the browser process. This parses the Java linker source
- file to get the appropriate information.
- Return:
- None in case of error (e.g. could not locate the source file).
- 'NEVER' if the browser process shall never use shared RELROs.
- 'LOW_RAM_ONLY' if if uses it only on low-end devices.
- 'ALWAYS' if it always uses a shared RELRO.
- """
- source_path = \
- os.path.join(constants.DIR_SOURCE_ROOT, _LINKER_JAVA_SOURCE_PATH)
- if not os.path.exists(source_path):
- logging.error('Could not find linker source file: ' + source_path)
- return None
-
- with open(source_path) as f:
- configs = _RE_LINKER_BROWSER_CONFIG.findall(f.read())
- if not configs:
- logging.error(
- 'Can\'t find browser shared RELRO configuration value in ' + \
- source_path)
- return None
-
- if configs[0] not in ['NEVER', 'LOW_RAM_ONLY', 'ALWAYS']:
- logging.error('Unexpected browser config value: ' + configs[0])
- return None
-
- logging.info('Found linker browser shared RELRO config: ' + configs[0])
- return configs[0]
-
-
-def _StartActivityAndWaitForLinkerTestStatus(device, timeout):
- """Force-start an activity and wait up to |timeout| seconds until the full
- linker test status lines appear in the logcat, recorded through |device|.
- Args:
- device: A DeviceUtils instance.
- timeout: Timeout in seconds
- Returns:
- A (status, logs) tuple, where status is a ResultType constant, and logs
- if the final logcat output as a string.
- """
-
- # 1. Start recording logcat with appropriate filters.
- with device.GetLogcatMonitor(filter_specs=_LOGCAT_FILTERS) as logmon:
-
- # 2. Force-start activity.
- device.StartActivity(
- intent.Intent(package=_PACKAGE_NAME, activity=_ACTIVITY_NAME),
- force_stop=True)
-
- # 3. Wait up to |timeout| seconds until the test status is in the logcat.
- result = ResultType.PASS
- try:
- browser_match = logmon.WaitFor(_RE_BROWSER_STATUS_LINE, timeout=timeout)
- logging.debug('Found browser match: %s', browser_match.group(0))
- renderer_match = logmon.WaitFor(_RE_RENDERER_STATUS_LINE,
- timeout=timeout)
- logging.debug('Found renderer match: %s', renderer_match.group(0))
- if (browser_match.group(1) != 'SUCCESS'
- or renderer_match.group(1) != 'SUCCESS'):
- result = ResultType.FAIL
- except device_errors.CommandTimeoutError:
- result = ResultType.TIMEOUT
-
- return result, '\n'.join(device.adb.Logcat(dump=True))
-
-
-class LibraryLoadMap(dict):
- """A helper class to pretty-print a map of library names to load addresses."""
- def __str__(self):
- items = ['\'%s\': 0x%x' % (name, address) for \
- (name, address) in self.iteritems()]
- return '{%s}' % (', '.join(items))
-
- def __repr__(self):
- return 'LibraryLoadMap(%s)' % self.__str__()
-
-
-class AddressList(list):
- """A helper class to pretty-print a list of load addresses."""
- def __str__(self):
- items = ['0x%x' % address for address in self]
- return '[%s]' % (', '.join(items))
-
- def __repr__(self):
- return 'AddressList(%s)' % self.__str__()
-
-
-def _ExtractLibraryLoadAddressesFromLogcat(logs):
- """Extract the names and addresses of shared libraries loaded in the
- browser and renderer processes.
- Args:
- logs: A string containing logcat output.
- Returns:
- A tuple (browser_libs, renderer_libs), where each item is a map of
- library names (strings) to library load addresses (ints), for the
- browser and renderer processes, respectively.
- """
- browser_libs = LibraryLoadMap()
- renderer_libs = LibraryLoadMap()
- for m in _RE_LIBRARY_ADDRESS.finditer(logs):
- process_type, lib_name, lib_address = m.groups()
- lib_address = int(lib_address, 16)
- if process_type == 'BROWSER':
- browser_libs[lib_name] = lib_address
- elif process_type == 'RENDERER':
- renderer_libs[lib_name] = lib_address
- else:
- assert False, 'Invalid process type'
-
- return browser_libs, renderer_libs
-
-
-def _CheckLoadAddressRandomization(lib_map_list, process_type):
- """Check that a map of library load addresses is random enough.
- Args:
- lib_map_list: a list of dictionaries that map library names (string)
- to load addresses (int). Each item in the list corresponds to a
- different run / process start.
- process_type: a string describing the process type.
- Returns:
- (status, logs) tuple, where <status> is True iff the load addresses are
- randomized, False otherwise, and <logs> is a string containing an error
- message detailing the libraries that are not randomized properly.
- """
- # Collect, for each library, its list of load addresses.
- lib_addr_map = {}
- for lib_map in lib_map_list:
- for lib_name, lib_address in lib_map.iteritems():
- if lib_name not in lib_addr_map:
- lib_addr_map[lib_name] = AddressList()
- lib_addr_map[lib_name].append(lib_address)
-
- logging.info('%s library load map: %s', process_type, lib_addr_map)
-
- # For each library, check the randomness of its load addresses.
- bad_libs = {}
- for lib_name, lib_address_list in lib_addr_map.iteritems():
- # If all addresses are different, skip to next item.
- lib_address_set = set(lib_address_list)
- # Consider that if there is more than one pair of identical addresses in
- # the list, then randomization is broken.
- if len(lib_address_set) < len(lib_address_list) - 1:
- bad_libs[lib_name] = lib_address_list
-
-
- if bad_libs:
- return False, '%s libraries failed randomization: %s' % \
- (process_type, bad_libs)
-
- return True, '%s libraries properly randomized: %s' % \
- (process_type, lib_addr_map)
-
-
-class LinkerTestCaseBase(object):
- """Base class for linker test cases."""
-
- def __init__(self, is_low_memory=False):
- """Create a test case.
- Args:
- is_low_memory: True to simulate a low-memory device, False otherwise.
- """
- self.is_low_memory = is_low_memory
- if is_low_memory:
- test_suffix = 'ForLowMemoryDevice'
- else:
- test_suffix = 'ForRegularDevice'
- class_name = self.__class__.__name__
- self.qualified_name = '%s.%s' % (class_name, test_suffix)
- self.tagged_name = self.qualified_name
-
- def _RunTest(self, _device):
- """Run the test, must be overriden.
- Args:
- _device: A DeviceUtils interface.
- Returns:
- A (status, log) tuple, where <status> is a ResultType constant, and <log>
- is the logcat output captured during the test in case of error, or None
- in case of success.
- """
- return ResultType.FAIL, 'Unimplemented _RunTest() method!'
-
- def Run(self, device):
- """Run the test on a given device.
- Args:
- device: Name of target device where to run the test.
- Returns:
- A base_test_result.TestRunResult() instance.
- """
- margin = 8
- print '[ %-*s ] %s' % (margin, 'RUN', self.tagged_name)
- logging.info('Running linker test: %s', self.tagged_name)
-
- # Create command-line file on device.
- command_line_flags = ''
- if self.is_low_memory:
- command_line_flags = '--low-memory-device'
- device.WriteFile(_COMMAND_LINE_FILE, command_line_flags)
-
- # Run the test.
- status, logs = self._RunTest(device)
-
- result_text = 'OK'
- if status == ResultType.FAIL:
- result_text = 'FAILED'
- elif status == ResultType.TIMEOUT:
- result_text = 'TIMEOUT'
- print '[ %*s ] %s' % (margin, result_text, self.tagged_name)
-
- results = base_test_result.TestRunResults()
- results.AddResult(
- base_test_result.BaseTestResult(
- self.tagged_name,
- status,
- log=logs))
-
- return results
-
- def __str__(self):
- return self.tagged_name
-
- def __repr__(self):
- return self.tagged_name
-
-
-class LinkerSharedRelroTest(LinkerTestCaseBase):
- """A linker test case to check the status of shared RELRO sections.
-
- The core of the checks performed here are pretty simple:
-
- - Clear the logcat and start recording with an appropriate set of filters.
- - Create the command-line appropriate for the test-case.
- - Start the activity (always forcing a cold start).
- - Every second, look at the current content of the filtered logcat lines
- and look for instances of the following:
-
- BROWSER_LINKER_TEST: <status>
- RENDERER_LINKER_TEST: <status>
-
- where <status> can be either FAIL or SUCCESS. These lines can appear
- in any order in the logcat. Once both browser and renderer status are
- found, stop the loop. Otherwise timeout after 30 seconds.
-
- Note that there can be other lines beginning with BROWSER_LINKER_TEST:
- and RENDERER_LINKER_TEST:, but are not followed by a <status> code.
-
- - The test case passes if the <status> for both the browser and renderer
- process are SUCCESS. Otherwise its a fail.
- """
- def _RunTest(self, device):
- # Wait up to 30 seconds until the linker test status is in the logcat.
- return _StartActivityAndWaitForLinkerTestStatus(device, timeout=30)
-
-
-class LinkerLibraryAddressTest(LinkerTestCaseBase):
- """A test case that verifies library load addresses.
-
- The point of this check is to ensure that the libraries are loaded
- according to the following rules:
-
- - For low-memory devices, they should always be loaded at the same address
- in both browser and renderer processes, both below 0x4000_0000.
-
- - For regular devices, the browser process should load libraries above
- 0x4000_0000, and renderer ones below it.
- """
- def _RunTest(self, device):
- result, logs = _StartActivityAndWaitForLinkerTestStatus(device, timeout=30)
-
- # Return immediately in case of timeout.
- if result == ResultType.TIMEOUT:
- return result, logs
-
- # Collect the library load addresses in the browser and renderer processes.
- browser_libs, renderer_libs = _ExtractLibraryLoadAddressesFromLogcat(logs)
-
- logging.info('Browser libraries: %s', browser_libs)
- logging.info('Renderer libraries: %s', renderer_libs)
-
- # Check that the same libraries are loaded into both processes:
- browser_set = set(browser_libs.keys())
- renderer_set = set(renderer_libs.keys())
- if browser_set != renderer_set:
- logging.error('Library set mistmach browser=%s renderer=%s',
- browser_libs.keys(), renderer_libs.keys())
- return ResultType.FAIL, logs
-
- # And that there are not empty.
- if not browser_set:
- logging.error('No libraries loaded in any process!')
- return ResultType.FAIL, logs
-
- # Check that the renderer libraries are loaded at 'low-addresses'. i.e.
- # below 0x4000_0000, for every kind of device.
- memory_boundary = 0x40000000
- bad_libs = []
- for lib_name, lib_address in renderer_libs.iteritems():
- if lib_address >= memory_boundary:
- bad_libs.append((lib_name, lib_address))
-
- if bad_libs:
- logging.error('Renderer libraries loaded at high addresses: %s', bad_libs)
- return ResultType.FAIL, logs
-
- browser_config = _GetBrowserSharedRelroConfig()
- if not browser_config:
- return ResultType.FAIL, 'Bad linker source configuration'
-
- if browser_config == 'ALWAYS' or \
- (browser_config == 'LOW_RAM_ONLY' and self.is_low_memory):
- # The libraries must all be loaded at the same addresses. This also
- # implicitly checks that the browser libraries are at low addresses.
- addr_mismatches = []
- for lib_name, lib_address in browser_libs.iteritems():
- lib_address2 = renderer_libs[lib_name]
- if lib_address != lib_address2:
- addr_mismatches.append((lib_name, lib_address, lib_address2))
-
- if addr_mismatches:
- logging.error('Library load address mismatches: %s',
- addr_mismatches)
- return ResultType.FAIL, logs
-
- # Otherwise, check that libraries are loaded at 'high-addresses'.
- # Note that for low-memory devices, the previous checks ensure that they
- # were loaded at low-addresses.
- else:
- bad_libs = []
- for lib_name, lib_address in browser_libs.iteritems():
- if lib_address < memory_boundary:
- bad_libs.append((lib_name, lib_address))
-
- if bad_libs:
- logging.error('Browser libraries loaded at low addresses: %s', bad_libs)
- return ResultType.FAIL, logs
-
- # Everything's ok.
- return ResultType.PASS, logs
-
-
-class LinkerRandomizationTest(LinkerTestCaseBase):
- """A linker test case to check that library load address randomization works
- properly between successive starts of the test program/activity.
-
- This starts the activity several time (each time forcing a new process
- creation) and compares the load addresses of the libraries in them to
- detect that they have changed.
-
- In theory, two successive runs could (very rarely) use the same load
- address, so loop 5 times and compare the values there. It is assumed
- that if there are more than one pair of identical addresses, then the
- load addresses are not random enough for this test.
- """
- def _RunTest(self, device):
- max_loops = 5
- browser_lib_map_list = []
- renderer_lib_map_list = []
- logs_list = []
- for _ in range(max_loops):
- # Start the activity.
- result, logs = _StartActivityAndWaitForLinkerTestStatus(
- device, timeout=30)
- if result == ResultType.TIMEOUT:
- # Something bad happened. Return immediately.
- return result, logs
-
- # Collect library addresses.
- browser_libs, renderer_libs = _ExtractLibraryLoadAddressesFromLogcat(logs)
- browser_lib_map_list.append(browser_libs)
- renderer_lib_map_list.append(renderer_libs)
- logs_list.append(logs)
-
- # Check randomization in the browser libraries.
- logs = '\n'.join(logs_list)
-
- browser_status, browser_logs = _CheckLoadAddressRandomization(
- browser_lib_map_list, 'Browser')
-
- renderer_status, renderer_logs = _CheckLoadAddressRandomization(
- renderer_lib_map_list, 'Renderer')
-
- browser_config = _GetBrowserSharedRelroConfig()
- if not browser_config:
- return ResultType.FAIL, 'Bad linker source configuration'
-
- if not browser_status:
- if browser_config == 'ALWAYS' or \
- (browser_config == 'LOW_RAM_ONLY' and self.is_low_memory):
- return ResultType.FAIL, browser_logs
-
- # IMPORTANT NOTE: The system's ASLR implementation seems to be very poor
- # when starting an activity process in a loop with "adb shell am start".
- #
- # When simulating a regular device, loading libraries in the browser
- # process uses a simple mmap(NULL, ...) to let the kernel device where to
- # load the file (this is similar to what System.loadLibrary() does).
- #
- # Unfortunately, at least in the context of this test, doing so while
- # restarting the activity with the activity manager very, very, often
- # results in the system using the same load address for all 5 runs, or
- # sometimes only 4 out of 5.
- #
- # This has been tested experimentally on both Android 4.1.2 and 4.3.
- #
- # Note that this behaviour doesn't seem to happen when starting an
- # application 'normally', i.e. when using the application launcher to
- # start the activity.
- logging.info('Ignoring system\'s low randomization of browser libraries' +
- ' for regular devices')
-
- if not renderer_status:
- return ResultType.FAIL, renderer_logs
-
- return ResultType.PASS, logs
diff --git a/build/android/pylib/linker/test_runner.py b/build/android/pylib/linker/test_runner.py
deleted file mode 100644
index b6803e4..0000000
--- a/build/android/pylib/linker/test_runner.py
+++ /dev/null
@@ -1,98 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Runs linker tests on a particular device."""
-
-import logging
-import os.path
-import sys
-import traceback
-
-from pylib import constants
-from pylib.base import base_test_result
-from pylib.base import base_test_runner
-from pylib.linker import test_case
-from pylib.utils import apk_helper
-
-
-# Name of the Android package to install for this to work.
-_PACKAGE_NAME = 'ChromiumLinkerTest'
-
-
-class LinkerExceptionTestResult(base_test_result.BaseTestResult):
- """Test result corresponding to a python exception in a host-custom test."""
-
- def __init__(self, test_name, exc_info):
- """Constructs a LinkerExceptionTestResult object.
-
- Args:
- test_name: name of the test which raised an exception.
- exc_info: exception info, ostensibly from sys.exc_info().
- """
- exc_type, exc_value, exc_traceback = exc_info
- trace_info = ''.join(traceback.format_exception(exc_type, exc_value,
- exc_traceback))
- log_msg = 'Exception:\n' + trace_info
-
- super(LinkerExceptionTestResult, self).__init__(
- test_name,
- base_test_result.ResultType.FAIL,
- log="%s %s" % (exc_type, log_msg))
-
-
-class LinkerTestRunner(base_test_runner.BaseTestRunner):
- """Orchestrates running a set of linker tests.
-
- Any Python exceptions in the tests are caught and translated into a failed
- result, rather than being re-raised on the main thread.
- """
-
- #override
- def __init__(self, device, tool):
- """Creates a new LinkerTestRunner.
-
- Args:
- device: Attached android device.
- tool: Name of the Valgrind tool.
- """
- super(LinkerTestRunner, self).__init__(device, tool)
-
- #override
- def InstallTestPackage(self):
- apk_path = os.path.join(
- constants.GetOutDirectory(), 'apks', '%s.apk' % _PACKAGE_NAME)
-
- if not os.path.exists(apk_path):
- raise Exception('%s not found, please build it' % apk_path)
-
- self.device.Install(apk_path)
-
- #override
- def RunTest(self, test):
- """Sets up and runs a test case.
-
- Args:
- test: An object which is ostensibly a subclass of LinkerTestCaseBase.
-
- Returns:
- A TestRunResults object which contains the result produced by the test
- and, in the case of a failure, the test that should be retried.
- """
-
- assert isinstance(test, test_case.LinkerTestCaseBase)
-
- try:
- results = test.Run(self.device)
- except Exception:
- logging.exception('Caught exception while trying to run test: ' +
- test.tagged_name)
- exc_info = sys.exc_info()
- results = base_test_result.TestRunResults()
- results.AddResult(LinkerExceptionTestResult(
- test.tagged_name, exc_info))
-
- if not results.DidRunPass():
- return results, test
- else:
- return results, None
diff --git a/build/android/pylib/local/__init__.py b/build/android/pylib/local/__init__.py
deleted file mode 100644
index 4d6aabb..0000000
--- a/build/android/pylib/local/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
diff --git a/build/android/pylib/local/device/__init__.py b/build/android/pylib/local/device/__init__.py
deleted file mode 100644
index 4d6aabb..0000000
--- a/build/android/pylib/local/device/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
diff --git a/build/android/pylib/local/device/local_device_environment.py b/build/android/pylib/local/device/local_device_environment.py
deleted file mode 100644
index 04f9ab7..0000000
--- a/build/android/pylib/local/device/local_device_environment.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from pylib.base import environment
-from pylib.device import adb_wrapper
-from pylib.device import device_errors
-from pylib.device import device_utils
-from pylib.utils import parallelizer
-
-
-class LocalDeviceEnvironment(environment.Environment):
-
- def __init__(self, args, _error_func):
- super(LocalDeviceEnvironment, self).__init__()
- self._device_serial = args.test_device
- self._devices = []
- self._max_tries = 1 + args.num_retries
- self._tool_name = args.tool
-
- #override
- def SetUp(self):
- available_devices = device_utils.DeviceUtils.HealthyDevices()
- if not available_devices:
- raise device_errors.NoDevicesError
- if self._device_serial:
- self._devices = [d for d in available_devices
- if d.adb.GetDeviceSerial() == self._device_serial]
- if not self._devices:
- raise device_errors.DeviceUnreachableError(
- 'Could not find device %r' % self._device_serial)
- else:
- self._devices = available_devices
-
- @property
- def devices(self):
- return self._devices
-
- @property
- def parallel_devices(self):
- return parallelizer.SyncParallelizer(self._devices)
-
- @property
- def max_tries(self):
- return self._max_tries
-
- @property
- def tool(self):
- return self._tool_name
-
- #override
- def TearDown(self):
- pass
-
diff --git a/build/android/pylib/local/device/local_device_instrumentation_test_run.py b/build/android/pylib/local/device/local_device_instrumentation_test_run.py
deleted file mode 100644
index e388fce..0000000
--- a/build/android/pylib/local/device/local_device_instrumentation_test_run.py
+++ /dev/null
@@ -1,207 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import re
-import time
-
-from pylib import flag_changer
-from pylib.base import base_test_result
-from pylib.base import test_run
-from pylib.constants import keyevent
-from pylib.device import device_errors
-from pylib.local.device import local_device_test_run
-
-
-TIMEOUT_ANNOTATIONS = [
- ('Manual', 10 * 60 * 60),
- ('IntegrationTest', 30 * 60),
- ('External', 10 * 60),
- ('EnormousTest', 10 * 60),
- ('LargeTest', 5 * 60),
- ('MediumTest', 3 * 60),
- ('SmallTest', 1 * 60),
-]
-
-
-# TODO(jbudorick): Make this private once the instrumentation test_runner is
-# deprecated.
-def DidPackageCrashOnDevice(package_name, device):
- # Dismiss any error dialogs. Limit the number in case we have an error
- # loop or we are failing to dismiss.
- try:
- for _ in xrange(10):
- package = _DismissCrashDialog(device)
- if not package:
- return False
- # Assume test package convention of ".test" suffix
- if package in package_name:
- return True
- except device_errors.CommandFailedError:
- logging.exception('Error while attempting to dismiss crash dialog.')
- return False
-
-
-_CURRENT_FOCUS_CRASH_RE = re.compile(
- r'\s*mCurrentFocus.*Application (Error|Not Responding): (\S+)}')
-
-
-def _DismissCrashDialog(device):
- # TODO(jbudorick): Try to grep the output on the device instead of using
- # large_output if/when DeviceUtils exposes a public interface for piped
- # shell command handling.
- for l in device.RunShellCommand(
- ['dumpsys', 'window', 'windows'], check_return=True, large_output=True):
- m = re.match(_CURRENT_FOCUS_CRASH_RE, l)
- if m:
- device.SendKeyEvent(keyevent.KEYCODE_DPAD_RIGHT)
- device.SendKeyEvent(keyevent.KEYCODE_DPAD_RIGHT)
- device.SendKeyEvent(keyevent.KEYCODE_ENTER)
- return m.group(2)
-
- return None
-
-
-class LocalDeviceInstrumentationTestRun(
- local_device_test_run.LocalDeviceTestRun):
- def __init__(self, env, test_instance):
- super(LocalDeviceInstrumentationTestRun, self).__init__(env, test_instance)
- self._flag_changers = {}
-
- def TestPackage(self):
- return None
-
- def SetUp(self):
- def substitute_external_storage(d, external_storage):
- if not d:
- return external_storage
- elif isinstance(d, list):
- return '/'.join(p if p else external_storage for p in d)
- else:
- return d
-
- def individual_device_set_up(dev, host_device_tuples):
- dev.Install(self._test_instance.apk_under_test)
- dev.Install(self._test_instance.test_apk)
-
- external_storage = dev.GetExternalStoragePath()
- host_device_tuples = [
- (h, substitute_external_storage(d, external_storage))
- for h, d in host_device_tuples]
- logging.info('instrumentation data deps:')
- for h, d in host_device_tuples:
- logging.info('%r -> %r', h, d)
- dev.PushChangedFiles(host_device_tuples)
- if self._test_instance.flags:
- if not self._test_instance.package_info:
- logging.error("Couldn't set flags: no package info")
- elif not self._test_instance.package_info.cmdline_file:
- logging.error("Couldn't set flags: no cmdline_file")
- else:
- self._flag_changers[str(dev)] = flag_changer.FlagChanger(
- dev, self._test_instance.package_info.cmdline_file)
- logging.debug('Attempting to set flags: %r',
- self._test_instance.flags)
- self._flag_changers[str(dev)].AddFlags(self._test_instance.flags)
-
- self._env.parallel_devices.pMap(
- individual_device_set_up,
- self._test_instance.GetDataDependencies())
-
- def TearDown(self):
- def individual_device_tear_down(dev):
- if str(dev) in self._flag_changers:
- self._flag_changers[str(dev)].Restore()
-
- self._env.parallel_devices.pMap(individual_device_tear_down)
-
- #override
- def _CreateShards(self, tests):
- return tests
-
- #override
- def _GetTests(self):
- return self._test_instance.GetTests()
-
- #override
- def _GetTestName(self, test):
- return '%s#%s' % (test['class'], test['method'])
-
- #override
- def _RunTest(self, device, test):
- extras = self._test_instance.GetHttpServerEnvironmentVars()
-
- if isinstance(test, list):
- if not self._test_instance.driver_apk:
- raise Exception('driver_apk does not exist. '
- 'Please build it and try again.')
-
- def name_and_timeout(t):
- n = self._GetTestName(t)
- i = self._GetTimeoutFromAnnotations(t['annotations'], n)
- return (n, i)
-
- test_names, timeouts = zip(*(name_and_timeout(t) for t in test))
-
- test_name = ','.join(test_names)
- target = '%s/%s' % (
- self._test_instance.driver_package,
- self._test_instance.driver_name)
- extras.update(
- self._test_instance.GetDriverEnvironmentVars(
- test_list=test_names))
- timeout = sum(timeouts)
- else:
- test_name = self._GetTestName(test)
- target = '%s/%s' % (
- self._test_instance.test_package, self._test_instance.test_runner)
- extras['class'] = test_name
- timeout = self._GetTimeoutFromAnnotations(test['annotations'], test_name)
-
- logging.info('preparing to run %s: %s' % (test_name, test))
-
- time_ms = lambda: int(time.time() * 1e3)
- start_ms = time_ms()
- output = device.StartInstrumentation(
- target, raw=True, extras=extras, timeout=timeout, retries=0)
- duration_ms = time_ms() - start_ms
-
- # TODO(jbudorick): Make instrumentation tests output a JSON so this
- # doesn't have to parse the output.
- logging.debug('output from %s:', test_name)
- for l in output:
- logging.debug(' %s', l)
-
- result_code, result_bundle, statuses = (
- self._test_instance.ParseAmInstrumentRawOutput(output))
- results = self._test_instance.GenerateTestResults(
- result_code, result_bundle, statuses, start_ms, duration_ms)
- if DidPackageCrashOnDevice(self._test_instance.test_package, device):
- for r in results:
- if r.GetType() == base_test_result.ResultType.UNKNOWN:
- r.SetType(base_test_result.ResultType.CRASH)
- return results
-
- #override
- def _ShouldShard(self):
- return True
-
- @staticmethod
- def _GetTimeoutFromAnnotations(annotations, test_name):
- for k, v in TIMEOUT_ANNOTATIONS:
- if k in annotations:
- timeout = v
- else:
- logging.warning('Using default 1 minute timeout for %s' % test_name)
- timeout = 60
-
- try:
- scale = int(annotations.get('TimeoutScale', 1))
- except ValueError as e:
- logging.warning("Non-integer value of TimeoutScale ignored. (%s)", str(e))
- scale = 1
- timeout *= scale
-
- return timeout
-
diff --git a/build/android/pylib/local/device/local_device_test_run.py b/build/android/pylib/local/device/local_device_test_run.py
deleted file mode 100644
index fa24eb1..0000000
--- a/build/android/pylib/local/device/local_device_test_run.py
+++ /dev/null
@@ -1,99 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-
-from pylib import valgrind_tools
-from pylib.base import base_test_result
-from pylib.base import test_run
-from pylib.base import test_collection
-
-
-class LocalDeviceTestRun(test_run.TestRun):
-
- def __init__(self, env, test_instance):
- super(LocalDeviceTestRun, self).__init__(env, test_instance)
- self._tools = {}
-
- #override
- def RunTests(self):
- tests = self._GetTests()
-
- def run_tests_on_device(dev, tests):
- r = base_test_result.TestRunResults()
- for test in tests:
- result = self._RunTest(dev, test)
- if isinstance(result, base_test_result.BaseTestResult):
- r.AddResult(result)
- elif isinstance(result, list):
- r.AddResults(result)
- else:
- raise Exception('Unexpected result type: %s' % type(result).__name__)
- if isinstance(tests, test_collection.TestCollection):
- tests.test_completed()
- return r
-
- tries = 0
- results = base_test_result.TestRunResults()
- all_fail_results = {}
- while tries < self._env.max_tries and tests:
- logging.debug('try %d, will run %d tests:', tries, len(tests))
- for t in tests:
- logging.debug(' %s', t)
-
- if self._ShouldShard():
- tc = test_collection.TestCollection(self._CreateShards(tests))
- try_results = self._env.parallel_devices.pMap(
- run_tests_on_device, tc).pGet(None)
- else:
- try_results = self._env.parallel_devices.pMap(
- run_tests_on_device, tests).pGet(None)
- for try_result in try_results:
- for result in try_result.GetAll():
- if result.GetType() in (base_test_result.ResultType.PASS,
- base_test_result.ResultType.SKIP):
- results.AddResult(result)
- else:
- all_fail_results[result.GetName()] = result
-
- results_names = set(r.GetName() for r in results.GetAll())
- tests = [t for t in tests if self._GetTestName(t) not in results_names]
- tries += 1
-
- all_unknown_test_names = set(self._GetTestName(t) for t in tests)
- all_failed_test_names = set(all_fail_results.iterkeys())
-
- unknown_tests = all_unknown_test_names.difference(all_failed_test_names)
- failed_tests = all_failed_test_names.intersection(all_unknown_test_names)
-
- if unknown_tests:
- results.AddResults(
- base_test_result.BaseTestResult(
- u, base_test_result.ResultType.UNKNOWN)
- for u in unknown_tests)
- if failed_tests:
- results.AddResults(all_fail_results[f] for f in failed_tests)
-
- return results
-
- def GetTool(self, device):
- if not str(device) in self._tools:
- self._tools[str(device)] = valgrind_tools.CreateTool(
- self._env.tool, device)
- return self._tools[str(device)]
-
- def _CreateShards(self, tests):
- raise NotImplementedError
-
- def _GetTestName(self, test):
- return test
-
- def _GetTests(self):
- raise NotImplementedError
-
- def _RunTest(self, device, test):
- raise NotImplementedError
-
- def _ShouldShard(self):
- raise NotImplementedError
diff --git a/build/android/pylib/local/local_test_server_spawner.py b/build/android/pylib/local/local_test_server_spawner.py
deleted file mode 100644
index 77f552e..0000000
--- a/build/android/pylib/local/local_test_server_spawner.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from pylib import chrome_test_server_spawner
-from pylib import forwarder
-from pylib.base import test_server
-
-
-class LocalTestServerSpawner(test_server.TestServer):
-
- def __init__(self, port, device, tool):
- super(LocalTestServerSpawner, self).__init__()
- self._device = device
- self._spawning_server = chrome_test_server_spawner.SpawningServer(
- port, device, tool)
- self._tool = tool
-
- @property
- def server_address(self):
- return self._spawning_server.server.server_address
-
- @property
- def port(self):
- return self.server_address[1]
-
- #override
- def SetUp(self):
- self._device.WriteFile(
- '%s/net-test-server-ports' % self._device.GetExternalStoragePath(),
- '%s:0' % str(self.port))
- forwarder.Forwarder.Map(
- [(self.port, self.port)], self._device, self._tool)
- self._spawning_server.Start()
-
- #override
- def Reset(self):
- self._spawning_server.CleanupState()
-
- #override
- def TearDown(self):
- self.Reset()
- self._spawning_server.Stop()
- forwarder.Forwarder.UnmapDevicePort(self.port, self._device)
-
diff --git a/build/android/pylib/monkey/__init__.py b/build/android/pylib/monkey/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/build/android/pylib/monkey/__init__.py
+++ /dev/null
diff --git a/build/android/pylib/monkey/setup.py b/build/android/pylib/monkey/setup.py
deleted file mode 100644
index fe690a5..0000000
--- a/build/android/pylib/monkey/setup.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Generates test runner factory and tests for monkey tests."""
-
-from pylib.monkey import test_runner
-
-
-def Setup(test_options):
- """Create and return the test runner factory and tests.
-
- Args:
- test_options: A MonkeyOptions object.
-
- Returns:
- A tuple of (TestRunnerFactory, tests).
- """
- # Token to replicate across devices as the "test". The TestRunner does all of
- # the work to run the test.
- tests = ['MonkeyTest']
-
- def TestRunnerFactory(device, shard_index):
- return test_runner.TestRunner(
- test_options, device, shard_index)
-
- return (TestRunnerFactory, tests)
diff --git a/build/android/pylib/monkey/test_options.py b/build/android/pylib/monkey/test_options.py
deleted file mode 100644
index 54d3d08..0000000
--- a/build/android/pylib/monkey/test_options.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Defines the MonkeyOptions named tuple."""
-
-import collections
-
-MonkeyOptions = collections.namedtuple('MonkeyOptions', [
- 'verbose_count',
- 'package',
- 'event_count',
- 'category',
- 'throttle',
- 'seed',
- 'extra_args'])
diff --git a/build/android/pylib/monkey/test_runner.py b/build/android/pylib/monkey/test_runner.py
deleted file mode 100644
index 3fd1797..0000000
--- a/build/android/pylib/monkey/test_runner.py
+++ /dev/null
@@ -1,106 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Runs a monkey test on a single device."""
-
-import logging
-import random
-
-from pylib import constants
-from pylib.base import base_test_result
-from pylib.base import base_test_runner
-from pylib.device import device_errors
-from pylib.device import intent
-
-_CHROME_PACKAGE = constants.PACKAGE_INFO['chrome'].package
-
-class TestRunner(base_test_runner.BaseTestRunner):
- """A TestRunner instance runs a monkey test on a single device."""
-
- def __init__(self, test_options, device, _):
- super(TestRunner, self).__init__(device, None)
- self._options = test_options
- self._package = constants.PACKAGE_INFO[self._options.package].package
- self._activity = constants.PACKAGE_INFO[self._options.package].activity
-
- def _LaunchMonkeyTest(self):
- """Runs monkey test for a given package.
-
- Returns:
- Output from the monkey command on the device.
- """
-
- timeout_ms = self._options.event_count * self._options.throttle * 1.5
-
- cmd = ['monkey',
- '-p %s' % self._package,
- ' '.join(['-c %s' % c for c in self._options.category]),
- '--throttle %d' % self._options.throttle,
- '-s %d' % (self._options.seed or random.randint(1, 100)),
- '-v ' * self._options.verbose_count,
- '--monitor-native-crashes',
- '--kill-process-after-error',
- self._options.extra_args,
- '%d' % self._options.event_count]
- return self.device.RunShellCommand(' '.join(cmd), timeout=timeout_ms)
-
- def RunTest(self, test_name):
- """Run a Monkey test on the device.
-
- Args:
- test_name: String to use for logging the test result.
-
- Returns:
- A tuple of (TestRunResults, retry).
- """
- self.device.StartActivity(
- intent.Intent(package=self._package, activity=self._activity,
- action='android.intent.action.MAIN'),
- blocking=True, force_stop=True)
-
- # Chrome crashes are not always caught by Monkey test runner.
- # Verify Chrome has the same PID before and after the test.
- before_pids = self.device.GetPids(self._package)
-
- # Run the test.
- output = ''
- if before_pids:
- output = '\n'.join(self._LaunchMonkeyTest())
- after_pids = self.device.GetPids(self._package)
-
- crashed = True
- if not self._package in before_pids:
- logging.error('Failed to start the process.')
- elif not self._package in after_pids:
- logging.error('Process %s has died.', before_pids[self._package])
- elif before_pids[self._package] != after_pids[self._package]:
- logging.error('Detected process restart %s -> %s',
- before_pids[self._package], after_pids[self._package])
- else:
- crashed = False
-
- results = base_test_result.TestRunResults()
- success_pattern = 'Events injected: %d' % self._options.event_count
- if success_pattern in output and not crashed:
- result = base_test_result.BaseTestResult(
- test_name, base_test_result.ResultType.PASS, log=output)
- else:
- result = base_test_result.BaseTestResult(
- test_name, base_test_result.ResultType.FAIL, log=output)
- if 'chrome' in self._options.package:
- logging.warning('Starting MinidumpUploadService...')
- # TODO(jbudorick): Update this after upstreaming.
- minidump_intent = intent.Intent(
- action='%s.crash.ACTION_FIND_ALL' % _CHROME_PACKAGE,
- package=self._package,
- activity='%s.crash.MinidumpUploadService' % _CHROME_PACKAGE)
- try:
- self.device.RunShellCommand(
- ['am', 'startservice'] + minidump_intent.am_args,
- as_root=True, check_return=True)
- except device_errors.CommandFailedError:
- logging.exception('Failed to start MinidumpUploadService')
-
- results.AddResult(result)
- return results, False
diff --git a/build/android/pylib/perf/__init__.py b/build/android/pylib/perf/__init__.py
deleted file mode 100644
index 9228df8..0000000
--- a/build/android/pylib/perf/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
diff --git a/build/android/pylib/perf/cache_control.py b/build/android/pylib/perf/cache_control.py
deleted file mode 100644
index 8065cf9..0000000
--- a/build/android/pylib/perf/cache_control.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from pylib import android_commands
-from pylib.device import device_utils
-
-class CacheControl(object):
- _DROP_CACHES = '/proc/sys/vm/drop_caches'
-
- def __init__(self, device):
- # TODO(jbudorick) Remove once telemetry gets switched over.
- if isinstance(device, android_commands.AndroidCommands):
- device = device_utils.DeviceUtils(device)
- self._device = device
-
- def DropRamCaches(self):
- """Drops the filesystem ram caches for performance testing."""
- self._device.RunShellCommand('sync', as_root=True)
- self._device.WriteFile(CacheControl._DROP_CACHES, '3', as_root=True)
-
diff --git a/build/android/pylib/perf/perf_control.py b/build/android/pylib/perf/perf_control.py
deleted file mode 100644
index f89f397..0000000
--- a/build/android/pylib/perf/perf_control.py
+++ /dev/null
@@ -1,161 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import atexit
-import logging
-
-from pylib import android_commands
-from pylib.device import device_errors
-from pylib.device import device_utils
-
-
-class PerfControl(object):
- """Provides methods for setting the performance mode of a device."""
- _CPU_PATH = '/sys/devices/system/cpu'
- _KERNEL_MAX = '/sys/devices/system/cpu/kernel_max'
-
- def __init__(self, device):
- # TODO(jbudorick) Remove once telemetry gets switched over.
- if isinstance(device, android_commands.AndroidCommands):
- device = device_utils.DeviceUtils(device)
- self._device = device
- # this will raise an AdbCommandFailedError if no CPU files are found
- self._cpu_files = self._device.RunShellCommand(
- 'ls -d cpu[0-9]*', cwd=self._CPU_PATH, check_return=True, as_root=True)
- assert self._cpu_files, 'Failed to detect CPUs.'
- self._cpu_file_list = ' '.join(self._cpu_files)
- logging.info('CPUs found: %s', self._cpu_file_list)
- self._have_mpdecision = self._device.FileExists('/system/bin/mpdecision')
-
- def SetHighPerfMode(self):
- """Sets the highest stable performance mode for the device."""
- try:
- self._device.EnableRoot()
- except device_errors.CommandFailedError:
- message = 'Need root for performance mode. Results may be NOISY!!'
- logging.warning(message)
- # Add an additional warning at exit, such that it's clear that any results
- # may be different/noisy (due to the lack of intended performance mode).
- atexit.register(logging.warning, message)
- return
-
- product_model = self._device.product_model
- # TODO(epenner): Enable on all devices (http://crbug.com/383566)
- if 'Nexus 4' == product_model:
- self._ForceAllCpusOnline(True)
- if not self._AllCpusAreOnline():
- logging.warning('Failed to force CPUs online. Results may be NOISY!')
- self._SetScalingGovernorInternal('performance')
- elif 'Nexus 5' == product_model:
- self._ForceAllCpusOnline(True)
- if not self._AllCpusAreOnline():
- logging.warning('Failed to force CPUs online. Results may be NOISY!')
- self._SetScalingGovernorInternal('performance')
- self._SetScalingMaxFreq(1190400)
- self._SetMaxGpuClock(200000000)
- else:
- self._SetScalingGovernorInternal('performance')
-
- def SetPerfProfilingMode(self):
- """Enables all cores for reliable perf profiling."""
- self._ForceAllCpusOnline(True)
- self._SetScalingGovernorInternal('performance')
- if not self._AllCpusAreOnline():
- if not self._device.HasRoot():
- raise RuntimeError('Need root to force CPUs online.')
- raise RuntimeError('Failed to force CPUs online.')
-
- def SetDefaultPerfMode(self):
- """Sets the performance mode for the device to its default mode."""
- if not self._device.HasRoot():
- return
- product_model = self._device.product_model
- if 'Nexus 5' == product_model:
- if self._AllCpusAreOnline():
- self._SetScalingMaxFreq(2265600)
- self._SetMaxGpuClock(450000000)
-
- governor_mode = {
- 'GT-I9300': 'pegasusq',
- 'Galaxy Nexus': 'interactive',
- 'Nexus 4': 'ondemand',
- 'Nexus 5': 'ondemand',
- 'Nexus 7': 'interactive',
- 'Nexus 10': 'interactive'
- }.get(product_model, 'ondemand')
- self._SetScalingGovernorInternal(governor_mode)
- self._ForceAllCpusOnline(False)
-
- def GetCpuInfo(self):
- online = (output.rstrip() == '1' and status == 0
- for (_, output, status) in self._ForEachCpu('cat "$CPU/online"'))
- governor = (output.rstrip() if status == 0 else None
- for (_, output, status)
- in self._ForEachCpu('cat "$CPU/cpufreq/scaling_governor"'))
- return zip(self._cpu_files, online, governor)
-
- def _ForEachCpu(self, cmd):
- script = '; '.join([
- 'for CPU in %s' % self._cpu_file_list,
- 'do %s' % cmd,
- 'echo -n "%~%$?%~%"',
- 'done'
- ])
- output = self._device.RunShellCommand(
- script, cwd=self._CPU_PATH, check_return=True, as_root=True)
- output = '\n'.join(output).split('%~%')
- return zip(self._cpu_files, output[0::2], (int(c) for c in output[1::2]))
-
- def _WriteEachCpuFile(self, path, value):
- results = self._ForEachCpu(
- 'test -e "$CPU/{path}" && echo {value} > "$CPU/{path}"'.format(
- path=path, value=value))
- cpus = ' '.join(cpu for (cpu, _, status) in results if status == 0)
- if cpus:
- logging.info('Successfully set %s to %r on: %s', path, value, cpus)
- else:
- logging.warning('Failed to set %s to %r on any cpus')
-
- def _SetScalingGovernorInternal(self, value):
- self._WriteEachCpuFile('cpufreq/scaling_governor', value)
-
- def _SetScalingMaxFreq(self, value):
- self._WriteEachCpuFile('cpufreq/scaling_max_freq', '%d' % value)
-
- def _SetMaxGpuClock(self, value):
- self._device.WriteFile('/sys/class/kgsl/kgsl-3d0/max_gpuclk',
- str(value),
- as_root=True)
-
- def _AllCpusAreOnline(self):
- results = self._ForEachCpu('cat "$CPU/online"')
- # TODO(epenner): Investigate why file may be missing
- # (http://crbug.com/397118)
- return all(output.rstrip() == '1' and status == 0
- for (cpu, output, status) in results
- if cpu != 'cpu0')
-
- def _ForceAllCpusOnline(self, force_online):
- """Enable all CPUs on a device.
-
- Some vendors (or only Qualcomm?) hot-plug their CPUs, which can add noise
- to measurements:
- - In perf, samples are only taken for the CPUs that are online when the
- measurement is started.
- - The scaling governor can't be set for an offline CPU and frequency scaling
- on newly enabled CPUs adds noise to both perf and tracing measurements.
-
- It appears Qualcomm is the only vendor that hot-plugs CPUs, and on Qualcomm
- this is done by "mpdecision".
-
- """
- if self._have_mpdecision:
- script = 'stop mpdecision' if force_online else 'start mpdecision'
- self._device.RunShellCommand(script, check_return=True, as_root=True)
-
- if not self._have_mpdecision and not self._AllCpusAreOnline():
- logging.warning('Unexpected cpu hot plugging detected.')
-
- if force_online:
- self._ForEachCpu('echo 1 > "$CPU/online"')
diff --git a/build/android/pylib/perf/perf_control_unittest.py b/build/android/pylib/perf/perf_control_unittest.py
deleted file mode 100644
index 69b8b46..0000000
--- a/build/android/pylib/perf/perf_control_unittest.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-# pylint: disable=W0212
-
-import os
-import sys
-import unittest
-
-sys.path.append(os.path.join(os.path.dirname(__file__), os.pardir, os.pardir))
-
-from pylib.device import device_utils
-from pylib.perf import perf_control
-
-class TestPerfControl(unittest.TestCase):
- def setUp(self):
- if not os.getenv('BUILDTYPE'):
- os.environ['BUILDTYPE'] = 'Debug'
-
- devices = device_utils.DeviceUtils.HealthyDevices()
- self.assertGreater(len(devices), 0, 'No device attached!')
- self._device = devices[0]
-
- def testHighPerfMode(self):
- perf = perf_control.PerfControl(self._device)
- try:
- perf.SetPerfProfilingMode()
- cpu_info = perf.GetCpuInfo()
- self.assertEquals(len(perf._cpu_files), len(cpu_info))
- for _, online, governor in cpu_info:
- self.assertTrue(online)
- self.assertEquals('performance', governor)
- finally:
- perf.SetDefaultPerfMode()
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/build/android/pylib/perf/setup.py b/build/android/pylib/perf/setup.py
deleted file mode 100644
index 8e1fc28..0000000
--- a/build/android/pylib/perf/setup.py
+++ /dev/null
@@ -1,97 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Generates test runner factory and tests for performance tests."""
-
-import json
-import fnmatch
-import logging
-import os
-import shutil
-
-from pylib import constants
-from pylib import forwarder
-from pylib.device import device_list
-from pylib.device import device_utils
-from pylib.perf import test_runner
-from pylib.utils import test_environment
-
-
-def _GetAllDevices():
- devices_path = os.path.join(os.environ.get('CHROMIUM_OUT_DIR', 'out'),
- device_list.LAST_DEVICES_FILENAME)
- try:
- devices = [device_utils.DeviceUtils(s)
- for s in device_list.GetPersistentDeviceList(devices_path)]
- except IOError as e:
- logging.error('Unable to find %s [%s]', devices_path, e)
- devices = device_utils.DeviceUtils.HealthyDevices()
- return sorted(devices)
-
-
-def _GetStepsDictFromSingleStep(test_options):
- # Running a single command, build the tests structure.
- steps_dict = {
- 'version': 1,
- 'steps': {
- 'single_step': {
- 'device_affinity': 0,
- 'cmd': test_options.single_step
- },
- }
- }
- return steps_dict
-
-
-def _GetStepsDict(test_options):
- if test_options.single_step:
- return _GetStepsDictFromSingleStep(test_options)
- if test_options.steps:
- with file(test_options.steps, 'r') as f:
- steps = json.load(f)
-
- # Already using the new format.
- assert steps['version'] == 1
- return steps
-
-
-def Setup(test_options):
- """Create and return the test runner factory and tests.
-
- Args:
- test_options: A PerformanceOptions object.
-
- Returns:
- A tuple of (TestRunnerFactory, tests, devices).
- """
- # TODO(bulach): remove this once the bot side lands. BUG=318369
- constants.SetBuildType('Release')
- if os.path.exists(constants.PERF_OUTPUT_DIR):
- shutil.rmtree(constants.PERF_OUTPUT_DIR)
- os.makedirs(constants.PERF_OUTPUT_DIR)
-
- # Before running the tests, kill any leftover server.
- test_environment.CleanupLeftoverProcesses()
-
- # We want to keep device affinity, so return all devices ever seen.
- all_devices = _GetAllDevices()
-
- steps_dict = _GetStepsDict(test_options)
- sorted_step_names = sorted(steps_dict['steps'].keys())
-
- if test_options.test_filter:
- sorted_step_names = fnmatch.filter(sorted_step_names,
- test_options.test_filter)
-
- flaky_steps = []
- if test_options.flaky_steps:
- with file(test_options.flaky_steps, 'r') as f:
- flaky_steps = json.load(f)
-
- def TestRunnerFactory(device, shard_index):
- return test_runner.TestRunner(
- test_options, device, shard_index, len(all_devices),
- steps_dict, flaky_steps)
-
- return (TestRunnerFactory, sorted_step_names, all_devices)
diff --git a/build/android/pylib/perf/surface_stats_collector.py b/build/android/pylib/perf/surface_stats_collector.py
deleted file mode 100644
index c7e7527..0000000
--- a/build/android/pylib/perf/surface_stats_collector.py
+++ /dev/null
@@ -1,191 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import Queue
-import datetime
-import logging
-import re
-import threading
-from pylib import android_commands
-from pylib.device import device_utils
-
-
-# Log marker containing SurfaceTexture timestamps.
-_SURFACE_TEXTURE_TIMESTAMPS_MESSAGE = 'SurfaceTexture update timestamps'
-_SURFACE_TEXTURE_TIMESTAMP_RE = r'\d+'
-
-
-class SurfaceStatsCollector(object):
- """Collects surface stats for a SurfaceView from the output of SurfaceFlinger.
-
- Args:
- device: A DeviceUtils instance.
- """
-
- def __init__(self, device):
- # TODO(jbudorick) Remove once telemetry gets switched over.
- if isinstance(device, android_commands.AndroidCommands):
- device = device_utils.DeviceUtils(device)
- self._device = device
- self._collector_thread = None
- self._surface_before = None
- self._get_data_event = None
- self._data_queue = None
- self._stop_event = None
- self._warn_about_empty_data = True
-
- def DisableWarningAboutEmptyData(self):
- self._warn_about_empty_data = False
-
- def Start(self):
- assert not self._collector_thread
-
- if self._ClearSurfaceFlingerLatencyData():
- self._get_data_event = threading.Event()
- self._stop_event = threading.Event()
- self._data_queue = Queue.Queue()
- self._collector_thread = threading.Thread(target=self._CollectorThread)
- self._collector_thread.start()
- else:
- raise Exception('SurfaceFlinger not supported on this device.')
-
- def Stop(self):
- assert self._collector_thread
- (refresh_period, timestamps) = self._GetDataFromThread()
- if self._collector_thread:
- self._stop_event.set()
- self._collector_thread.join()
- self._collector_thread = None
- return (refresh_period, timestamps)
-
- def _CollectorThread(self):
- last_timestamp = 0
- timestamps = []
- retries = 0
-
- while not self._stop_event.is_set():
- self._get_data_event.wait(1)
- try:
- refresh_period, new_timestamps = self._GetSurfaceFlingerFrameData()
- if refresh_period is None or timestamps is None:
- retries += 1
- if retries < 3:
- continue
- if last_timestamp:
- # Some data has already been collected, but either the app
- # was closed or there's no new data. Signal the main thread and
- # wait.
- self._data_queue.put((None, None))
- self._stop_event.wait()
- break
- raise Exception('Unable to get surface flinger latency data')
-
- timestamps += [timestamp for timestamp in new_timestamps
- if timestamp > last_timestamp]
- if len(timestamps):
- last_timestamp = timestamps[-1]
-
- if self._get_data_event.is_set():
- self._get_data_event.clear()
- self._data_queue.put((refresh_period, timestamps))
- timestamps = []
- except Exception as e:
- # On any error, before aborting, put the exception into _data_queue to
- # prevent the main thread from waiting at _data_queue.get() infinitely.
- self._data_queue.put(e)
- raise
-
- def _GetDataFromThread(self):
- self._get_data_event.set()
- ret = self._data_queue.get()
- if isinstance(ret, Exception):
- raise ret
- return ret
-
- def _ClearSurfaceFlingerLatencyData(self):
- """Clears the SurfaceFlinger latency data.
-
- Returns:
- True if SurfaceFlinger latency is supported by the device, otherwise
- False.
- """
- # The command returns nothing if it is supported, otherwise returns many
- # lines of result just like 'dumpsys SurfaceFlinger'.
- results = self._device.RunShellCommand(
- 'dumpsys SurfaceFlinger --latency-clear SurfaceView')
- return not len(results)
-
- def GetSurfaceFlingerPid(self):
- results = self._device.RunShellCommand('ps | grep surfaceflinger')
- if not results:
- raise Exception('Unable to get surface flinger process id')
- pid = results[0].split()[1]
- return pid
-
- def _GetSurfaceFlingerFrameData(self):
- """Returns collected SurfaceFlinger frame timing data.
-
- Returns:
- A tuple containing:
- - The display's nominal refresh period in milliseconds.
- - A list of timestamps signifying frame presentation times in
- milliseconds.
- The return value may be (None, None) if there was no data collected (for
- example, if the app was closed before the collector thread has finished).
- """
- # adb shell dumpsys SurfaceFlinger --latency <window name>
- # prints some information about the last 128 frames displayed in
- # that window.
- # The data returned looks like this:
- # 16954612
- # 7657467895508 7657482691352 7657493499756
- # 7657484466553 7657499645964 7657511077881
- # 7657500793457 7657516600576 7657527404785
- # (...)
- #
- # The first line is the refresh period (here 16.95 ms), it is followed
- # by 128 lines w/ 3 timestamps in nanosecond each:
- # A) when the app started to draw
- # B) the vsync immediately preceding SF submitting the frame to the h/w
- # C) timestamp immediately after SF submitted that frame to the h/w
- #
- # The difference between the 1st and 3rd timestamp is the frame-latency.
- # An interesting data is when the frame latency crosses a refresh period
- # boundary, this can be calculated this way:
- #
- # ceil((C - A) / refresh-period)
- #
- # (each time the number above changes, we have a "jank").
- # If this happens a lot during an animation, the animation appears
- # janky, even if it runs at 60 fps in average.
- #
- # We use the special "SurfaceView" window name because the statistics for
- # the activity's main window are not updated when the main web content is
- # composited into a SurfaceView.
- results = self._device.RunShellCommand(
- 'dumpsys SurfaceFlinger --latency SurfaceView')
- if not len(results):
- return (None, None)
-
- timestamps = []
- nanoseconds_per_millisecond = 1e6
- refresh_period = long(results[0]) / nanoseconds_per_millisecond
-
- # If a fence associated with a frame is still pending when we query the
- # latency data, SurfaceFlinger gives the frame a timestamp of INT64_MAX.
- # Since we only care about completed frames, we will ignore any timestamps
- # with this value.
- pending_fence_timestamp = (1 << 63) - 1
-
- for line in results[1:]:
- fields = line.split()
- if len(fields) != 3:
- continue
- timestamp = long(fields[1])
- if timestamp == pending_fence_timestamp:
- continue
- timestamp /= nanoseconds_per_millisecond
- timestamps.append(timestamp)
-
- return (refresh_period, timestamps)
diff --git a/build/android/pylib/perf/surface_stats_collector_unittest.py b/build/android/pylib/perf/surface_stats_collector_unittest.py
deleted file mode 100644
index e905d73..0000000
--- a/build/android/pylib/perf/surface_stats_collector_unittest.py
+++ /dev/null
@@ -1,64 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Unittests for SurfaceStatsCollector."""
-# pylint: disable=W0212
-
-import unittest
-
-from pylib.perf.surface_stats_collector import SurfaceStatsCollector
-
-
-class TestSurfaceStatsCollector(unittest.TestCase):
- @staticmethod
- def _CreateUniformTimestamps(base, num, delta):
- return [base + i * delta for i in range(1, num + 1)]
-
- @staticmethod
- def _CreateDictionaryFromResults(results):
- dictionary = {}
- for result in results:
- dictionary[result.name] = result
- return dictionary
-
- def setUp(self):
- self.refresh_period = 0.1
-
- def testOneFrameDelta(self):
- timestamps = self._CreateUniformTimestamps(0, 10, self.refresh_period)
- results = self._CreateDictionaryFromResults(
- SurfaceStatsCollector._CalculateResults(
- self.refresh_period, timestamps, ''))
-
- self.assertEquals(results['avg_surface_fps'].value,
- int(round(1 / self.refresh_period)))
- self.assertEquals(results['jank_count'].value, 0)
- self.assertEquals(results['max_frame_delay'].value, 1)
- self.assertEquals(len(results['frame_lengths'].value), len(timestamps) - 1)
-
- def testAllFramesTooShort(self):
- timestamps = self._CreateUniformTimestamps(0, 10, self.refresh_period / 100)
- self.assertRaises(Exception,
- SurfaceStatsCollector._CalculateResults,
- [self.refresh_period, timestamps, ''])
-
- def testSomeFramesTooShort(self):
- timestamps = self._CreateUniformTimestamps(0, 5, self.refresh_period)
- # The following timestamps should be skipped.
- timestamps += self._CreateUniformTimestamps(timestamps[4],
- 5,
- self.refresh_period / 100)
- timestamps += self._CreateUniformTimestamps(timestamps[4],
- 5,
- self.refresh_period)
-
- results = self._CreateDictionaryFromResults(
- SurfaceStatsCollector._CalculateResults(
- self.refresh_period, timestamps, ''))
-
- self.assertEquals(len(results['frame_lengths'].value), 9)
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/build/android/pylib/perf/test_options.py b/build/android/pylib/perf/test_options.py
deleted file mode 100644
index eff928e..0000000
--- a/build/android/pylib/perf/test_options.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Defines the PerfOptions named tuple."""
-
-import collections
-
-PerfOptions = collections.namedtuple('PerfOptions', [
- 'steps',
- 'flaky_steps',
- 'output_json_list',
- 'print_step',
- 'no_timeout',
- 'test_filter',
- 'dry_run',
- 'single_step',
- 'collect_chartjson_data',
- 'output_chartjson_data',
- 'max_battery_temp',
- 'min_battery_level',
-])
diff --git a/build/android/pylib/perf/test_runner.py b/build/android/pylib/perf/test_runner.py
deleted file mode 100644
index d21a9b7..0000000
--- a/build/android/pylib/perf/test_runner.py
+++ /dev/null
@@ -1,374 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Runs perf tests.
-
-Our buildbot infrastructure requires each slave to run steps serially.
-This is sub-optimal for android, where these steps can run independently on
-multiple connected devices.
-
-The buildbots will run this script multiple times per cycle:
-- First: all steps listed in --steps in will be executed in parallel using all
-connected devices. Step results will be pickled to disk. Each step has a unique
-name. The result code will be ignored if the step name is listed in
---flaky-steps.
-The buildbot will treat this step as a regular step, and will not process any
-graph data.
-
-- Then, with -print-step STEP_NAME: at this stage, we'll simply print the file
-with the step results previously saved. The buildbot will then process the graph
-data accordingly.
-
-The JSON steps file contains a dictionary in the format:
-{ "version": int,
- "steps": {
- "foo": {
- "device_affinity": int,
- "cmd": "script_to_execute foo"
- },
- "bar": {
- "device_affinity": int,
- "cmd": "script_to_execute bar"
- }
- }
-}
-
-The JSON flaky steps file contains a list with step names which results should
-be ignored:
-[
- "step_name_foo",
- "step_name_bar"
-]
-
-Note that script_to_execute necessarily have to take at least the following
-option:
- --device: the serial number to be passed to all adb commands.
-"""
-
-import collections
-import datetime
-import json
-import logging
-import os
-import pickle
-import shutil
-import sys
-import tempfile
-import threading
-import time
-
-from pylib import cmd_helper
-from pylib import constants
-from pylib import forwarder
-from pylib.base import base_test_result
-from pylib.base import base_test_runner
-from pylib.device import battery_utils
-from pylib.device import device_errors
-
-
-def GetPersistedResult(test_name):
- file_name = os.path.join(constants.PERF_OUTPUT_DIR, test_name)
- if not os.path.exists(file_name):
- logging.error('File not found %s', file_name)
- return None
-
- with file(file_name, 'r') as f:
- return pickle.loads(f.read())
-
-
-def OutputJsonList(json_input, json_output):
- with file(json_input, 'r') as i:
- all_steps = json.load(i)
-
- step_values = []
- for k, v in all_steps['steps'].iteritems():
- data = {'test': k, 'device_affinity': v['device_affinity']}
-
- persisted_result = GetPersistedResult(k)
- if persisted_result:
- data['total_time'] = persisted_result['total_time']
- step_values.append(data)
-
- with file(json_output, 'w') as o:
- o.write(json.dumps(step_values))
- return 0
-
-
-def PrintTestOutput(test_name, json_file_name=None):
- """Helper method to print the output of previously executed test_name.
-
- Args:
- test_name: name of the test that has been previously executed.
- json_file_name: name of the file to output chartjson data to.
-
- Returns:
- exit code generated by the test step.
- """
- persisted_result = GetPersistedResult(test_name)
- if not persisted_result:
- return 1
- logging.info('*' * 80)
- logging.info('Output from:')
- logging.info(persisted_result['cmd'])
- logging.info('*' * 80)
- print persisted_result['output']
-
- if json_file_name:
- with file(json_file_name, 'w') as f:
- f.write(persisted_result['chartjson'])
-
- return persisted_result['exit_code']
-
-
-def PrintSummary(test_names):
- logging.info('*' * 80)
- logging.info('Sharding summary')
- device_total_time = collections.defaultdict(int)
- for test_name in test_names:
- file_name = os.path.join(constants.PERF_OUTPUT_DIR, test_name)
- if not os.path.exists(file_name):
- logging.info('%s : No status file found', test_name)
- continue
- with file(file_name, 'r') as f:
- result = pickle.loads(f.read())
- logging.info('%s : exit_code=%d in %d secs at %s',
- result['name'], result['exit_code'], result['total_time'],
- result['device'])
- device_total_time[result['device']] += result['total_time']
- for device, device_time in device_total_time.iteritems():
- logging.info('Total for device %s : %d secs', device, device_time)
- logging.info('Total steps time: %d secs', sum(device_total_time.values()))
-
-
-class _HeartBeatLogger(object):
- # How often to print the heartbeat on flush().
- _PRINT_INTERVAL = 30.0
-
- def __init__(self):
- """A file-like class for keeping the buildbot alive."""
- self._len = 0
- self._tick = time.time()
- self._stopped = threading.Event()
- self._timer = threading.Thread(target=self._runner)
- self._timer.start()
-
- def _runner(self):
- while not self._stopped.is_set():
- self.flush()
- self._stopped.wait(_HeartBeatLogger._PRINT_INTERVAL)
-
- def write(self, data):
- self._len += len(data)
-
- def flush(self):
- now = time.time()
- if now - self._tick >= _HeartBeatLogger._PRINT_INTERVAL:
- self._tick = now
- print '--single-step output length %d' % self._len
- sys.stdout.flush()
-
- def stop(self):
- self._stopped.set()
-
-
-class TestRunner(base_test_runner.BaseTestRunner):
- def __init__(self, test_options, device, shard_index, max_shard, tests,
- flaky_tests):
- """A TestRunner instance runs a perf test on a single device.
-
- Args:
- test_options: A PerfOptions object.
- device: Device to run the tests.
- shard_index: the index of this device.
- max_shards: the maximum shard index.
- tests: a dict mapping test_name to command.
- flaky_tests: a list of flaky test_name.
- """
- super(TestRunner, self).__init__(device, None)
- self._options = test_options
- self._shard_index = shard_index
- self._max_shard = max_shard
- self._tests = tests
- self._flaky_tests = flaky_tests
- self._output_dir = None
- self._device_battery = battery_utils.BatteryUtils(self.device)
-
- @staticmethod
- def _IsBetter(result):
- if result['actual_exit_code'] == 0:
- return True
- pickled = os.path.join(constants.PERF_OUTPUT_DIR,
- result['name'])
- if not os.path.exists(pickled):
- return True
- with file(pickled, 'r') as f:
- previous = pickle.loads(f.read())
- return result['actual_exit_code'] < previous['actual_exit_code']
-
- @staticmethod
- def _SaveResult(result):
- if TestRunner._IsBetter(result):
- with file(os.path.join(constants.PERF_OUTPUT_DIR,
- result['name']), 'w') as f:
- f.write(pickle.dumps(result))
-
- def _CheckDeviceAffinity(self, test_name):
- """Returns True if test_name has affinity for this shard."""
- affinity = (self._tests['steps'][test_name]['device_affinity'] %
- self._max_shard)
- if self._shard_index == affinity:
- return True
- logging.info('Skipping %s on %s (affinity is %s, device is %s)',
- test_name, self.device_serial, affinity, self._shard_index)
- return False
-
- def _CleanupOutputDirectory(self):
- if self._output_dir:
- shutil.rmtree(self._output_dir, ignore_errors=True)
- self._output_dir = None
-
- def _ReadChartjsonOutput(self):
- if not self._output_dir:
- return ''
-
- json_output_path = os.path.join(self._output_dir, 'results-chart.json')
- try:
- with open(json_output_path) as f:
- return f.read()
- except IOError:
- logging.exception('Exception when reading chartjson.')
- logging.error('This usually means that telemetry did not run, so it could'
- ' not generate the file. Please check the device running'
- ' the test.')
- return ''
-
- def _LaunchPerfTest(self, test_name):
- """Runs a perf test.
-
- Args:
- test_name: the name of the test to be executed.
-
- Returns:
- A tuple containing (Output, base_test_result.ResultType)
- """
- if not self._CheckDeviceAffinity(test_name):
- return '', base_test_result.ResultType.PASS
-
- try:
- logging.warning('Unmapping device ports')
- forwarder.Forwarder.UnmapAllDevicePorts(self.device)
- self.device.old_interface.RestartAdbdOnDevice()
- except Exception as e:
- logging.error('Exception when tearing down device %s', e)
-
- cmd = ('%s --device %s' %
- (self._tests['steps'][test_name]['cmd'],
- self.device_serial))
-
- if self._options.collect_chartjson_data:
- self._output_dir = tempfile.mkdtemp()
- cmd = cmd + ' --output-dir=%s' % self._output_dir
-
- logging.info(
- 'temperature: %s (0.1 C)',
- str(self._device_battery.GetBatteryInfo().get('temperature')))
- if self._options.max_battery_temp:
- self._device_battery.LetBatteryCoolToTemperature(
- self._options.max_battery_temp)
-
- logging.info('Charge level: %s%%',
- str(self._device_battery.GetBatteryInfo().get('level')))
- if self._options.min_battery_level:
- self._device_battery.ChargeDeviceToLevel(
- self._options.min_battery_level)
-
- logging.info('%s : %s', test_name, cmd)
- start_time = datetime.datetime.now()
-
- timeout = self._tests['steps'][test_name].get('timeout', 5400)
- if self._options.no_timeout:
- timeout = None
- logging.info('Timeout for %s test: %s', test_name, timeout)
- full_cmd = cmd
- if self._options.dry_run:
- full_cmd = 'echo %s' % cmd
-
- logfile = sys.stdout
- if self._options.single_step:
- # Just print a heart-beat so that the outer buildbot scripts won't timeout
- # without response.
- logfile = _HeartBeatLogger()
- cwd = os.path.abspath(constants.DIR_SOURCE_ROOT)
- if full_cmd.startswith('src/'):
- cwd = os.path.abspath(os.path.join(constants.DIR_SOURCE_ROOT, os.pardir))
- try:
- exit_code, output = cmd_helper.GetCmdStatusAndOutputWithTimeout(
- full_cmd, timeout, cwd=cwd, shell=True, logfile=logfile)
- json_output = self._ReadChartjsonOutput()
- except cmd_helper.TimeoutError as e:
- exit_code = -1
- output = str(e)
- json_output = ''
- finally:
- self._CleanupOutputDirectory()
- if self._options.single_step:
- logfile.stop()
- end_time = datetime.datetime.now()
- if exit_code is None:
- exit_code = -1
- logging.info('%s : exit_code=%d in %d secs at %s',
- test_name, exit_code, (end_time - start_time).seconds,
- self.device_serial)
-
- if exit_code == 0:
- result_type = base_test_result.ResultType.PASS
- else:
- result_type = base_test_result.ResultType.FAIL
- # Since perf tests use device affinity, give the device a chance to
- # recover if it is offline after a failure. Otherwise, the master sharder
- # will remove it from the pool and future tests on this device will fail.
- try:
- self.device.WaitUntilFullyBooted(timeout=120)
- except device_errors.CommandTimeoutError as e:
- logging.error('Device failed to return after %s: %s' % (test_name, e))
-
- actual_exit_code = exit_code
- if test_name in self._flaky_tests:
- # The exit_code is used at the second stage when printing the
- # test output. If the test is flaky, force to "0" to get that step green
- # whilst still gathering data to the perf dashboards.
- # The result_type is used by the test_dispatcher to retry the test.
- exit_code = 0
-
- persisted_result = {
- 'name': test_name,
- 'output': output,
- 'chartjson': json_output,
- 'exit_code': exit_code,
- 'actual_exit_code': actual_exit_code,
- 'result_type': result_type,
- 'total_time': (end_time - start_time).seconds,
- 'device': self.device_serial,
- 'cmd': cmd,
- }
- self._SaveResult(persisted_result)
-
- return (output, result_type)
-
- def RunTest(self, test_name):
- """Run a perf test on the device.
-
- Args:
- test_name: String to use for logging the test result.
-
- Returns:
- A tuple of (TestRunResults, retry).
- """
- _, result_type = self._LaunchPerfTest(test_name)
- results = base_test_result.TestRunResults()
- results.AddResult(base_test_result.BaseTestResult(test_name, result_type))
- retry = None
- if not results.DidRunPass():
- retry = test_name
- return results, retry
diff --git a/build/android/pylib/perf/thermal_throttle.py b/build/android/pylib/perf/thermal_throttle.py
deleted file mode 100644
index 383b6d5..0000000
--- a/build/android/pylib/perf/thermal_throttle.py
+++ /dev/null
@@ -1,137 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-from pylib import android_commands
-from pylib.device import device_utils
-
-
-class OmapThrottlingDetector(object):
- """Class to detect and track thermal throttling on an OMAP 4."""
- OMAP_TEMP_FILE = ('/sys/devices/platform/omap/omap_temp_sensor.0/'
- 'temperature')
-
- @staticmethod
- def IsSupported(device):
- return device.FileExists(OmapThrottlingDetector.OMAP_TEMP_FILE)
-
- def __init__(self, device):
- self._device = device
-
- @staticmethod
- def BecameThrottled(log_line):
- return 'omap_thermal_throttle' in log_line
-
- @staticmethod
- def BecameUnthrottled(log_line):
- return 'omap_thermal_unthrottle' in log_line
-
- @staticmethod
- def GetThrottlingTemperature(log_line):
- if 'throttle_delayed_work_fn' in log_line:
- return float([s for s in log_line.split() if s.isdigit()][0]) / 1000.0
-
- def GetCurrentTemperature(self):
- tempdata = self._device.ReadFile(OmapThrottlingDetector.OMAP_TEMP_FILE)
- return float(tempdata) / 1000.0
-
-
-class ExynosThrottlingDetector(object):
- """Class to detect and track thermal throttling on an Exynos 5."""
- @staticmethod
- def IsSupported(device):
- return device.FileExists('/sys/bus/exynos5-core')
-
- def __init__(self, device):
- pass
-
- @staticmethod
- def BecameThrottled(log_line):
- return 'exynos_tmu: Throttling interrupt' in log_line
-
- @staticmethod
- def BecameUnthrottled(log_line):
- return 'exynos_thermal_unthrottle: not throttling' in log_line
-
- @staticmethod
- def GetThrottlingTemperature(_log_line):
- return None
-
- @staticmethod
- def GetCurrentTemperature():
- return None
-
-
-class ThermalThrottle(object):
- """Class to detect and track thermal throttling.
-
- Usage:
- Wait for IsThrottled() to be False before running test
- After running test call HasBeenThrottled() to find out if the
- test run was affected by thermal throttling.
- """
-
- def __init__(self, device):
- # TODO(jbudorick) Remove once telemetry gets switched over.
- if isinstance(device, android_commands.AndroidCommands):
- device = device_utils.DeviceUtils(device)
- self._device = device
- self._throttled = False
- self._detector = None
- if OmapThrottlingDetector.IsSupported(device):
- self._detector = OmapThrottlingDetector(device)
- elif ExynosThrottlingDetector.IsSupported(device):
- self._detector = ExynosThrottlingDetector(device)
-
- def HasBeenThrottled(self):
- """True if there has been any throttling since the last call to
- HasBeenThrottled or IsThrottled.
- """
- return self._ReadLog()
-
- def IsThrottled(self):
- """True if currently throttled."""
- self._ReadLog()
- return self._throttled
-
- def _ReadLog(self):
- if not self._detector:
- return False
- has_been_throttled = False
- serial_number = str(self._device)
- log = self._device.RunShellCommand('dmesg -c')
- degree_symbol = unichr(0x00B0)
- for line in log:
- if self._detector.BecameThrottled(line):
- if not self._throttled:
- logging.warning('>>> Device %s thermally throttled', serial_number)
- self._throttled = True
- has_been_throttled = True
- elif self._detector.BecameUnthrottled(line):
- if self._throttled:
- logging.warning('>>> Device %s thermally unthrottled', serial_number)
- self._throttled = False
- has_been_throttled = True
- temperature = self._detector.GetThrottlingTemperature(line)
- if temperature is not None:
- logging.info(u'Device %s thermally throttled at %3.1f%sC',
- serial_number, temperature, degree_symbol)
-
- if logging.getLogger().isEnabledFor(logging.DEBUG):
- # Print current temperature of CPU SoC.
- temperature = self._detector.GetCurrentTemperature()
- if temperature is not None:
- logging.debug(u'Current SoC temperature of %s = %3.1f%sC',
- serial_number, temperature, degree_symbol)
-
- # Print temperature of battery, to give a system temperature
- dumpsys_log = self._device.RunShellCommand('dumpsys battery')
- for line in dumpsys_log:
- if 'temperature' in line:
- btemp = float([s for s in line.split() if s.isdigit()][0]) / 10.0
- logging.debug(u'Current battery temperature of %s = %3.1f%sC',
- serial_number, btemp, degree_symbol)
-
- return has_been_throttled
-
diff --git a/build/android/pylib/pexpect.py b/build/android/pylib/pexpect.py
deleted file mode 100644
index cf59fb0..0000000
--- a/build/android/pylib/pexpect.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-from __future__ import absolute_import
-
-import os
-import sys
-
-_CHROME_SRC = os.path.join(
- os.path.abspath(os.path.dirname(__file__)), '..', '..', '..')
-
-_PEXPECT_PATH = os.path.join(_CHROME_SRC, 'third_party', 'pexpect')
-if _PEXPECT_PATH not in sys.path:
- sys.path.append(_PEXPECT_PATH)
-
-# pexpect is not available on all platforms. We allow this file to be imported
-# on platforms without pexpect and only fail when pexpect is actually used.
-try:
- from pexpect import * # pylint: disable=W0401,W0614
-except ImportError:
- pass
diff --git a/build/android/pylib/ports.py b/build/android/pylib/ports.py
deleted file mode 100644
index 578152c..0000000
--- a/build/android/pylib/ports.py
+++ /dev/null
@@ -1,172 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Functions that deal with local and device ports."""
-
-import contextlib
-import fcntl
-import httplib
-import logging
-import os
-import socket
-import traceback
-
-from pylib import constants
-
-
-# The following two methods are used to allocate the port source for various
-# types of test servers. Because some net-related tests can be run on shards at
-# same time, it's important to have a mechanism to allocate the port
-# process-safe. In here, we implement the safe port allocation by leveraging
-# flock.
-def ResetTestServerPortAllocation():
- """Resets the port allocation to start from TEST_SERVER_PORT_FIRST.
-
- Returns:
- Returns True if reset successes. Otherwise returns False.
- """
- try:
- with open(constants.TEST_SERVER_PORT_FILE, 'w') as fp:
- fp.write('%d' % constants.TEST_SERVER_PORT_FIRST)
- if os.path.exists(constants.TEST_SERVER_PORT_LOCKFILE):
- os.unlink(constants.TEST_SERVER_PORT_LOCKFILE)
- return True
- except Exception as e:
- logging.error(e)
- return False
-
-
-def AllocateTestServerPort():
- """Allocates a port incrementally.
-
- Returns:
- Returns a valid port which should be in between TEST_SERVER_PORT_FIRST and
- TEST_SERVER_PORT_LAST. Returning 0 means no more valid port can be used.
- """
- port = 0
- ports_tried = []
- try:
- fp_lock = open(constants.TEST_SERVER_PORT_LOCKFILE, 'w')
- fcntl.flock(fp_lock, fcntl.LOCK_EX)
- # Get current valid port and calculate next valid port.
- if not os.path.exists(constants.TEST_SERVER_PORT_FILE):
- ResetTestServerPortAllocation()
- with open(constants.TEST_SERVER_PORT_FILE, 'r+') as fp:
- port = int(fp.read())
- ports_tried.append(port)
- while not IsHostPortAvailable(port):
- port += 1
- ports_tried.append(port)
- if (port > constants.TEST_SERVER_PORT_LAST or
- port < constants.TEST_SERVER_PORT_FIRST):
- port = 0
- else:
- fp.seek(0, os.SEEK_SET)
- fp.write('%d' % (port + 1))
- except Exception as e:
- logging.error(e)
- finally:
- if fp_lock:
- fcntl.flock(fp_lock, fcntl.LOCK_UN)
- fp_lock.close()
- if port:
- logging.info('Allocate port %d for test server.', port)
- else:
- logging.error('Could not allocate port for test server. '
- 'List of ports tried: %s', str(ports_tried))
- return port
-
-
-def IsHostPortAvailable(host_port):
- """Checks whether the specified host port is available.
-
- Args:
- host_port: Port on host to check.
-
- Returns:
- True if the port on host is available, otherwise returns False.
- """
- s = socket.socket()
- try:
- s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
- s.bind(('', host_port))
- s.close()
- return True
- except socket.error:
- return False
-
-
-def IsDevicePortUsed(device, device_port, state=''):
- """Checks whether the specified device port is used or not.
-
- Args:
- device: A DeviceUtils instance.
- device_port: Port on device we want to check.
- state: String of the specified state. Default is empty string, which
- means any state.
-
- Returns:
- True if the port on device is already used, otherwise returns False.
- """
- base_url = '127.0.0.1:%d' % device_port
- netstat_results = device.RunShellCommand('netstat')
- for single_connect in netstat_results:
- # Column 3 is the local address which we want to check with.
- connect_results = single_connect.split()
- if connect_results[0] != 'tcp':
- continue
- if len(connect_results) < 6:
- raise Exception('Unexpected format while parsing netstat line: ' +
- single_connect)
- is_state_match = connect_results[5] == state if state else True
- if connect_results[3] == base_url and is_state_match:
- return True
- return False
-
-
-def IsHttpServerConnectable(host, port, tries=3, command='GET', path='/',
- expected_read='', timeout=2):
- """Checks whether the specified http server is ready to serve request or not.
-
- Args:
- host: Host name of the HTTP server.
- port: Port number of the HTTP server.
- tries: How many times we want to test the connection. The default value is
- 3.
- command: The http command we use to connect to HTTP server. The default
- command is 'GET'.
- path: The path we use when connecting to HTTP server. The default path is
- '/'.
- expected_read: The content we expect to read from the response. The default
- value is ''.
- timeout: Timeout (in seconds) for each http connection. The default is 2s.
-
- Returns:
- Tuple of (connect status, client error). connect status is a boolean value
- to indicate whether the server is connectable. client_error is the error
- message the server returns when connect status is false.
- """
- assert tries >= 1
- for i in xrange(0, tries):
- client_error = None
- try:
- with contextlib.closing(httplib.HTTPConnection(
- host, port, timeout=timeout)) as http:
- # Output some debug information when we have tried more than 2 times.
- http.set_debuglevel(i >= 2)
- http.request(command, path)
- r = http.getresponse()
- content = r.read()
- if r.status == 200 and r.reason == 'OK' and content == expected_read:
- return (True, '')
- client_error = ('Bad response: %s %s version %s\n ' %
- (r.status, r.reason, r.version) +
- '\n '.join([': '.join(h) for h in r.getheaders()]))
- except (httplib.HTTPException, socket.error) as e:
- # Probably too quick connecting: try again.
- exception_error_msgs = traceback.format_exception_only(type(e), e)
- if exception_error_msgs:
- client_error = ''.join(exception_error_msgs)
- # Only returns last client_error.
- return (False, client_error or 'Timeout')
diff --git a/build/android/pylib/remote/__init__.py b/build/android/pylib/remote/__init__.py
deleted file mode 100644
index 4d6aabb..0000000
--- a/build/android/pylib/remote/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
diff --git a/build/android/pylib/remote/device/__init__.py b/build/android/pylib/remote/device/__init__.py
deleted file mode 100644
index 4d6aabb..0000000
--- a/build/android/pylib/remote/device/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
diff --git a/build/android/pylib/remote/device/appurify_constants.py b/build/android/pylib/remote/device/appurify_constants.py
deleted file mode 100644
index 9343178..0000000
--- a/build/android/pylib/remote/device/appurify_constants.py
+++ /dev/null
@@ -1,57 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Defines a set of constants specific to appurify."""
-
-# Appurify network config constants.
-class NETWORK(object):
- WIFI_1_BAR = 1
- SPRINT_4G_LTE_4_BARS = 2
- SPRINT_3G_5_BARS = 3
- SPRINT_3G_4_BARS = 4
- SPRINT_3G_3_BARS = 5
- SPRINT_3G_2_BARS = 6
- SPRINT_3G_1_BAR = 7
- SPRING_4G_1_BAR = 8
- VERIZON_3G_5_BARS = 9
- VERIZON_3G_4_BARS = 10
- VERIZON_3G_3_BARS = 11
- VERIZON_3G_2_BARS = 12
- VERIZON_3G_1_BAR = 13
- VERIZON_4G_1_BAR = 14
- ATANDT_3G_5_BARS = 15
- ATANDT_3G_4_BARS = 16
- ATANDT_3G_3_BARS = 17
- ATANDT_3G_2_BARS = 18
- ATANDT_3G_1_BAR = 19
- GENERIC_2G_4_BARS = 20
- GENERIC_2G_3_BARS = 21
- GENERIC_EVOLVED_EDGE = 22
- GENERIC_GPRS = 23
- GENERIC_ENHANCED_GPRS = 24
- GENERIC_LTE = 25
- GENERIC_HIGH_LATENCY_DNS = 26
- GENERIC_100_PERCENT_PACKET_LOSS = 27
- ATANDT_HSPA_PLUS = 28
- ATANDT_4G_LTE_4_BARS = 29
- VERIZON_4G_LTE_4_BARS = 30
- GENERIC_DIGITAL_SUBSCRIBE_LINE = 31
- WIFI_STARBUCKS_3_BARS = 32
- WIFI_STARBUCKS_4_BARS = 33
- WIFI_STARBUCKS_HIGH_TRAFFIC = 34
- WIFI_TARGET_1_BAR = 35
- WIFI_TARGET_3_BARS = 36
- WIFI_TARGET_4_BARS = 37
- PUBLIC_WIFI_MCDONALDS_5_BARS = 38
- PUBLIC_WIFI_MCDONALDS_4_BARS = 39
- PUBLIC_WIFI_MCDONALDS_2_BARS = 40
- PUBLIC_WIFI_MCDONALDS_1_BAR = 41
- PUBLIC_WIFI_KOHLS_5_BARS = 42
- PUBLIC_WIFI_KOHLS_4_BARS = 43
- PUBLIC_WIFI_KOHLS_2_BARS = 44
- PUBLIC_WIFI_ATANDT_5_BARS = 45
- PUBLIC_WIFI_ATANDT_4_BARS = 46
- PUBLIC_WIFI_ATANDT_2_BARS = 47
- PUBLIC_WIFI_ATANDT_1_BAR = 48
- BOINGO = 49
\ No newline at end of file
diff --git a/build/android/pylib/remote/device/appurify_sanitized.py b/build/android/pylib/remote/device/appurify_sanitized.py
deleted file mode 100644
index 9f6ab40..0000000
--- a/build/android/pylib/remote/device/appurify_sanitized.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import contextlib
-import logging
-import os
-import sys
-
-from pylib import constants
-
-sys.path.append(os.path.join(
- constants.DIR_SOURCE_ROOT, 'third_party', 'requests', 'src'))
-sys.path.append(os.path.join(
- constants.DIR_SOURCE_ROOT, 'third_party', 'appurify-python', 'src'))
-handlers_before = list(logging.getLogger().handlers)
-
-import appurify.api
-import appurify.utils
-
-handlers_after = list(logging.getLogger().handlers)
-new_handler = list(set(handlers_after) - set(handlers_before))
-while new_handler:
- logging.info("Removing logging handler.")
- logging.getLogger().removeHandler(new_handler.pop())
-
-api = appurify.api
-utils = appurify.utils
-
-# This is not thread safe. If multiple threads are ever supported with appurify
-# this may cause logging messages to go missing.
-@contextlib.contextmanager
-def SanitizeLogging(verbose_count, level):
- if verbose_count < 2:
- logging.disable(level)
- yield True
- logging.disable(logging.NOTSET)
- else:
- yield False
-
diff --git a/build/android/pylib/remote/device/dummy/BUILD.gn b/build/android/pylib/remote/device/dummy/BUILD.gn
deleted file mode 100644
index 54ca275..0000000
--- a/build/android/pylib/remote/device/dummy/BUILD.gn
+++ /dev/null
@@ -1,14 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/config/android/config.gni")
-import("//build/config/android/rules.gni")
-
-# GYP: //build/android/pylib/remote/device/dummy/dummy.gyp:remote_device_dummy_apk
-android_apk("remote_device_dummy_apk") {
- android_manifest = "//build/android/AndroidManifest.xml"
- java_files = [ "src/org/chromium/dummy/Dummy.java" ]
- apk_name = "remote_device_dummy"
- testonly = true
-}
diff --git a/build/android/pylib/remote/device/dummy/dummy.gyp b/build/android/pylib/remote/device/dummy/dummy.gyp
deleted file mode 100644
index b003edc..0000000
--- a/build/android/pylib/remote/device/dummy/dummy.gyp
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# Running gtests on a remote device via am instrument requires both an "app"
-# APK and a "test" APK with different package names. Our gtests only use one
-# APK, so we build a dummy APK to upload as the app.
-
-{
- 'targets': [
- {
- # GN: //build/android/pylib/remote/device/dummy:remote_device_dummy_apk
- 'target_name': 'remote_device_dummy_apk',
- 'type': 'none',
- 'variables': {
- 'apk_name': 'remote_device_dummy',
- 'java_in_dir': '.',
- 'android_manifest_path': '../../../../../../build/android/AndroidManifest.xml',
- },
- 'includes': [
- '../../../../../../build/java_apk.gypi',
- ]
- },
- ]
-}
diff --git a/build/android/pylib/remote/device/dummy/src/org/chromium/dummy/Dummy.java b/build/android/pylib/remote/device/dummy/src/org/chromium/dummy/Dummy.java
deleted file mode 100644
index 1281b39..0000000
--- a/build/android/pylib/remote/device/dummy/src/org/chromium/dummy/Dummy.java
+++ /dev/null
@@ -1,9 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-package org.chromium.dummy;
-
-/** Does nothing. */
-class Dummy {}
-
diff --git a/build/android/pylib/remote/device/remote_device_environment.py b/build/android/pylib/remote/device/remote_device_environment.py
deleted file mode 100644
index dc11845..0000000
--- a/build/android/pylib/remote/device/remote_device_environment.py
+++ /dev/null
@@ -1,368 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Environment setup and teardown for remote devices."""
-
-import distutils.version
-import json
-import logging
-import os
-import random
-import sys
-
-from pylib import constants
-from pylib.base import environment
-from pylib.remote.device import appurify_sanitized
-from pylib.remote.device import remote_device_helper
-from pylib.utils import timeout_retry
-from pylib.utils import reraiser_thread
-
-class RemoteDeviceEnvironment(environment.Environment):
- """An environment for running on remote devices."""
-
- _ENV_KEY = 'env'
- _DEVICE_KEY = 'device'
- _DEFAULT_RETRIES = 0
-
- def __init__(self, args, error_func):
- """Constructor.
-
- Args:
- args: Command line arguments.
- error_func: error to show when using bad command line arguments.
- """
- super(RemoteDeviceEnvironment, self).__init__()
- self._access_token = None
- self._device = None
- self._device_type = args.device_type
- self._verbose_count = args.verbose_count
- self._timeouts = {
- 'queueing': 60 * 10,
- 'installing': 60 * 10,
- 'in-progress': 60 * 30,
- 'unknown': 60 * 5
- }
- # Example config file:
- # {
- # "remote_device": ["Galaxy S4", "Galaxy S3"],
- # "remote_device_os": ["4.4.2", "4.4.4"],
- # "remote_device_minimum_os": "4.4.2",
- # "api_address": "www.example.com",
- # "api_port": "80",
- # "api_protocol": "http",
- # "api_secret": "apisecret",
- # "api_key": "apikey",
- # "timeouts": {
- # "queueing": 600,
- # "installing": 600,
- # "in-progress": 1800,
- # "unknown": 300
- # }
- # }
- if args.remote_device_file:
- with open(args.remote_device_file) as device_file:
- device_json = json.load(device_file)
- else:
- device_json = {}
-
- self._api_address = device_json.get('api_address', None)
- self._api_key = device_json.get('api_key', None)
- self._api_port = device_json.get('api_port', None)
- self._api_protocol = device_json.get('api_protocol', None)
- self._api_secret = device_json.get('api_secret', None)
- self._device_oem = device_json.get('device_oem', None)
- self._device_type = device_json.get('device_type', 'Android')
- self._network_config = device_json.get('network_config', None)
- self._remote_device = device_json.get('remote_device', None)
- self._remote_device_minimum_os = device_json.get(
- 'remote_device_minimum_os', None)
- self._remote_device_os = device_json.get('remote_device_os', None)
- self._remote_device_timeout = device_json.get(
- 'remote_device_timeout', None)
- self._results_path = device_json.get('results_path', None)
- self._runner_package = device_json.get('runner_package', None)
- self._runner_type = device_json.get('runner_type', None)
- self._timeouts.update(device_json.get('timeouts', {}))
-
- def command_line_override(
- file_value, cmd_line_value, desc, print_value=True):
- if cmd_line_value:
- if file_value and file_value != cmd_line_value:
- if print_value:
- logging.info('Overriding %s from %s to %s',
- desc, file_value, cmd_line_value)
- else:
- logging.info('overriding %s', desc)
- return cmd_line_value
- return file_value
-
- self._api_address = command_line_override(
- self._api_address, args.api_address, 'api_address')
- self._api_port = command_line_override(
- self._api_port, args.api_port, 'api_port')
- self._api_protocol = command_line_override(
- self._api_protocol, args.api_protocol, 'api_protocol')
- self._device_oem = command_line_override(
- self._device_oem, args.device_oem, 'device_oem')
- self._device_type = command_line_override(
- self._device_type, args.device_type, 'device_type')
- self._network_config = command_line_override(
- self._network_config, args.network_config, 'network_config')
- self._remote_device = command_line_override(
- self._remote_device, args.remote_device, 'remote_device')
- self._remote_device_minimum_os = command_line_override(
- self._remote_device_minimum_os, args.remote_device_minimum_os,
- 'remote_device_minimum_os')
- self._remote_device_os = command_line_override(
- self._remote_device_os, args.remote_device_os, 'remote_device_os')
- self._remote_device_timeout = command_line_override(
- self._remote_device_timeout, args.remote_device_timeout,
- 'remote_device_timeout')
- self._results_path = command_line_override(
- self._results_path, args.results_path, 'results_path')
- self._runner_package = command_line_override(
- self._runner_package, args.runner_package, 'runner_package')
- self._runner_type = command_line_override(
- self._runner_type, args.runner_type, 'runner_type')
-
- if args.api_key_file:
- with open(args.api_key_file) as api_key_file:
- temp_key = api_key_file.read().strip()
- self._api_key = command_line_override(
- self._api_key, temp_key, 'api_key', print_value=False)
- self._api_key = command_line_override(
- self._api_key, args.api_key, 'api_key', print_value=False)
-
- if args.api_secret_file:
- with open(args.api_secret_file) as api_secret_file:
- temp_secret = api_secret_file.read().strip()
- self._api_secret = command_line_override(
- self._api_secret, temp_secret, 'api_secret', print_value=False)
- self._api_secret = command_line_override(
- self._api_secret, args.api_secret, 'api_secret', print_value=False)
-
- if not self._api_address:
- error_func('Must set api address with --api-address'
- ' or in --remote-device-file.')
- if not self._api_key:
- error_func('Must set api key with --api-key, --api-key-file'
- ' or in --remote-device-file')
- if not self._api_port:
- error_func('Must set api port with --api-port'
- ' or in --remote-device-file')
- if not self._api_protocol:
- error_func('Must set api protocol with --api-protocol'
- ' or in --remote-device-file. Example: http')
- if not self._api_secret:
- error_func('Must set api secret with --api-secret, --api-secret-file'
- ' or in --remote-device-file')
-
- logging.info('Api address: %s', self._api_address)
- logging.info('Api port: %s', self._api_port)
- logging.info('Api protocol: %s', self._api_protocol)
- logging.info('Remote device: %s', self._remote_device)
- logging.info('Remote device minimum OS: %s',
- self._remote_device_minimum_os)
- logging.info('Remote device OS: %s', self._remote_device_os)
- logging.info('Remote device OEM: %s', self._device_oem)
- logging.info('Remote device type: %s', self._device_type)
- logging.info('Remote device timout: %s', self._remote_device_timeout)
- logging.info('Results Path: %s', self._results_path)
- logging.info('Runner package: %s', self._runner_package)
- logging.info('Runner type: %s', self._runner_type)
- logging.info('Timeouts: %s', self._timeouts)
-
- if not args.trigger and not args.collect:
- self._trigger = True
- self._collect = True
- else:
- self._trigger = args.trigger
- self._collect = args.collect
-
- def SetUp(self):
- """Set up the test environment."""
- os.environ['APPURIFY_API_PROTO'] = self._api_protocol
- os.environ['APPURIFY_API_HOST'] = self._api_address
- os.environ['APPURIFY_API_PORT'] = self._api_port
- os.environ['APPURIFY_STATUS_BASE_URL'] = 'none'
- self._GetAccessToken()
- if self._trigger:
- self._SelectDevice()
-
- def TearDown(self):
- """Teardown the test environment."""
- self._RevokeAccessToken()
-
- def __enter__(self):
- """Set up the test run when used as a context manager."""
- try:
- self.SetUp()
- return self
- except:
- self.__exit__(*sys.exc_info())
- raise
-
- def __exit__(self, exc_type, exc_val, exc_tb):
- """Tears down the test run when used as a context manager."""
- self.TearDown()
-
- def DumpTo(self, persisted_data):
- env_data = {
- self._DEVICE_KEY: self._device,
- }
- persisted_data[self._ENV_KEY] = env_data
-
- def LoadFrom(self, persisted_data):
- env_data = persisted_data[self._ENV_KEY]
- self._device = env_data[self._DEVICE_KEY]
-
- def _GetAccessToken(self):
- """Generates access token for remote device service."""
- logging.info('Generating remote service access token')
- with appurify_sanitized.SanitizeLogging(self._verbose_count,
- logging.WARNING):
- access_token_results = appurify_sanitized.api.access_token_generate(
- self._api_key, self._api_secret)
- remote_device_helper.TestHttpResponse(access_token_results,
- 'Unable to generate access token.')
- self._access_token = access_token_results.json()['response']['access_token']
-
- def _RevokeAccessToken(self):
- """Destroys access token for remote device service."""
- logging.info('Revoking remote service access token')
- with appurify_sanitized.SanitizeLogging(self._verbose_count,
- logging.WARNING):
- revoke_token_results = appurify_sanitized.api.access_token_revoke(
- self._access_token)
- remote_device_helper.TestHttpResponse(revoke_token_results,
- 'Unable to revoke access token.')
-
- def _SelectDevice(self):
- if self._remote_device_timeout:
- try:
- timeout_retry.Run(self._FindDeviceWithTimeout,
- self._remote_device_timeout, self._DEFAULT_RETRIES)
- except reraiser_thread.TimeoutError:
- self._NoDeviceFound()
- else:
- if not self._FindDevice():
- self._NoDeviceFound()
-
- def _FindDevice(self):
- """Find which device to use."""
- logging.info('Finding device to run tests on.')
- device_list = self._GetDeviceList()
- random.shuffle(device_list)
- for device in device_list:
- if device['os_name'] != self._device_type:
- continue
- if self._remote_device and device['name'] not in self._remote_device:
- continue
- if (self._remote_device_os
- and device['os_version'] not in self._remote_device_os):
- continue
- if self._device_oem and device['brand'] not in self._device_oem:
- continue
- if (self._remote_device_minimum_os
- and distutils.version.LooseVersion(device['os_version'])
- < distutils.version.LooseVersion(self._remote_device_minimum_os)):
- continue
- if device['has_available_device']:
- logging.info('Found device: %s %s',
- device['name'], device['os_version'])
- self._device = device
- return True
- return False
-
- def _FindDeviceWithTimeout(self):
- """Find which device to use with timeout."""
- timeout_retry.WaitFor(self._FindDevice, wait_period=1)
-
- def _PrintAvailableDevices(self, device_list):
- def compare_devices(a,b):
- for key in ('os_version', 'name'):
- c = cmp(a[key], b[key])
- if c:
- return c
- return 0
-
- logging.critical('Available %s Devices:', self._device_type)
- logging.critical(
- ' %s %s %s %s %s',
- 'OS'.ljust(10),
- 'Device Name'.ljust(30),
- 'Available'.ljust(10),
- 'Busy'.ljust(10),
- 'All'.ljust(10))
- devices = (d for d in device_list if d['os_name'] == self._device_type)
- for d in sorted(devices, compare_devices):
- logging.critical(
- ' %s %s %s %s %s',
- d['os_version'].ljust(10),
- d['name'].ljust(30),
- str(d['available_devices_count']).ljust(10),
- str(d['busy_devices_count']).ljust(10),
- str(d['all_devices_count']).ljust(10))
-
- def _GetDeviceList(self):
- with appurify_sanitized.SanitizeLogging(self._verbose_count,
- logging.WARNING):
- dev_list_res = appurify_sanitized.api.devices_list(self._access_token)
- remote_device_helper.TestHttpResponse(dev_list_res,
- 'Unable to generate access token.')
- return dev_list_res.json()['response']
-
- def _NoDeviceFound(self):
- self._PrintAvailableDevices(self._GetDeviceList())
- raise remote_device_helper.RemoteDeviceError(
- 'No device found.', is_infra_error=True)
-
- @property
- def collect(self):
- return self._collect
-
- @property
- def device_type_id(self):
- return self._device['device_type_id']
-
- @property
- def network_config(self):
- return self._network_config
-
- @property
- def only_output_failures(self):
- # TODO(jbudorick): Remove this once b/18981674 is fixed.
- return True
-
- @property
- def results_path(self):
- return self._results_path
-
- @property
- def runner_package(self):
- return self._runner_package
-
- @property
- def runner_type(self):
- return self._runner_type
-
- @property
- def timeouts(self):
- return self._timeouts
-
- @property
- def token(self):
- return self._access_token
-
- @property
- def trigger(self):
- return self._trigger
-
- @property
- def verbose_count(self):
- return self._verbose_count
-
- @property
- def device_type(self):
- return self._device_type
diff --git a/build/android/pylib/remote/device/remote_device_gtest_run.py b/build/android/pylib/remote/device/remote_device_gtest_run.py
deleted file mode 100644
index 98d41e4..0000000
--- a/build/android/pylib/remote/device/remote_device_gtest_run.py
+++ /dev/null
@@ -1,81 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Run specific test on specific environment."""
-
-import logging
-import os
-import sys
-import tempfile
-
-from pylib import constants
-from pylib.base import base_test_result
-from pylib.remote.device import appurify_sanitized
-from pylib.remote.device import remote_device_test_run
-from pylib.remote.device import remote_device_helper
-
-
-_EXTRA_COMMAND_LINE_FILE = (
- 'org.chromium.native_test.NativeTestActivity.CommandLineFile')
-
-
-class RemoteDeviceGtestTestRun(remote_device_test_run.RemoteDeviceTestRun):
- """Run gtests and uirobot tests on a remote device."""
-
- DEFAULT_RUNNER_PACKAGE = (
- 'org.chromium.native_test.NativeTestInstrumentationTestRunner')
-
- #override
- def TestPackage(self):
- return self._test_instance.suite
-
- #override
- def _TriggerSetUp(self):
- """Set up the triggering of a test run."""
- logging.info('Triggering test run.')
-
- if self._env.runner_type:
- logging.warning('Ignoring configured runner_type "%s"',
- self._env.runner_type)
-
- if not self._env.runner_package:
- runner_package = self.DEFAULT_RUNNER_PACKAGE
- logging.info('Using default runner package: %s',
- self.DEFAULT_RUNNER_PACKAGE)
- else:
- runner_package = self._env.runner_package
-
- dummy_app_path = os.path.join(
- constants.GetOutDirectory(), 'apks', 'remote_device_dummy.apk')
- with tempfile.NamedTemporaryFile(suffix='.flags.txt') as flag_file:
- env_vars = {}
- filter_string = self._test_instance._GenerateDisabledFilterString(None)
- if filter_string:
- flag_file.write('_ --gtest_filter=%s' % filter_string)
- flag_file.flush()
- env_vars[_EXTRA_COMMAND_LINE_FILE] = os.path.basename(flag_file.name)
- self._test_instance._data_deps.append(
- (os.path.abspath(flag_file.name), None))
- self._AmInstrumentTestSetup(
- dummy_app_path, self._test_instance.apk, runner_package,
- environment_variables=env_vars)
-
- _INSTRUMENTATION_STREAM_LEADER = 'INSTRUMENTATION_STATUS: stream='
-
- #override
- def _ParseTestResults(self):
- logging.info('Parsing results from stdout.')
- results = base_test_result.TestRunResults()
- output = self._results['results']['output'].splitlines()
- output = (l[len(self._INSTRUMENTATION_STREAM_LEADER):] for l in output
- if l.startswith(self._INSTRUMENTATION_STREAM_LEADER))
- results_list = self._test_instance.ParseGTestOutput(output)
- results.AddResults(results_list)
- if self._env.only_output_failures:
- logging.info('See logcat for more results information.')
- if not self._results['results']['pass']:
- results.AddResult(base_test_result.BaseTestResult(
- 'Remote Service detected error.',
- base_test_result.ResultType.FAIL))
- return results
diff --git a/build/android/pylib/remote/device/remote_device_helper.py b/build/android/pylib/remote/device/remote_device_helper.py
deleted file mode 100644
index 896ae99..0000000
--- a/build/android/pylib/remote/device/remote_device_helper.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Common functions and Exceptions for remote_device_*"""
-
-from pylib.utils import base_error
-
-
-class RemoteDeviceError(base_error.BaseError):
- """Exception to throw when problems occur with remote device service."""
- pass
-
-
-def TestHttpResponse(response, error_msg):
- """Checks the Http response from remote device service.
-
- Args:
- response: response dict from the remote device service.
- error_msg: Error message to display if bad response is seen.
- """
- if response.status_code != 200:
- raise RemoteDeviceError(
- '%s (%d: %s)' % (error_msg, response.status_code, response.reason))
diff --git a/build/android/pylib/remote/device/remote_device_instrumentation_test_run.py b/build/android/pylib/remote/device/remote_device_instrumentation_test_run.py
deleted file mode 100644
index bcdb90c..0000000
--- a/build/android/pylib/remote/device/remote_device_instrumentation_test_run.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Run specific test on specific environment."""
-
-import logging
-import os
-import tempfile
-
-from pylib import constants
-from pylib.base import base_test_result
-from pylib.remote.device import remote_device_test_run
-from pylib.utils import apk_helper
-
-
-class RemoteDeviceInstrumentationTestRun(
- remote_device_test_run.RemoteDeviceTestRun):
- """Run instrumentation tests on a remote device."""
-
- #override
- def TestPackage(self):
- return self._test_instance.test_package
-
- #override
- def _TriggerSetUp(self):
- """Set up the triggering of a test run."""
- logging.info('Triggering test run.')
-
- with tempfile.NamedTemporaryFile(suffix='.txt') as test_list_file:
- tests = self._test_instance.GetTests()
- logging.debug('preparing to run %d instrumentation tests remotely:',
- len(tests))
- for t in tests:
- test_name = '%s#%s' % (t['class'], t['method'])
- logging.debug(' %s', test_name)
- test_list_file.write('%s\n' % test_name)
- test_list_file.flush()
- self._test_instance._data_deps.append(
- (os.path.abspath(test_list_file.name), None))
-
- env_vars = self._test_instance.GetDriverEnvironmentVars(
- test_list_file_path=test_list_file.name)
- env_vars.update(self._test_instance.GetHttpServerEnvironmentVars())
-
- logging.debug('extras:')
- for k, v in env_vars.iteritems():
- logging.debug(' %s: %s', k, v)
-
- self._AmInstrumentTestSetup(
- self._test_instance.apk_under_test,
- self._test_instance.driver_apk,
- self._test_instance.driver_name,
- environment_variables=env_vars,
- extra_apks=[self._test_instance.test_apk])
-
- #override
- def _ParseTestResults(self):
- logging.info('Parsing results from stdout.')
- r = base_test_result.TestRunResults()
- result_code, result_bundle, statuses = (
- self._test_instance.ParseAmInstrumentRawOutput(
- self._results['results']['output'].splitlines()))
- result = self._test_instance.GenerateTestResults(
- result_code, result_bundle, statuses, 0, 0)
-
- if isinstance(result, base_test_result.BaseTestResult):
- r.AddResult(result)
- elif isinstance(result, list):
- r.AddResults(result)
- else:
- raise Exception('Unexpected result type: %s' % type(result).__name__)
-
- return r
diff --git a/build/android/pylib/remote/device/remote_device_test_run.py b/build/android/pylib/remote/device/remote_device_test_run.py
deleted file mode 100644
index 60cc735..0000000
--- a/build/android/pylib/remote/device/remote_device_test_run.py
+++ /dev/null
@@ -1,308 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Run specific test on specific environment."""
-
-import json
-import logging
-import os
-import sys
-import tempfile
-import time
-import zipfile
-
-from pylib import constants
-from pylib.base import test_run
-from pylib.remote.device import appurify_constants
-from pylib.remote.device import appurify_sanitized
-from pylib.remote.device import remote_device_helper
-from pylib.utils import zip_utils
-
-class RemoteDeviceTestRun(test_run.TestRun):
- """Run tests on a remote device."""
-
- _TEST_RUN_KEY = 'test_run'
- _TEST_RUN_ID_KEY = 'test_run_id'
-
- WAIT_TIME = 5
- COMPLETE = 'complete'
- HEARTBEAT_INTERVAL = 300
-
- def __init__(self, env, test_instance):
- """Constructor.
-
- Args:
- env: Environment the tests will run in.
- test_instance: The test that will be run.
- """
- super(RemoteDeviceTestRun, self).__init__(env, test_instance)
- self._env = env
- self._test_instance = test_instance
- self._app_id = ''
- self._test_id = ''
- self._results = ''
- self._test_run_id = ''
-
- #override
- def SetUp(self):
- """Set up a test run."""
- if self._env.trigger:
- self._TriggerSetUp()
- elif self._env.collect:
- assert isinstance(self._env.collect, basestring), (
- 'File for storing test_run_id must be a string.')
- with open(self._env.collect, 'r') as persisted_data_file:
- persisted_data = json.loads(persisted_data_file.read())
- self._env.LoadFrom(persisted_data)
- self.LoadFrom(persisted_data)
-
- def _TriggerSetUp(self):
- """Set up the triggering of a test run."""
- raise NotImplementedError
-
- #override
- def RunTests(self):
- """Run the test."""
- if self._env.trigger:
- with appurify_sanitized.SanitizeLogging(self._env.verbose_count,
- logging.WARNING):
- test_start_res = appurify_sanitized.api.tests_run(
- self._env.token, self._env.device_type_id, self._app_id,
- self._test_id)
- remote_device_helper.TestHttpResponse(
- test_start_res, 'Unable to run test.')
- self._test_run_id = test_start_res.json()['response']['test_run_id']
- logging.info('Test run id: %s' % self._test_run_id)
-
- if self._env.collect:
- current_status = ''
- timeout_counter = 0
- heartbeat_counter = 0
- while self._GetTestStatus(self._test_run_id) != self.COMPLETE:
- if self._results['detailed_status'] != current_status:
- logging.info('Test status: %s', self._results['detailed_status'])
- current_status = self._results['detailed_status']
- timeout_counter = 0
- heartbeat_counter = 0
- if heartbeat_counter > self.HEARTBEAT_INTERVAL:
- logging.info('Test status: %s', self._results['detailed_status'])
- heartbeat_counter = 0
-
- timeout = self._env.timeouts.get(
- current_status, self._env.timeouts['unknown'])
- if timeout_counter > timeout:
- raise remote_device_helper.RemoteDeviceError(
- 'Timeout while in %s state for %s seconds'
- % (current_status, timeout),
- is_infra_error=True)
- time.sleep(self.WAIT_TIME)
- timeout_counter += self.WAIT_TIME
- heartbeat_counter += self.WAIT_TIME
- self._DownloadTestResults(self._env.results_path)
-
- if self._results['results']['exception']:
- raise remote_device_helper.RemoteDeviceError(
- self._results['results']['exception'], is_infra_error=True)
-
- return self._ParseTestResults()
-
- #override
- def TearDown(self):
- """Tear down the test run."""
- if self._env.collect:
- self._CollectTearDown()
- elif self._env.trigger:
- assert isinstance(self._env.trigger, basestring), (
- 'File for storing test_run_id must be a string.')
- with open(self._env.trigger, 'w') as persisted_data_file:
- persisted_data = {}
- self.DumpTo(persisted_data)
- self._env.DumpTo(persisted_data)
- persisted_data_file.write(json.dumps(persisted_data))
-
- def _CollectTearDown(self):
- if self._GetTestStatus(self._test_run_id) != self.COMPLETE:
- with appurify_sanitized.SanitizeLogging(self._env.verbose_count,
- logging.WARNING):
- test_abort_res = appurify_sanitized.api.tests_abort(
- self._env.token, self._test_run_id, reason='Test runner exiting.')
- remote_device_helper.TestHttpResponse(test_abort_res,
- 'Unable to abort test.')
-
- def __enter__(self):
- """Set up the test run when used as a context manager."""
- self.SetUp()
- return self
-
- def __exit__(self, exc_type, exc_val, exc_tb):
- """Tear down the test run when used as a context manager."""
- self.TearDown()
-
- def DumpTo(self, persisted_data):
- test_run_data = {
- self._TEST_RUN_ID_KEY: self._test_run_id,
- }
- persisted_data[self._TEST_RUN_KEY] = test_run_data
-
- def LoadFrom(self, persisted_data):
- test_run_data = persisted_data[self._TEST_RUN_KEY]
- self._test_run_id = test_run_data[self._TEST_RUN_ID_KEY]
-
- def _ParseTestResults(self):
- raise NotImplementedError
-
- def _GetTestByName(self, test_name):
- """Gets test_id for specific test.
-
- Args:
- test_name: Test to find the ID of.
- """
- with appurify_sanitized.SanitizeLogging(self._env.verbose_count,
- logging.WARNING):
- test_list_res = appurify_sanitized.api.tests_list(self._env.token)
- remote_device_helper.TestHttpResponse(test_list_res,
- 'Unable to get tests list.')
- for test in test_list_res.json()['response']:
- if test['test_type'] == test_name:
- return test['test_id']
- raise remote_device_helper.RemoteDeviceError(
- 'No test found with name %s' % (test_name))
-
- def _DownloadTestResults(self, results_path):
- """Download the test results from remote device service.
-
- Args:
- results_path: Path to download appurify results zipfile.
- """
- if results_path:
- logging.info('Downloading results to %s.' % results_path)
- if not os.path.exists(os.path.dirname(results_path)):
- os.makedirs(os.path.dirname(results_path))
- with appurify_sanitized.SanitizeLogging(self._env.verbose_count,
- logging.WARNING):
- appurify_sanitized.utils.wget(self._results['results']['url'],
- results_path)
-
- def _GetTestStatus(self, test_run_id):
- """Checks the state of the test, and sets self._results
-
- Args:
- test_run_id: Id of test on on remote service.
- """
-
- with appurify_sanitized.SanitizeLogging(self._env.verbose_count,
- logging.WARNING):
- test_check_res = appurify_sanitized.api.tests_check_result(
- self._env.token, test_run_id)
- remote_device_helper.TestHttpResponse(test_check_res,
- 'Unable to get test status.')
- self._results = test_check_res.json()['response']
- return self._results['status']
-
- def _AmInstrumentTestSetup(self, app_path, test_path, runner_package,
- environment_variables, extra_apks=None):
- config = {'runner': runner_package}
- if environment_variables:
- config['environment_vars'] = ','.join(
- '%s=%s' % (k, v) for k, v in environment_variables.iteritems())
-
- self._app_id = self._UploadAppToDevice(app_path)
-
- data_deps = self._test_instance.GetDataDependencies()
- if data_deps:
- with tempfile.NamedTemporaryFile(suffix='.zip') as test_with_deps:
- sdcard_files = []
- additional_apks = []
- host_test = os.path.basename(test_path)
- with zipfile.ZipFile(test_with_deps.name, 'w') as zip_file:
- zip_file.write(test_path, host_test, zipfile.ZIP_DEFLATED)
- for h, _ in data_deps:
- if os.path.isdir(h):
- zip_utils.WriteToZipFile(zip_file, h, '.')
- sdcard_files.extend(os.listdir(h))
- else:
- zip_utils.WriteToZipFile(zip_file, h, os.path.basename(h))
- sdcard_files.append(os.path.basename(h))
- for a in extra_apks or ():
- zip_utils.WriteToZipFile(zip_file, a, os.path.basename(a));
- additional_apks.append(os.path.basename(a))
-
- config['sdcard_files'] = ','.join(sdcard_files)
- config['host_test'] = host_test
- if additional_apks:
- config['additional_apks'] = ','.join(additional_apks)
- self._test_id = self._UploadTestToDevice(
- 'robotium', test_with_deps.name, app_id=self._app_id)
- else:
- self._test_id = self._UploadTestToDevice('robotium', test_path)
-
- logging.info('Setting config: %s' % config)
- appurify_configs = {}
- if self._env.network_config:
- appurify_configs['network'] = self._env.network_config
- self._SetTestConfig('robotium', config, **appurify_configs)
-
- def _UploadAppToDevice(self, app_path):
- """Upload app to device."""
- logging.info('Uploading %s to remote service as %s.', app_path,
- self._test_instance.suite)
- with open(app_path, 'rb') as apk_src:
- with appurify_sanitized.SanitizeLogging(self._env.verbose_count,
- logging.WARNING):
- upload_results = appurify_sanitized.api.apps_upload(
- self._env.token, apk_src, 'raw', name=self._test_instance.suite)
- remote_device_helper.TestHttpResponse(
- upload_results, 'Unable to upload %s.' % app_path)
- return upload_results.json()['response']['app_id']
-
- def _UploadTestToDevice(self, test_type, test_path, app_id=None):
- """Upload test to device
- Args:
- test_type: Type of test that is being uploaded. Ex. uirobot, gtest..
- """
- logging.info('Uploading %s to remote service.' % test_path)
- with open(test_path, 'rb') as test_src:
- with appurify_sanitized.SanitizeLogging(self._env.verbose_count,
- logging.WARNING):
- upload_results = appurify_sanitized.api.tests_upload(
- self._env.token, test_src, 'raw', test_type, app_id=app_id)
- remote_device_helper.TestHttpResponse(upload_results,
- 'Unable to upload %s.' % test_path)
- return upload_results.json()['response']['test_id']
-
- def _SetTestConfig(self, runner_type, runner_configs,
- network=appurify_constants.NETWORK.WIFI_1_BAR,
- pcap=0, profiler=0, videocapture=0):
- """Generates and uploads config file for test.
- Args:
- runner_configs: Configs specific to the runner you are using.
- network: Config to specify the network environment the devices running
- the tests will be in.
- pcap: Option to set the recording the of network traffic from the device.
- profiler: Option to set the recording of CPU, memory, and network
- transfer usage in the tests.
- videocapture: Option to set video capture during the tests.
-
- """
- logging.info('Generating config file for test.')
- with tempfile.TemporaryFile() as config:
- config_data = [
- '[appurify]',
- 'network=%s' % network,
- 'pcap=%s' % pcap,
- 'profiler=%s' % profiler,
- 'videocapture=%s' % videocapture,
- '[%s]' % runner_type
- ]
- config_data.extend(
- '%s=%s' % (k, v) for k, v in runner_configs.iteritems())
- config.write(''.join('%s\n' % l for l in config_data))
- config.flush()
- config.seek(0)
- with appurify_sanitized.SanitizeLogging(self._env.verbose_count,
- logging.WARNING):
- config_response = appurify_sanitized.api.config_upload(
- self._env.token, config, self._test_id)
- remote_device_helper.TestHttpResponse(
- config_response, 'Unable to upload test config.')
diff --git a/build/android/pylib/remote/device/remote_device_uirobot_test_run.py b/build/android/pylib/remote/device/remote_device_uirobot_test_run.py
deleted file mode 100644
index f818c98..0000000
--- a/build/android/pylib/remote/device/remote_device_uirobot_test_run.py
+++ /dev/null
@@ -1,88 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Run specific test on specific environment."""
-
-import logging
-import os
-import sys
-
-from pylib import constants
-from pylib.base import base_test_result
-from pylib.remote.device import appurify_sanitized
-from pylib.remote.device import remote_device_test_run
-from pylib.remote.device import remote_device_helper
-
-
-class RemoteDeviceUirobotTestRun(remote_device_test_run.RemoteDeviceTestRun):
- """Run uirobot tests on a remote device."""
-
-
- def __init__(self, env, test_instance):
- """Constructor.
-
- Args:
- env: Environment the tests will run in.
- test_instance: The test that will be run.
- """
- super(RemoteDeviceUirobotTestRun, self).__init__(env, test_instance)
-
- #override
- def TestPackage(self):
- return self._test_instance.package_name
-
- #override
- def _TriggerSetUp(self):
- """Set up the triggering of a test run."""
- logging.info('Triggering test run.')
-
- if self._env.device_type == 'Android':
- default_runner_type = 'android_robot'
- elif self._env.device_type == 'iOS':
- default_runner_type = 'ios_robot'
- else:
- raise remote_device_helper.RemoteDeviceError(
- 'Unknown device type: %s' % self._env.device_type)
-
- self._app_id = self._UploadAppToDevice(self._test_instance.app_under_test)
- if not self._env.runner_type:
- runner_type = default_runner_type
- logging.info('Using default runner type: %s', default_runner_type)
- else:
- runner_type = self._env.runner_type
-
- self._test_id = self._UploadTestToDevice(
- 'android_robot', None, app_id=self._app_id)
- config_body = {'duration': self._test_instance.minutes}
- self._SetTestConfig(runner_type, config_body)
-
-
- # TODO(rnephew): Switch to base class implementation when supported.
- #override
- def _UploadTestToDevice(self, test_type, test_path, app_id=None):
- if test_path:
- logging.info("Ignoring test path.")
- data = {
- 'access_token':self._env.token,
- 'test_type':test_type,
- 'app_id':app_id,
- }
- with appurify_sanitized.SanitizeLogging(self._env.verbose_count,
- logging.WARNING):
- test_upload_res = appurify_sanitized.utils.post('tests/upload',
- data, None)
- remote_device_helper.TestHttpResponse(
- test_upload_res, 'Unable to get UiRobot test id.')
- return test_upload_res.json()['response']['test_id']
-
- #override
- def _ParseTestResults(self):
- logging.info('Parsing results from remote service.')
- results = base_test_result.TestRunResults()
- if self._results['results']['pass']:
- result_type = base_test_result.ResultType.PASS
- else:
- result_type = base_test_result.ResultType.FAIL
- results.AddResult(base_test_result.BaseTestResult('uirobot', result_type))
- return results
diff --git a/build/android/pylib/restart_adbd.sh b/build/android/pylib/restart_adbd.sh
deleted file mode 100755
index 393b2eb..0000000
--- a/build/android/pylib/restart_adbd.sh
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/system/bin/sh
-
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# Android shell script to restart adbd on the device. This has to be run
-# atomically as a shell script because stopping adbd prevents further commands
-# from running (even if called in the same adb shell).
-
-trap '' HUP
-trap '' TERM
-trap '' PIPE
-
-function restart() {
- stop adbd
- start adbd
-}
-
-restart &
diff --git a/build/android/pylib/results/__init__.py b/build/android/pylib/results/__init__.py
deleted file mode 100644
index 4d6aabb..0000000
--- a/build/android/pylib/results/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
diff --git a/build/android/pylib/results/flakiness_dashboard/__init__.py b/build/android/pylib/results/flakiness_dashboard/__init__.py
deleted file mode 100644
index 4d6aabb..0000000
--- a/build/android/pylib/results/flakiness_dashboard/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
diff --git a/build/android/pylib/results/flakiness_dashboard/json_results_generator.py b/build/android/pylib/results/flakiness_dashboard/json_results_generator.py
deleted file mode 100644
index e5c433d..0000000
--- a/build/android/pylib/results/flakiness_dashboard/json_results_generator.py
+++ /dev/null
@@ -1,697 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-#
-# Most of this file was ported over from Blink's
-# Tools/Scripts/webkitpy/layout_tests/layout_package/json_results_generator.py
-# Tools/Scripts/webkitpy/common/net/file_uploader.py
-#
-
-import json
-import logging
-import mimetypes
-import os
-import time
-import urllib2
-
-_log = logging.getLogger(__name__)
-
-_JSON_PREFIX = 'ADD_RESULTS('
-_JSON_SUFFIX = ');'
-
-
-def HasJSONWrapper(string):
- return string.startswith(_JSON_PREFIX) and string.endswith(_JSON_SUFFIX)
-
-
-def StripJSONWrapper(json_content):
- # FIXME: Kill this code once the server returns json instead of jsonp.
- if HasJSONWrapper(json_content):
- return json_content[len(_JSON_PREFIX):len(json_content) - len(_JSON_SUFFIX)]
- return json_content
-
-
-def WriteJSON(json_object, file_path, callback=None):
- # Specify separators in order to get compact encoding.
- json_string = json.dumps(json_object, separators=(',', ':'))
- if callback:
- json_string = callback + '(' + json_string + ');'
- with open(file_path, 'w') as fp:
- fp.write(json_string)
-
-
-def ConvertTrieToFlatPaths(trie, prefix=None):
- """Flattens the trie of paths, prepending a prefix to each."""
- result = {}
- for name, data in trie.iteritems():
- if prefix:
- name = prefix + '/' + name
-
- if len(data) and not 'results' in data:
- result.update(ConvertTrieToFlatPaths(data, name))
- else:
- result[name] = data
-
- return result
-
-
-def AddPathToTrie(path, value, trie):
- """Inserts a single path and value into a directory trie structure."""
- if not '/' in path:
- trie[path] = value
- return
-
- directory, _slash, rest = path.partition('/')
- if not directory in trie:
- trie[directory] = {}
- AddPathToTrie(rest, value, trie[directory])
-
-
-def TestTimingsTrie(individual_test_timings):
- """Breaks a test name into dicts by directory
-
- foo/bar/baz.html: 1ms
- foo/bar/baz1.html: 3ms
-
- becomes
- foo: {
- bar: {
- baz.html: 1,
- baz1.html: 3
- }
- }
- """
- trie = {}
- for test_result in individual_test_timings:
- test = test_result.test_name
-
- AddPathToTrie(test, int(1000 * test_result.test_run_time), trie)
-
- return trie
-
-
-class TestResult(object):
- """A simple class that represents a single test result."""
-
- # Test modifier constants.
- (NONE, FAILS, FLAKY, DISABLED) = range(4)
-
- def __init__(self, test, failed=False, elapsed_time=0):
- self.test_name = test
- self.failed = failed
- self.test_run_time = elapsed_time
-
- test_name = test
- try:
- test_name = test.split('.')[1]
- except IndexError:
- _log.warn('Invalid test name: %s.', test)
-
- if test_name.startswith('FAILS_'):
- self.modifier = self.FAILS
- elif test_name.startswith('FLAKY_'):
- self.modifier = self.FLAKY
- elif test_name.startswith('DISABLED_'):
- self.modifier = self.DISABLED
- else:
- self.modifier = self.NONE
-
- def Fixable(self):
- return self.failed or self.modifier == self.DISABLED
-
-
-class JSONResultsGeneratorBase(object):
- """A JSON results generator for generic tests."""
-
- MAX_NUMBER_OF_BUILD_RESULTS_TO_LOG = 750
- # Min time (seconds) that will be added to the JSON.
- MIN_TIME = 1
-
- # Note that in non-chromium tests those chars are used to indicate
- # test modifiers (FAILS, FLAKY, etc) but not actual test results.
- PASS_RESULT = 'P'
- SKIP_RESULT = 'X'
- FAIL_RESULT = 'F'
- FLAKY_RESULT = 'L'
- NO_DATA_RESULT = 'N'
-
- MODIFIER_TO_CHAR = {TestResult.NONE: PASS_RESULT,
- TestResult.DISABLED: SKIP_RESULT,
- TestResult.FAILS: FAIL_RESULT,
- TestResult.FLAKY: FLAKY_RESULT}
-
- VERSION = 4
- VERSION_KEY = 'version'
- RESULTS = 'results'
- TIMES = 'times'
- BUILD_NUMBERS = 'buildNumbers'
- TIME = 'secondsSinceEpoch'
- TESTS = 'tests'
-
- FIXABLE_COUNT = 'fixableCount'
- FIXABLE = 'fixableCounts'
- ALL_FIXABLE_COUNT = 'allFixableCount'
-
- RESULTS_FILENAME = 'results.json'
- TIMES_MS_FILENAME = 'times_ms.json'
- INCREMENTAL_RESULTS_FILENAME = 'incremental_results.json'
-
- # line too long pylint: disable=line-too-long
- URL_FOR_TEST_LIST_JSON = (
- 'http://%s/testfile?builder=%s&name=%s&testlistjson=1&testtype=%s&master=%s')
- # pylint: enable=line-too-long
-
- def __init__(self, builder_name, build_name, build_number,
- results_file_base_path, builder_base_url,
- test_results_map, svn_repositories=None,
- test_results_server=None,
- test_type='',
- master_name=''):
- """Modifies the results.json file. Grabs it off the archive directory
- if it is not found locally.
-
- Args
- builder_name: the builder name (e.g. Webkit).
- build_name: the build name (e.g. webkit-rel).
- build_number: the build number.
- results_file_base_path: Absolute path to the directory containing the
- results json file.
- builder_base_url: the URL where we have the archived test results.
- If this is None no archived results will be retrieved.
- test_results_map: A dictionary that maps test_name to TestResult.
- svn_repositories: A (json_field_name, svn_path) pair for SVN
- repositories that tests rely on. The SVN revision will be
- included in the JSON with the given json_field_name.
- test_results_server: server that hosts test results json.
- test_type: test type string (e.g. 'layout-tests').
- master_name: the name of the buildbot master.
- """
- self._builder_name = builder_name
- self._build_name = build_name
- self._build_number = build_number
- self._builder_base_url = builder_base_url
- self._results_directory = results_file_base_path
-
- self._test_results_map = test_results_map
- self._test_results = test_results_map.values()
-
- self._svn_repositories = svn_repositories
- if not self._svn_repositories:
- self._svn_repositories = {}
-
- self._test_results_server = test_results_server
- self._test_type = test_type
- self._master_name = master_name
-
- self._archived_results = None
-
- def GenerateJSONOutput(self):
- json_object = self.GetJSON()
- if json_object:
- file_path = (
- os.path.join(
- self._results_directory,
- self.INCREMENTAL_RESULTS_FILENAME))
- WriteJSON(json_object, file_path)
-
- def GenerateTimesMSFile(self):
- times = TestTimingsTrie(self._test_results_map.values())
- file_path = os.path.join(self._results_directory, self.TIMES_MS_FILENAME)
- WriteJSON(times, file_path)
-
- def GetJSON(self):
- """Gets the results for the results.json file."""
- results_json = {}
-
- if not results_json:
- results_json, error = self._GetArchivedJSONResults()
- if error:
- # If there was an error don't write a results.json
- # file at all as it would lose all the information on the
- # bot.
- _log.error('Archive directory is inaccessible. Not '
- 'modifying or clobbering the results.json '
- 'file: ' + str(error))
- return None
-
- builder_name = self._builder_name
- if results_json and builder_name not in results_json:
- _log.debug('Builder name (%s) is not in the results.json file.'
- % builder_name)
-
- self._ConvertJSONToCurrentVersion(results_json)
-
- if builder_name not in results_json:
- results_json[builder_name] = (
- self._CreateResultsForBuilderJSON())
-
- results_for_builder = results_json[builder_name]
-
- if builder_name:
- self._InsertGenericMetaData(results_for_builder)
-
- self._InsertFailureSummaries(results_for_builder)
-
- # Update the all failing tests with result type and time.
- tests = results_for_builder[self.TESTS]
- all_failing_tests = self._GetFailedTestNames()
- all_failing_tests.update(ConvertTrieToFlatPaths(tests))
-
- for test in all_failing_tests:
- self._InsertTestTimeAndResult(test, tests)
-
- return results_json
-
- def SetArchivedResults(self, archived_results):
- self._archived_results = archived_results
-
- def UploadJSONFiles(self, json_files):
- """Uploads the given json_files to the test_results_server (if the
- test_results_server is given)."""
- if not self._test_results_server:
- return
-
- if not self._master_name:
- _log.error(
- '--test-results-server was set, but --master-name was not. Not '
- 'uploading JSON files.')
- return
-
- _log.info('Uploading JSON files for builder: %s', self._builder_name)
- attrs = [('builder', self._builder_name),
- ('testtype', self._test_type),
- ('master', self._master_name)]
-
- files = [(json_file, os.path.join(self._results_directory, json_file))
- for json_file in json_files]
-
- url = 'http://%s/testfile/upload' % self._test_results_server
- # Set uploading timeout in case appengine server is having problems.
- # 120 seconds are more than enough to upload test results.
- uploader = _FileUploader(url, 120)
- try:
- response = uploader.UploadAsMultipartFormData(files, attrs)
- if response:
- if response.code == 200:
- _log.info('JSON uploaded.')
- else:
- _log.debug(
- "JSON upload failed, %d: '%s'" %
- (response.code, response.read()))
- else:
- _log.error('JSON upload failed; no response returned')
- except Exception, err:
- _log.error('Upload failed: %s' % err)
- return
-
- def _GetTestTiming(self, test_name):
- """Returns test timing data (elapsed time) in second
- for the given test_name."""
- if test_name in self._test_results_map:
- # Floor for now to get time in seconds.
- return int(self._test_results_map[test_name].test_run_time)
- return 0
-
- def _GetFailedTestNames(self):
- """Returns a set of failed test names."""
- return set([r.test_name for r in self._test_results if r.failed])
-
- def _GetModifierChar(self, test_name):
- """Returns a single char (e.g. SKIP_RESULT, FAIL_RESULT,
- PASS_RESULT, NO_DATA_RESULT, etc) that indicates the test modifier
- for the given test_name.
- """
- if test_name not in self._test_results_map:
- return self.__class__.NO_DATA_RESULT
-
- test_result = self._test_results_map[test_name]
- if test_result.modifier in self.MODIFIER_TO_CHAR.keys():
- return self.MODIFIER_TO_CHAR[test_result.modifier]
-
- return self.__class__.PASS_RESULT
-
- def _get_result_char(self, test_name):
- """Returns a single char (e.g. SKIP_RESULT, FAIL_RESULT,
- PASS_RESULT, NO_DATA_RESULT, etc) that indicates the test result
- for the given test_name.
- """
- if test_name not in self._test_results_map:
- return self.__class__.NO_DATA_RESULT
-
- test_result = self._test_results_map[test_name]
- if test_result.modifier == TestResult.DISABLED:
- return self.__class__.SKIP_RESULT
-
- if test_result.failed:
- return self.__class__.FAIL_RESULT
-
- return self.__class__.PASS_RESULT
-
- def _GetSVNRevision(self, in_directory):
- """Returns the svn revision for the given directory.
-
- Args:
- in_directory: The directory where svn is to be run.
- """
- # This is overridden in flakiness_dashboard_results_uploader.py.
- raise NotImplementedError()
-
- def _GetArchivedJSONResults(self):
- """Download JSON file that only contains test
- name list from test-results server. This is for generating incremental
- JSON so the file generated has info for tests that failed before but
- pass or are skipped from current run.
-
- Returns (archived_results, error) tuple where error is None if results
- were successfully read.
- """
- results_json = {}
- old_results = None
- error = None
-
- if not self._test_results_server:
- return {}, None
-
- results_file_url = (self.URL_FOR_TEST_LIST_JSON %
- (urllib2.quote(self._test_results_server),
- urllib2.quote(self._builder_name),
- self.RESULTS_FILENAME,
- urllib2.quote(self._test_type),
- urllib2.quote(self._master_name)))
-
- try:
- # FIXME: We should talk to the network via a Host object.
- results_file = urllib2.urlopen(results_file_url)
- old_results = results_file.read()
- except urllib2.HTTPError, http_error:
- # A non-4xx status code means the bot is hosed for some reason
- # and we can't grab the results.json file off of it.
- if http_error.code < 400 and http_error.code >= 500:
- error = http_error
- except urllib2.URLError, url_error:
- error = url_error
-
- if old_results:
- # Strip the prefix and suffix so we can get the actual JSON object.
- old_results = StripJSONWrapper(old_results)
-
- try:
- results_json = json.loads(old_results)
- except Exception:
- _log.debug('results.json was not valid JSON. Clobbering.')
- # The JSON file is not valid JSON. Just clobber the results.
- results_json = {}
- else:
- _log.debug('Old JSON results do not exist. Starting fresh.')
- results_json = {}
-
- return results_json, error
-
- def _InsertFailureSummaries(self, results_for_builder):
- """Inserts aggregate pass/failure statistics into the JSON.
- This method reads self._test_results and generates
- FIXABLE, FIXABLE_COUNT and ALL_FIXABLE_COUNT entries.
-
- Args:
- results_for_builder: Dictionary containing the test results for a
- single builder.
- """
- # Insert the number of tests that failed or skipped.
- fixable_count = len([r for r in self._test_results if r.Fixable()])
- self._InsertItemIntoRawList(results_for_builder,
- fixable_count, self.FIXABLE_COUNT)
-
- # Create a test modifiers (FAILS, FLAKY etc) summary dictionary.
- entry = {}
- for test_name in self._test_results_map.iterkeys():
- result_char = self._GetModifierChar(test_name)
- entry[result_char] = entry.get(result_char, 0) + 1
-
- # Insert the pass/skip/failure summary dictionary.
- self._InsertItemIntoRawList(results_for_builder, entry,
- self.FIXABLE)
-
- # Insert the number of all the tests that are supposed to pass.
- all_test_count = len(self._test_results)
- self._InsertItemIntoRawList(results_for_builder,
- all_test_count, self.ALL_FIXABLE_COUNT)
-
- def _InsertItemIntoRawList(self, results_for_builder, item, key):
- """Inserts the item into the list with the given key in the results for
- this builder. Creates the list if no such list exists.
-
- Args:
- results_for_builder: Dictionary containing the test results for a
- single builder.
- item: Number or string to insert into the list.
- key: Key in results_for_builder for the list to insert into.
- """
- if key in results_for_builder:
- raw_list = results_for_builder[key]
- else:
- raw_list = []
-
- raw_list.insert(0, item)
- raw_list = raw_list[:self.MAX_NUMBER_OF_BUILD_RESULTS_TO_LOG]
- results_for_builder[key] = raw_list
-
- def _InsertItemRunLengthEncoded(self, item, encoded_results):
- """Inserts the item into the run-length encoded results.
-
- Args:
- item: String or number to insert.
- encoded_results: run-length encoded results. An array of arrays, e.g.
- [[3,'A'],[1,'Q']] encodes AAAQ.
- """
- if len(encoded_results) and item == encoded_results[0][1]:
- num_results = encoded_results[0][0]
- if num_results <= self.MAX_NUMBER_OF_BUILD_RESULTS_TO_LOG:
- encoded_results[0][0] = num_results + 1
- else:
- # Use a list instead of a class for the run-length encoding since
- # we want the serialized form to be concise.
- encoded_results.insert(0, [1, item])
-
- def _InsertGenericMetaData(self, results_for_builder):
- """ Inserts generic metadata (such as version number, current time etc)
- into the JSON.
-
- Args:
- results_for_builder: Dictionary containing the test results for
- a single builder.
- """
- self._InsertItemIntoRawList(results_for_builder,
- self._build_number, self.BUILD_NUMBERS)
-
- # Include SVN revisions for the given repositories.
- for (name, path) in self._svn_repositories:
- # Note: for JSON file's backward-compatibility we use 'chrome' rather
- # than 'chromium' here.
- lowercase_name = name.lower()
- if lowercase_name == 'chromium':
- lowercase_name = 'chrome'
- self._InsertItemIntoRawList(results_for_builder,
- self._GetSVNRevision(path),
- lowercase_name + 'Revision')
-
- self._InsertItemIntoRawList(results_for_builder,
- int(time.time()),
- self.TIME)
-
- def _InsertTestTimeAndResult(self, test_name, tests):
- """ Insert a test item with its results to the given tests dictionary.
-
- Args:
- tests: Dictionary containing test result entries.
- """
-
- result = self._get_result_char(test_name)
- test_time = self._GetTestTiming(test_name)
-
- this_test = tests
- for segment in test_name.split('/'):
- if segment not in this_test:
- this_test[segment] = {}
- this_test = this_test[segment]
-
- if not len(this_test):
- self._PopulateResultsAndTimesJSON(this_test)
-
- if self.RESULTS in this_test:
- self._InsertItemRunLengthEncoded(result, this_test[self.RESULTS])
- else:
- this_test[self.RESULTS] = [[1, result]]
-
- if self.TIMES in this_test:
- self._InsertItemRunLengthEncoded(test_time, this_test[self.TIMES])
- else:
- this_test[self.TIMES] = [[1, test_time]]
-
- def _ConvertJSONToCurrentVersion(self, results_json):
- """If the JSON does not match the current version, converts it to the
- current version and adds in the new version number.
- """
- if self.VERSION_KEY in results_json:
- archive_version = results_json[self.VERSION_KEY]
- if archive_version == self.VERSION:
- return
- else:
- archive_version = 3
-
- # version 3->4
- if archive_version == 3:
- for results in results_json.values():
- self._ConvertTestsToTrie(results)
-
- results_json[self.VERSION_KEY] = self.VERSION
-
- def _ConvertTestsToTrie(self, results):
- if not self.TESTS in results:
- return
-
- test_results = results[self.TESTS]
- test_results_trie = {}
- for test in test_results.iterkeys():
- single_test_result = test_results[test]
- AddPathToTrie(test, single_test_result, test_results_trie)
-
- results[self.TESTS] = test_results_trie
-
- def _PopulateResultsAndTimesJSON(self, results_and_times):
- results_and_times[self.RESULTS] = []
- results_and_times[self.TIMES] = []
- return results_and_times
-
- def _CreateResultsForBuilderJSON(self):
- results_for_builder = {}
- results_for_builder[self.TESTS] = {}
- return results_for_builder
-
- def _RemoveItemsOverMaxNumberOfBuilds(self, encoded_list):
- """Removes items from the run-length encoded list after the final
- item that exceeds the max number of builds to track.
-
- Args:
- encoded_results: run-length encoded results. An array of arrays, e.g.
- [[3,'A'],[1,'Q']] encodes AAAQ.
- """
- num_builds = 0
- index = 0
- for result in encoded_list:
- num_builds = num_builds + result[0]
- index = index + 1
- if num_builds > self.MAX_NUMBER_OF_BUILD_RESULTS_TO_LOG:
- return encoded_list[:index]
- return encoded_list
-
- def _NormalizeResultsJSON(self, test, test_name, tests):
- """ Prune tests where all runs pass or tests that no longer exist and
- truncate all results to maxNumberOfBuilds.
-
- Args:
- test: ResultsAndTimes object for this test.
- test_name: Name of the test.
- tests: The JSON object with all the test results for this builder.
- """
- test[self.RESULTS] = self._RemoveItemsOverMaxNumberOfBuilds(
- test[self.RESULTS])
- test[self.TIMES] = self._RemoveItemsOverMaxNumberOfBuilds(
- test[self.TIMES])
-
- is_all_pass = self._IsResultsAllOfType(test[self.RESULTS],
- self.PASS_RESULT)
- is_all_no_data = self._IsResultsAllOfType(test[self.RESULTS],
- self.NO_DATA_RESULT)
- max_time = max([test_time[1] for test_time in test[self.TIMES]])
-
- # Remove all passes/no-data from the results to reduce noise and
- # filesize. If a test passes every run, but takes > MIN_TIME to run,
- # don't throw away the data.
- if is_all_no_data or (is_all_pass and max_time <= self.MIN_TIME):
- del tests[test_name]
-
- # method could be a function pylint: disable=R0201
- def _IsResultsAllOfType(self, results, result_type):
- """Returns whether all the results are of the given type
- (e.g. all passes)."""
- return len(results) == 1 and results[0][1] == result_type
-
-
-class _FileUploader(object):
-
- def __init__(self, url, timeout_seconds):
- self._url = url
- self._timeout_seconds = timeout_seconds
-
- def UploadAsMultipartFormData(self, files, attrs):
- file_objs = []
- for filename, path in files:
- with file(path, 'rb') as fp:
- file_objs.append(('file', filename, fp.read()))
-
- # FIXME: We should use the same variable names for the formal and actual
- # parameters.
- content_type, data = _EncodeMultipartFormData(attrs, file_objs)
- return self._UploadData(content_type, data)
-
- def _UploadData(self, content_type, data):
- start = time.time()
- end = start + self._timeout_seconds
- while time.time() < end:
- try:
- request = urllib2.Request(self._url, data,
- {'Content-Type': content_type})
- return urllib2.urlopen(request)
- except urllib2.HTTPError as e:
- _log.warn("Received HTTP status %s loading \"%s\". "
- 'Retrying in 10 seconds...' % (e.code, e.filename))
- time.sleep(10)
-
-
-def _GetMIMEType(filename):
- return mimetypes.guess_type(filename)[0] or 'application/octet-stream'
-
-
-# FIXME: Rather than taking tuples, this function should take more
-# structured data.
-def _EncodeMultipartFormData(fields, files):
- """Encode form fields for multipart/form-data.
-
- Args:
- fields: A sequence of (name, value) elements for regular form fields.
- files: A sequence of (name, filename, value) elements for data to be
- uploaded as files.
- Returns:
- (content_type, body) ready for httplib.HTTP instance.
-
- Source:
- http://code.google.com/p/rietveld/source/browse/trunk/upload.py
- """
- BOUNDARY = '-M-A-G-I-C---B-O-U-N-D-A-R-Y-'
- CRLF = '\r\n'
- lines = []
-
- for key, value in fields:
- lines.append('--' + BOUNDARY)
- lines.append('Content-Disposition: form-data; name="%s"' % key)
- lines.append('')
- if isinstance(value, unicode):
- value = value.encode('utf-8')
- lines.append(value)
-
- for key, filename, value in files:
- lines.append('--' + BOUNDARY)
- lines.append('Content-Disposition: form-data; name="%s"; '
- 'filename="%s"' % (key, filename))
- lines.append('Content-Type: %s' % _GetMIMEType(filename))
- lines.append('')
- if isinstance(value, unicode):
- value = value.encode('utf-8')
- lines.append(value)
-
- lines.append('--' + BOUNDARY + '--')
- lines.append('')
- body = CRLF.join(lines)
- content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
- return content_type, body
diff --git a/build/android/pylib/results/flakiness_dashboard/results_uploader.py b/build/android/pylib/results/flakiness_dashboard/results_uploader.py
deleted file mode 100644
index b86d7ac..0000000
--- a/build/android/pylib/results/flakiness_dashboard/results_uploader.py
+++ /dev/null
@@ -1,181 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Uploads the results to the flakiness dashboard server."""
-# pylint: disable=E1002,R0201
-
-import logging
-import os
-import shutil
-import tempfile
-import xml
-
-
-from pylib import cmd_helper
-from pylib import constants
-from pylib.results.flakiness_dashboard import json_results_generator
-from pylib.utils import repo_utils
-
-
-
-class JSONResultsGenerator(json_results_generator.JSONResultsGeneratorBase):
- """Writes test results to a JSON file and handles uploading that file to
- the test results server.
- """
- def __init__(self, builder_name, build_name, build_number, tmp_folder,
- test_results_map, test_results_server, test_type, master_name):
- super(JSONResultsGenerator, self).__init__(
- builder_name=builder_name,
- build_name=build_name,
- build_number=build_number,
- results_file_base_path=tmp_folder,
- builder_base_url=None,
- test_results_map=test_results_map,
- svn_repositories=(('webkit', 'third_party/WebKit'),
- ('chrome', '.')),
- test_results_server=test_results_server,
- test_type=test_type,
- master_name=master_name)
-
- #override
- def _GetModifierChar(self, test_name):
- if test_name not in self._test_results_map:
- return self.__class__.NO_DATA_RESULT
-
- return self._test_results_map[test_name].modifier
-
- #override
- def _GetSVNRevision(self, in_directory):
- """Returns the git/svn revision for the given directory.
-
- Args:
- in_directory: The directory relative to src.
- """
- def _is_git_directory(in_directory):
- """Returns true if the given directory is in a git repository.
-
- Args:
- in_directory: The directory path to be tested.
- """
- if os.path.exists(os.path.join(in_directory, '.git')):
- return True
- parent = os.path.dirname(in_directory)
- if parent == constants.DIR_SOURCE_ROOT or parent == in_directory:
- return False
- return _is_git_directory(parent)
-
- in_directory = os.path.join(constants.DIR_SOURCE_ROOT, in_directory)
-
- if not os.path.exists(os.path.join(in_directory, '.svn')):
- if _is_git_directory(in_directory):
- return repo_utils.GetGitHeadSHA1(in_directory)
- else:
- return ''
-
- output = cmd_helper.GetCmdOutput(['svn', 'info', '--xml'], cwd=in_directory)
- try:
- dom = xml.dom.minidom.parseString(output)
- return dom.getElementsByTagName('entry')[0].getAttribute('revision')
- except xml.parsers.expat.ExpatError:
- return ''
- return ''
-
-
-class ResultsUploader(object):
- """Handles uploading buildbot tests results to the flakiness dashboard."""
- def __init__(self, tests_type):
- self._build_number = os.environ.get('BUILDBOT_BUILDNUMBER')
- self._builder_name = os.environ.get('BUILDBOT_BUILDERNAME')
- self._tests_type = tests_type
-
- if not self._build_number or not self._builder_name:
- raise Exception('You should not be uploading tests results to the server'
- 'from your local machine.')
-
- upstream = (tests_type != 'Chromium_Android_Instrumentation')
- if upstream:
- # TODO(frankf): Use factory properties (see buildbot/bb_device_steps.py)
- # This requires passing the actual master name (e.g. 'ChromiumFYI' not
- # 'chromium.fyi').
- from slave import slave_utils # pylint: disable=F0401
- self._build_name = slave_utils.SlaveBuildName(constants.DIR_SOURCE_ROOT)
- self._master_name = slave_utils.GetActiveMaster()
- else:
- self._build_name = 'chromium-android'
- buildbot_branch = os.environ.get('BUILDBOT_BRANCH')
- if not buildbot_branch:
- buildbot_branch = 'master'
- else:
- # Ensure there's no leading "origin/"
- buildbot_branch = buildbot_branch[buildbot_branch.find('/') + 1:]
- self._master_name = '%s-%s' % (self._build_name, buildbot_branch)
-
- self._test_results_map = {}
-
- def AddResults(self, test_results):
- # TODO(frankf): Differentiate between fail/crash/timeouts.
- conversion_map = [
- (test_results.GetPass(), False,
- json_results_generator.JSONResultsGeneratorBase.PASS_RESULT),
- (test_results.GetFail(), True,
- json_results_generator.JSONResultsGeneratorBase.FAIL_RESULT),
- (test_results.GetCrash(), True,
- json_results_generator.JSONResultsGeneratorBase.FAIL_RESULT),
- (test_results.GetTimeout(), True,
- json_results_generator.JSONResultsGeneratorBase.FAIL_RESULT),
- (test_results.GetUnknown(), True,
- json_results_generator.JSONResultsGeneratorBase.NO_DATA_RESULT),
- ]
-
- for results_list, failed, modifier in conversion_map:
- for single_test_result in results_list:
- test_result = json_results_generator.TestResult(
- test=single_test_result.GetName(),
- failed=failed,
- elapsed_time=single_test_result.GetDuration() / 1000)
- # The WebKit TestResult object sets the modifier it based on test name.
- # Since we don't use the same test naming convention as WebKit the
- # modifier will be wrong, so we need to overwrite it.
- test_result.modifier = modifier
-
- self._test_results_map[single_test_result.GetName()] = test_result
-
- def Upload(self, test_results_server):
- if not self._test_results_map:
- return
-
- tmp_folder = tempfile.mkdtemp()
-
- try:
- results_generator = JSONResultsGenerator(
- builder_name=self._builder_name,
- build_name=self._build_name,
- build_number=self._build_number,
- tmp_folder=tmp_folder,
- test_results_map=self._test_results_map,
- test_results_server=test_results_server,
- test_type=self._tests_type,
- master_name=self._master_name)
-
- json_files = ["incremental_results.json", "times_ms.json"]
- results_generator.GenerateJSONOutput()
- results_generator.GenerateTimesMSFile()
- results_generator.UploadJSONFiles(json_files)
- except Exception as e:
- logging.error("Uploading results to test server failed: %s." % e)
- finally:
- shutil.rmtree(tmp_folder)
-
-
-def Upload(results, flakiness_dashboard_server, test_type):
- """Reports test results to the flakiness dashboard for Chrome for Android.
-
- Args:
- results: test results.
- flakiness_dashboard_server: the server to upload the results to.
- test_type: the type of the tests (as displayed by the flakiness dashboard).
- """
- uploader = ResultsUploader(test_type)
- uploader.AddResults(results)
- uploader.Upload(flakiness_dashboard_server)
diff --git a/build/android/pylib/results/json_results.py b/build/android/pylib/results/json_results.py
deleted file mode 100644
index 65664e3..0000000
--- a/build/android/pylib/results/json_results.py
+++ /dev/null
@@ -1,139 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import json
-import logging
-
-from pylib.base import base_test_result
-
-
-def GenerateResultsDict(test_run_result):
- """Create a results dict from |test_run_result| suitable for writing to JSON.
- Args:
- test_run_result: a base_test_result.TestRunResults object.
- Returns:
- A results dict that mirrors the one generated by
- base/test/launcher/test_results_tracker.cc:SaveSummaryAsJSON.
- """
- # Example json output.
- # {
- # "global_tags": [],
- # "all_tests": [
- # "test1",
- # "test2",
- # ],
- # "disabled_tests": [],
- # "per_iteration_data": [
- # {
- # "test1": [
- # {
- # "status": "SUCCESS",
- # "elapsed_time_ms": 1,
- # "output_snippet": "",
- # "output_snippet_base64": "",
- # "losless_snippet": "",
- # },
- # ],
- # "test2": [
- # {
- # "status": "FAILURE",
- # "elapsed_time_ms": 12,
- # "output_snippet": "",
- # "output_snippet_base64": "",
- # "losless_snippet": "",
- # },
- # ],
- # },
- # ],
- # }
-
- assert isinstance(test_run_result, base_test_result.TestRunResults)
-
- def status_as_string(s):
- if s == base_test_result.ResultType.PASS:
- return 'SUCCESS'
- elif s == base_test_result.ResultType.SKIP:
- return 'SKIPPED'
- elif s == base_test_result.ResultType.FAIL:
- return 'FAILURE'
- elif s == base_test_result.ResultType.CRASH:
- return 'CRASH'
- elif s == base_test_result.ResultType.TIMEOUT:
- return 'TIMEOUT'
- elif s == base_test_result.ResultType.UNKNOWN:
- return 'UNKNOWN'
-
- def generate_iteration_data(t):
- return {
- t.GetName(): [
- {
- 'status': status_as_string(t.GetType()),
- 'elapsed_time_ms': t.GetDuration(),
- 'output_snippet': '',
- 'losless_snippet': '',
- 'output_snippet_base64:': '',
- }
- ]
- }
-
- all_tests_tuple, per_iteration_data_tuple = zip(
- *[(t.GetName(), generate_iteration_data(t))
- for t in test_run_result.GetAll()])
-
- return {
- 'global_tags': [],
- 'all_tests': list(all_tests_tuple),
- # TODO(jbudorick): Add support for disabled tests within base_test_result.
- 'disabled_tests': [],
- 'per_iteration_data': list(per_iteration_data_tuple),
- }
-
-
-def GenerateJsonResultsFile(test_run_result, file_path):
- """Write |test_run_result| to JSON.
-
- This emulates the format of the JSON emitted by
- base/test/launcher/test_results_tracker.cc:SaveSummaryAsJSON.
-
- Args:
- test_run_result: a base_test_result.TestRunResults object.
- file_path: The path to the JSON file to write.
- """
- with open(file_path, 'w') as json_result_file:
- json_result_file.write(json.dumps(GenerateResultsDict(test_run_result)))
-
-
-def ParseResultsFromJson(json_results):
- """Creates a list of BaseTestResult objects from JSON.
-
- Args:
- json_results: A JSON dict in the format created by
- GenerateJsonResultsFile.
- """
-
- def string_as_status(s):
- if s == 'SUCCESS':
- return base_test_result.ResultType.PASS
- elif s == 'SKIPPED':
- return base_test_result.ResultType.SKIP
- elif s == 'FAILURE':
- return base_test_result.ResultType.FAIL
- elif s == 'CRASH':
- return base_test_result.ResultType.CRASH
- elif s == 'TIMEOUT':
- return base_test_result.ResultType.TIMEOUT
- else:
- return base_test_result.ResultType.UNKNOWN
-
- results_list = []
- testsuite_runs = json_results['per_iteration_data']
- for testsuite_run in testsuite_runs:
- for test, test_runs in testsuite_run.iteritems():
- results_list.extend(
- [base_test_result.BaseTestResult(test,
- string_as_status(tr['status']),
- duration=tr['elapsed_time_ms'])
- for tr in test_runs])
- return results_list
-
diff --git a/build/android/pylib/results/json_results_test.py b/build/android/pylib/results/json_results_test.py
deleted file mode 100755
index 1bc730d..0000000
--- a/build/android/pylib/results/json_results_test.py
+++ /dev/null
@@ -1,133 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import unittest
-
-from pylib.base import base_test_result
-from pylib.results import json_results
-
-
-class JsonResultsTest(unittest.TestCase):
-
- def testGenerateResultsDict_passedResult(self):
- result = base_test_result.BaseTestResult(
- 'test.package.TestName', base_test_result.ResultType.PASS)
-
- all_results = base_test_result.TestRunResults()
- all_results.AddResult(result)
-
- results_dict = json_results.GenerateResultsDict(all_results)
- self.assertEquals(
- ['test.package.TestName'],
- results_dict['all_tests'])
- self.assertEquals(1, len(results_dict['per_iteration_data']))
-
- iteration_result = results_dict['per_iteration_data'][0]
- self.assertTrue('test.package.TestName' in iteration_result)
- self.assertEquals(1, len(iteration_result['test.package.TestName']))
-
- test_iteration_result = iteration_result['test.package.TestName'][0]
- self.assertTrue('status' in test_iteration_result)
- self.assertEquals('SUCCESS', test_iteration_result['status'])
-
- def testGenerateResultsDict_skippedResult(self):
- result = base_test_result.BaseTestResult(
- 'test.package.TestName', base_test_result.ResultType.SKIP)
-
- all_results = base_test_result.TestRunResults()
- all_results.AddResult(result)
-
- results_dict = json_results.GenerateResultsDict(all_results)
- self.assertEquals(
- ['test.package.TestName'],
- results_dict['all_tests'])
- self.assertEquals(1, len(results_dict['per_iteration_data']))
-
- iteration_result = results_dict['per_iteration_data'][0]
- self.assertTrue('test.package.TestName' in iteration_result)
- self.assertEquals(1, len(iteration_result['test.package.TestName']))
-
- test_iteration_result = iteration_result['test.package.TestName'][0]
- self.assertTrue('status' in test_iteration_result)
- self.assertEquals('SKIPPED', test_iteration_result['status'])
-
- def testGenerateResultsDict_failedResult(self):
- result = base_test_result.BaseTestResult(
- 'test.package.TestName', base_test_result.ResultType.FAIL)
-
- all_results = base_test_result.TestRunResults()
- all_results.AddResult(result)
-
- results_dict = json_results.GenerateResultsDict(all_results)
- self.assertEquals(
- ['test.package.TestName'],
- results_dict['all_tests'])
- self.assertEquals(1, len(results_dict['per_iteration_data']))
-
- iteration_result = results_dict['per_iteration_data'][0]
- self.assertTrue('test.package.TestName' in iteration_result)
- self.assertEquals(1, len(iteration_result['test.package.TestName']))
-
- test_iteration_result = iteration_result['test.package.TestName'][0]
- self.assertTrue('status' in test_iteration_result)
- self.assertEquals('FAILURE', test_iteration_result['status'])
-
- def testGenerateResultsDict_duration(self):
- result = base_test_result.BaseTestResult(
- 'test.package.TestName', base_test_result.ResultType.PASS, duration=123)
-
- all_results = base_test_result.TestRunResults()
- all_results.AddResult(result)
-
- results_dict = json_results.GenerateResultsDict(all_results)
- self.assertEquals(
- ['test.package.TestName'],
- results_dict['all_tests'])
- self.assertEquals(1, len(results_dict['per_iteration_data']))
-
- iteration_result = results_dict['per_iteration_data'][0]
- self.assertTrue('test.package.TestName' in iteration_result)
- self.assertEquals(1, len(iteration_result['test.package.TestName']))
-
- test_iteration_result = iteration_result['test.package.TestName'][0]
- self.assertTrue('elapsed_time_ms' in test_iteration_result)
- self.assertEquals(123, test_iteration_result['elapsed_time_ms'])
-
- def testGenerateResultsDict_multipleResults(self):
- result1 = base_test_result.BaseTestResult(
- 'test.package.TestName1', base_test_result.ResultType.PASS)
- result2 = base_test_result.BaseTestResult(
- 'test.package.TestName2', base_test_result.ResultType.PASS)
-
- all_results = base_test_result.TestRunResults()
- all_results.AddResult(result1)
- all_results.AddResult(result2)
-
- results_dict = json_results.GenerateResultsDict(all_results)
- self.assertEquals(
- ['test.package.TestName1', 'test.package.TestName2'],
- results_dict['all_tests'])
- self.assertEquals(2, len(results_dict['per_iteration_data']))
-
- expected_tests = set([
- 'test.package.TestName1',
- 'test.package.TestName2',
- ])
-
- for iteration_result in results_dict['per_iteration_data']:
- self.assertEquals(1, len(iteration_result))
- name = iteration_result.keys()[0]
- self.assertTrue(name in expected_tests)
- expected_tests.remove(name)
- self.assertEquals(1, len(iteration_result[name]))
-
- test_iteration_result = iteration_result[name][0]
- self.assertTrue('status' in test_iteration_result)
- self.assertEquals('SUCCESS', test_iteration_result['status'])
-
-
-if __name__ == '__main__':
- unittest.main(verbosity=2)
-
diff --git a/build/android/pylib/results/report_results.py b/build/android/pylib/results/report_results.py
deleted file mode 100644
index 4fc6aa0..0000000
--- a/build/android/pylib/results/report_results.py
+++ /dev/null
@@ -1,114 +0,0 @@
-# Copyright (c) 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Module containing utility functions for reporting results."""
-
-import logging
-import os
-import re
-
-from pylib import constants
-from pylib.results.flakiness_dashboard import results_uploader
-
-
-def _LogToFile(results, test_type, suite_name):
- """Log results to local files which can be used for aggregation later."""
- log_file_path = os.path.join(constants.GetOutDirectory(), 'test_logs')
- if not os.path.exists(log_file_path):
- os.mkdir(log_file_path)
- full_file_name = os.path.join(
- log_file_path, re.sub(r'\W', '_', test_type).lower() + '.log')
- if not os.path.exists(full_file_name):
- with open(full_file_name, 'w') as log_file:
- print >> log_file, '\n%s results for %s build %s:' % (
- test_type, os.environ.get('BUILDBOT_BUILDERNAME'),
- os.environ.get('BUILDBOT_BUILDNUMBER'))
- logging.info('Writing results to %s.' % full_file_name)
-
- logging.info('Writing results to %s.' % full_file_name)
- with open(full_file_name, 'a') as log_file:
- shortened_suite_name = suite_name[:25] + (suite_name[25:] and '...')
- print >> log_file, '%s%s' % (shortened_suite_name.ljust(30),
- results.GetShortForm())
-
-
-def _LogToFlakinessDashboard(results, test_type, test_package,
- flakiness_server):
- """Upload results to the flakiness dashboard"""
- logging.info('Upload results for test type "%s", test package "%s" to %s' %
- (test_type, test_package, flakiness_server))
-
- try:
- if test_type == 'Instrumentation':
- if flakiness_server == constants.UPSTREAM_FLAKINESS_SERVER:
- assert test_package in ['ContentShellTest',
- 'ChromePublicTest',
- 'ChromeShellTest',
- 'ChromeSyncShellTest',
- 'AndroidWebViewTest']
- dashboard_test_type = ('%s_instrumentation_tests' %
- test_package.lower().rstrip('test'))
- # Downstream server.
- else:
- dashboard_test_type = 'Chromium_Android_Instrumentation'
-
- elif test_type == 'Unit test':
- dashboard_test_type = test_package
-
- else:
- logging.warning('Invalid test type')
- return
-
- results_uploader.Upload(
- results, flakiness_server, dashboard_test_type)
-
- except Exception as e:
- logging.error(e)
-
-
-def LogFull(results, test_type, test_package, annotation=None,
- flakiness_server=None):
- """Log the tests results for the test suite.
-
- The results will be logged three different ways:
- 1. Log to stdout.
- 2. Log to local files for aggregating multiple test steps
- (on buildbots only).
- 3. Log to flakiness dashboard (on buildbots only).
-
- Args:
- results: An instance of TestRunResults object.
- test_type: Type of the test (e.g. 'Instrumentation', 'Unit test', etc.).
- test_package: Test package name (e.g. 'ipc_tests' for gtests,
- 'ContentShellTest' for instrumentation tests)
- annotation: If instrumenation test type, this is a list of annotations
- (e.g. ['Smoke', 'SmallTest']).
- flakiness_server: If provider, upload the results to flakiness dashboard
- with this URL.
- """
- if not results.DidRunPass():
- logging.critical('*' * 80)
- logging.critical('Detailed Logs')
- logging.critical('*' * 80)
- for line in results.GetLogs().splitlines():
- logging.critical(line)
- logging.critical('*' * 80)
- logging.critical('Summary')
- logging.critical('*' * 80)
- for line in results.GetGtestForm().splitlines():
- logging.critical(line)
- logging.critical('*' * 80)
-
- if os.environ.get('BUILDBOT_BUILDERNAME'):
- # It is possible to have multiple buildbot steps for the same
- # instrumenation test package using different annotations.
- if annotation and len(annotation) == 1:
- suite_name = annotation[0]
- else:
- suite_name = test_package
- _LogToFile(results, test_type, suite_name)
-
- if flakiness_server:
- _LogToFlakinessDashboard(results, test_type, test_package,
- flakiness_server)
diff --git a/build/android/pylib/screenshot.py b/build/android/pylib/screenshot.py
deleted file mode 100644
index 0fcc590..0000000
--- a/build/android/pylib/screenshot.py
+++ /dev/null
@@ -1,99 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import os
-import tempfile
-import time
-
-from pylib import cmd_helper
-from pylib import device_signal
-from pylib.device import device_errors
-
-# TODO(jbudorick) Remove once telemetry gets switched over.
-import pylib.android_commands
-import pylib.device.device_utils
-
-
-class VideoRecorder(object):
- """Records a screen capture video from an Android Device (KitKat or newer).
-
- Args:
- device: DeviceUtils instance.
- host_file: Path to the video file to store on the host.
- megabits_per_second: Video bitrate in megabits per second. Allowed range
- from 0.1 to 100 mbps.
- size: Video frame size tuple (width, height) or None to use the device
- default.
- rotate: If True, the video will be rotated 90 degrees.
- """
- def __init__(self, device, megabits_per_second=4, size=None,
- rotate=False):
- # TODO(jbudorick) Remove once telemetry gets switched over.
- if isinstance(device, pylib.android_commands.AndroidCommands):
- device = pylib.device.device_utils.DeviceUtils(device)
- self._device = device
- self._device_file = (
- '%s/screen-recording.mp4' % device.GetExternalStoragePath())
- self._recorder = None
- self._recorder_stdout = None
- self._is_started = False
-
- self._args = ['adb']
- if str(self._device):
- self._args += ['-s', str(self._device)]
- self._args += ['shell', 'screenrecord', '--verbose']
- self._args += ['--bit-rate', str(megabits_per_second * 1000 * 1000)]
- if size:
- self._args += ['--size', '%dx%d' % size]
- if rotate:
- self._args += ['--rotate']
- self._args += [self._device_file]
-
- def Start(self):
- """Start recording video."""
- self._recorder_stdout = tempfile.mkstemp()[1]
- self._recorder = cmd_helper.Popen(
- self._args, stdout=open(self._recorder_stdout, 'w'))
- if not self._device.GetPids('screenrecord'):
- raise RuntimeError('Recording failed. Is your device running Android '
- 'KitKat or later?')
-
- def IsStarted(self):
- if not self._is_started:
- for line in open(self._recorder_stdout):
- self._is_started = line.startswith('Content area is ')
- if self._is_started:
- break
- return self._is_started
-
- def Stop(self):
- """Stop recording video."""
- os.remove(self._recorder_stdout)
- self._is_started = False
- if not self._recorder:
- return
- if not self._device.KillAll('screenrecord', signum=device_signal.SIGINT,
- quiet=True):
- logging.warning('Nothing to kill: screenrecord was not running')
- self._recorder.wait()
-
- def Pull(self, host_file=None):
- """Pull resulting video file from the device.
-
- Args:
- host_file: Path to the video file to store on the host.
- Returns:
- Output video file name on the host.
- """
- # TODO(jbudorick): Merge filename generation with the logic for doing so in
- # DeviceUtils.
- host_file_name = (
- host_file
- or 'screen-recording-%s.mp4' % time.strftime('%Y%m%dT%H%M%S',
- time.localtime()))
- host_file_name = os.path.abspath(host_file_name)
- self._device.PullFile(self._device_file, host_file_name)
- self._device.RunShellCommand('rm -f "%s"' % self._device_file)
- return host_file_name
diff --git a/build/android/pylib/sdk/__init__.py b/build/android/pylib/sdk/__init__.py
deleted file mode 100644
index 50b23df..0000000
--- a/build/android/pylib/sdk/__init__.py
+++ /dev/null
@@ -1,3 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
diff --git a/build/android/pylib/sdk/aapt.py b/build/android/pylib/sdk/aapt.py
deleted file mode 100644
index 3d317ff..0000000
--- a/build/android/pylib/sdk/aapt.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""This module wraps the Android Asset Packaging Tool."""
-
-import os
-
-from pylib import cmd_helper
-from pylib import constants
-from pylib.utils import timeout_retry
-
-_AAPT_PATH = os.path.join(constants.ANDROID_SDK_TOOLS, 'aapt')
-
-def _RunAaptCmd(args):
- """Runs an aapt command.
-
- Args:
- args: A list of arguments for aapt.
-
- Returns:
- The output of the command.
- """
- cmd = [_AAPT_PATH] + args
- status, output = cmd_helper.GetCmdStatusAndOutput(cmd)
- if status != 0:
- raise Exception('Failed running aapt command: "%s" with output "%s".' %
- (' '.join(cmd), output))
- return output
-
-def Dump(what, apk, assets=None):
- """Returns the output of the aapt dump command.
-
- Args:
- what: What you want to dump.
- apk: Path to apk you want to dump information for.
- assets: List of assets in apk you want to dump information for.
- """
- assets = assets or []
- if isinstance(assets, basestring):
- assets = [assets]
- return _RunAaptCmd(['dump', what, apk] + assets).splitlines()
\ No newline at end of file
diff --git a/build/android/pylib/sdk/dexdump.py b/build/android/pylib/sdk/dexdump.py
deleted file mode 100644
index ec10aba..0000000
--- a/build/android/pylib/sdk/dexdump.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-
-from pylib import cmd_helper
-from pylib import constants
-
-_DEXDUMP_PATH = os.path.join(constants.ANDROID_SDK_TOOLS, 'dexdump')
-
-def DexDump(dexfiles, file_summary=False):
- """A wrapper around the Android SDK's dexdump tool.
-
- Args:
- dexfiles: The dexfile or list of dex files to dump.
- file_summary: Display summary information from the file header. (-f)
-
- Returns:
- An iterable over the output lines.
- """
- # TODO(jbudorick): Add support for more options as necessary.
- if isinstance(dexfiles, basestring):
- dexfiles = [dexfiles]
- args = [_DEXDUMP_PATH] + dexfiles
- if file_summary:
- args.append('-f')
-
- return cmd_helper.IterCmdOutputLines(args)
-
diff --git a/build/android/pylib/sdk/split_select.py b/build/android/pylib/sdk/split_select.py
deleted file mode 100644
index e204662..0000000
--- a/build/android/pylib/sdk/split_select.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""This module wraps Android's split-select tool."""
-
-import os
-
-from pylib import cmd_helper
-from pylib import constants
-from pylib.utils import timeout_retry
-
-_SPLIT_SELECT_PATH = os.path.join(constants.ANDROID_SDK_TOOLS, 'split-select')
-
-def _RunSplitSelectCmd(args):
- """Runs a split-select command.
-
- Args:
- args: A list of arguments for split-select.
-
- Returns:
- The output of the command.
- """
- cmd = [_SPLIT_SELECT_PATH] + args
- status, output = cmd_helper.GetCmdStatusAndOutput(cmd)
- if status != 0:
- raise Exception('Failed running command "%s" with output "%s".' %
- (' '.join(cmd), output))
- return output
-
-def _SplitConfig(device):
- """Returns a config specifying which APK splits are required by the device.
-
- Args:
- device: A DeviceUtils object.
- """
- return ('%s-r%s-%s:%s' %
- (device.language,
- device.country,
- device.screen_density,
- device.product_cpu_abi))
-
-def SelectSplits(device, base_apk, split_apks):
- """Determines which APK splits the device requires.
-
- Args:
- device: A DeviceUtils object.
- base_apk: The path of the base APK.
- split_apks: A list of paths of APK splits.
-
- Returns:
- The list of APK splits that the device requires.
- """
- config = _SplitConfig(device)
- args = ['--target', config, '--base', base_apk]
- for split in split_apks:
- args.extend(['--split', split])
- return _RunSplitSelectCmd(args).splitlines()
\ No newline at end of file
diff --git a/build/android/pylib/symbols/PRESUBMIT.py b/build/android/pylib/symbols/PRESUBMIT.py
deleted file mode 100644
index b4d94ae..0000000
--- a/build/android/pylib/symbols/PRESUBMIT.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-def CommonChecks(input_api, output_api):
- output = []
- output.extend(input_api.canned_checks.RunPylint(input_api, output_api))
- output.extend(input_api.canned_checks.RunUnitTestsInDirectory(
- input_api,
- output_api,
- input_api.PresubmitLocalPath(),
- whitelist=[r'^.+_unittest\.py$']))
- return output
-
-
-def CheckChangeOnUpload(input_api, output_api):
- return CommonChecks(input_api, output_api)
-
-
-def CheckChangeOnCommit(input_api, output_api):
- return CommonChecks(input_api, output_api)
\ No newline at end of file
diff --git a/build/android/pylib/symbols/__init__.py b/build/android/pylib/symbols/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/build/android/pylib/symbols/__init__.py
+++ /dev/null
diff --git a/build/android/pylib/symbols/elf_symbolizer.py b/build/android/pylib/symbols/elf_symbolizer.py
deleted file mode 100644
index 374063a..0000000
--- a/build/android/pylib/symbols/elf_symbolizer.py
+++ /dev/null
@@ -1,467 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import collections
-import datetime
-import logging
-import multiprocessing
-import os
-import posixpath
-import Queue
-import re
-import subprocess
-import sys
-import threading
-import time
-
-
-# addr2line builds a possibly infinite memory cache that can exhaust
-# the computer's memory if allowed to grow for too long. This constant
-# controls how many lookups we do before restarting the process. 4000
-# gives near peak performance without extreme memory usage.
-ADDR2LINE_RECYCLE_LIMIT = 4000
-
-
-class ELFSymbolizer(object):
- """An uber-fast (multiprocessing, pipelined and asynchronous) ELF symbolizer.
-
- This class is a frontend for addr2line (part of GNU binutils), designed to
- symbolize batches of large numbers of symbols for a given ELF file. It
- supports sharding symbolization against many addr2line instances and
- pipelining of multiple requests per each instance (in order to hide addr2line
- internals and OS pipe latencies).
-
- The interface exhibited by this class is a very simple asynchronous interface,
- which is based on the following three methods:
- - SymbolizeAsync(): used to request (enqueue) resolution of a given address.
- - The |callback| method: used to communicated back the symbol information.
- - Join(): called to conclude the batch to gather the last outstanding results.
- In essence, before the Join method returns, this class will have issued as
- many callbacks as the number of SymbolizeAsync() calls. In this regard, note
- that due to multiprocess sharding, callbacks can be delivered out of order.
-
- Some background about addr2line:
- - it is invoked passing the elf path in the cmdline, piping the addresses in
- its stdin and getting results on its stdout.
- - it has pretty large response times for the first requests, but it
- works very well in streaming mode once it has been warmed up.
- - it doesn't scale by itself (on more cores). However, spawning multiple
- instances at the same time on the same file is pretty efficient as they
- keep hitting the pagecache and become mostly CPU bound.
- - it might hang or crash, mostly for OOM. This class deals with both of these
- problems.
-
- Despite the "scary" imports and the multi* words above, (almost) no multi-
- threading/processing is involved from the python viewpoint. Concurrency
- here is achieved by spawning several addr2line subprocesses and handling their
- output pipes asynchronously. Therefore, all the code here (with the exception
- of the Queue instance in Addr2Line) should be free from mind-blowing
- thread-safety concerns.
-
- The multiprocess sharding works as follows:
- The symbolizer tries to use the lowest number of addr2line instances as
- possible (with respect of |max_concurrent_jobs|) and enqueue all the requests
- in a single addr2line instance. For few symbols (i.e. dozens) sharding isn't
- worth the startup cost.
- The multiprocess logic kicks in as soon as the queues for the existing
- instances grow. Specifically, once all the existing instances reach the
- |max_queue_size| bound, a new addr2line instance is kicked in.
- In the case of a very eager producer (i.e. all |max_concurrent_jobs| instances
- have a backlog of |max_queue_size|), back-pressure is applied on the caller by
- blocking the SymbolizeAsync method.
-
- This module has been deliberately designed to be dependency free (w.r.t. of
- other modules in this project), to allow easy reuse in external projects.
- """
-
- def __init__(self, elf_file_path, addr2line_path, callback, inlines=False,
- max_concurrent_jobs=None, addr2line_timeout=30, max_queue_size=50,
- source_root_path=None, strip_base_path=None):
- """Args:
- elf_file_path: path of the elf file to be symbolized.
- addr2line_path: path of the toolchain's addr2line binary.
- callback: a callback which will be invoked for each resolved symbol with
- the two args (sym_info, callback_arg). The former is an instance of
- |ELFSymbolInfo| and contains the symbol information. The latter is an
- embedder-provided argument which is passed to SymbolizeAsync().
- inlines: when True, the ELFSymbolInfo will contain also the details about
- the outer inlining functions. When False, only the innermost function
- will be provided.
- max_concurrent_jobs: Max number of addr2line instances spawned.
- Parallelize responsibly, addr2line is a memory and I/O monster.
- max_queue_size: Max number of outstanding requests per addr2line instance.
- addr2line_timeout: Max time (in seconds) to wait for a addr2line response.
- After the timeout, the instance will be considered hung and respawned.
- source_root_path: In some toolchains only the name of the source file is
- is output, without any path information; disambiguation searches
- through the source directory specified by |source_root_path| argument
- for files whose name matches, adding the full path information to the
- output. For example, if the toolchain outputs "unicode.cc" and there
- is a file called "unicode.cc" located under |source_root_path|/foo,
- the tool will replace "unicode.cc" with
- "|source_root_path|/foo/unicode.cc". If there are multiple files with
- the same name, disambiguation will fail because the tool cannot
- determine which of the files was the source of the symbol.
- strip_base_path: Rebases the symbols source paths onto |source_root_path|
- (i.e replace |strip_base_path| with |source_root_path).
- """
- assert(os.path.isfile(addr2line_path)), 'Cannot find ' + addr2line_path
- self.elf_file_path = elf_file_path
- self.addr2line_path = addr2line_path
- self.callback = callback
- self.inlines = inlines
- self.max_concurrent_jobs = (max_concurrent_jobs or
- min(multiprocessing.cpu_count(), 4))
- self.max_queue_size = max_queue_size
- self.addr2line_timeout = addr2line_timeout
- self.requests_counter = 0 # For generating monotonic request IDs.
- self._a2l_instances = [] # Up to |max_concurrent_jobs| _Addr2Line inst.
-
- # If necessary, create disambiguation lookup table
- self.disambiguate = source_root_path is not None
- self.disambiguation_table = {}
- self.strip_base_path = strip_base_path
- if(self.disambiguate):
- self.source_root_path = os.path.abspath(source_root_path)
- self._CreateDisambiguationTable()
-
- # Create one addr2line instance. More instances will be created on demand
- # (up to |max_concurrent_jobs|) depending on the rate of the requests.
- self._CreateNewA2LInstance()
-
- def SymbolizeAsync(self, addr, callback_arg=None):
- """Requests symbolization of a given address.
-
- This method is not guaranteed to return immediately. It generally does, but
- in some scenarios (e.g. all addr2line instances have full queues) it can
- block to create back-pressure.
-
- Args:
- addr: address to symbolize.
- callback_arg: optional argument which will be passed to the |callback|."""
- assert(isinstance(addr, int))
-
- # Process all the symbols that have been resolved in the meanwhile.
- # Essentially, this drains all the addr2line(s) out queues.
- for a2l_to_purge in self._a2l_instances:
- a2l_to_purge.ProcessAllResolvedSymbolsInQueue()
- a2l_to_purge.RecycleIfNecessary()
-
- # Find the best instance according to this logic:
- # 1. Find an existing instance with the shortest queue.
- # 2. If all of instances' queues are full, but there is room in the pool,
- # (i.e. < |max_concurrent_jobs|) create a new instance.
- # 3. If there were already |max_concurrent_jobs| instances and all of them
- # had full queues, make back-pressure.
-
- # 1.
- def _SortByQueueSizeAndReqID(a2l):
- return (a2l.queue_size, a2l.first_request_id)
- a2l = min(self._a2l_instances, key=_SortByQueueSizeAndReqID)
-
- # 2.
- if (a2l.queue_size >= self.max_queue_size and
- len(self._a2l_instances) < self.max_concurrent_jobs):
- a2l = self._CreateNewA2LInstance()
-
- # 3.
- if a2l.queue_size >= self.max_queue_size:
- a2l.WaitForNextSymbolInQueue()
-
- a2l.EnqueueRequest(addr, callback_arg)
-
- def Join(self):
- """Waits for all the outstanding requests to complete and terminates."""
- for a2l in self._a2l_instances:
- a2l.WaitForIdle()
- a2l.Terminate()
-
- def _CreateNewA2LInstance(self):
- assert(len(self._a2l_instances) < self.max_concurrent_jobs)
- a2l = ELFSymbolizer.Addr2Line(self)
- self._a2l_instances.append(a2l)
- return a2l
-
- def _CreateDisambiguationTable(self):
- """ Non-unique file names will result in None entries"""
- start_time = time.time()
- logging.info('Collecting information about available source files...')
- self.disambiguation_table = {}
-
- for root, _, filenames in os.walk(self.source_root_path):
- for f in filenames:
- self.disambiguation_table[f] = os.path.join(root, f) if (f not in
- self.disambiguation_table) else None
- logging.info('Finished collecting information about '
- 'possible files (took %.1f s).',
- (time.time() - start_time))
-
-
- class Addr2Line(object):
- """A python wrapper around an addr2line instance.
-
- The communication with the addr2line process looks as follows:
- [STDIN] [STDOUT] (from addr2line's viewpoint)
- > f001111
- > f002222
- < Symbol::Name(foo, bar) for f001111
- < /path/to/source/file.c:line_number
- > f003333
- < Symbol::Name2() for f002222
- < /path/to/source/file.c:line_number
- < Symbol::Name3() for f003333
- < /path/to/source/file.c:line_number
- """
-
- SYM_ADDR_RE = re.compile(r'([^:]+):(\?|\d+).*')
-
- def __init__(self, symbolizer):
- self._symbolizer = symbolizer
- self._lib_file_name = posixpath.basename(symbolizer.elf_file_path)
-
- # The request queue (i.e. addresses pushed to addr2line's stdin and not
- # yet retrieved on stdout)
- self._request_queue = collections.deque()
-
- # This is essentially len(self._request_queue). It has been optimized to a
- # separate field because turned out to be a perf hot-spot.
- self.queue_size = 0
-
- # Keep track of the number of symbols a process has processed to
- # avoid a single process growing too big and using all the memory.
- self._processed_symbols_count = 0
-
- # Objects required to handle the addr2line subprocess.
- self._proc = None # Subprocess.Popen(...) instance.
- self._thread = None # Threading.thread instance.
- self._out_queue = None # Queue.Queue instance (for buffering a2l stdout).
- self._RestartAddr2LineProcess()
-
- def EnqueueRequest(self, addr, callback_arg):
- """Pushes an address to addr2line's stdin (and keeps track of it)."""
- self._symbolizer.requests_counter += 1 # For global "age" of requests.
- req_idx = self._symbolizer.requests_counter
- self._request_queue.append((addr, callback_arg, req_idx))
- self.queue_size += 1
- self._WriteToA2lStdin(addr)
-
- def WaitForIdle(self):
- """Waits until all the pending requests have been symbolized."""
- while self.queue_size > 0:
- self.WaitForNextSymbolInQueue()
-
- def WaitForNextSymbolInQueue(self):
- """Waits for the next pending request to be symbolized."""
- if not self.queue_size:
- return
-
- # This outer loop guards against a2l hanging (detecting stdout timeout).
- while True:
- start_time = datetime.datetime.now()
- timeout = datetime.timedelta(seconds=self._symbolizer.addr2line_timeout)
-
- # The inner loop guards against a2l crashing (checking if it exited).
- while (datetime.datetime.now() - start_time < timeout):
- # poll() returns !None if the process exited. a2l should never exit.
- if self._proc.poll():
- logging.warning('addr2line crashed, respawning (lib: %s).' %
- self._lib_file_name)
- self._RestartAddr2LineProcess()
- # TODO(primiano): the best thing to do in this case would be
- # shrinking the pool size as, very likely, addr2line is crashed
- # due to low memory (and the respawned one will die again soon).
-
- try:
- lines = self._out_queue.get(block=True, timeout=0.25)
- except Queue.Empty:
- # On timeout (1/4 s.) repeat the inner loop and check if either the
- # addr2line process did crash or we waited its output for too long.
- continue
-
- # In nominal conditions, we get straight to this point.
- self._ProcessSymbolOutput(lines)
- return
-
- # If this point is reached, we waited more than |addr2line_timeout|.
- logging.warning('Hung addr2line process, respawning (lib: %s).' %
- self._lib_file_name)
- self._RestartAddr2LineProcess()
-
- def ProcessAllResolvedSymbolsInQueue(self):
- """Consumes all the addr2line output lines produced (without blocking)."""
- if not self.queue_size:
- return
- while True:
- try:
- lines = self._out_queue.get_nowait()
- except Queue.Empty:
- break
- self._ProcessSymbolOutput(lines)
-
- def RecycleIfNecessary(self):
- """Restarts the process if it has been used for too long.
-
- A long running addr2line process will consume excessive amounts
- of memory without any gain in performance."""
- if self._processed_symbols_count >= ADDR2LINE_RECYCLE_LIMIT:
- self._RestartAddr2LineProcess()
-
-
- def Terminate(self):
- """Kills the underlying addr2line process.
-
- The poller |_thread| will terminate as well due to the broken pipe."""
- try:
- self._proc.kill()
- self._proc.communicate() # Essentially wait() without risking deadlock.
- except Exception: # An exception while terminating? How interesting.
- pass
- self._proc = None
-
- def _WriteToA2lStdin(self, addr):
- self._proc.stdin.write('%s\n' % hex(addr))
- if self._symbolizer.inlines:
- # In the case of inlines we output an extra blank line, which causes
- # addr2line to emit a (??,??:0) tuple that we use as a boundary marker.
- self._proc.stdin.write('\n')
- self._proc.stdin.flush()
-
- def _ProcessSymbolOutput(self, lines):
- """Parses an addr2line symbol output and triggers the client callback."""
- (_, callback_arg, _) = self._request_queue.popleft()
- self.queue_size -= 1
-
- innermost_sym_info = None
- sym_info = None
- for (line1, line2) in lines:
- prev_sym_info = sym_info
- name = line1 if not line1.startswith('?') else None
- source_path = None
- source_line = None
- m = ELFSymbolizer.Addr2Line.SYM_ADDR_RE.match(line2)
- if m:
- if not m.group(1).startswith('?'):
- source_path = m.group(1)
- if not m.group(2).startswith('?'):
- source_line = int(m.group(2))
- else:
- logging.warning('Got invalid symbol path from addr2line: %s' % line2)
-
- # In case disambiguation is on, and needed
- was_ambiguous = False
- disambiguated = False
- if self._symbolizer.disambiguate:
- if source_path and not posixpath.isabs(source_path):
- path = self._symbolizer.disambiguation_table.get(source_path)
- was_ambiguous = True
- disambiguated = path is not None
- source_path = path if disambiguated else source_path
-
- # Use absolute paths (so that paths are consistent, as disambiguation
- # uses absolute paths)
- if source_path and not was_ambiguous:
- source_path = os.path.abspath(source_path)
-
- if source_path and self._symbolizer.strip_base_path:
- # Strip the base path
- source_path = re.sub('^' + self._symbolizer.strip_base_path,
- self._symbolizer.source_root_path or '', source_path)
-
- sym_info = ELFSymbolInfo(name, source_path, source_line, was_ambiguous,
- disambiguated)
- if prev_sym_info:
- prev_sym_info.inlined_by = sym_info
- if not innermost_sym_info:
- innermost_sym_info = sym_info
-
- self._processed_symbols_count += 1
- self._symbolizer.callback(innermost_sym_info, callback_arg)
-
- def _RestartAddr2LineProcess(self):
- if self._proc:
- self.Terminate()
-
- # The only reason of existence of this Queue (and the corresponding
- # Thread below) is the lack of a subprocess.stdout.poll_avail_lines().
- # Essentially this is a pipe able to extract a couple of lines atomically.
- self._out_queue = Queue.Queue()
-
- # Start the underlying addr2line process in line buffered mode.
-
- cmd = [self._symbolizer.addr2line_path, '--functions', '--demangle',
- '--exe=' + self._symbolizer.elf_file_path]
- if self._symbolizer.inlines:
- cmd += ['--inlines']
- self._proc = subprocess.Popen(cmd, bufsize=1, stdout=subprocess.PIPE,
- stdin=subprocess.PIPE, stderr=sys.stderr, close_fds=True)
-
- # Start the poller thread, which simply moves atomically the lines read
- # from the addr2line's stdout to the |_out_queue|.
- self._thread = threading.Thread(
- target=ELFSymbolizer.Addr2Line.StdoutReaderThread,
- args=(self._proc.stdout, self._out_queue, self._symbolizer.inlines))
- self._thread.daemon = True # Don't prevent early process exit.
- self._thread.start()
-
- self._processed_symbols_count = 0
-
- # Replay the pending requests on the new process (only for the case
- # of a hung addr2line timing out during the game).
- for (addr, _, _) in self._request_queue:
- self._WriteToA2lStdin(addr)
-
- @staticmethod
- def StdoutReaderThread(process_pipe, queue, inlines):
- """The poller thread fn, which moves the addr2line stdout to the |queue|.
-
- This is the only piece of code not running on the main thread. It merely
- writes to a Queue, which is thread-safe. In the case of inlines, it
- detects the ??,??:0 marker and sends the lines atomically, such that the
- main thread always receives all the lines corresponding to one symbol in
- one shot."""
- try:
- lines_for_one_symbol = []
- while True:
- line1 = process_pipe.readline().rstrip('\r\n')
- line2 = process_pipe.readline().rstrip('\r\n')
- if not line1 or not line2:
- break
- inline_has_more_lines = inlines and (len(lines_for_one_symbol) == 0 or
- (line1 != '??' and line2 != '??:0'))
- if not inlines or inline_has_more_lines:
- lines_for_one_symbol += [(line1, line2)]
- if inline_has_more_lines:
- continue
- queue.put(lines_for_one_symbol)
- lines_for_one_symbol = []
- process_pipe.close()
-
- # Every addr2line processes will die at some point, please die silently.
- except (IOError, OSError):
- pass
-
- @property
- def first_request_id(self):
- """Returns the request_id of the oldest pending request in the queue."""
- return self._request_queue[0][2] if self._request_queue else 0
-
-
-class ELFSymbolInfo(object):
- """The result of the symbolization passed as first arg. of each callback."""
-
- def __init__(self, name, source_path, source_line, was_ambiguous=False,
- disambiguated=False):
- """All the fields here can be None (if addr2line replies with '??')."""
- self.name = name
- self.source_path = source_path
- self.source_line = source_line
- # In the case of |inlines|=True, the |inlined_by| points to the outer
- # function inlining the current one (and so on, to form a chain).
- self.inlined_by = None
- self.disambiguated = disambiguated
- self.was_ambiguous = was_ambiguous
-
- def __str__(self):
- return '%s [%s:%d]' % (
- self.name or '??', self.source_path or '??', self.source_line or 0)
diff --git a/build/android/pylib/symbols/elf_symbolizer_unittest.py b/build/android/pylib/symbols/elf_symbolizer_unittest.py
deleted file mode 100755
index e963a34..0000000
--- a/build/android/pylib/symbols/elf_symbolizer_unittest.py
+++ /dev/null
@@ -1,173 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import functools
-import logging
-import os
-import sys
-import unittest
-
-sys.path.insert(0, os.path.dirname(__file__))
-import elf_symbolizer
-import mock_addr2line
-
-
-_MOCK_A2L_PATH = os.path.join(os.path.dirname(mock_addr2line.__file__),
- 'mock_addr2line')
-_INCOMPLETE_MOCK_ADDR = 1024 * 1024
-_UNKNOWN_MOCK_ADDR = 2 * 1024 * 1024
-_INLINE_MOCK_ADDR = 3 * 1024 * 1024
-
-
-class ELFSymbolizerTest(unittest.TestCase):
- def setUp(self):
- self._callback = functools.partial(
- ELFSymbolizerTest._SymbolizeCallback, self)
- self._resolved_addresses = set()
- # Mute warnings, we expect them due to the crash/hang tests.
- logging.getLogger().setLevel(logging.ERROR)
-
- def testParallelism1(self):
- self._RunTest(max_concurrent_jobs=1, num_symbols=100)
-
- def testParallelism4(self):
- self._RunTest(max_concurrent_jobs=4, num_symbols=100)
-
- def testParallelism8(self):
- self._RunTest(max_concurrent_jobs=8, num_symbols=100)
-
- def testCrash(self):
- os.environ['MOCK_A2L_CRASH_EVERY'] = '99'
- self._RunTest(max_concurrent_jobs=1, num_symbols=100)
- os.environ['MOCK_A2L_CRASH_EVERY'] = '0'
-
- def testHang(self):
- os.environ['MOCK_A2L_HANG_EVERY'] = '99'
- self._RunTest(max_concurrent_jobs=1, num_symbols=100)
- os.environ['MOCK_A2L_HANG_EVERY'] = '0'
-
- def testInlines(self):
- """Stimulate the inline processing logic."""
- symbolizer = elf_symbolizer.ELFSymbolizer(
- elf_file_path='/path/doesnt/matter/mock_lib1.so',
- addr2line_path=_MOCK_A2L_PATH,
- callback=self._callback,
- inlines=True,
- max_concurrent_jobs=4)
-
- for addr in xrange(1000):
- exp_inline = False
- exp_unknown = False
-
- # First 100 addresses with inlines.
- if addr < 100:
- addr += _INLINE_MOCK_ADDR
- exp_inline = True
-
- # Followed by 100 without inlines.
- elif addr < 200:
- pass
-
- # Followed by 100 interleaved inlines and not inlines.
- elif addr < 300:
- if addr & 1:
- addr += _INLINE_MOCK_ADDR
- exp_inline = True
-
- # Followed by 100 interleaved inlines and unknonwn.
- elif addr < 400:
- if addr & 1:
- addr += _INLINE_MOCK_ADDR
- exp_inline = True
- else:
- addr += _UNKNOWN_MOCK_ADDR
- exp_unknown = True
-
- exp_name = 'mock_sym_for_addr_%d' % addr if not exp_unknown else None
- exp_source_path = 'mock_src/mock_lib1.so.c' if not exp_unknown else None
- exp_source_line = addr if not exp_unknown else None
- cb_arg = (addr, exp_name, exp_source_path, exp_source_line, exp_inline)
- symbolizer.SymbolizeAsync(addr, cb_arg)
-
- symbolizer.Join()
-
- def testIncompleteSyminfo(self):
- """Stimulate the symbol-not-resolved logic."""
- symbolizer = elf_symbolizer.ELFSymbolizer(
- elf_file_path='/path/doesnt/matter/mock_lib1.so',
- addr2line_path=_MOCK_A2L_PATH,
- callback=self._callback,
- max_concurrent_jobs=1)
-
- # Test symbols with valid name but incomplete path.
- addr = _INCOMPLETE_MOCK_ADDR
- exp_name = 'mock_sym_for_addr_%d' % addr
- exp_source_path = None
- exp_source_line = None
- cb_arg = (addr, exp_name, exp_source_path, exp_source_line, False)
- symbolizer.SymbolizeAsync(addr, cb_arg)
-
- # Test symbols with no name or sym info.
- addr = _UNKNOWN_MOCK_ADDR
- exp_name = None
- exp_source_path = None
- exp_source_line = None
- cb_arg = (addr, exp_name, exp_source_path, exp_source_line, False)
- symbolizer.SymbolizeAsync(addr, cb_arg)
-
- symbolizer.Join()
-
- def _RunTest(self, max_concurrent_jobs, num_symbols):
- symbolizer = elf_symbolizer.ELFSymbolizer(
- elf_file_path='/path/doesnt/matter/mock_lib1.so',
- addr2line_path=_MOCK_A2L_PATH,
- callback=self._callback,
- max_concurrent_jobs=max_concurrent_jobs,
- addr2line_timeout=0.5)
-
- for addr in xrange(num_symbols):
- exp_name = 'mock_sym_for_addr_%d' % addr
- exp_source_path = 'mock_src/mock_lib1.so.c'
- exp_source_line = addr
- cb_arg = (addr, exp_name, exp_source_path, exp_source_line, False)
- symbolizer.SymbolizeAsync(addr, cb_arg)
-
- symbolizer.Join()
-
- # Check that all the expected callbacks have been received.
- for addr in xrange(num_symbols):
- self.assertIn(addr, self._resolved_addresses)
- self._resolved_addresses.remove(addr)
-
- # Check for unexpected callbacks.
- self.assertEqual(len(self._resolved_addresses), 0)
-
- def _SymbolizeCallback(self, sym_info, cb_arg):
- self.assertTrue(isinstance(sym_info, elf_symbolizer.ELFSymbolInfo))
- self.assertTrue(isinstance(cb_arg, tuple))
- self.assertEqual(len(cb_arg), 5)
-
- # Unpack expectations from the callback extra argument.
- (addr, exp_name, exp_source_path, exp_source_line, exp_inlines) = cb_arg
- if exp_name is None:
- self.assertIsNone(sym_info.name)
- else:
- self.assertTrue(sym_info.name.startswith(exp_name))
- self.assertEqual(sym_info.source_path, exp_source_path)
- self.assertEqual(sym_info.source_line, exp_source_line)
-
- if exp_inlines:
- self.assertEqual(sym_info.name, exp_name + '_inner')
- self.assertEqual(sym_info.inlined_by.name, exp_name + '_middle')
- self.assertEqual(sym_info.inlined_by.inlined_by.name,
- exp_name + '_outer')
-
- # Check against duplicate callbacks.
- self.assertNotIn(addr, self._resolved_addresses)
- self._resolved_addresses.add(addr)
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/build/android/pylib/symbols/mock_addr2line/__init__.py b/build/android/pylib/symbols/mock_addr2line/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/build/android/pylib/symbols/mock_addr2line/__init__.py
+++ /dev/null
diff --git a/build/android/pylib/symbols/mock_addr2line/mock_addr2line b/build/android/pylib/symbols/mock_addr2line/mock_addr2line
deleted file mode 100755
index cd58f56..0000000
--- a/build/android/pylib/symbols/mock_addr2line/mock_addr2line
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Simple mock for addr2line.
-
-Outputs mock symbol information, with each symbol being a function of the
-original address (so it is easy to double-check consistency in unittests).
-"""
-
-import optparse
-import os
-import posixpath
-import sys
-import time
-
-
-def main(argv):
- parser = optparse.OptionParser()
- parser.add_option('-e', '--exe', dest='exe') # Path of the debug-library.so.
- # Silently swallow the other unnecessary arguments.
- parser.add_option('-C', '--demangle', action='store_true')
- parser.add_option('-f', '--functions', action='store_true')
- parser.add_option('-i', '--inlines', action='store_true')
- options, _ = parser.parse_args(argv[1:])
- lib_file_name = posixpath.basename(options.exe)
- processed_sym_count = 0
- crash_every = int(os.environ.get('MOCK_A2L_CRASH_EVERY', 0))
- hang_every = int(os.environ.get('MOCK_A2L_HANG_EVERY', 0))
-
- while(True):
- line = sys.stdin.readline().rstrip('\r')
- if not line:
- break
-
- # An empty line should generate '??,??:0' (is used as marker for inlines).
- if line == '\n':
- print '??'
- print '??:0'
- sys.stdout.flush()
- continue
-
- addr = int(line, 16)
- processed_sym_count += 1
- if crash_every and processed_sym_count % crash_every == 0:
- sys.exit(1)
- if hang_every and processed_sym_count % hang_every == 0:
- time.sleep(1)
-
- # Addresses < 1M will return good mock symbol information.
- if addr < 1024 * 1024:
- print 'mock_sym_for_addr_%d' % addr
- print 'mock_src/%s.c:%d' % (lib_file_name, addr)
-
- # Addresses 1M <= x < 2M will return symbols with a name but a missing path.
- elif addr < 2 * 1024 * 1024:
- print 'mock_sym_for_addr_%d' % addr
- print '??:0'
-
- # Addresses 2M <= x < 3M will return unknown symbol information.
- elif addr < 3 * 1024 * 1024:
- print '??'
- print '??'
-
- # Addresses 3M <= x < 4M will return inlines.
- elif addr < 4 * 1024 * 1024:
- print 'mock_sym_for_addr_%d_inner' % addr
- print 'mock_src/%s.c:%d' % (lib_file_name, addr)
- print 'mock_sym_for_addr_%d_middle' % addr
- print 'mock_src/%s.c:%d' % (lib_file_name, addr)
- print 'mock_sym_for_addr_%d_outer' % addr
- print 'mock_src/%s.c:%d' % (lib_file_name, addr)
-
- sys.stdout.flush()
-
-
-if __name__ == '__main__':
- main(sys.argv)
\ No newline at end of file
diff --git a/build/android/pylib/system_properties.py b/build/android/pylib/system_properties.py
deleted file mode 100644
index 3f16f86..0000000
--- a/build/android/pylib/system_properties.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-
-class SystemProperties(dict):
-
- """A dict interface to interact with device system properties.
-
- System properties are key/value pairs as exposed by adb shell getprop/setprop.
-
- This implementation minimizes interaction with the physical device. It is
- valid for the lifetime of a boot.
- """
-
- def __init__(self, android_commands):
- super(SystemProperties, self).__init__()
- self._adb = android_commands
- self._cached_static_properties = {}
-
- def __getitem__(self, key):
- if self._IsStatic(key):
- if key not in self._cached_static_properties:
- self._cached_static_properties[key] = self._GetProperty(key)
- return self._cached_static_properties[key]
- return self._GetProperty(key)
-
- def __setitem__(self, key, value):
- # TODO(tonyg): This can fail with no root. Verify that it succeeds.
- self._adb.SendShellCommand('setprop %s "%s"' % (key, value), retry_count=3)
-
- @staticmethod
- def _IsStatic(key):
- # TODO(tonyg): This list is conservative and could be expanded as needed.
- return (key.startswith('ro.boot.') or
- key.startswith('ro.build.') or
- key.startswith('ro.product.'))
-
- def _GetProperty(self, key):
- return self._adb.SendShellCommand('getprop %s' % key, retry_count=3).strip()
diff --git a/build/android/pylib/uiautomator/__init__.py b/build/android/pylib/uiautomator/__init__.py
deleted file mode 100644
index cda7672..0000000
--- a/build/android/pylib/uiautomator/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-# Copyright (c) 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
diff --git a/build/android/pylib/uiautomator/setup.py b/build/android/pylib/uiautomator/setup.py
deleted file mode 100644
index bd8ffc7..0000000
--- a/build/android/pylib/uiautomator/setup.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Generates test runner factory and tests for uiautomator tests."""
-
-import logging
-
-from pylib.uiautomator import test_package
-from pylib.uiautomator import test_runner
-
-
-def Setup(test_options):
- """Runs uiautomator tests on connected device(s).
-
- Args:
- test_options: A UIAutomatorOptions object.
-
- Returns:
- A tuple of (TestRunnerFactory, tests).
- """
- test_pkg = test_package.TestPackage(test_options.uiautomator_jar,
- test_options.uiautomator_info_jar)
- tests = test_pkg.GetAllMatchingTests(test_options.annotations,
- test_options.exclude_annotations,
- test_options.test_filter)
-
- if not tests:
- logging.error('No uiautomator tests to run with current args.')
-
- def TestRunnerFactory(device, shard_index):
- return test_runner.TestRunner(
- test_options, device, shard_index, test_pkg)
-
- return (TestRunnerFactory, tests)
diff --git a/build/android/pylib/uiautomator/test_options.py b/build/android/pylib/uiautomator/test_options.py
deleted file mode 100644
index 3f5f950..0000000
--- a/build/android/pylib/uiautomator/test_options.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Defines the UIAutomatorOptions named tuple."""
-
-import collections
-
-UIAutomatorOptions = collections.namedtuple('UIAutomatorOptions', [
- 'tool',
- 'annotations',
- 'exclude_annotations',
- 'test_filter',
- 'test_data',
- 'save_perf_json',
- 'screenshot_failures',
- 'uiautomator_jar',
- 'uiautomator_info_jar',
- 'package',
- 'set_asserts'])
diff --git a/build/android/pylib/uiautomator/test_package.py b/build/android/pylib/uiautomator/test_package.py
deleted file mode 100644
index cb51fdf..0000000
--- a/build/android/pylib/uiautomator/test_package.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright (c) 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Class representing uiautomator test package."""
-
-import os
-
-from pylib import constants
-from pylib.instrumentation import test_jar
-
-
-class TestPackage(test_jar.TestJar):
-
- UIAUTOMATOR_PATH = 'uiautomator/'
- UIAUTOMATOR_DEVICE_DIR = os.path.join(constants.TEST_EXECUTABLE_DIR,
- UIAUTOMATOR_PATH)
-
- def __init__(self, jar_path, jar_info_path):
- test_jar.TestJar.__init__(self, jar_info_path)
-
- if not os.path.exists(jar_path):
- raise Exception('%s not found, please build it' % jar_path)
- self._jar_path = jar_path
-
- def GetPackageName(self):
- """Returns the JAR named that is installed on the device."""
- return os.path.basename(self._jar_path)
-
- # Override.
- def Install(self, device):
- device.PushChangedFiles([(self._jar_path, self.UIAUTOMATOR_DEVICE_DIR +
- self.GetPackageName())])
diff --git a/build/android/pylib/uiautomator/test_runner.py b/build/android/pylib/uiautomator/test_runner.py
deleted file mode 100644
index bda6687..0000000
--- a/build/android/pylib/uiautomator/test_runner.py
+++ /dev/null
@@ -1,89 +0,0 @@
-# Copyright (c) 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Class for running uiautomator tests on a single device."""
-
-from pylib import constants
-from pylib import flag_changer
-from pylib.device import intent
-from pylib.instrumentation import test_options as instr_test_options
-from pylib.instrumentation import test_runner as instr_test_runner
-
-
-class TestRunner(instr_test_runner.TestRunner):
- """Responsible for running a series of tests connected to a single device."""
-
- def __init__(self, test_options, device, shard_index, test_pkg):
- """Create a new TestRunner.
-
- Args:
- test_options: A UIAutomatorOptions object.
- device: Attached android device.
- shard_index: Shard index.
- test_pkg: A TestPackage object.
- """
- # Create an InstrumentationOptions object to pass to the super class
- instrumentation_options = instr_test_options.InstrumentationOptions(
- test_options.tool,
- test_options.annotations,
- test_options.exclude_annotations,
- test_options.test_filter,
- test_options.test_data,
- test_options.save_perf_json,
- test_options.screenshot_failures,
- wait_for_debugger=False,
- coverage_dir=None,
- test_apk=None,
- test_apk_path=None,
- test_apk_jar_path=None,
- test_runner=None,
- test_support_apk_path=None,
- device_flags=None,
- isolate_file_path=None,
- set_asserts=test_options.set_asserts,
- delete_stale_data=False)
- super(TestRunner, self).__init__(instrumentation_options, device,
- shard_index, test_pkg)
-
- cmdline_file = constants.PACKAGE_INFO[test_options.package].cmdline_file
- self.flags = None
- if cmdline_file:
- self.flags = flag_changer.FlagChanger(self.device, cmdline_file)
- self._package = constants.PACKAGE_INFO[test_options.package].package
- self._activity = constants.PACKAGE_INFO[test_options.package].activity
-
- #override
- def InstallTestPackage(self):
- self.test_pkg.Install(self.device)
-
- #override
- def _RunTest(self, test, timeout):
- self.device.ClearApplicationState(self._package)
- if self.flags:
- annotations = self.test_pkg.GetTestAnnotations(test)
- if 'FirstRunExperience' == annotations.get('Feature', None):
- self.flags.RemoveFlags(['--disable-fre'])
- else:
- self.flags.AddFlags(['--disable-fre'])
- self.device.StartActivity(
- intent.Intent(action='android.intent.action.MAIN',
- activity=self._activity,
- package=self._package),
- blocking=True,
- force_stop=True)
- cmd = ['uiautomator', 'runtest',
- self.test_pkg.UIAUTOMATOR_PATH + self.test_pkg.GetPackageName(),
- '-e', 'class', test,
- '-e', 'test_package', self._package]
- return self.device.RunShellCommand(cmd, timeout=timeout, retries=0)
-
- #override
- def _GenerateTestResult(self, test, _result_code, _result_bundle, statuses,
- start_ms, duration_ms):
- # uiautomator emits its summary status with INSTRUMENTATION_STATUS_CODE,
- # not INSTRUMENTATION_CODE, so we have to drop if off the list of statuses.
- summary_code, summary_bundle = statuses[-1]
- return super(TestRunner, self)._GenerateTestResult(
- test, summary_code, summary_bundle, statuses[:-1], start_ms,
- duration_ms)
diff --git a/build/android/pylib/uirobot/__init__.py b/build/android/pylib/uirobot/__init__.py
deleted file mode 100644
index 5cac026..0000000
--- a/build/android/pylib/uirobot/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
diff --git a/build/android/pylib/uirobot/uirobot_test_instance.py b/build/android/pylib/uirobot/uirobot_test_instance.py
deleted file mode 100644
index e3f6eb7..0000000
--- a/build/android/pylib/uirobot/uirobot_test_instance.py
+++ /dev/null
@@ -1,79 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import json
-import logging
-
-from pylib import constants
-from pylib.base import test_instance
-from pylib.utils import apk_helper
-
-class UirobotTestInstance(test_instance.TestInstance):
-
- def __init__(self, args, error_func):
- """Constructor.
-
- Args:
- args: Command line arguments.
- """
- super(UirobotTestInstance, self).__init__()
- if not args.app_under_test:
- error_func('Must set --app-under-test.')
- self._app_under_test = args.app_under_test
- self._minutes = args.minutes
-
- if args.remote_device_file:
- with open(args.remote_device_file) as remote_device_file:
- device_json = json.load(remote_device_file)
- else:
- device_json = {}
- device_type = device_json.get('device_type', 'Android')
- if args.device_type:
- if device_type and device_type != args.device_type:
- logging.info('Overriding device_type from %s to %s',
- device_type, args.device_type)
- device_type = args.device_type
-
- if device_type == 'Android':
- self._suite = 'Android Uirobot'
- self._package_name = apk_helper.GetPackageName(self._app_under_test)
- elif device_type == 'iOS':
- self._suite = 'iOS Uirobot'
- self._package_name = self._app_under_test
-
-
- #override
- def TestType(self):
- """Returns type of test."""
- return 'uirobot'
-
- #override
- def SetUp(self):
- """Setup for test."""
- pass
-
- #override
- def TearDown(self):
- """Teardown for test."""
- pass
-
- @property
- def app_under_test(self):
- """Returns the app to run the test on."""
- return self._app_under_test
-
- @property
- def minutes(self):
- """Returns the number of minutes to run the uirobot for."""
- return self._minutes
-
- @property
- def package_name(self):
- """Returns the name of the package in the APK."""
- return self._package_name
-
- @property
- def suite(self):
- return self._suite
diff --git a/build/android/pylib/utils/__init__.py b/build/android/pylib/utils/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/build/android/pylib/utils/__init__.py
+++ /dev/null
diff --git a/build/android/pylib/utils/apk_helper.py b/build/android/pylib/utils/apk_helper.py
deleted file mode 100644
index a556e7b..0000000
--- a/build/android/pylib/utils/apk_helper.py
+++ /dev/null
@@ -1,131 +0,0 @@
-# Copyright (c) 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Module containing utilities for apk packages."""
-
-import os.path
-import re
-
-from pylib import cmd_helper
-from pylib import constants
-from pylib.sdk import aapt
-
-
-_AAPT_PATH = os.path.join(constants.ANDROID_SDK_TOOLS, 'aapt')
-_MANIFEST_ATTRIBUTE_RE = re.compile(
- r'\s*A: ([^\(\)= ]*)\([^\(\)= ]*\)="(.*)" \(Raw: .*\)$')
-_MANIFEST_ELEMENT_RE = re.compile(r'\s*(?:E|N): (\S*) .*$')
-_PACKAGE_NAME_RE = re.compile(r'package: .*name=\'(\S*)\'')
-_SPLIT_NAME_RE = re.compile(r'package: .*split=\'(\S*)\'')
-
-
-def GetPackageName(apk_path):
- """Returns the package name of the apk."""
- return ApkHelper(apk_path).GetPackageName()
-
-
-# TODO(jbudorick): Deprecate and remove this function once callers have been
-# converted to ApkHelper.GetInstrumentationName
-def GetInstrumentationName(apk_path):
- """Returns the name of the Instrumentation in the apk."""
- return ApkHelper(apk_path).GetInstrumentationName()
-
-
-def _ParseManifestFromApk(apk_path):
- aapt_output = aapt.Dump('xmltree', apk_path, 'AndroidManifest.xml')
-
- parsed_manifest = {}
- node_stack = [parsed_manifest]
- indent = ' '
-
- for line in aapt_output[1:]:
- if len(line) == 0:
- continue
-
- indent_depth = 0
- while line[(len(indent) * indent_depth):].startswith(indent):
- indent_depth += 1
-
- node_stack = node_stack[:indent_depth]
- node = node_stack[-1]
-
- m = _MANIFEST_ELEMENT_RE.match(line[len(indent) * indent_depth:])
- if m:
- if not m.group(1) in node:
- node[m.group(1)] = {}
- node_stack += [node[m.group(1)]]
- continue
-
- m = _MANIFEST_ATTRIBUTE_RE.match(line[len(indent) * indent_depth:])
- if m:
- if not m.group(1) in node:
- node[m.group(1)] = []
- node[m.group(1)].append(m.group(2))
- continue
-
- return parsed_manifest
-
-
-class ApkHelper(object):
- def __init__(self, apk_path):
- self._apk_path = apk_path
- self._manifest = None
- self._package_name = None
- self._split_name = None
-
- def GetActivityName(self):
- """Returns the name of the Activity in the apk."""
- manifest_info = self._GetManifest()
- try:
- activity = (
- manifest_info['manifest']['application']['activity']
- ['android:name'][0])
- except KeyError:
- return None
- if '.' not in activity:
- activity = '%s.%s' % (self.GetPackageName(), activity)
- elif activity.startswith('.'):
- activity = '%s%s' % (self.GetPackageName(), activity)
- return activity
-
- def GetInstrumentationName(
- self, default='android.test.InstrumentationTestRunner'):
- """Returns the name of the Instrumentation in the apk."""
- manifest_info = self._GetManifest()
- try:
- return manifest_info['manifest']['instrumentation']['android:name'][0]
- except KeyError:
- return default
-
- def GetPackageName(self):
- """Returns the package name of the apk."""
- if self._package_name:
- return self._package_name
-
- aapt_output = aapt.Dump('badging', self._apk_path)
- for line in aapt_output:
- m = _PACKAGE_NAME_RE.match(line)
- if m:
- self._package_name = m.group(1)
- return self._package_name
- raise Exception('Failed to determine package name of %s' % self._apk_path)
-
- def GetSplitName(self):
- """Returns the name of the split of the apk."""
- if self._split_name:
- return self._split_name
-
- aapt_output = aapt.Dump('badging', self._apk_path)
- for line in aapt_output:
- m = _SPLIT_NAME_RE.match(line)
- if m:
- self._split_name = m.group(1)
- return self._split_name
- return None
-
- def _GetManifest(self):
- if not self._manifest:
- self._manifest = _ParseManifestFromApk(self._apk_path)
- return self._manifest
-
diff --git a/build/android/pylib/utils/base_error.py b/build/android/pylib/utils/base_error.py
deleted file mode 100644
index 31eaa54..0000000
--- a/build/android/pylib/utils/base_error.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-
-class BaseError(Exception):
- """Base error for all test runner errors."""
-
- def __init__(self, message, is_infra_error=False):
- super(BaseError, self).__init__(message)
- self._is_infra_error = is_infra_error
-
- @property
- def is_infra_error(self):
- """Property to indicate if error was caused by an infrastructure issue."""
- return self._is_infra_error
\ No newline at end of file
diff --git a/build/android/pylib/utils/command_option_parser.py b/build/android/pylib/utils/command_option_parser.py
deleted file mode 100644
index cf501d0..0000000
--- a/build/android/pylib/utils/command_option_parser.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""An option parser which handles the first arg as a command.
-
-Add other nice functionality such as printing a list of commands
-and an example in usage.
-"""
-
-import optparse
-import sys
-
-
-class CommandOptionParser(optparse.OptionParser):
- """Wrapper class for OptionParser to help with listing commands."""
-
- def __init__(self, *args, **kwargs):
- """Creates a CommandOptionParser.
-
- Args:
- commands_dict: A dictionary mapping command strings to an object defining
- - add_options_func: Adds options to the option parser
- - run_command_func: Runs the command itself.
- example: An example command.
- everything else: Passed to optparse.OptionParser contructor.
- """
- self.commands_dict = kwargs.pop('commands_dict', {})
- self.example = kwargs.pop('example', '')
- if not 'usage' in kwargs:
- kwargs['usage'] = 'Usage: %prog <command> [options]'
- optparse.OptionParser.__init__(self, *args, **kwargs)
-
- #override
- def get_usage(self):
- normal_usage = optparse.OptionParser.get_usage(self)
- command_list = self.get_command_list()
- example = self.get_example()
- return self.expand_prog_name(normal_usage + example + command_list)
-
- #override
- def get_command_list(self):
- if self.commands_dict.keys():
- return '\nCommands:\n %s\n' % '\n '.join(
- sorted(self.commands_dict.keys()))
- return ''
-
- def get_example(self):
- if self.example:
- return '\nExample:\n %s\n' % self.example
- return ''
-
-
-def ParseAndExecute(option_parser, argv=None):
- """Parses options/args from argv and runs the specified command.
-
- Args:
- option_parser: A CommandOptionParser object.
- argv: Command line arguments. If None, automatically draw from sys.argv.
-
- Returns:
- An exit code.
- """
- if not argv:
- argv = sys.argv
-
- if len(argv) < 2 or argv[1] not in option_parser.commands_dict:
- # Parse args first, if this is '--help', optparse will print help and exit
- option_parser.parse_args(argv)
- option_parser.error('Invalid command.')
-
- cmd = option_parser.commands_dict[argv[1]]
- cmd.add_options_func(option_parser)
- options, args = option_parser.parse_args(argv)
- return cmd.run_command_func(argv[1], options, args, option_parser)
diff --git a/build/android/pylib/utils/device_temp_file.py b/build/android/pylib/utils/device_temp_file.py
deleted file mode 100644
index 7d3b95b..0000000
--- a/build/android/pylib/utils/device_temp_file.py
+++ /dev/null
@@ -1,57 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""A temp file that automatically gets pushed and deleted from a device."""
-
-# pylint: disable=W0622
-
-import random
-import time
-
-from pylib import cmd_helper
-from pylib.device import device_errors
-
-
-class DeviceTempFile(object):
- def __init__(self, adb, suffix='', prefix='temp_file', dir='/data/local/tmp'):
- """Find an unused temporary file path in the devices external directory.
-
- When this object is closed, the file will be deleted on the device.
-
- Args:
- adb: An instance of AdbWrapper
- suffix: The suffix of the name of the temp file.
- prefix: The prefix of the name of the temp file.
- dir: The directory on the device where to place the temp file.
- """
- self._adb = adb
- # make sure that the temp dir is writable
- self._adb.Shell('test -d %s' % cmd_helper.SingleQuote(dir))
- while True:
- self.name = '{dir}/{prefix}-{time:d}-{nonce:d}{suffix}'.format(
- dir=dir, prefix=prefix, time=int(time.time()),
- nonce=random.randint(0, 1000000), suffix=suffix)
- self.name_quoted = cmd_helper.SingleQuote(self.name)
- try:
- self._adb.Shell('test -e %s' % self.name_quoted)
- except device_errors.AdbCommandFailedError:
- break # file does not exist
-
- # Immediately touch the file, so other temp files can't get the same name.
- self._adb.Shell('touch %s' % self.name_quoted)
-
- def close(self):
- """Deletes the temporary file from the device."""
- # ignore exception if the file is already gone.
- try:
- self._adb.Shell('rm -f %s' % self.name_quoted)
- except device_errors.AdbCommandFailedError:
- # file does not exist on Android version without 'rm -f' support (ICS)
- pass
-
- def __enter__(self):
- return self
-
- def __exit__(self, type, value, traceback):
- self.close()
diff --git a/build/android/pylib/utils/device_temp_file_test.py b/build/android/pylib/utils/device_temp_file_test.py
deleted file mode 100755
index f839ce0..0000000
--- a/build/android/pylib/utils/device_temp_file_test.py
+++ /dev/null
@@ -1,91 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""
-Unit tests for the contents of device_temp_file.py.
-"""
-
-import logging
-import os
-import sys
-import unittest
-
-from pylib import constants
-from pylib.device import adb_wrapper
-from pylib.device import device_errors
-from pylib.utils import device_temp_file
-from pylib.utils import mock_calls
-
-sys.path.append(os.path.join(
- constants.DIR_SOURCE_ROOT, 'third_party', 'pymock'))
-import mock # pylint: disable=F0401
-
-class DeviceTempFileTest(mock_calls.TestCase):
-
- def setUp(self):
- test_serial = '0123456789abcdef'
- self.adb = mock.Mock(spec=adb_wrapper.AdbWrapper)
- self.adb.__str__ = mock.Mock(return_value=test_serial)
- self.watchMethodCalls(self.call.adb)
-
- def mockShellCall(self, cmd_prefix, action=''):
- """Expect an adb.Shell(cmd) call with cmd_prefix and do some action
-
- Args:
- cmd_prefix: A string, the cmd of the received call is expected to have
- this as a prefix.
- action: If callable, an action to perform when the expected call is
- received, otherwise a return value.
- Returns:
- An (expected_call, action) pair suitable for use in assertCalls.
- """
- def check_and_return(cmd):
- self.assertTrue(
- cmd.startswith(cmd_prefix),
- 'command %r does not start with prefix %r' % (cmd, cmd_prefix))
- if callable(action):
- return action(cmd)
- else:
- return action
- return (self.call.adb.Shell(mock.ANY), check_and_return)
-
- def mockExistsTest(self, exists_result):
- def action(cmd):
- if exists_result:
- return ''
- else:
- raise device_errors.AdbCommandFailedError(
- cmd, 'File not found', 1, str(self.adb))
- return self.mockShellCall('test -e ', action)
-
- def testTempFileNameAlreadyExists(self):
- with self.assertCalls(
- self.mockShellCall('test -d /data/local/tmp'),
- self.mockExistsTest(True),
- self.mockExistsTest(True),
- self.mockExistsTest(True),
- self.mockExistsTest(False),
- self.mockShellCall('touch '),
- self.mockShellCall('rm -f ')):
- with device_temp_file.DeviceTempFile(self.adb) as tmpfile:
- logging.debug('Temp file name: %s' % tmpfile.name)
-
- def testTempFileLifecycle(self):
- with self.assertCalls(
- self.mockShellCall('test -d /data/local/tmp'),
- self.mockExistsTest(False),
- self.mockShellCall('touch ')):
- tempFileContextManager = device_temp_file.DeviceTempFile(self.adb)
- with mock.patch.object(self.adb, 'Shell'):
- with tempFileContextManager as tmpfile:
- logging.debug('Temp file name: %s' % tmpfile.name)
- self.assertEquals(0, self.adb.Shell.call_count)
- self.assertEquals(1, self.adb.Shell.call_count)
- args, _ = self.adb.Shell.call_args
- self.assertTrue(args[0].startswith('rm -f '))
-
-if __name__ == '__main__':
- logging.getLogger().setLevel(logging.DEBUG)
- unittest.main(verbosity=2)
diff --git a/build/android/pylib/utils/emulator.py b/build/android/pylib/utils/emulator.py
deleted file mode 100644
index cc07e61..0000000
--- a/build/android/pylib/utils/emulator.py
+++ /dev/null
@@ -1,444 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Provides an interface to start and stop Android emulator.
-
- Emulator: The class provides the methods to launch/shutdown the emulator with
- the android virtual device named 'avd_armeabi' .
-"""
-
-import logging
-import os
-import signal
-import subprocess
-import time
-
-# TODO(craigdh): Move these pylib dependencies to pylib/utils/.
-from pylib import cmd_helper
-from pylib import constants
-from pylib import pexpect
-from pylib.device import device_errors
-from pylib.device import device_utils
-from pylib.utils import time_profile
-
-import errors
-import run_command
-
-# SD card size
-SDCARD_SIZE = '512M'
-
-# Template used to generate config.ini files for the emulator
-CONFIG_TEMPLATE = """avd.ini.encoding=ISO-8859-1
-hw.dPad=no
-hw.lcd.density=320
-sdcard.size=512M
-hw.cpu.arch={hw.cpu.arch}
-hw.device.hash=-708107041
-hw.camera.back=none
-disk.dataPartition.size=800M
-hw.gpu.enabled=yes
-skin.path=720x1280
-skin.dynamic=yes
-hw.keyboard=yes
-hw.ramSize=1024
-hw.device.manufacturer=Google
-hw.sdCard=yes
-hw.mainKeys=no
-hw.accelerometer=yes
-skin.name=720x1280
-abi.type={abi.type}
-hw.trackBall=no
-hw.device.name=Galaxy Nexus
-hw.battery=yes
-hw.sensors.proximity=yes
-image.sysdir.1=system-images/android-{api.level}/{abi.type}/
-hw.sensors.orientation=yes
-hw.audioInput=yes
-hw.camera.front=none
-hw.gps=yes
-vm.heapSize=128
-{extras}"""
-
-CONFIG_REPLACEMENTS = {
- 'x86': {
- '{hw.cpu.arch}': 'x86',
- '{abi.type}': 'x86',
- '{extras}': ''
- },
- 'arm': {
- '{hw.cpu.arch}': 'arm',
- '{abi.type}': 'armeabi-v7a',
- '{extras}': 'hw.cpu.model=cortex-a8\n'
- },
- 'mips': {
- '{hw.cpu.arch}': 'mips',
- '{abi.type}': 'mips',
- '{extras}': ''
- }
-}
-
-class EmulatorLaunchException(Exception):
- """Emulator failed to launch."""
- pass
-
-def _KillAllEmulators():
- """Kill all running emulators that look like ones we started.
-
- There are odd 'sticky' cases where there can be no emulator process
- running but a device slot is taken. A little bot trouble and we're out of
- room forever.
- """
- emulators = [d for d in device_utils.DeviceUtils.HealthyDevices()
- if d.adb.is_emulator]
- if not emulators:
- return
- for e in emulators:
- e.adb.Emu(['kill'])
- logging.info('Emulator killing is async; give a few seconds for all to die.')
- for _ in range(5):
- if not any(d.adb.is_emulator for d
- in device_utils.DeviceUtils.HealthyDevices()):
- return
- time.sleep(1)
-
-
-def DeleteAllTempAVDs():
- """Delete all temporary AVDs which are created for tests.
-
- If the test exits abnormally and some temporary AVDs created when testing may
- be left in the system. Clean these AVDs.
- """
- avds = device_utils.GetAVDs()
- if not avds:
- return
- for avd_name in avds:
- if 'run_tests_avd' in avd_name:
- cmd = ['android', '-s', 'delete', 'avd', '--name', avd_name]
- cmd_helper.RunCmd(cmd)
- logging.info('Delete AVD %s' % avd_name)
-
-
-class PortPool(object):
- """Pool for emulator port starting position that changes over time."""
- _port_min = 5554
- _port_max = 5585
- _port_current_index = 0
-
- @classmethod
- def port_range(cls):
- """Return a range of valid ports for emulator use.
-
- The port must be an even number between 5554 and 5584. Sometimes
- a killed emulator "hangs on" to a port long enough to prevent
- relaunch. This is especially true on slow machines (like a bot).
- Cycling through a port start position helps make us resilient."""
- ports = range(cls._port_min, cls._port_max, 2)
- n = cls._port_current_index
- cls._port_current_index = (n + 1) % len(ports)
- return ports[n:] + ports[:n]
-
-
-def _GetAvailablePort():
- """Returns an available TCP port for the console."""
- used_ports = []
- emulators = [d for d in device_utils.DeviceUtils.HealthyDevices()
- if d.adb.is_emulator]
- for emulator in emulators:
- used_ports.append(emulator.adb.GetDeviceSerial().split('-')[1])
- for port in PortPool.port_range():
- if str(port) not in used_ports:
- return port
-
-
-def LaunchTempEmulators(emulator_count, abi, api_level, wait_for_boot=True):
- """Create and launch temporary emulators and wait for them to boot.
-
- Args:
- emulator_count: number of emulators to launch.
- abi: the emulator target platform
- api_level: the api level (e.g., 19 for Android v4.4 - KitKat release)
- wait_for_boot: whether or not to wait for emulators to boot up
-
- Returns:
- List of emulators.
- """
- emulators = []
- for n in xrange(emulator_count):
- t = time_profile.TimeProfile('Emulator launch %d' % n)
- # Creates a temporary AVD.
- avd_name = 'run_tests_avd_%d' % n
- logging.info('Emulator launch %d with avd_name=%s and api=%d',
- n, avd_name, api_level)
- emulator = Emulator(avd_name, abi)
- emulator.CreateAVD(api_level)
- emulator.Launch(kill_all_emulators=n == 0)
- t.Stop()
- emulators.append(emulator)
- # Wait for all emulators to boot completed.
- if wait_for_boot:
- for emulator in emulators:
- emulator.ConfirmLaunch(True)
- return emulators
-
-
-def LaunchEmulator(avd_name, abi):
- """Launch an existing emulator with name avd_name.
-
- Args:
- avd_name: name of existing emulator
- abi: the emulator target platform
-
- Returns:
- emulator object.
- """
- logging.info('Specified emulator named avd_name=%s launched', avd_name)
- emulator = Emulator(avd_name, abi)
- emulator.Launch(kill_all_emulators=True)
- emulator.ConfirmLaunch(True)
- return emulator
-
-
-class Emulator(object):
- """Provides the methods to launch/shutdown the emulator.
-
- The emulator has the android virtual device named 'avd_armeabi'.
-
- The emulator could use any even TCP port between 5554 and 5584 for the
- console communication, and this port will be part of the device name like
- 'emulator-5554'. Assume it is always True, as the device name is the id of
- emulator managed in this class.
-
- Attributes:
- emulator: Path of Android's emulator tool.
- popen: Popen object of the running emulator process.
- device: Device name of this emulator.
- """
-
- # Signals we listen for to kill the emulator on
- _SIGNALS = (signal.SIGINT, signal.SIGHUP)
-
- # Time to wait for an emulator launch, in seconds. This includes
- # the time to launch the emulator and a wait-for-device command.
- _LAUNCH_TIMEOUT = 120
-
- # Timeout interval of wait-for-device command before bouncing to a a
- # process life check.
- _WAITFORDEVICE_TIMEOUT = 5
-
- # Time to wait for a "wait for boot complete" (property set on device).
- _WAITFORBOOT_TIMEOUT = 300
-
- def __init__(self, avd_name, abi):
- """Init an Emulator.
-
- Args:
- avd_name: name of the AVD to create
- abi: target platform for emulator being created, defaults to x86
- """
- android_sdk_root = os.path.join(constants.EMULATOR_SDK_ROOT, 'sdk')
- self.emulator = os.path.join(android_sdk_root, 'tools', 'emulator')
- self.android = os.path.join(android_sdk_root, 'tools', 'android')
- self.popen = None
- self.device_serial = None
- self.abi = abi
- self.avd_name = avd_name
-
- @staticmethod
- def _DeviceName():
- """Return our device name."""
- port = _GetAvailablePort()
- return ('emulator-%d' % port, port)
-
- def CreateAVD(self, api_level):
- """Creates an AVD with the given name.
-
- Args:
- api_level: the api level of the image
-
- Return avd_name.
- """
-
- if self.abi == 'arm':
- abi_option = 'armeabi-v7a'
- elif self.abi == 'mips':
- abi_option = 'mips'
- else:
- abi_option = 'x86'
-
- api_target = 'android-%s' % api_level
-
- avd_command = [
- self.android,
- '--silent',
- 'create', 'avd',
- '--name', self.avd_name,
- '--abi', abi_option,
- '--target', api_target,
- '--sdcard', SDCARD_SIZE,
- '--force',
- ]
- avd_cmd_str = ' '.join(avd_command)
- logging.info('Create AVD command: %s', avd_cmd_str)
- avd_process = pexpect.spawn(avd_cmd_str)
-
- # Instead of creating a custom profile, we overwrite config files.
- avd_process.expect('Do you wish to create a custom hardware profile')
- avd_process.sendline('no\n')
- avd_process.expect('Created AVD \'%s\'' % self.avd_name)
-
- # Replace current configuration with default Galaxy Nexus config.
- avds_dir = os.path.join(os.path.expanduser('~'), '.android', 'avd')
- ini_file = os.path.join(avds_dir, '%s.ini' % self.avd_name)
- new_config_ini = os.path.join(avds_dir, '%s.avd' % self.avd_name,
- 'config.ini')
-
- # Remove config files with defaults to replace with Google's GN settings.
- os.unlink(ini_file)
- os.unlink(new_config_ini)
-
- # Create new configuration files with Galaxy Nexus by Google settings.
- with open(ini_file, 'w') as new_ini:
- new_ini.write('avd.ini.encoding=ISO-8859-1\n')
- new_ini.write('target=%s\n' % api_target)
- new_ini.write('path=%s/%s.avd\n' % (avds_dir, self.avd_name))
- new_ini.write('path.rel=avd/%s.avd\n' % self.avd_name)
-
- custom_config = CONFIG_TEMPLATE
- replacements = CONFIG_REPLACEMENTS[self.abi]
- for key in replacements:
- custom_config = custom_config.replace(key, replacements[key])
- custom_config = custom_config.replace('{api.level}', str(api_level))
-
- with open(new_config_ini, 'w') as new_config_ini:
- new_config_ini.write(custom_config)
-
- return self.avd_name
-
-
- def _DeleteAVD(self):
- """Delete the AVD of this emulator."""
- avd_command = [
- self.android,
- '--silent',
- 'delete',
- 'avd',
- '--name', self.avd_name,
- ]
- logging.info('Delete AVD command: %s', ' '.join(avd_command))
- cmd_helper.RunCmd(avd_command)
-
-
- def Launch(self, kill_all_emulators):
- """Launches the emulator asynchronously. Call ConfirmLaunch() to ensure the
- emulator is ready for use.
-
- If fails, an exception will be raised.
- """
- if kill_all_emulators:
- _KillAllEmulators() # just to be sure
- self._AggressiveImageCleanup()
- (self.device_serial, port) = self._DeviceName()
- emulator_command = [
- self.emulator,
- # Speed up emulator launch by 40%. Really.
- '-no-boot-anim',
- # The default /data size is 64M.
- # That's not enough for 8 unit test bundles and their data.
- '-partition-size', '512',
- # Use a familiar name and port.
- '-avd', self.avd_name,
- '-port', str(port),
- # Wipe the data. We've seen cases where an emulator gets 'stuck' if we
- # don't do this (every thousand runs or so).
- '-wipe-data',
- # Enable GPU by default.
- '-gpu', 'on',
- '-qemu', '-m', '1024',
- ]
- if self.abi == 'x86':
- emulator_command.extend([
- # For x86 emulator --enable-kvm will fail early, avoiding accidental
- # runs in a slow mode (i.e. without hardware virtualization support).
- '--enable-kvm',
- ])
-
- logging.info('Emulator launch command: %s', ' '.join(emulator_command))
- self.popen = subprocess.Popen(args=emulator_command,
- stderr=subprocess.STDOUT)
- self._InstallKillHandler()
-
- @staticmethod
- def _AggressiveImageCleanup():
- """Aggressive cleanup of emulator images.
-
- Experimentally it looks like our current emulator use on the bot
- leaves image files around in /tmp/android-$USER. If a "random"
- name gets reused, we choke with a 'File exists' error.
- TODO(jrg): is there a less hacky way to accomplish the same goal?
- """
- logging.info('Aggressive Image Cleanup')
- emulator_imagedir = '/tmp/android-%s' % os.environ['USER']
- if not os.path.exists(emulator_imagedir):
- return
- for image in os.listdir(emulator_imagedir):
- full_name = os.path.join(emulator_imagedir, image)
- if 'emulator' in full_name:
- logging.info('Deleting emulator image %s', full_name)
- os.unlink(full_name)
-
- def ConfirmLaunch(self, wait_for_boot=False):
- """Confirm the emulator launched properly.
-
- Loop on a wait-for-device with a very small timeout. On each
- timeout, check the emulator process is still alive.
- After confirming a wait-for-device can be successful, make sure
- it returns the right answer.
- """
- seconds_waited = 0
- number_of_waits = 2 # Make sure we can wfd twice
-
- device = device_utils.DeviceUtils(self.device_serial)
- while seconds_waited < self._LAUNCH_TIMEOUT:
- try:
- device.adb.WaitForDevice(
- timeout=self._WAITFORDEVICE_TIMEOUT, retries=1)
- number_of_waits -= 1
- if not number_of_waits:
- break
- except device_errors.CommandTimeoutError:
- seconds_waited += self._WAITFORDEVICE_TIMEOUT
- device.adb.KillServer()
- self.popen.poll()
- if self.popen.returncode != None:
- raise EmulatorLaunchException('EMULATOR DIED')
-
- if seconds_waited >= self._LAUNCH_TIMEOUT:
- raise EmulatorLaunchException('TIMEOUT with wait-for-device')
-
- logging.info('Seconds waited on wait-for-device: %d', seconds_waited)
- if wait_for_boot:
- # Now that we checked for obvious problems, wait for a boot complete.
- # Waiting for the package manager is sometimes problematic.
- device.WaitUntilFullyBooted(timeout=self._WAITFORBOOT_TIMEOUT)
-
- def Shutdown(self):
- """Shuts down the process started by launch."""
- self._DeleteAVD()
- if self.popen:
- self.popen.poll()
- if self.popen.returncode == None:
- self.popen.kill()
- self.popen = None
-
- def _ShutdownOnSignal(self, _signum, _frame):
- logging.critical('emulator _ShutdownOnSignal')
- for sig in self._SIGNALS:
- signal.signal(sig, signal.SIG_DFL)
- self.Shutdown()
- raise KeyboardInterrupt # print a stack
-
- def _InstallKillHandler(self):
- """Install a handler to kill the emulator when we exit unexpectedly."""
- for sig in self._SIGNALS:
- signal.signal(sig, self._ShutdownOnSignal)
diff --git a/build/android/pylib/utils/findbugs.py b/build/android/pylib/utils/findbugs.py
deleted file mode 100644
index 8deb0fe..0000000
--- a/build/android/pylib/utils/findbugs.py
+++ /dev/null
@@ -1,154 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import argparse
-import logging
-import os
-import re
-import shlex
-import sys
-import xml.dom.minidom
-
-from pylib import cmd_helper
-from pylib import constants
-
-
-_FINDBUGS_HOME = os.path.join(constants.DIR_SOURCE_ROOT, 'third_party',
- 'findbugs')
-_FINDBUGS_JAR = os.path.join(_FINDBUGS_HOME, 'lib', 'findbugs.jar')
-_FINDBUGS_MAX_HEAP = 768
-_FINDBUGS_PLUGIN_PATH = os.path.join(
- constants.DIR_SOURCE_ROOT, 'tools', 'android', 'findbugs_plugin', 'lib',
- 'chromiumPlugin.jar')
-
-
-def _ParseXmlResults(results_doc):
- warnings = set()
- for en in (n for n in results_doc.documentElement.childNodes
- if n.nodeType == xml.dom.Node.ELEMENT_NODE):
- if en.tagName == 'BugInstance':
- warnings.add(_ParseBugInstance(en))
- return warnings
-
-
-def _GetMessage(node):
- for c in (n for n in node.childNodes
- if n.nodeType == xml.dom.Node.ELEMENT_NODE):
- if c.tagName == 'Message':
- if (len(c.childNodes) == 1
- and c.childNodes[0].nodeType == xml.dom.Node.TEXT_NODE):
- return c.childNodes[0].data
- return None
-
-
-def _ParseBugInstance(node):
- bug = FindBugsWarning(node.getAttribute('type'))
- msg_parts = []
- for c in (n for n in node.childNodes
- if n.nodeType == xml.dom.Node.ELEMENT_NODE):
- if c.tagName == 'Class':
- msg_parts.append(_GetMessage(c))
- elif c.tagName == 'Method':
- msg_parts.append(_GetMessage(c))
- elif c.tagName == 'Field':
- msg_parts.append(_GetMessage(c))
- elif c.tagName == 'SourceLine':
- bug.file_name = c.getAttribute('sourcefile')
- if c.hasAttribute('start'):
- bug.start_line = int(c.getAttribute('start'))
- if c.hasAttribute('end'):
- bug.end_line = int(c.getAttribute('end'))
- msg_parts.append(_GetMessage(c))
- elif (c.tagName == 'ShortMessage' and len(c.childNodes) == 1
- and c.childNodes[0].nodeType == xml.dom.Node.TEXT_NODE):
- msg_parts.append(c.childNodes[0].data)
- bug.message = tuple(m for m in msg_parts if m)
- return bug
-
-
-class FindBugsWarning(object):
-
- def __init__(self, bug_type='', end_line=0, file_name='', message=None,
- start_line=0):
- self.bug_type = bug_type
- self.end_line = end_line
- self.file_name = file_name
- if message is None:
- self.message = tuple()
- else:
- self.message = message
- self.start_line = start_line
-
- def __cmp__(self, other):
- return (cmp(self.file_name, other.file_name)
- or cmp(self.start_line, other.start_line)
- or cmp(self.end_line, other.end_line)
- or cmp(self.bug_type, other.bug_type)
- or cmp(self.message, other.message))
-
- def __eq__(self, other):
- return self.__dict__ == other.__dict__
-
- def __hash__(self):
- return hash((self.bug_type, self.end_line, self.file_name, self.message,
- self.start_line))
-
- def __ne__(self, other):
- return not self == other
-
- def __str__(self):
- return '%s: %s' % (self.bug_type, '\n '.join(self.message))
-
-
-def Run(exclude, classes_to_analyze, auxiliary_classes, output_file,
- findbug_args, jars):
- """Run FindBugs.
-
- Args:
- exclude: the exclude xml file, refer to FindBugs's -exclude command option.
- classes_to_analyze: the list of classes need to analyze, refer to FindBug's
- -onlyAnalyze command line option.
- auxiliary_classes: the classes help to analyze, refer to FindBug's
- -auxclasspath command line option.
- output_file: An optional path to dump XML results to.
- findbug_args: A list of addtional command line options to pass to Findbugs.
- """
- # TODO(jbudorick): Get this from the build system.
- system_classes = [
- os.path.join(constants.ANDROID_SDK_ROOT, 'platforms',
- 'android-%s' % constants.ANDROID_SDK_VERSION, 'android.jar')
- ]
- system_classes.extend(os.path.abspath(classes)
- for classes in auxiliary_classes or [])
-
- cmd = ['java',
- '-classpath', '%s:' % _FINDBUGS_JAR,
- '-Xmx%dm' % _FINDBUGS_MAX_HEAP,
- '-Dfindbugs.home="%s"' % _FINDBUGS_HOME,
- '-jar', _FINDBUGS_JAR,
- '-textui', '-sortByClass',
- '-pluginList', _FINDBUGS_PLUGIN_PATH, '-xml:withMessages']
- if system_classes:
- cmd.extend(['-auxclasspath', ':'.join(system_classes)])
- if classes_to_analyze:
- cmd.extend(['-onlyAnalyze', classes_to_analyze])
- if exclude:
- cmd.extend(['-exclude', os.path.abspath(exclude)])
- if output_file:
- cmd.extend(['-output', output_file])
- if findbug_args:
- cmd.extend(findbug_args)
- cmd.extend(os.path.abspath(j) for j in jars or [])
-
- if output_file:
- cmd_helper.RunCmd(cmd)
- results_doc = xml.dom.minidom.parse(output_file)
- else:
- raw_out = cmd_helper.GetCmdOutput(cmd)
- results_doc = xml.dom.minidom.parseString(raw_out)
-
- current_warnings_set = _ParseXmlResults(results_doc)
-
- return (' '.join(cmd), current_warnings_set)
-
diff --git a/build/android/pylib/utils/host_path_finder.py b/build/android/pylib/utils/host_path_finder.py
deleted file mode 100644
index 389ac43..0000000
--- a/build/android/pylib/utils/host_path_finder.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-
-from pylib import constants
-
-
-def GetMostRecentHostPath(file_name):
- """Returns the most recent existing full path for the given file name.
-
- Returns: An empty string if no path could be found.
- """
- out_dir = os.path.join(
- constants.DIR_SOURCE_ROOT, os.environ.get('CHROMIUM_OUT_DIR', 'out'))
- candidate_paths = [os.path.join(out_dir, build_type, file_name)
- for build_type in ['Debug', 'Release']]
- candidate_paths = filter(os.path.exists, candidate_paths)
- candidate_paths = sorted(candidate_paths, key=os.path.getmtime, reverse=True)
- candidate_paths.append('')
- return candidate_paths[0]
diff --git a/build/android/pylib/utils/host_utils.py b/build/android/pylib/utils/host_utils.py
deleted file mode 100644
index 580721f..0000000
--- a/build/android/pylib/utils/host_utils.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-
-
-def GetRecursiveDiskUsage(path):
- """Returns the disk usage in bytes of |path|. Similar to `du -sb |path|`."""
- running_size = os.path.getsize(path)
- if os.path.isdir(path):
- for root, dirs, files in os.walk(path):
- running_size += sum([os.path.getsize(os.path.join(root, f))
- for f in files + dirs])
- return running_size
-
diff --git a/build/android/pylib/utils/isolator.py b/build/android/pylib/utils/isolator.py
deleted file mode 100644
index cac39d8..0000000
--- a/build/android/pylib/utils/isolator.py
+++ /dev/null
@@ -1,173 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import fnmatch
-import glob
-import os
-import shutil
-import sys
-
-from pylib import cmd_helper
-from pylib import constants
-
-
-_ISOLATE_SCRIPT = os.path.join(
- constants.DIR_SOURCE_ROOT, 'tools', 'swarming_client', 'isolate.py')
-
-
-def DefaultPathVariables():
- return {
- 'DEPTH': constants.DIR_SOURCE_ROOT,
- 'PRODUCT_DIR': constants.GetOutDirectory(),
- }
-
-
-def DefaultConfigVariables():
- # Note: This list must match the --config-vars in build/isolate.gypi
- return {
- 'CONFIGURATION_NAME': constants.GetBuildType(),
- 'OS': 'android',
- 'asan': '0',
- 'branding': 'Chromium',
- 'chromeos': '0',
- 'component': 'static_library',
- 'enable_pepper_cdms': '0',
- 'enable_plugins': '0',
- 'fastbuild': '0',
- 'icu_use_data_file_flag': '1',
- 'kasko': '0',
- 'lsan': '0',
- 'msan': '0',
- # TODO(maruel): This may not always be true.
- 'target_arch': 'arm',
- 'tsan': '0',
- 'use_custom_libcxx': '0',
- 'use_instrumented_libraries': '0',
- 'use_prebuilt_instrumented_libraries': '0',
- 'use_openssl': '0',
- 'use_ozone': '0',
- 'use_x11': '0',
- 'v8_use_external_startup_data': '1',
- }
-
-
-class Isolator(object):
- """Manages calls to isolate.py for the android test runner scripts."""
-
- def __init__(self, isolate_deps_dir):
- """
- Args:
- isolate_deps_dir: The directory in which dependencies specified by
- isolate are or should be stored.
- """
- self._isolate_deps_dir = isolate_deps_dir
-
- def Clear(self):
- """Deletes the isolate dependency directory."""
- if os.path.exists(self._isolate_deps_dir):
- shutil.rmtree(self._isolate_deps_dir)
-
- def Remap(self, isolate_abs_path, isolated_abs_path,
- path_variables=None, config_variables=None):
- """Remaps data dependencies into |self._isolate_deps_dir|.
-
- Args:
- isolate_abs_path: The absolute path to the .isolate file, which specifies
- data dependencies in the source tree.
- isolated_abs_path: The absolute path to the .isolated file, which is
- generated by isolate.py and specifies data dependencies in
- |self._isolate_deps_dir| and their digests.
- path_variables: A dict containing everything that should be passed
- as a |--path-variable| to the isolate script. Defaults to the return
- value of |DefaultPathVariables()|.
- config_variables: A dict containing everything that should be passed
- as a |--config-variable| to the isolate script. Defaults to the return
- value of |DefaultConfigVariables()|.
- Raises:
- Exception if the isolate command fails for some reason.
- """
- if not path_variables:
- path_variables = DefaultPathVariables()
- if not config_variables:
- config_variables = DefaultConfigVariables()
-
- isolate_cmd = [
- sys.executable, _ISOLATE_SCRIPT, 'remap',
- '--isolate', isolate_abs_path,
- '--isolated', isolated_abs_path,
- '--outdir', self._isolate_deps_dir,
- ]
- for k, v in path_variables.iteritems():
- isolate_cmd.extend(['--path-variable', k, v])
- for k, v in config_variables.iteritems():
- isolate_cmd.extend(['--config-variable', k, v])
-
- if cmd_helper.RunCmd(isolate_cmd):
- raise Exception('isolate command failed: %s' % ' '.join(isolate_cmd))
-
- def VerifyHardlinks(self):
- """Checks |isolate_deps_dir| for a hardlink.
-
- Returns:
- True if a hardlink is found.
- False if nothing is found.
- Raises:
- Exception if a non-hardlink is found.
- """
- for root, _, filenames in os.walk(self._isolate_deps_dir):
- if filenames:
- linked_file = os.path.join(root, filenames[0])
- orig_file = os.path.join(
- self._isolate_deps_dir,
- os.path.relpath(linked_file, self._isolate_deps_dir))
- if os.stat(linked_file).st_ino == os.stat(orig_file).st_ino:
- return True
- else:
- raise Exception('isolate remap command did not use hardlinks.')
- return False
-
- def PurgeExcluded(self, deps_exclusion_list):
- """Deletes anything on |deps_exclusion_list| from |self._isolate_deps_dir|.
-
- Args:
- deps_exclusion_list: A list of globs to exclude from the isolate
- dependency directory.
- """
- excluded_paths = (
- x for y in deps_exclusion_list
- for x in glob.glob(
- os.path.abspath(os.path.join(self._isolate_deps_dir, y))))
- for p in excluded_paths:
- if os.path.isdir(p):
- shutil.rmtree(p)
- else:
- os.remove(p)
-
- def MoveOutputDeps(self):
- """Moves files from the output directory to the top level of
- |self._isolate_deps_dir|.
-
- Moves pak files from the output directory to to <isolate_deps_dir>/paks
- Moves files from the product directory to <isolate_deps_dir>
- """
- # On Android, all pak files need to be in the top-level 'paks' directory.
- paks_dir = os.path.join(self._isolate_deps_dir, 'paks')
- os.mkdir(paks_dir)
-
- deps_out_dir = os.path.join(
- self._isolate_deps_dir,
- os.path.relpath(os.path.join(constants.GetOutDirectory(), os.pardir),
- constants.DIR_SOURCE_ROOT))
- for root, _, filenames in os.walk(deps_out_dir):
- for filename in fnmatch.filter(filenames, '*.pak'):
- shutil.move(os.path.join(root, filename), paks_dir)
-
- # Move everything in PRODUCT_DIR to top level.
- deps_product_dir = os.path.join(deps_out_dir, constants.GetBuildType())
- if os.path.isdir(deps_product_dir):
- for p in os.listdir(deps_product_dir):
- shutil.move(os.path.join(deps_product_dir, p), self._isolate_deps_dir)
- os.rmdir(deps_product_dir)
- os.rmdir(deps_out_dir)
-
diff --git a/build/android/pylib/utils/json_results_generator_unittest.py b/build/android/pylib/utils/json_results_generator_unittest.py
deleted file mode 100644
index 41ab77b..0000000
--- a/build/android/pylib/utils/json_results_generator_unittest.py
+++ /dev/null
@@ -1,213 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-#
-# Most of this file was ported over from Blink's
-# webkitpy/layout_tests/layout_package/json_results_generator_unittest.py
-#
-
-import unittest
-import json
-
-from pylib.utils import json_results_generator
-
-
-class JSONGeneratorTest(unittest.TestCase):
-
- def setUp(self):
- self.builder_name = 'DUMMY_BUILDER_NAME'
- self.build_name = 'DUMMY_BUILD_NAME'
- self.build_number = 'DUMMY_BUILDER_NUMBER'
-
- # For archived results.
- self._json = None
- self._num_runs = 0
- self._tests_set = set([])
- self._test_timings = {}
- self._failed_count_map = {}
-
- self._PASS_count = 0
- self._DISABLED_count = 0
- self._FLAKY_count = 0
- self._FAILS_count = 0
- self._fixable_count = 0
-
- self._orig_write_json = json_results_generator.WriteJSON
-
- # unused arguments ... pylint: disable=W0613
- def _WriteJSONStub(json_object, file_path, callback=None):
- pass
-
- json_results_generator.WriteJSON = _WriteJSONStub
-
- def tearDown(self):
- json_results_generator.WriteJSON = self._orig_write_json
-
- def _TestJSONGeneration(self, passed_tests_list, failed_tests_list):
- tests_set = set(passed_tests_list) | set(failed_tests_list)
-
- DISABLED_tests = set([t for t in tests_set
- if t.startswith('DISABLED_')])
- FLAKY_tests = set([t for t in tests_set
- if t.startswith('FLAKY_')])
- FAILS_tests = set([t for t in tests_set
- if t.startswith('FAILS_')])
- PASS_tests = tests_set - (DISABLED_tests | FLAKY_tests | FAILS_tests)
-
- failed_tests = set(failed_tests_list) - DISABLED_tests
- failed_count_map = dict([(t, 1) for t in failed_tests])
-
- test_timings = {}
- i = 0
- for test in tests_set:
- test_timings[test] = float(self._num_runs * 100 + i)
- i += 1
-
- test_results_map = dict()
- for test in tests_set:
- test_results_map[test] = json_results_generator.TestResult(
- test, failed=(test in failed_tests),
- elapsed_time=test_timings[test])
-
- generator = json_results_generator.JSONResultsGeneratorBase(
- self.builder_name, self.build_name, self.build_number,
- '',
- None, # don't fetch past json results archive
- test_results_map)
-
- failed_count_map = dict([(t, 1) for t in failed_tests])
-
- # Test incremental json results
- incremental_json = generator.GetJSON()
- self._VerifyJSONResults(
- tests_set,
- test_timings,
- failed_count_map,
- len(PASS_tests),
- len(DISABLED_tests),
- len(FLAKY_tests),
- len(DISABLED_tests | failed_tests),
- incremental_json,
- 1)
-
- # We don't verify the results here, but at least we make sure the code
- # runs without errors.
- generator.GenerateJSONOutput()
- generator.GenerateTimesMSFile()
-
- def _VerifyJSONResults(self, tests_set, test_timings, failed_count_map,
- PASS_count, DISABLED_count, FLAKY_count,
- fixable_count, json_obj, num_runs):
- # Aliasing to a short name for better access to its constants.
- JRG = json_results_generator.JSONResultsGeneratorBase
-
- self.assertIn(JRG.VERSION_KEY, json_obj)
- self.assertIn(self.builder_name, json_obj)
-
- buildinfo = json_obj[self.builder_name]
- self.assertIn(JRG.FIXABLE, buildinfo)
- self.assertIn(JRG.TESTS, buildinfo)
- self.assertEqual(len(buildinfo[JRG.BUILD_NUMBERS]), num_runs)
- self.assertEqual(buildinfo[JRG.BUILD_NUMBERS][0], self.build_number)
-
- if tests_set or DISABLED_count:
- fixable = {}
- for fixable_items in buildinfo[JRG.FIXABLE]:
- for (result_type, count) in fixable_items.iteritems():
- if result_type in fixable:
- fixable[result_type] = fixable[result_type] + count
- else:
- fixable[result_type] = count
-
- if PASS_count:
- self.assertEqual(fixable[JRG.PASS_RESULT], PASS_count)
- else:
- self.assertTrue(JRG.PASS_RESULT not in fixable or
- fixable[JRG.PASS_RESULT] == 0)
- if DISABLED_count:
- self.assertEqual(fixable[JRG.SKIP_RESULT], DISABLED_count)
- else:
- self.assertTrue(JRG.SKIP_RESULT not in fixable or
- fixable[JRG.SKIP_RESULT] == 0)
- if FLAKY_count:
- self.assertEqual(fixable[JRG.FLAKY_RESULT], FLAKY_count)
- else:
- self.assertTrue(JRG.FLAKY_RESULT not in fixable or
- fixable[JRG.FLAKY_RESULT] == 0)
-
- if failed_count_map:
- tests = buildinfo[JRG.TESTS]
- for test_name in failed_count_map.iterkeys():
- test = self._FindTestInTrie(test_name, tests)
-
- failed = 0
- for result in test[JRG.RESULTS]:
- if result[1] == JRG.FAIL_RESULT:
- failed += result[0]
- self.assertEqual(failed_count_map[test_name], failed)
-
- timing_count = 0
- for timings in test[JRG.TIMES]:
- if timings[1] == test_timings[test_name]:
- timing_count = timings[0]
- self.assertEqual(1, timing_count)
-
- if fixable_count:
- self.assertEqual(sum(buildinfo[JRG.FIXABLE_COUNT]), fixable_count)
-
- def _FindTestInTrie(self, path, trie):
- nodes = path.split('/')
- sub_trie = trie
- for node in nodes:
- self.assertIn(node, sub_trie)
- sub_trie = sub_trie[node]
- return sub_trie
-
- def testJSONGeneration(self):
- self._TestJSONGeneration([], [])
- self._TestJSONGeneration(['A1', 'B1'], [])
- self._TestJSONGeneration([], ['FAILS_A2', 'FAILS_B2'])
- self._TestJSONGeneration(['DISABLED_A3', 'DISABLED_B3'], [])
- self._TestJSONGeneration(['A4'], ['B4', 'FAILS_C4'])
- self._TestJSONGeneration(['DISABLED_C5', 'DISABLED_D5'], ['A5', 'B5'])
- self._TestJSONGeneration(
- ['A6', 'B6', 'FAILS_C6', 'DISABLED_E6', 'DISABLED_F6'],
- ['FAILS_D6'])
-
- # Generate JSON with the same test sets. (Both incremental results and
- # archived results must be updated appropriately.)
- self._TestJSONGeneration(
- ['A', 'FLAKY_B', 'DISABLED_C'],
- ['FAILS_D', 'FLAKY_E'])
- self._TestJSONGeneration(
- ['A', 'DISABLED_C', 'FLAKY_E'],
- ['FLAKY_B', 'FAILS_D'])
- self._TestJSONGeneration(
- ['FLAKY_B', 'DISABLED_C', 'FAILS_D'],
- ['A', 'FLAKY_E'])
-
- def testHierarchicalJSNGeneration(self):
- # FIXME: Re-work tests to be more comprehensible and comprehensive.
- self._TestJSONGeneration(['foo/A'], ['foo/B', 'bar/C'])
-
- def testTestTimingsTrie(self):
- individual_test_timings = []
- individual_test_timings.append(
- json_results_generator.TestResult(
- 'foo/bar/baz.html',
- elapsed_time=1.2))
- individual_test_timings.append(
- json_results_generator.TestResult('bar.html', elapsed_time=0.0001))
- trie = json_results_generator.TestTimingsTrie(individual_test_timings)
-
- expected_trie = {
- 'bar.html': 0,
- 'foo': {
- 'bar': {
- 'baz.html': 1200,
- }
- }
- }
-
- self.assertEqual(json.dumps(trie), json.dumps(expected_trie))
diff --git a/build/android/pylib/utils/logging_utils.py b/build/android/pylib/utils/logging_utils.py
deleted file mode 100644
index 1e46fa8..0000000
--- a/build/android/pylib/utils/logging_utils.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import contextlib
-import logging
-
-@contextlib.contextmanager
-def SuppressLogging(level=logging.ERROR):
- """Momentarilly suppress logging events from all loggers.
-
- TODO(jbudorick): This is not thread safe. Log events from other threads might
- also inadvertently dissapear.
-
- Example:
-
- with logging_utils.SuppressLogging():
- # all but CRITICAL logging messages are suppressed
- logging.info('just doing some thing') # not shown
- logging.critical('something really bad happened') # still shown
-
- Args:
- level: logging events with this or lower levels are suppressed.
- """
- logging.disable(level)
- yield
- logging.disable(logging.NOTSET)
diff --git a/build/android/pylib/utils/md5sum.py b/build/android/pylib/utils/md5sum.py
deleted file mode 100644
index 3e61c8f..0000000
--- a/build/android/pylib/utils/md5sum.py
+++ /dev/null
@@ -1,91 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import collections
-import logging
-import os
-import re
-import tempfile
-import types
-
-from pylib import cmd_helper
-from pylib import constants
-from pylib.utils import device_temp_file
-
-MD5SUM_DEVICE_LIB_PATH = '/data/local/tmp/md5sum/'
-MD5SUM_DEVICE_BIN_PATH = MD5SUM_DEVICE_LIB_PATH + 'md5sum_bin'
-
-MD5SUM_DEVICE_SCRIPT_FORMAT = (
- 'test -f {path} -o -d {path} '
- '&& LD_LIBRARY_PATH={md5sum_lib} {md5sum_bin} {path}')
-
-_STARTS_WITH_CHECKSUM_RE = re.compile(r'^\s*[0-9a-fA-F]{32}\s+')
-
-
-def CalculateHostMd5Sums(paths):
- """Calculates the MD5 sum value for all items in |paths|.
-
- Directories are traversed recursively and the MD5 sum of each file found is
- reported in the result.
-
- Args:
- paths: A list of host paths to md5sum.
- Returns:
- A dict mapping file paths to their respective md5sum checksums.
- """
- if isinstance(paths, basestring):
- paths = [paths]
-
- md5sum_bin_host_path = os.path.join(
- constants.GetOutDirectory(), 'md5sum_bin_host')
- if not os.path.exists(md5sum_bin_host_path):
- raise IOError('File not built: %s' % md5sum_bin_host_path)
- out = cmd_helper.GetCmdOutput([md5sum_bin_host_path] + [p for p in paths])
-
- return _ParseMd5SumOutput(out.splitlines())
-
-
-def CalculateDeviceMd5Sums(paths, device):
- """Calculates the MD5 sum value for all items in |paths|.
-
- Directories are traversed recursively and the MD5 sum of each file found is
- reported in the result.
-
- Args:
- paths: A list of device paths to md5sum.
- Returns:
- A dict mapping file paths to their respective md5sum checksums.
- """
- if isinstance(paths, basestring):
- paths = [paths]
-
- if not device.FileExists(MD5SUM_DEVICE_BIN_PATH):
- md5sum_dist_path = os.path.join(constants.GetOutDirectory(), 'md5sum_dist')
- if not os.path.exists(md5sum_dist_path):
- raise IOError('File not built: %s' % md5sum_dist_path)
- device.adb.Push(md5sum_dist_path, MD5SUM_DEVICE_LIB_PATH)
-
- out = []
-
- with tempfile.NamedTemporaryFile() as md5sum_script_file:
- with device_temp_file.DeviceTempFile(
- device.adb) as md5sum_device_script_file:
- md5sum_script = (
- MD5SUM_DEVICE_SCRIPT_FORMAT.format(
- path=p, md5sum_lib=MD5SUM_DEVICE_LIB_PATH,
- md5sum_bin=MD5SUM_DEVICE_BIN_PATH)
- for p in paths)
- md5sum_script_file.write('; '.join(md5sum_script))
- md5sum_script_file.flush()
- device.adb.Push(md5sum_script_file.name, md5sum_device_script_file.name)
- out = device.RunShellCommand(['sh', md5sum_device_script_file.name])
-
- return _ParseMd5SumOutput(out)
-
-
-def _ParseMd5SumOutput(out):
- hash_and_path = (l.split(None, 1) for l in out
- if l and _STARTS_WITH_CHECKSUM_RE.match(l))
- return dict((p, h) for h, p in hash_and_path)
-
diff --git a/build/android/pylib/utils/md5sum_test.py b/build/android/pylib/utils/md5sum_test.py
deleted file mode 100755
index c94c19d..0000000
--- a/build/android/pylib/utils/md5sum_test.py
+++ /dev/null
@@ -1,231 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import sys
-import unittest
-
-from pylib import cmd_helper
-from pylib import constants
-from pylib.utils import md5sum
-
-sys.path.append(
- os.path.join(constants.DIR_SOURCE_ROOT, 'third_party', 'pymock'))
-import mock
-
-TEST_OUT_DIR = os.path.join('test', 'out', 'directory')
-HOST_MD5_EXECUTABLE = os.path.join(TEST_OUT_DIR, 'md5sum_bin_host')
-
-class Md5SumTest(unittest.TestCase):
-
- def setUp(self):
- self._patchers = [
- mock.patch('pylib.constants.GetOutDirectory',
- new=mock.Mock(return_value=TEST_OUT_DIR)),
- mock.patch('os.path.exists',
- new=mock.Mock(return_value=True)),
- ]
- for p in self._patchers:
- p.start()
-
- def tearDown(self):
- for p in self._patchers:
- p.stop()
-
- def testCalculateHostMd5Sums_singlePath(self):
- test_path = '/test/host/file.dat'
- mock_get_cmd_output = mock.Mock(
- return_value='0123456789abcdeffedcba9876543210 /test/host/file.dat')
- with mock.patch('pylib.cmd_helper.GetCmdOutput', new=mock_get_cmd_output):
- out = md5sum.CalculateHostMd5Sums(test_path)
- self.assertEquals(1, len(out))
- self.assertTrue('/test/host/file.dat' in out)
- self.assertEquals('0123456789abcdeffedcba9876543210',
- out['/test/host/file.dat'])
- mock_get_cmd_output.assert_called_once_with(
- [HOST_MD5_EXECUTABLE, '/test/host/file.dat'])
-
- def testCalculateHostMd5Sums_list(self):
- test_paths = ['/test/host/file0.dat', '/test/host/file1.dat']
- mock_get_cmd_output = mock.Mock(
- return_value='0123456789abcdeffedcba9876543210 /test/host/file0.dat\n'
- '123456789abcdef00fedcba987654321 /test/host/file1.dat\n')
- with mock.patch('pylib.cmd_helper.GetCmdOutput', new=mock_get_cmd_output):
- out = md5sum.CalculateHostMd5Sums(test_paths)
- self.assertEquals(2, len(out))
- self.assertTrue('/test/host/file0.dat' in out)
- self.assertEquals('0123456789abcdeffedcba9876543210',
- out['/test/host/file0.dat'])
- self.assertTrue('/test/host/file1.dat' in out)
- self.assertEquals('123456789abcdef00fedcba987654321',
- out['/test/host/file1.dat'])
- mock_get_cmd_output.assert_called_once_with(
- [HOST_MD5_EXECUTABLE, '/test/host/file0.dat',
- '/test/host/file1.dat'])
-
- def testCalculateHostMd5Sums_generator(self):
- test_paths = ('/test/host/' + p for p in ['file0.dat', 'file1.dat'])
- mock_get_cmd_output = mock.Mock(
- return_value='0123456789abcdeffedcba9876543210 /test/host/file0.dat\n'
- '123456789abcdef00fedcba987654321 /test/host/file1.dat\n')
- with mock.patch('pylib.cmd_helper.GetCmdOutput', new=mock_get_cmd_output):
- out = md5sum.CalculateHostMd5Sums(test_paths)
- self.assertEquals(2, len(out))
- self.assertTrue('/test/host/file0.dat' in out)
- self.assertEquals('0123456789abcdeffedcba9876543210',
- out['/test/host/file0.dat'])
- self.assertTrue('/test/host/file1.dat' in out)
- self.assertEquals('123456789abcdef00fedcba987654321',
- out['/test/host/file1.dat'])
- mock_get_cmd_output.assert_called_once_with(
- [HOST_MD5_EXECUTABLE, '/test/host/file0.dat', '/test/host/file1.dat'])
-
- def testCalculateDeviceMd5Sums_singlePath(self):
- test_path = '/storage/emulated/legacy/test/file.dat'
-
- device = mock.NonCallableMock()
- device.adb = mock.NonCallableMock()
- device.adb.Push = mock.Mock()
- device_md5sum_output = [
- '0123456789abcdeffedcba9876543210 '
- '/storage/emulated/legacy/test/file.dat',
- ]
- device.RunShellCommand = mock.Mock(return_value=device_md5sum_output)
-
- mock_temp_file = mock.mock_open()
- mock_temp_file.return_value.name = '/tmp/test/script/file.sh'
-
- mock_device_temp_file = mock.mock_open()
- mock_device_temp_file.return_value.name = (
- '/data/local/tmp/test/script/file.sh')
-
- with mock.patch('tempfile.NamedTemporaryFile', new=mock_temp_file), (
- mock.patch('pylib.utils.device_temp_file.DeviceTempFile',
- new=mock_device_temp_file)):
- out = md5sum.CalculateDeviceMd5Sums(test_path, device)
- self.assertEquals(1, len(out))
- self.assertTrue('/storage/emulated/legacy/test/file.dat' in out)
- self.assertEquals('0123456789abcdeffedcba9876543210',
- out['/storage/emulated/legacy/test/file.dat'])
- device.adb.Push.assert_called_once_with(
- '/tmp/test/script/file.sh', '/data/local/tmp/test/script/file.sh')
- device.RunShellCommand.assert_called_once_with(
- ['sh', '/data/local/tmp/test/script/file.sh'])
-
- def testCalculateDeviceMd5Sums_list(self):
- test_path = ['/storage/emulated/legacy/test/file0.dat',
- '/storage/emulated/legacy/test/file1.dat']
- device = mock.NonCallableMock()
- device.adb = mock.NonCallableMock()
- device.adb.Push = mock.Mock()
- device_md5sum_output = [
- '0123456789abcdeffedcba9876543210 '
- '/storage/emulated/legacy/test/file0.dat',
- '123456789abcdef00fedcba987654321 '
- '/storage/emulated/legacy/test/file1.dat',
- ]
- device.RunShellCommand = mock.Mock(return_value=device_md5sum_output)
-
- mock_temp_file = mock.mock_open()
- mock_temp_file.return_value.name = '/tmp/test/script/file.sh'
-
- mock_device_temp_file = mock.mock_open()
- mock_device_temp_file.return_value.name = (
- '/data/local/tmp/test/script/file.sh')
-
- with mock.patch('tempfile.NamedTemporaryFile', new=mock_temp_file), (
- mock.patch('pylib.utils.device_temp_file.DeviceTempFile',
- new=mock_device_temp_file)):
- out = md5sum.CalculateDeviceMd5Sums(test_path, device)
- self.assertEquals(2, len(out))
- self.assertTrue('/storage/emulated/legacy/test/file0.dat' in out)
- self.assertEquals('0123456789abcdeffedcba9876543210',
- out['/storage/emulated/legacy/test/file0.dat'])
- self.assertTrue('/storage/emulated/legacy/test/file1.dat' in out)
- self.assertEquals('123456789abcdef00fedcba987654321',
- out['/storage/emulated/legacy/test/file1.dat'])
- device.adb.Push.assert_called_once_with(
- '/tmp/test/script/file.sh', '/data/local/tmp/test/script/file.sh')
- device.RunShellCommand.assert_called_once_with(
- ['sh', '/data/local/tmp/test/script/file.sh'])
-
- def testCalculateDeviceMd5Sums_generator(self):
- test_path = ('/storage/emulated/legacy/test/file%d.dat' % n
- for n in xrange(0, 2))
-
- device = mock.NonCallableMock()
- device.adb = mock.NonCallableMock()
- device.adb.Push = mock.Mock()
- device_md5sum_output = [
- '0123456789abcdeffedcba9876543210 '
- '/storage/emulated/legacy/test/file0.dat',
- '123456789abcdef00fedcba987654321 '
- '/storage/emulated/legacy/test/file1.dat',
- ]
- device.RunShellCommand = mock.Mock(return_value=device_md5sum_output)
-
- mock_temp_file = mock.mock_open()
- mock_temp_file.return_value.name = '/tmp/test/script/file.sh'
-
- mock_device_temp_file = mock.mock_open()
- mock_device_temp_file.return_value.name = (
- '/data/local/tmp/test/script/file.sh')
-
- with mock.patch('tempfile.NamedTemporaryFile', new=mock_temp_file), (
- mock.patch('pylib.utils.device_temp_file.DeviceTempFile',
- new=mock_device_temp_file)):
- out = md5sum.CalculateDeviceMd5Sums(test_path, device)
- self.assertEquals(2, len(out))
- self.assertTrue('/storage/emulated/legacy/test/file0.dat' in out)
- self.assertEquals('0123456789abcdeffedcba9876543210',
- out['/storage/emulated/legacy/test/file0.dat'])
- self.assertTrue('/storage/emulated/legacy/test/file1.dat' in out)
- self.assertEquals('123456789abcdef00fedcba987654321',
- out['/storage/emulated/legacy/test/file1.dat'])
- device.adb.Push.assert_called_once_with(
- '/tmp/test/script/file.sh', '/data/local/tmp/test/script/file.sh')
- device.RunShellCommand.assert_called_once_with(
- ['sh', '/data/local/tmp/test/script/file.sh'])
-
- def testCalculateDeviceMd5Sums_singlePath_linkerWarning(self):
- # See crbug/479966
- test_path = '/storage/emulated/legacy/test/file.dat'
-
- device = mock.NonCallableMock()
- device.adb = mock.NonCallableMock()
- device.adb.Push = mock.Mock()
- device_md5sum_output = [
- 'WARNING: linker: /data/local/tmp/md5sum/md5sum_bin: '
- 'unused DT entry: type 0x1d arg 0x15db',
- 'THIS_IS_NOT_A_VALID_CHECKSUM_ZZZ some random text',
- '0123456789abcdeffedcba9876543210 '
- '/storage/emulated/legacy/test/file.dat',
- ]
- device.RunShellCommand = mock.Mock(return_value=device_md5sum_output)
-
- mock_temp_file = mock.mock_open()
- mock_temp_file.return_value.name = '/tmp/test/script/file.sh'
-
- mock_device_temp_file = mock.mock_open()
- mock_device_temp_file.return_value.name = (
- '/data/local/tmp/test/script/file.sh')
-
- with mock.patch('tempfile.NamedTemporaryFile', new=mock_temp_file), (
- mock.patch('pylib.utils.device_temp_file.DeviceTempFile',
- new=mock_device_temp_file)):
- out = md5sum.CalculateDeviceMd5Sums(test_path, device)
- self.assertEquals(1, len(out))
- self.assertTrue('/storage/emulated/legacy/test/file.dat' in out)
- self.assertEquals('0123456789abcdeffedcba9876543210',
- out['/storage/emulated/legacy/test/file.dat'])
- device.adb.Push.assert_called_once_with(
- '/tmp/test/script/file.sh', '/data/local/tmp/test/script/file.sh')
- device.RunShellCommand.assert_called_once_with(
- ['sh', '/data/local/tmp/test/script/file.sh'])
-
-
-if __name__ == '__main__':
- unittest.main(verbosity=2)
-
diff --git a/build/android/pylib/utils/mock_calls.py b/build/android/pylib/utils/mock_calls.py
deleted file mode 100644
index 59167ba..0000000
--- a/build/android/pylib/utils/mock_calls.py
+++ /dev/null
@@ -1,182 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""
-A test facility to assert call sequences while mocking their behavior.
-"""
-
-import os
-import sys
-import unittest
-
-from pylib import constants
-
-sys.path.append(os.path.join(
- constants.DIR_SOURCE_ROOT, 'third_party', 'pymock'))
-import mock # pylint: disable=F0401
-
-
-class TestCase(unittest.TestCase):
- """Adds assertCalls to TestCase objects."""
- class _AssertCalls(object):
- def __init__(self, test_case, expected_calls, watched):
- def call_action(pair):
- if isinstance(pair, type(mock.call)):
- return (pair, None)
- else:
- return pair
-
- def do_check(call):
- def side_effect(*args, **kwargs):
- received_call = call(*args, **kwargs)
- self._test_case.assertTrue(
- self._expected_calls,
- msg=('Unexpected call: %s' % str(received_call)))
- expected_call, action = self._expected_calls.pop(0)
- self._test_case.assertTrue(
- received_call == expected_call,
- msg=('Expected call mismatch:\n'
- ' expected: %s\n'
- ' received: %s\n'
- % (str(expected_call), str(received_call))))
- if callable(action):
- return action(*args, **kwargs)
- else:
- return action
- return side_effect
-
- self._test_case = test_case
- self._expected_calls = [call_action(pair) for pair in expected_calls]
- watched = watched.copy() # do not pollute the caller's dict
- watched.update((call.parent.name, call.parent)
- for call, _ in self._expected_calls)
- self._patched = [test_case.patch_call(call, side_effect=do_check(call))
- for call in watched.itervalues()]
-
- def __enter__(self):
- for patch in self._patched:
- patch.__enter__()
- return self
-
- def __exit__(self, exc_type, exc_val, exc_tb):
- for patch in self._patched:
- patch.__exit__(exc_type, exc_val, exc_tb)
- if exc_type is None:
- missing = ''.join(' expected: %s\n' % str(call)
- for call, _ in self._expected_calls)
- self._test_case.assertFalse(
- missing,
- msg='Expected calls not found:\n' + missing)
-
- def __init__(self, *args, **kwargs):
- super(TestCase, self).__init__(*args, **kwargs)
- self.call = mock.call.self
- self._watched = {}
-
- def call_target(self, call):
- """Resolve a self.call instance to the target it represents.
-
- Args:
- call: a self.call instance, e.g. self.call.adb.Shell
-
- Returns:
- The target object represented by the call, e.g. self.adb.Shell
-
- Raises:
- ValueError if the path of the call does not start with "self", i.e. the
- target of the call is external to the self object.
- AttributeError if the path of the call does not specify a valid
- chain of attributes (without any calls) starting from "self".
- """
- path = call.name.split('.')
- if path.pop(0) != 'self':
- raise ValueError("Target %r outside of 'self' object" % call.name)
- target = self
- for attr in path:
- target = getattr(target, attr)
- return target
-
- def patch_call(self, call, **kwargs):
- """Patch the target of a mock.call instance.
-
- Args:
- call: a mock.call instance identifying a target to patch
- Extra keyword arguments are processed by mock.patch
-
- Returns:
- A context manager to mock/unmock the target of the call
- """
- if call.name.startswith('self.'):
- target = self.call_target(call.parent)
- _, attribute = call.name.rsplit('.', 1)
- if (hasattr(type(target), attribute)
- and isinstance(getattr(type(target), attribute), property)):
- return mock.patch.object(
- type(target), attribute, new_callable=mock.PropertyMock, **kwargs)
- else:
- return mock.patch.object(target, attribute, **kwargs)
- else:
- return mock.patch(call.name, **kwargs)
-
- def watchCalls(self, calls):
- """Add calls to the set of watched calls.
-
- Args:
- calls: a sequence of mock.call instances identifying targets to watch
- """
- self._watched.update((call.name, call) for call in calls)
-
- def watchMethodCalls(self, call, ignore=None):
- """Watch all public methods of the target identified by a self.call.
-
- Args:
- call: a self.call instance indetifying an object
- ignore: a list of public methods to ignore when watching for calls
- """
- target = self.call_target(call)
- if ignore is None:
- ignore = []
- self.watchCalls(getattr(call, method)
- for method in dir(target.__class__)
- if not method.startswith('_') and not method in ignore)
-
- def clearWatched(self):
- """Clear the set of watched calls."""
- self._watched = {}
-
- def assertCalls(self, *calls):
- """A context manager to assert that a sequence of calls is made.
-
- During the assertion, a number of functions and methods will be "watched",
- and any calls made to them is expected to appear---in the exact same order,
- and with the exact same arguments---as specified by the argument |calls|.
-
- By default, the targets of all expected calls are watched. Further targets
- to watch may be added using watchCalls and watchMethodCalls.
-
- Optionaly, each call may be accompanied by an action. If the action is a
- (non-callable) value, this value will be used as the return value given to
- the caller when the matching call is found. Alternatively, if the action is
- a callable, the action will be then called with the same arguments as the
- intercepted call, so that it can provide a return value or perform other
- side effects. If the action is missing, a return value of None is assumed.
-
- Note that mock.Mock objects are often convenient to use as a callable
- action, e.g. to raise exceptions or return other objects which are
- themselves callable.
-
- Args:
- calls: each argument is either a pair (expected_call, action) or just an
- expected_call, where expected_call is a mock.call instance.
-
- Raises:
- AssertionError if the watched targets do not receive the exact sequence
- of calls specified. Missing calls, extra calls, and calls with
- mismatching arguments, all cause the assertion to fail.
- """
- return self._AssertCalls(self, calls, self._watched)
-
- def assertCall(self, call, action=None):
- return self.assertCalls((call, action))
-
diff --git a/build/android/pylib/utils/mock_calls_test.py b/build/android/pylib/utils/mock_calls_test.py
deleted file mode 100755
index 4dbafd4..0000000
--- a/build/android/pylib/utils/mock_calls_test.py
+++ /dev/null
@@ -1,175 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""
-Unit tests for the contents of mock_calls.py.
-"""
-
-import logging
-import os
-import sys
-import unittest
-
-from pylib import constants
-from pylib.utils import mock_calls
-
-sys.path.append(os.path.join(
- constants.DIR_SOURCE_ROOT, 'third_party', 'pymock'))
-import mock # pylint: disable=F0401
-
-
-class _DummyAdb(object):
- def __str__(self):
- return '0123456789abcdef'
-
- def Push(self, host_path, device_path):
- logging.debug('(device %s) pushing %r to %r', self, host_path, device_path)
-
- def IsOnline(self):
- logging.debug('(device %s) checking device online', self)
- return True
-
- def Shell(self, cmd):
- logging.debug('(device %s) running command %r', self, cmd)
- return "nice output\n"
-
- def Reboot(self):
- logging.debug('(device %s) rebooted!', self)
-
- @property
- def build_version_sdk(self):
- logging.debug('(device %s) getting build_version_sdk', self)
- return constants.ANDROID_SDK_VERSION_CODES.LOLLIPOP
-
-
-class TestCaseWithAssertCallsTest(mock_calls.TestCase):
- def setUp(self):
- self.adb = _DummyAdb()
-
- def ShellError(self):
- def action(cmd):
- raise ValueError('(device %s) command %r is not nice' % (self.adb, cmd))
- return action
-
- def get_answer(self):
- logging.debug("called 'get_answer' of %r object", self)
- return 42
-
- def echo(self, thing):
- logging.debug("called 'echo' of %r object", self)
- return thing
-
- def testCallTarget_succeds(self):
- self.assertEquals(self.adb.Shell,
- self.call_target(self.call.adb.Shell))
-
- def testCallTarget_failsExternal(self):
- with self.assertRaises(ValueError):
- self.call_target(mock.call.sys.getcwd)
-
- def testCallTarget_failsUnknownAttribute(self):
- with self.assertRaises(AttributeError):
- self.call_target(self.call.adb.Run)
-
- def testCallTarget_failsIntermediateCalls(self):
- with self.assertRaises(AttributeError):
- self.call_target(self.call.adb.RunShell('cmd').append)
-
- def testPatchCall_method(self):
- self.assertEquals(42, self.get_answer())
- with self.patch_call(self.call.get_answer, return_value=123):
- self.assertEquals(123, self.get_answer())
- self.assertEquals(42, self.get_answer())
-
- def testPatchCall_attribute_method(self):
- with self.patch_call(self.call.adb.Shell, return_value='hello'):
- self.assertEquals('hello', self.adb.Shell('echo hello'))
-
- def testPatchCall_global(self):
- with self.patch_call(mock.call.os.getcwd, return_value='/some/path'):
- self.assertEquals('/some/path', os.getcwd())
-
- def testPatchCall_withSideEffect(self):
- with self.patch_call(self.call.adb.Shell, side_effect=ValueError):
- with self.assertRaises(ValueError):
- self.adb.Shell('echo hello')
-
- def testPatchCall_property(self):
- self.assertEquals(constants.ANDROID_SDK_VERSION_CODES.LOLLIPOP,
- self.adb.build_version_sdk)
- with self.patch_call(
- self.call.adb.build_version_sdk,
- return_value=constants.ANDROID_SDK_VERSION_CODES.KITKAT):
- self.assertEquals(constants.ANDROID_SDK_VERSION_CODES.KITKAT,
- self.adb.build_version_sdk)
- self.assertEquals(constants.ANDROID_SDK_VERSION_CODES.LOLLIPOP,
- self.adb.build_version_sdk)
-
- def testAssertCalls_succeeds_simple(self):
- self.assertEquals(42, self.get_answer())
- with self.assertCall(self.call.get_answer(), 123):
- self.assertEquals(123, self.get_answer())
- self.assertEquals(42, self.get_answer())
-
- def testAssertCalls_succeeds_multiple(self):
- with self.assertCalls(
- (mock.call.os.getcwd(), '/some/path'),
- (self.call.echo('hello'), 'hello'),
- (self.call.get_answer(), 11),
- self.call.adb.Push('this_file', 'that_file'),
- (self.call.get_answer(), 12)):
- self.assertEquals(os.getcwd(), '/some/path')
- self.assertEquals('hello', self.echo('hello'))
- self.assertEquals(11, self.get_answer())
- self.adb.Push('this_file', 'that_file')
- self.assertEquals(12, self.get_answer())
-
- def testAsserCalls_succeeds_withAction(self):
- with self.assertCall(
- self.call.adb.Shell('echo hello'), self.ShellError()):
- with self.assertRaises(ValueError):
- self.adb.Shell('echo hello')
-
- def testAssertCalls_fails_tooManyCalls(self):
- with self.assertRaises(AssertionError):
- with self.assertCalls(self.call.adb.IsOnline()):
- self.adb.IsOnline()
- self.adb.IsOnline()
-
- def testAssertCalls_fails_tooFewCalls(self):
- with self.assertRaises(AssertionError):
- with self.assertCalls(self.call.adb.IsOnline()):
- pass
-
- def testAssertCalls_succeeds_extraCalls(self):
- # we are not watching Reboot, so the assertion succeeds
- with self.assertCalls(self.call.adb.IsOnline()):
- self.adb.IsOnline()
- self.adb.Reboot()
-
- def testAssertCalls_fails_extraCalls(self):
- self.watchCalls([self.call.adb.Reboot])
- # this time we are also watching Reboot, so the assertion fails
- with self.assertRaises(AssertionError):
- with self.assertCalls(self.call.adb.IsOnline()):
- self.adb.IsOnline()
- self.adb.Reboot()
-
- def testAssertCalls_succeeds_NoCalls(self):
- self.watchMethodCalls(self.call.adb) # we are watching all adb methods
- with self.assertCalls():
- pass
-
- def testAssertCalls_fails_NoCalls(self):
- self.watchMethodCalls(self.call.adb)
- with self.assertRaises(AssertionError):
- with self.assertCalls():
- self.adb.IsOnline()
-
-
-if __name__ == '__main__':
- logging.getLogger().setLevel(logging.DEBUG)
- unittest.main(verbosity=2)
-
diff --git a/build/android/pylib/utils/parallelizer.py b/build/android/pylib/utils/parallelizer.py
deleted file mode 100644
index 9a85b54..0000000
--- a/build/android/pylib/utils/parallelizer.py
+++ /dev/null
@@ -1,242 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-""" Wrapper that allows method execution in parallel.
-
-This class wraps a list of objects of the same type, emulates their
-interface, and executes any functions called on the objects in parallel
-in ReraiserThreads.
-
-This means that, given a list of objects:
-
- class Foo:
- def __init__(self):
- self.baz = Baz()
-
- def bar(self, my_param):
- // do something
-
- list_of_foos = [Foo(1), Foo(2), Foo(3)]
-
-we can take a sequential operation on that list of objects:
-
- for f in list_of_foos:
- f.bar('Hello')
-
-and run it in parallel across all of the objects:
-
- Parallelizer(list_of_foos).bar('Hello')
-
-It can also handle (non-method) attributes of objects, so that this:
-
- for f in list_of_foos:
- f.baz.myBazMethod()
-
-can be run in parallel with:
-
- Parallelizer(list_of_foos).baz.myBazMethod()
-
-Because it emulates the interface of the wrapped objects, a Parallelizer
-can be passed to a method or function that takes objects of that type:
-
- def DoesSomethingWithFoo(the_foo):
- the_foo.bar('Hello')
- the_foo.bar('world')
- the_foo.baz.myBazMethod
-
- DoesSomethingWithFoo(Parallelizer(list_of_foos))
-
-Note that this class spins up a thread for each object. Using this class
-to parallelize operations that are already fast will incur a net performance
-penalty.
-
-"""
-# pylint: disable=protected-access
-
-from pylib.utils import reraiser_thread
-from pylib.utils import watchdog_timer
-
-_DEFAULT_TIMEOUT = 30
-_DEFAULT_RETRIES = 3
-
-
-class Parallelizer(object):
- """Allows parallel execution of method calls across a group of objects."""
-
- def __init__(self, objs):
- assert (objs is not None and len(objs) > 0), (
- "Passed empty list to 'Parallelizer'")
- self._orig_objs = objs
- self._objs = objs
-
- def __getattr__(self, name):
- """Emulate getting the |name| attribute of |self|.
-
- Args:
- name: The name of the attribute to retrieve.
- Returns:
- A Parallelizer emulating the |name| attribute of |self|.
- """
- self.pGet(None)
-
- r = type(self)(self._orig_objs)
- r._objs = [getattr(o, name) for o in self._objs]
- return r
-
- def __getitem__(self, index):
- """Emulate getting the value of |self| at |index|.
-
- Returns:
- A Parallelizer emulating the value of |self| at |index|.
- """
- self.pGet(None)
-
- r = type(self)(self._orig_objs)
- r._objs = [o[index] for o in self._objs]
- return r
-
- def __call__(self, *args, **kwargs):
- """Emulate calling |self| with |args| and |kwargs|.
-
- Note that this call is asynchronous. Call pFinish on the return value to
- block until the call finishes.
-
- Returns:
- A Parallelizer wrapping the ReraiserThreadGroup running the call in
- parallel.
- Raises:
- AttributeError if the wrapped objects aren't callable.
- """
- self.pGet(None)
-
- if not self._objs:
- raise AttributeError('Nothing to call.')
- for o in self._objs:
- if not callable(o):
- raise AttributeError("'%s' is not callable" % o.__name__)
-
- r = type(self)(self._orig_objs)
- r._objs = reraiser_thread.ReraiserThreadGroup(
- [reraiser_thread.ReraiserThread(
- o, args=args, kwargs=kwargs,
- name='%s.%s' % (str(d), o.__name__))
- for d, o in zip(self._orig_objs, self._objs)])
- r._objs.StartAll() # pylint: disable=W0212
- return r
-
- def pFinish(self, timeout):
- """Finish any outstanding asynchronous operations.
-
- Args:
- timeout: The maximum number of seconds to wait for an individual
- result to return, or None to wait forever.
- Returns:
- self, now emulating the return values.
- """
- self._assertNoShadow('pFinish')
- if isinstance(self._objs, reraiser_thread.ReraiserThreadGroup):
- self._objs.JoinAll()
- self._objs = self._objs.GetAllReturnValues(
- watchdog_timer.WatchdogTimer(timeout))
- return self
-
- def pGet(self, timeout):
- """Get the current wrapped objects.
-
- Args:
- timeout: Same as |pFinish|.
- Returns:
- A list of the results, in order of the provided devices.
- Raises:
- Any exception raised by any of the called functions.
- """
- self._assertNoShadow('pGet')
- self.pFinish(timeout)
- return self._objs
-
- def pMap(self, f, *args, **kwargs):
- """Map a function across the current wrapped objects in parallel.
-
- This calls f(o, *args, **kwargs) for each o in the set of wrapped objects.
-
- Note that this call is asynchronous. Call pFinish on the return value to
- block until the call finishes.
-
- Args:
- f: The function to call.
- args: The positional args to pass to f.
- kwargs: The keyword args to pass to f.
- Returns:
- A Parallelizer wrapping the ReraiserThreadGroup running the map in
- parallel.
- """
- self._assertNoShadow('pMap')
- r = type(self)(self._orig_objs)
- r._objs = reraiser_thread.ReraiserThreadGroup(
- [reraiser_thread.ReraiserThread(
- f, args=tuple([o] + list(args)), kwargs=kwargs,
- name='%s(%s)' % (f.__name__, d))
- for d, o in zip(self._orig_objs, self._objs)])
- r._objs.StartAll() # pylint: disable=W0212
- return r
-
- def _assertNoShadow(self, attr_name):
- """Ensures that |attr_name| isn't shadowing part of the wrapped obejcts.
-
- If the wrapped objects _do_ have an |attr_name| attribute, it will be
- inaccessible to clients.
-
- Args:
- attr_name: The attribute to check.
- Raises:
- AssertionError if the wrapped objects have an attribute named 'attr_name'
- or '_assertNoShadow'.
- """
- if isinstance(self._objs, reraiser_thread.ReraiserThreadGroup):
- assert not hasattr(self._objs, '_assertNoShadow')
- assert not hasattr(self._objs, attr_name)
- else:
- assert not any(hasattr(o, '_assertNoShadow') for o in self._objs)
- assert not any(hasattr(o, attr_name) for o in self._objs)
-
-
-class SyncParallelizer(Parallelizer):
- """A Parallelizer that blocks on function calls."""
-
- #override
- def __call__(self, *args, **kwargs):
- """Emulate calling |self| with |args| and |kwargs|.
-
- Note that this call is synchronous.
-
- Returns:
- A Parallelizer emulating the value returned from calling |self| with
- |args| and |kwargs|.
- Raises:
- AttributeError if the wrapped objects aren't callable.
- """
- r = super(SyncParallelizer, self).__call__(*args, **kwargs)
- r.pFinish(None)
- return r
-
- #override
- def pMap(self, f, *args, **kwargs):
- """Map a function across the current wrapped objects in parallel.
-
- This calls f(o, *args, **kwargs) for each o in the set of wrapped objects.
-
- Note that this call is synchronous.
-
- Args:
- f: The function to call.
- args: The positional args to pass to f.
- kwargs: The keyword args to pass to f.
- Returns:
- A Parallelizer wrapping the ReraiserThreadGroup running the map in
- parallel.
- """
- r = super(SyncParallelizer, self).pMap(f, *args, **kwargs)
- r.pFinish(None)
- return r
-
diff --git a/build/android/pylib/utils/parallelizer_test.py b/build/android/pylib/utils/parallelizer_test.py
deleted file mode 100644
index 6e0c7e7..0000000
--- a/build/android/pylib/utils/parallelizer_test.py
+++ /dev/null
@@ -1,166 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Unit tests for the contents of parallelizer.py."""
-
-# pylint: disable=W0212
-# pylint: disable=W0613
-
-import os
-import tempfile
-import time
-import unittest
-
-from pylib.utils import parallelizer
-
-
-class ParallelizerTestObject(object):
- """Class used to test parallelizer.Parallelizer."""
-
- parallel = parallelizer.Parallelizer
-
- def __init__(self, thing, completion_file_name=None):
- self._thing = thing
- self._completion_file_name = completion_file_name
- self.helper = ParallelizerTestObjectHelper(thing)
-
- @staticmethod
- def doReturn(what):
- return what
-
- @classmethod
- def doRaise(cls, what):
- raise what
-
- def doSetTheThing(self, new_thing):
- self._thing = new_thing
-
- def doReturnTheThing(self):
- return self._thing
-
- def doRaiseTheThing(self):
- raise self._thing
-
- def doRaiseIfExceptionElseSleepFor(self, sleep_duration):
- if isinstance(self._thing, Exception):
- raise self._thing
- time.sleep(sleep_duration)
- self._write_completion_file()
- return self._thing
-
- def _write_completion_file(self):
- if self._completion_file_name and len(self._completion_file_name):
- with open(self._completion_file_name, 'w+b') as completion_file:
- completion_file.write('complete')
-
- def __getitem__(self, index):
- return self._thing[index]
-
- def __str__(self):
- return type(self).__name__
-
-
-class ParallelizerTestObjectHelper(object):
-
- def __init__(self, thing):
- self._thing = thing
-
- def doReturnStringThing(self):
- return str(self._thing)
-
-
-class ParallelizerTest(unittest.TestCase):
-
- def testInitWithNone(self):
- with self.assertRaises(AssertionError):
- parallelizer.Parallelizer(None)
-
- def testInitEmptyList(self):
- with self.assertRaises(AssertionError):
- parallelizer.Parallelizer([])
-
- def testMethodCall(self):
- test_data = ['abc_foo', 'def_foo', 'ghi_foo']
- expected = ['abc_bar', 'def_bar', 'ghi_bar']
- r = parallelizer.Parallelizer(test_data).replace('_foo', '_bar').pGet(0.1)
- self.assertEquals(expected, r)
-
- def testMutate(self):
- devices = [ParallelizerTestObject(True) for _ in xrange(0, 10)]
- self.assertTrue(all(d.doReturnTheThing() for d in devices))
- ParallelizerTestObject.parallel(devices).doSetTheThing(False).pFinish(1)
- self.assertTrue(not any(d.doReturnTheThing() for d in devices))
-
- def testAllReturn(self):
- devices = [ParallelizerTestObject(True) for _ in xrange(0, 10)]
- results = ParallelizerTestObject.parallel(
- devices).doReturnTheThing().pGet(1)
- self.assertTrue(isinstance(results, list))
- self.assertEquals(10, len(results))
- self.assertTrue(all(results))
-
- def testAllRaise(self):
- devices = [ParallelizerTestObject(Exception('thing %d' % i))
- for i in xrange(0, 10)]
- p = ParallelizerTestObject.parallel(devices).doRaiseTheThing()
- with self.assertRaises(Exception):
- p.pGet(1)
-
- def testOneFailOthersComplete(self):
- parallel_device_count = 10
- exception_index = 7
- exception_msg = 'thing %d' % exception_index
-
- try:
- completion_files = [tempfile.NamedTemporaryFile(delete=False)
- for _ in xrange(0, parallel_device_count)]
- devices = [
- ParallelizerTestObject(
- i if i != exception_index else Exception(exception_msg),
- completion_files[i].name)
- for i in xrange(0, parallel_device_count)]
- for f in completion_files:
- f.close()
- p = ParallelizerTestObject.parallel(devices)
- with self.assertRaises(Exception) as e:
- p.doRaiseIfExceptionElseSleepFor(2).pGet(3)
- self.assertTrue(exception_msg in str(e.exception))
- for i in xrange(0, parallel_device_count):
- with open(completion_files[i].name) as f:
- if i == exception_index:
- self.assertEquals('', f.read())
- else:
- self.assertEquals('complete', f.read())
- finally:
- for f in completion_files:
- os.remove(f.name)
-
- def testReusable(self):
- devices = [ParallelizerTestObject(True) for _ in xrange(0, 10)]
- p = ParallelizerTestObject.parallel(devices)
- results = p.doReturn(True).pGet(1)
- self.assertTrue(all(results))
- results = p.doReturn(True).pGet(1)
- self.assertTrue(all(results))
- with self.assertRaises(Exception):
- results = p.doRaise(Exception('reusableTest')).pGet(1)
-
- def testContained(self):
- devices = [ParallelizerTestObject(i) for i in xrange(0, 10)]
- results = (ParallelizerTestObject.parallel(devices).helper
- .doReturnStringThing().pGet(1))
- self.assertTrue(isinstance(results, list))
- self.assertEquals(10, len(results))
- for i in xrange(0, 10):
- self.assertEquals(str(i), results[i])
-
- def testGetItem(self):
- devices = [ParallelizerTestObject(range(i, i+10)) for i in xrange(0, 10)]
- results = ParallelizerTestObject.parallel(devices)[9].pGet(1)
- self.assertEquals(range(9, 19), results)
-
-
-if __name__ == '__main__':
- unittest.main(verbosity=2)
-
diff --git a/build/android/pylib/utils/proguard.py b/build/android/pylib/utils/proguard.py
deleted file mode 100644
index 34ad5c3..0000000
--- a/build/android/pylib/utils/proguard.py
+++ /dev/null
@@ -1,148 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import re
-import tempfile
-
-from pylib import constants
-from pylib import cmd_helper
-
-
-_PROGUARD_CLASS_RE = re.compile(r'\s*?- Program class:\s*([\S]+)$')
-_PROGUARD_SUPERCLASS_RE = re.compile(r'\s*? Superclass:\s*([\S]+)$')
-_PROGUARD_SECTION_RE = re.compile(
- r'^(?:Interfaces|Constant Pool|Fields|Methods|Class file attributes) '
- r'\(count = \d+\):$')
-_PROGUARD_METHOD_RE = re.compile(r'\s*?- Method:\s*(\S*)[(].*$')
-_PROGUARD_ANNOTATION_RE = re.compile(r'\s*?- Annotation \[L(\S*);\]:$')
-_PROGUARD_ANNOTATION_CONST_RE = (
- re.compile(r'\s*?- Constant element value.*$'))
-_PROGUARD_ANNOTATION_VALUE_RE = re.compile(r'\s*?- \S+? \[(.*)\]$')
-
-_PROGUARD_PATH_SDK = os.path.join(
- constants.ANDROID_SDK_ROOT, 'tools', 'proguard', 'lib', 'proguard.jar')
-_PROGUARD_PATH_BUILT = (
- os.path.join(os.environ['ANDROID_BUILD_TOP'], 'external', 'proguard',
- 'lib', 'proguard.jar')
- if 'ANDROID_BUILD_TOP' in os.environ else None)
-_PROGUARD_PATH = (
- _PROGUARD_PATH_SDK if os.path.exists(_PROGUARD_PATH_SDK)
- else _PROGUARD_PATH_BUILT)
-
-
-def Dump(jar_path):
- """Dumps class and method information from a JAR into a dict via proguard.
-
- Args:
- jar_path: An absolute path to the JAR file to dump.
- Returns:
- A dict in the following format:
- {
- 'classes': [
- {
- 'class': '',
- 'superclass': '',
- 'annotations': {},
- 'methods': [
- {
- 'method': '',
- 'annotations': {},
- },
- ...
- ],
- },
- ...
- ],
- }
- """
-
- with tempfile.NamedTemporaryFile() as proguard_output:
- cmd_helper.RunCmd(['java', '-jar',
- _PROGUARD_PATH,
- '-injars', jar_path,
- '-dontshrink',
- '-dontoptimize',
- '-dontobfuscate',
- '-dontpreverify',
- '-dump', proguard_output.name])
-
-
- results = {
- 'classes': [],
- }
-
- annotation = None
- annotation_has_value = False
- class_result = None
- method_result = None
-
- for line in proguard_output:
- line = line.strip('\r\n')
-
- m = _PROGUARD_CLASS_RE.match(line)
- if m:
- class_result = {
- 'class': m.group(1).replace('/', '.'),
- 'superclass': '',
- 'annotations': {},
- 'methods': [],
- }
- results['classes'].append(class_result)
- annotation = None
- annotation_has_value = False
- method_result = None
- continue
-
- if not class_result:
- continue
-
- m = _PROGUARD_SUPERCLASS_RE.match(line)
- if m:
- class_result['superclass'] = m.group(1).replace('/', '.')
- continue
-
- m = _PROGUARD_SECTION_RE.match(line)
- if m:
- annotation = None
- annotation_has_value = False
- method_result = None
- continue
-
- m = _PROGUARD_METHOD_RE.match(line)
- if m:
- method_result = {
- 'method': m.group(1),
- 'annotations': {},
- }
- class_result['methods'].append(method_result)
- annotation = None
- annotation_has_value = False
- continue
-
- m = _PROGUARD_ANNOTATION_RE.match(line)
- if m:
- # Ignore the annotation package.
- annotation = m.group(1).split('/')[-1]
- if method_result:
- method_result['annotations'][annotation] = None
- else:
- class_result['annotations'][annotation] = None
- continue
-
- if annotation:
- if not annotation_has_value:
- m = _PROGUARD_ANNOTATION_CONST_RE.match(line)
- annotation_has_value = bool(m)
- else:
- m = _PROGUARD_ANNOTATION_VALUE_RE.match(line)
- if m:
- if method_result:
- method_result['annotations'][annotation] = m.group(1)
- else:
- class_result['annotations'][annotation] = m.group(1)
- annotation_has_value = None
-
- return results
-
diff --git a/build/android/pylib/utils/repo_utils.py b/build/android/pylib/utils/repo_utils.py
deleted file mode 100644
index e0c7d2c..0000000
--- a/build/android/pylib/utils/repo_utils.py
+++ /dev/null
@@ -1,16 +0,0 @@
-# Copyright (c) 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-from pylib import cmd_helper
-
-
-def GetGitHeadSHA1(in_directory):
- """Returns the git hash tag for the given directory.
-
- Args:
- in_directory: The directory where git is to be run.
- """
- command_line = ['git', 'log', '-1', '--pretty=format:%H']
- output = cmd_helper.GetCmdOutput(command_line, cwd=in_directory)
- return output[0:40]
diff --git a/build/android/pylib/utils/reraiser_thread.py b/build/android/pylib/utils/reraiser_thread.py
deleted file mode 100644
index 0ec16b1..0000000
--- a/build/android/pylib/utils/reraiser_thread.py
+++ /dev/null
@@ -1,158 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Thread and ThreadGroup that reraise exceptions on the main thread."""
-# pylint: disable=W0212
-
-import logging
-import sys
-import threading
-import traceback
-
-from pylib.utils import watchdog_timer
-
-
-class TimeoutError(Exception):
- """Module-specific timeout exception."""
- pass
-
-
-def LogThreadStack(thread):
- """Log the stack for the given thread.
-
- Args:
- thread: a threading.Thread instance.
- """
- stack = sys._current_frames()[thread.ident]
- logging.critical('*' * 80)
- logging.critical('Stack dump for thread %r', thread.name)
- logging.critical('*' * 80)
- for filename, lineno, name, line in traceback.extract_stack(stack):
- logging.critical('File: "%s", line %d, in %s', filename, lineno, name)
- if line:
- logging.critical(' %s', line.strip())
- logging.critical('*' * 80)
-
-
-class ReraiserThread(threading.Thread):
- """Thread class that can reraise exceptions."""
-
- def __init__(self, func, args=None, kwargs=None, name=None):
- """Initialize thread.
-
- Args:
- func: callable to call on a new thread.
- args: list of positional arguments for callable, defaults to empty.
- kwargs: dictionary of keyword arguments for callable, defaults to empty.
- name: thread name, defaults to Thread-N.
- """
- super(ReraiserThread, self).__init__(name=name)
- if not args:
- args = []
- if not kwargs:
- kwargs = {}
- self.daemon = True
- self._func = func
- self._args = args
- self._kwargs = kwargs
- self._ret = None
- self._exc_info = None
-
- def ReraiseIfException(self):
- """Reraise exception if an exception was raised in the thread."""
- if self._exc_info:
- raise self._exc_info[0], self._exc_info[1], self._exc_info[2]
-
- def GetReturnValue(self):
- """Reraise exception if present, otherwise get the return value."""
- self.ReraiseIfException()
- return self._ret
-
- #override
- def run(self):
- """Overrides Thread.run() to add support for reraising exceptions."""
- try:
- self._ret = self._func(*self._args, **self._kwargs)
- except: # pylint: disable=W0702
- self._exc_info = sys.exc_info()
-
-
-class ReraiserThreadGroup(object):
- """A group of ReraiserThread objects."""
-
- def __init__(self, threads=None):
- """Initialize thread group.
-
- Args:
- threads: a list of ReraiserThread objects; defaults to empty.
- """
- if not threads:
- threads = []
- self._threads = threads
-
- def Add(self, thread):
- """Add a thread to the group.
-
- Args:
- thread: a ReraiserThread object.
- """
- self._threads.append(thread)
-
- def StartAll(self):
- """Start all threads."""
- for thread in self._threads:
- thread.start()
-
- def _JoinAll(self, watcher=None):
- """Join all threads without stack dumps.
-
- Reraises exceptions raised by the child threads and supports breaking
- immediately on exceptions raised on the main thread.
-
- Args:
- watcher: Watchdog object providing timeout, by default waits forever.
- """
- if watcher is None:
- watcher = watchdog_timer.WatchdogTimer(None)
- alive_threads = self._threads[:]
- while alive_threads:
- for thread in alive_threads[:]:
- if watcher.IsTimedOut():
- raise TimeoutError('Timed out waiting for %d of %d threads.' %
- (len(alive_threads), len(self._threads)))
- # Allow the main thread to periodically check for interrupts.
- thread.join(0.1)
- if not thread.isAlive():
- alive_threads.remove(thread)
- # All threads are allowed to complete before reraising exceptions.
- for thread in self._threads:
- thread.ReraiseIfException()
-
- def JoinAll(self, watcher=None):
- """Join all threads.
-
- Reraises exceptions raised by the child threads and supports breaking
- immediately on exceptions raised on the main thread. Unfinished threads'
- stacks will be logged on watchdog timeout.
-
- Args:
- watcher: Watchdog object providing timeout, by default waits forever.
- """
- try:
- self._JoinAll(watcher)
- except TimeoutError:
- for thread in (t for t in self._threads if t.isAlive()):
- LogThreadStack(thread)
- raise
-
- def GetAllReturnValues(self, watcher=None):
- """Get all return values, joining all threads if necessary.
-
- Args:
- watcher: same as in |JoinAll|. Only used if threads are alive.
- """
- if any([t.isAlive() for t in self._threads]):
- self.JoinAll(watcher)
- return [t.GetReturnValue() for t in self._threads]
-
diff --git a/build/android/pylib/utils/reraiser_thread_unittest.py b/build/android/pylib/utils/reraiser_thread_unittest.py
deleted file mode 100644
index 2392d0e..0000000
--- a/build/android/pylib/utils/reraiser_thread_unittest.py
+++ /dev/null
@@ -1,96 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Unittests for reraiser_thread.py."""
-
-import threading
-import unittest
-
-from pylib.utils import reraiser_thread
-from pylib.utils import watchdog_timer
-
-
-class TestException(Exception):
- pass
-
-
-class TestReraiserThread(unittest.TestCase):
- """Tests for reraiser_thread.ReraiserThread."""
- def testNominal(self):
- result = [None, None]
-
- def f(a, b=None):
- result[0] = a
- result[1] = b
-
- thread = reraiser_thread.ReraiserThread(f, [1], {'b': 2})
- thread.start()
- thread.join()
- self.assertEqual(result[0], 1)
- self.assertEqual(result[1], 2)
-
- def testRaise(self):
- def f():
- raise TestException
-
- thread = reraiser_thread.ReraiserThread(f)
- thread.start()
- thread.join()
- with self.assertRaises(TestException):
- thread.ReraiseIfException()
-
-
-class TestReraiserThreadGroup(unittest.TestCase):
- """Tests for reraiser_thread.ReraiserThreadGroup."""
- def testInit(self):
- ran = [False] * 5
- def f(i):
- ran[i] = True
-
- group = reraiser_thread.ReraiserThreadGroup(
- [reraiser_thread.ReraiserThread(f, args=[i]) for i in range(5)])
- group.StartAll()
- group.JoinAll()
- for v in ran:
- self.assertTrue(v)
-
- def testAdd(self):
- ran = [False] * 5
- def f(i):
- ran[i] = True
-
- group = reraiser_thread.ReraiserThreadGroup()
- for i in xrange(5):
- group.Add(reraiser_thread.ReraiserThread(f, args=[i]))
- group.StartAll()
- group.JoinAll()
- for v in ran:
- self.assertTrue(v)
-
- def testJoinRaise(self):
- def f():
- raise TestException
- group = reraiser_thread.ReraiserThreadGroup(
- [reraiser_thread.ReraiserThread(f) for _ in xrange(5)])
- group.StartAll()
- with self.assertRaises(TestException):
- group.JoinAll()
-
- def testJoinTimeout(self):
- def f():
- pass
- event = threading.Event()
- def g():
- event.wait()
- group = reraiser_thread.ReraiserThreadGroup(
- [reraiser_thread.ReraiserThread(g),
- reraiser_thread.ReraiserThread(f)])
- group.StartAll()
- with self.assertRaises(reraiser_thread.TimeoutError):
- group.JoinAll(watchdog_timer.WatchdogTimer(0.01))
- event.set()
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/build/android/pylib/utils/run_tests_helper.py b/build/android/pylib/utils/run_tests_helper.py
deleted file mode 100644
index 43f654d..0000000
--- a/build/android/pylib/utils/run_tests_helper.py
+++ /dev/null
@@ -1,44 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Helper functions common to native, java and host-driven test runners."""
-
-import logging
-import sys
-import time
-
-
-class CustomFormatter(logging.Formatter):
- """Custom log formatter."""
-
- #override
- def __init__(self, fmt='%(threadName)-4s %(message)s'):
- # Can't use super() because in older Python versions logging.Formatter does
- # not inherit from object.
- logging.Formatter.__init__(self, fmt=fmt)
- self._creation_time = time.time()
-
- #override
- def format(self, record):
- # Can't use super() because in older Python versions logging.Formatter does
- # not inherit from object.
- msg = logging.Formatter.format(self, record)
- if 'MainThread' in msg[:19]:
- msg = msg.replace('MainThread', 'Main', 1)
- timediff = time.time() - self._creation_time
- return '%s %8.3fs %s' % (record.levelname[0], timediff, msg)
-
-
-def SetLogLevel(verbose_count):
- """Sets log level as |verbose_count|."""
- log_level = logging.WARNING # Default.
- if verbose_count == 1:
- log_level = logging.INFO
- elif verbose_count >= 2:
- log_level = logging.DEBUG
- logger = logging.getLogger()
- logger.setLevel(log_level)
- custom_handler = logging.StreamHandler(sys.stdout)
- custom_handler.setFormatter(CustomFormatter())
- logging.getLogger().addHandler(custom_handler)
diff --git a/build/android/pylib/utils/test_environment.py b/build/android/pylib/utils/test_environment.py
deleted file mode 100644
index e78eb5c..0000000
--- a/build/android/pylib/utils/test_environment.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import psutil
-import signal
-
-from pylib.device import device_errors
-from pylib.device import device_utils
-
-
-def _KillWebServers():
- for s in [signal.SIGTERM, signal.SIGINT, signal.SIGQUIT, signal.SIGKILL]:
- signalled = []
- for server in ['lighttpd', 'webpagereplay']:
- for p in psutil.process_iter():
- try:
- if not server in ' '.join(p.cmdline):
- continue
- logging.info('Killing %s %s %s', s, server, p.pid)
- p.send_signal(s)
- signalled.append(p)
- except Exception as e:
- logging.warning('Failed killing %s %s %s', server, p.pid, e)
- for p in signalled:
- try:
- p.wait(1)
- except Exception as e:
- logging.warning('Failed waiting for %s to die. %s', p.pid, e)
-
-
-def CleanupLeftoverProcesses():
- """Clean up the test environment, restarting fresh adb and HTTP daemons."""
- _KillWebServers()
- device_utils.RestartServer()
-
- def cleanup_device(d):
- d.old_interface.RestartAdbdOnDevice()
- try:
- d.EnableRoot()
- except device_errors.CommandFailedError as e:
- logging.error(str(e))
- d.WaitUntilFullyBooted()
-
- device_utils.DeviceUtils.parallel().pMap(cleanup_device)
-
diff --git a/build/android/pylib/utils/time_profile.py b/build/android/pylib/utils/time_profile.py
deleted file mode 100644
index 45da7ff..0000000
--- a/build/android/pylib/utils/time_profile.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright (c) 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import time
-
-
-class TimeProfile(object):
- """Class for simple profiling of action, with logging of cost."""
-
- def __init__(self, description):
- self._starttime = None
- self._description = description
- self.Start()
-
- def Start(self):
- self._starttime = time.time()
-
- def Stop(self):
- """Stop profiling and dump a log."""
- if self._starttime:
- stoptime = time.time()
- logging.info('%fsec to perform %s',
- stoptime - self._starttime, self._description)
- self._starttime = None
diff --git a/build/android/pylib/utils/timeout_retry.py b/build/android/pylib/utils/timeout_retry.py
deleted file mode 100644
index 61f7c70..0000000
--- a/build/android/pylib/utils/timeout_retry.py
+++ /dev/null
@@ -1,167 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""A utility to run functions with timeouts and retries."""
-# pylint: disable=W0702
-
-import logging
-import threading
-import time
-import traceback
-
-from pylib.utils import reraiser_thread
-from pylib.utils import watchdog_timer
-
-
-class TimeoutRetryThread(reraiser_thread.ReraiserThread):
- def __init__(self, func, timeout, name):
- super(TimeoutRetryThread, self).__init__(func, name=name)
- self._watcher = watchdog_timer.WatchdogTimer(timeout)
- self._expired = False
-
- def GetWatcher(self):
- """Returns the watchdog keeping track of this thread's time."""
- return self._watcher
-
- def GetElapsedTime(self):
- return self._watcher.GetElapsed()
-
- def GetRemainingTime(self, required=0, msg=None):
- """Get the remaining time before the thread times out.
-
- Useful to send as the |timeout| parameter of async IO operations.
-
- Args:
- required: minimum amount of time that will be required to complete, e.g.,
- some sleep or IO operation.
- msg: error message to show if timing out.
-
- Returns:
- The number of seconds remaining before the thread times out, or None
- if the thread never times out.
-
- Raises:
- reraiser_thread.TimeoutError if the remaining time is less than the
- required time.
- """
- remaining = self._watcher.GetRemaining()
- if remaining is not None and remaining < required:
- if msg is None:
- msg = 'Timeout expired'
- if remaining > 0:
- msg += (', wait of %.1f secs required but only %.1f secs left'
- % (required, remaining))
- self._expired = True
- raise reraiser_thread.TimeoutError(msg)
- return remaining
-
- def LogTimeoutException(self):
- """Log the exception that terminated this thread."""
- if not self._expired:
- return
- logging.critical('*' * 80)
- logging.critical('%s on thread %r', self._exc_info[0].__name__, self.name)
- logging.critical('*' * 80)
- fmt_exc = ''.join(traceback.format_exception(*self._exc_info))
- for line in fmt_exc.splitlines():
- logging.critical(line.rstrip())
- logging.critical('*' * 80)
-
-
-def CurrentTimeoutThread():
- """Get the current thread if it is a TimeoutRetryThread.
-
- Returns:
- The current thread if it is a TimeoutRetryThread, otherwise None.
- """
- current_thread = threading.current_thread()
- if isinstance(current_thread, TimeoutRetryThread):
- return current_thread
- else:
- return None
-
-
-def WaitFor(condition, wait_period=5, max_tries=None):
- """Wait for a condition to become true.
-
- Repeadly call the function condition(), with no arguments, until it returns
- a true value.
-
- If called within a TimeoutRetryThread, it cooperates nicely with it.
-
- Args:
- condition: function with the condition to check
- wait_period: number of seconds to wait before retrying to check the
- condition
- max_tries: maximum number of checks to make, the default tries forever
- or until the TimeoutRetryThread expires.
-
- Returns:
- The true value returned by the condition, or None if the condition was
- not met after max_tries.
-
- Raises:
- reraiser_thread.TimeoutError if the current thread is a TimeoutRetryThread
- and the timeout expires.
- """
- condition_name = condition.__name__
- timeout_thread = CurrentTimeoutThread()
- while max_tries is None or max_tries > 0:
- result = condition()
- if max_tries is not None:
- max_tries -= 1
- msg = ['condition', repr(condition_name), 'met' if result else 'not met']
- if timeout_thread:
- msg.append('(%.1fs)' % timeout_thread.GetElapsedTime())
- logging.info(' '.join(msg))
- if result:
- return result
- if timeout_thread:
- timeout_thread.GetRemainingTime(wait_period,
- msg='Timed out waiting for %r' % condition_name)
- time.sleep(wait_period)
- return None
-
-
-def Run(func, timeout, retries, args=None, kwargs=None):
- """Runs the passed function in a separate thread with timeouts and retries.
-
- Args:
- func: the function to be wrapped.
- timeout: the timeout in seconds for each try.
- retries: the number of retries.
- args: list of positional args to pass to |func|.
- kwargs: dictionary of keyword args to pass to |func|.
-
- Returns:
- The return value of func(*args, **kwargs).
- """
- if not args:
- args = []
- if not kwargs:
- kwargs = {}
-
- # The return value uses a list because Python variables are references, not
- # values. Closures make a copy of the reference, so updating the closure's
- # reference wouldn't update where the original reference pointed.
- ret = [None]
- def RunOnTimeoutThread():
- ret[0] = func(*args, **kwargs)
-
- num_try = 1
- while True:
- child_thread = TimeoutRetryThread(
- RunOnTimeoutThread, timeout,
- name='TimeoutThread-%d-for-%s' % (num_try,
- threading.current_thread().name))
- try:
- thread_group = reraiser_thread.ReraiserThreadGroup([child_thread])
- thread_group.StartAll()
- thread_group.JoinAll(child_thread.GetWatcher())
- return ret[0]
- except:
- child_thread.LogTimeoutException()
- if num_try > retries:
- raise
- num_try += 1
diff --git a/build/android/pylib/utils/timeout_retry_unittest.py b/build/android/pylib/utils/timeout_retry_unittest.py
deleted file mode 100644
index dc36c42..0000000
--- a/build/android/pylib/utils/timeout_retry_unittest.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Unittests for timeout_and_retry.py."""
-
-import unittest
-
-from pylib.utils import reraiser_thread
-from pylib.utils import timeout_retry
-
-
-class TestException(Exception):
- pass
-
-
-def _NeverEnding(tries):
- tries[0] += 1
- while True:
- pass
-
-
-def _CountTries(tries):
- tries[0] += 1
- raise TestException
-
-
-class TestRun(unittest.TestCase):
- """Tests for timeout_retry.Run."""
-
- def testRun(self):
- self.assertTrue(timeout_retry.Run(
- lambda x: x, 30, 3, [True], {}))
-
- def testTimeout(self):
- tries = [0]
- self.assertRaises(reraiser_thread.TimeoutError,
- timeout_retry.Run, lambda: _NeverEnding(tries), 0, 3)
- self.assertEqual(tries[0], 4)
-
- def testRetries(self):
- tries = [0]
- self.assertRaises(TestException,
- timeout_retry.Run, lambda: _CountTries(tries), 30, 3)
- self.assertEqual(tries[0], 4)
-
- def testReturnValue(self):
- self.assertTrue(timeout_retry.Run(lambda: True, 30, 3))
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/build/android/pylib/utils/watchdog_timer.py b/build/android/pylib/utils/watchdog_timer.py
deleted file mode 100644
index 2f4c464..0000000
--- a/build/android/pylib/utils/watchdog_timer.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""WatchdogTimer timeout objects."""
-
-import time
-
-
-class WatchdogTimer(object):
- """A resetable timeout-based watchdog.
-
- This object is threadsafe.
- """
-
- def __init__(self, timeout):
- """Initializes the watchdog.
-
- Args:
- timeout: The timeout in seconds. If timeout is None it will never timeout.
- """
- self._start_time = time.time()
- self._timeout = timeout
-
- def Reset(self):
- """Resets the timeout countdown."""
- self._start_time = time.time()
-
- def GetElapsed(self):
- """Returns the elapsed time of the watchdog."""
- return time.time() - self._start_time
-
- def GetRemaining(self):
- """Returns the remaining time of the watchdog."""
- if self._timeout:
- return self._timeout - self.GetElapsed()
- else:
- return None
-
- def IsTimedOut(self):
- """Whether the watchdog has timed out.
-
- Returns:
- True if the watchdog has timed out, False otherwise.
- """
- remaining = self.GetRemaining()
- return remaining is not None and remaining < 0
diff --git a/build/android/pylib/utils/xvfb.py b/build/android/pylib/utils/xvfb.py
deleted file mode 100644
index cb9d50e..0000000
--- a/build/android/pylib/utils/xvfb.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# Copyright (c) 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# pylint: disable=W0702
-
-import os
-import signal
-import subprocess
-import sys
-import time
-
-
-def _IsLinux():
- """Return True if on Linux; else False."""
- return sys.platform.startswith('linux')
-
-
-class Xvfb(object):
- """Class to start and stop Xvfb if relevant. Nop if not Linux."""
-
- def __init__(self):
- self._pid = 0
-
- def Start(self):
- """Start Xvfb and set an appropriate DISPLAY environment. Linux only.
-
- Copied from tools/code_coverage/coverage_posix.py
- """
- if not _IsLinux():
- return
- proc = subprocess.Popen(['Xvfb', ':9', '-screen', '0', '1024x768x24',
- '-ac'],
- stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
- self._pid = proc.pid
- if not self._pid:
- raise Exception('Could not start Xvfb')
- os.environ['DISPLAY'] = ':9'
-
- # Now confirm, giving a chance for it to start if needed.
- for _ in range(10):
- proc = subprocess.Popen('xdpyinfo >/dev/null', shell=True)
- _, retcode = os.waitpid(proc.pid, 0)
- if retcode == 0:
- break
- time.sleep(0.25)
- if retcode != 0:
- raise Exception('Could not confirm Xvfb happiness')
-
- def Stop(self):
- """Stop Xvfb if needed. Linux only."""
- if self._pid:
- try:
- os.kill(self._pid, signal.SIGKILL)
- except:
- pass
- del os.environ['DISPLAY']
- self._pid = 0
diff --git a/build/android/pylib/utils/zip_utils.py b/build/android/pylib/utils/zip_utils.py
deleted file mode 100644
index d799463..0000000
--- a/build/android/pylib/utils/zip_utils.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import logging
-import os
-import zipfile
-
-
-def WriteToZipFile(zip_file, path, arc_path):
- """Recursively write |path| to |zip_file| as |arc_path|.
-
- zip_file: An open instance of zipfile.ZipFile.
- path: An absolute path to the file or directory to be zipped.
- arc_path: A relative path within the zip file to which the file or directory
- located at |path| should be written.
- """
- if os.path.isdir(path):
- for dir_path, _, file_names in os.walk(path):
- dir_arc_path = os.path.join(arc_path, os.path.relpath(dir_path, path))
- logging.debug('dir: %s -> %s', dir_path, dir_arc_path)
- zip_file.write(dir_path, dir_arc_path, zipfile.ZIP_STORED)
- for f in file_names:
- file_path = os.path.join(dir_path, f)
- file_arc_path = os.path.join(dir_arc_path, f)
- logging.debug('file: %s -> %s', file_path, file_arc_path)
- zip_file.write(file_path, file_arc_path, zipfile.ZIP_DEFLATED)
- else:
- logging.debug('file: %s -> %s', path, arc_path)
- zip_file.write(path, arc_path, zipfile.ZIP_DEFLATED)
-
diff --git a/build/android/pylib/valgrind_tools.py b/build/android/pylib/valgrind_tools.py
deleted file mode 100644
index 99719d0..0000000
--- a/build/android/pylib/valgrind_tools.py
+++ /dev/null
@@ -1,304 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""
-Classes in this file define additional actions that need to be taken to run a
-test under some kind of runtime error detection tool.
-
-The interface is intended to be used as follows.
-
-1. For tests that simply run a native process (i.e. no activity is spawned):
-
-Call tool.CopyFiles(device).
-Prepend test command line with tool.GetTestWrapper().
-
-2. For tests that spawn an activity:
-
-Call tool.CopyFiles(device).
-Call tool.SetupEnvironment().
-Run the test as usual.
-Call tool.CleanUpEnvironment().
-"""
-# pylint: disable=R0201
-
-import glob
-import logging
-import os.path
-import subprocess
-import sys
-
-from pylib.constants import DIR_SOURCE_ROOT
-from pylib.device import device_errors
-
-
-def SetChromeTimeoutScale(device, scale):
- """Sets the timeout scale in /data/local/tmp/chrome_timeout_scale to scale."""
- path = '/data/local/tmp/chrome_timeout_scale'
- if not scale or scale == 1.0:
- # Delete if scale is None/0.0/1.0 since the default timeout scale is 1.0
- device.RunShellCommand('rm %s' % path)
- else:
- device.WriteFile(path, '%f' % scale, as_root=True)
-
-
-class BaseTool(object):
- """A tool that does nothing."""
-
- def __init__(self):
- """Does nothing."""
- pass
-
- def GetTestWrapper(self):
- """Returns a string that is to be prepended to the test command line."""
- return ''
-
- def GetUtilWrapper(self):
- """Returns the wrapper name for the utilities.
-
- Returns:
- A string that is to be prepended to the command line of utility
- processes (forwarder, etc.).
- """
- return ''
-
- @classmethod
- def CopyFiles(cls, device):
- """Copies tool-specific files to the device, create directories, etc."""
- pass
-
- def SetupEnvironment(self):
- """Sets up the system environment for a test.
-
- This is a good place to set system properties.
- """
- pass
-
- def CleanUpEnvironment(self):
- """Cleans up environment."""
- pass
-
- def GetTimeoutScale(self):
- """Returns a multiplier that should be applied to timeout values."""
- return 1.0
-
- def NeedsDebugInfo(self):
- """Whether this tool requires debug info.
-
- Returns:
- True if this tool can not work with stripped binaries.
- """
- return False
-
-
-class AddressSanitizerTool(BaseTool):
- """AddressSanitizer tool."""
-
- WRAPPER_NAME = '/system/bin/asanwrapper'
- # Disable memcmp overlap check.There are blobs (gl drivers)
- # on some android devices that use memcmp on overlapping regions,
- # nothing we can do about that.
- EXTRA_OPTIONS = 'strict_memcmp=0,use_sigaltstack=1'
-
- def __init__(self, device):
- super(AddressSanitizerTool, self).__init__()
- self._device = device
- # Configure AndroidCommands to run utils (such as md5sum_bin) under ASan.
- # This is required because ASan is a compiler-based tool, and md5sum
- # includes instrumented code from base.
- device.old_interface.SetUtilWrapper(self.GetUtilWrapper())
-
- @classmethod
- def CopyFiles(cls, device):
- """Copies ASan tools to the device."""
- libs = glob.glob(os.path.join(DIR_SOURCE_ROOT,
- 'third_party/llvm-build/Release+Asserts/',
- 'lib/clang/*/lib/linux/',
- 'libclang_rt.asan-arm-android.so'))
- assert len(libs) == 1
- subprocess.call(
- [os.path.join(
- DIR_SOURCE_ROOT,
- 'tools/android/asan/third_party/asan_device_setup.sh'),
- '--device', str(device),
- '--lib', libs[0],
- '--extra-options', AddressSanitizerTool.EXTRA_OPTIONS])
- device.WaitUntilFullyBooted()
-
- def GetTestWrapper(self):
- return AddressSanitizerTool.WRAPPER_NAME
-
- def GetUtilWrapper(self):
- """Returns the wrapper for utilities, such as forwarder.
-
- AddressSanitizer wrapper must be added to all instrumented binaries,
- including forwarder and the like. This can be removed if such binaries
- were built without instrumentation. """
- return self.GetTestWrapper()
-
- def SetupEnvironment(self):
- try:
- self._device.EnableRoot()
- except device_errors.CommandFailedError as e:
- # Try to set the timeout scale anyway.
- # TODO(jbudorick) Handle this exception appropriately after interface
- # conversions are finished.
- logging.error(str(e))
- SetChromeTimeoutScale(self._device, self.GetTimeoutScale())
-
- def CleanUpEnvironment(self):
- SetChromeTimeoutScale(self._device, None)
-
- def GetTimeoutScale(self):
- # Very slow startup.
- return 20.0
-
-
-class ValgrindTool(BaseTool):
- """Base abstract class for Valgrind tools."""
-
- VG_DIR = '/data/local/tmp/valgrind'
- VGLOGS_DIR = '/data/local/tmp/vglogs'
-
- def __init__(self, device):
- super(ValgrindTool, self).__init__()
- self._device = device
- # exactly 31 chars, SystemProperties::PROP_NAME_MAX
- self._wrap_properties = ['wrap.com.google.android.apps.ch',
- 'wrap.org.chromium.native_test']
-
- @classmethod
- def CopyFiles(cls, device):
- """Copies Valgrind tools to the device."""
- device.RunShellCommand(
- 'rm -r %s; mkdir %s' % (ValgrindTool.VG_DIR, ValgrindTool.VG_DIR))
- device.RunShellCommand(
- 'rm -r %s; mkdir %s' % (ValgrindTool.VGLOGS_DIR,
- ValgrindTool.VGLOGS_DIR))
- files = cls.GetFilesForTool()
- device.PushChangedFiles(
- [((os.path.join(DIR_SOURCE_ROOT, f),
- os.path.join(ValgrindTool.VG_DIR, os.path.basename(f)))
- for f in files)])
-
- def SetupEnvironment(self):
- """Sets up device environment."""
- self._device.RunShellCommand('chmod 777 /data/local/tmp')
- self._device.RunShellCommand('setenforce 0')
- for prop in self._wrap_properties:
- self._device.RunShellCommand(
- 'setprop %s "logwrapper %s"' % (prop, self.GetTestWrapper()))
- SetChromeTimeoutScale(self._device, self.GetTimeoutScale())
-
- def CleanUpEnvironment(self):
- """Cleans up device environment."""
- for prop in self._wrap_properties:
- self._device.RunShellCommand('setprop %s ""' % (prop,))
- SetChromeTimeoutScale(self._device, None)
-
- @staticmethod
- def GetFilesForTool():
- """Returns a list of file names for the tool."""
- raise NotImplementedError()
-
- def NeedsDebugInfo(self):
- """Whether this tool requires debug info.
-
- Returns:
- True if this tool can not work with stripped binaries.
- """
- return True
-
-
-class MemcheckTool(ValgrindTool):
- """Memcheck tool."""
-
- def __init__(self, device):
- super(MemcheckTool, self).__init__(device)
-
- @staticmethod
- def GetFilesForTool():
- """Returns a list of file names for the tool."""
- return ['tools/valgrind/android/vg-chrome-wrapper.sh',
- 'tools/valgrind/memcheck/suppressions.txt',
- 'tools/valgrind/memcheck/suppressions_android.txt']
-
- def GetTestWrapper(self):
- """Returns a string that is to be prepended to the test command line."""
- return ValgrindTool.VG_DIR + '/' + 'vg-chrome-wrapper.sh'
-
- def GetTimeoutScale(self):
- """Returns a multiplier that should be applied to timeout values."""
- return 30
-
-
-class TSanTool(ValgrindTool):
- """ThreadSanitizer tool. See http://code.google.com/p/data-race-test ."""
-
- def __init__(self, device):
- super(TSanTool, self).__init__(device)
-
- @staticmethod
- def GetFilesForTool():
- """Returns a list of file names for the tool."""
- return ['tools/valgrind/android/vg-chrome-wrapper-tsan.sh',
- 'tools/valgrind/tsan/suppressions.txt',
- 'tools/valgrind/tsan/suppressions_android.txt',
- 'tools/valgrind/tsan/ignores.txt']
-
- def GetTestWrapper(self):
- """Returns a string that is to be prepended to the test command line."""
- return ValgrindTool.VG_DIR + '/' + 'vg-chrome-wrapper-tsan.sh'
-
- def GetTimeoutScale(self):
- """Returns a multiplier that should be applied to timeout values."""
- return 30.0
-
-
-TOOL_REGISTRY = {
- 'memcheck': MemcheckTool,
- 'memcheck-renderer': MemcheckTool,
- 'tsan': TSanTool,
- 'tsan-renderer': TSanTool,
- 'asan': AddressSanitizerTool,
-}
-
-
-def CreateTool(tool_name, device):
- """Creates a tool with the specified tool name.
-
- Args:
- tool_name: Name of the tool to create.
- device: A DeviceUtils instance.
- Returns:
- A tool for the specified tool_name.
- """
- if not tool_name:
- return BaseTool()
-
- ctor = TOOL_REGISTRY.get(tool_name)
- if ctor:
- return ctor(device)
- else:
- print 'Unknown tool %s, available tools: %s' % (
- tool_name, ', '.join(sorted(TOOL_REGISTRY.keys())))
- sys.exit(1)
-
-def PushFilesForTool(tool_name, device):
- """Pushes the files required for |tool_name| to |device|.
-
- Args:
- tool_name: Name of the tool to create.
- device: A DeviceUtils instance.
- """
- if not tool_name:
- return
-
- clazz = TOOL_REGISTRY.get(tool_name)
- if clazz:
- clazz.CopyFiles(device)
- else:
- print 'Unknown tool %s, available tools: %s' % (
- tool_name, ', '.join(sorted(TOOL_REGISTRY.keys())))
- sys.exit(1)
-
diff --git a/build/android/rezip.gyp b/build/android/rezip.gyp
deleted file mode 100644
index 1115177..0000000
--- a/build/android/rezip.gyp
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# Build the rezip build tool.
-{
- 'targets': [
- {
- # GN: //build/android/rezip:rezip
- 'target_name': 'rezip_apk_jar',
- 'type': 'none',
- 'variables': {
- 'java_in_dir': 'rezip',
- 'compile_stamp': '<(SHARED_INTERMEDIATE_DIR)/<(_target_name)/compile.stamp',
- 'javac_jar_path': '<(PRODUCT_DIR)/lib.java/rezip_apk.jar',
- },
- 'actions': [
- {
- 'action_name': 'javac_<(_target_name)',
- 'message': 'Compiling <(_target_name) java sources',
- 'variables': {
- 'java_sources': ['>!@(find >(java_in_dir) -name "*.java")'],
- },
- 'inputs': [
- '<(DEPTH)/build/android/gyp/util/build_utils.py',
- '<(DEPTH)/build/android/gyp/javac.py',
- '>@(java_sources)',
- ],
- 'outputs': [
- '<(compile_stamp)',
- '<(javac_jar_path)',
- ],
- 'action': [
- 'python', '<(DEPTH)/build/android/gyp/javac.py',
- '--classpath=',
- '--classes-dir=<(SHARED_INTERMEDIATE_DIR)/<(_target_name)',
- '--jar-path=<(javac_jar_path)',
- '--stamp=<(compile_stamp)',
- '>@(java_sources)',
- ]
- },
- ],
- }
- ],
-}
diff --git a/build/android/rezip/BUILD.gn b/build/android/rezip/BUILD.gn
deleted file mode 100644
index 8b8f78e..0000000
--- a/build/android/rezip/BUILD.gn
+++ /dev/null
@@ -1,11 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/config/android/rules.gni")
-
-# GYP: //build/android/rezip.gyp:rezip_apk_jar
-java_library("rezip") {
- jar_path = "$root_build_dir/lib.java/rezip_apk.jar"
- DEPRECATED_java_in_dir = "."
-}
diff --git a/build/android/rezip/RezipApk.java b/build/android/rezip/RezipApk.java
deleted file mode 100644
index 43d7544..0000000
--- a/build/android/rezip/RezipApk.java
+++ /dev/null
@@ -1,448 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.jar.JarEntry;
-import java.util.jar.JarFile;
-import java.util.jar.JarOutputStream;
-import java.util.regex.Pattern;
-import java.util.zip.CRC32;
-
-/**
- * Command line tool used to build APKs which support loading the native code library
- * directly from the APK file. To construct the APK we rename the native library by
- * adding the prefix "crazy." to the filename. This is done to prevent the Android
- * Package Manager from extracting the library. The native code must be page aligned
- * and uncompressed. The page alignment is implemented by adding a zero filled file
- * in front of the the native code library. This tool is designed so that running
- * SignApk and/or zipalign on the resulting APK does not break the page alignment.
- * This is achieved by outputing the filenames in the same canonical order used
- * by SignApk and adding the same alignment fields added by zipalign.
- */
-class RezipApk {
- // Alignment to use for non-compressed files (must match zipalign).
- private static final int ALIGNMENT = 4;
-
- // Alignment to use for non-compressed *.so files
- private static final int LIBRARY_ALIGNMENT = 4096;
-
- // Files matching this pattern are not copied to the output when adding alignment.
- // When reordering and verifying the APK they are copied to the end of the file.
- private static Pattern sMetaFilePattern =
- Pattern.compile("^(META-INF/((.*)[.](SF|RSA|DSA)|com/android/otacert))|("
- + Pattern.quote(JarFile.MANIFEST_NAME) + ")$");
-
- // Pattern for matching a shared library in the APK
- private static Pattern sLibraryPattern = Pattern.compile("^lib/[^/]*/lib.*[.]so$");
- // Pattern for match the crazy linker in the APK
- private static Pattern sCrazyLinkerPattern =
- Pattern.compile("^lib/[^/]*/libchromium_android_linker.so$");
- // Pattern for matching a crazy loaded shared library in the APK
- private static Pattern sCrazyLibraryPattern = Pattern.compile("^lib/[^/]*/crazy.lib.*[.]so$");
-
- private static boolean isLibraryFilename(String filename) {
- return sLibraryPattern.matcher(filename).matches()
- && !sCrazyLinkerPattern.matcher(filename).matches();
- }
-
- private static boolean isCrazyLibraryFilename(String filename) {
- return sCrazyLibraryPattern.matcher(filename).matches();
- }
-
- private static String renameLibraryForCrazyLinker(String filename) {
- int lastSlash = filename.lastIndexOf('/');
- // We rename the library, so that the Android Package Manager
- // no longer extracts the library.
- return filename.substring(0, lastSlash + 1) + "crazy." + filename.substring(lastSlash + 1);
- }
-
- /**
- * Wraps another output stream, counting the number of bytes written.
- */
- private static class CountingOutputStream extends OutputStream {
- private long mCount = 0;
- private OutputStream mOut;
-
- public CountingOutputStream(OutputStream out) {
- this.mOut = out;
- }
-
- /** Returns the number of bytes written. */
- public long getCount() {
- return mCount;
- }
-
- @Override public void write(byte[] b, int off, int len) throws IOException {
- mOut.write(b, off, len);
- mCount += len;
- }
-
- @Override public void write(int b) throws IOException {
- mOut.write(b);
- mCount++;
- }
-
- @Override public void close() throws IOException {
- mOut.close();
- }
-
- @Override public void flush() throws IOException {
- mOut.flush();
- }
- }
-
- private static String outputName(JarEntry entry, boolean rename) {
- String inName = entry.getName();
- if (rename && entry.getSize() > 0 && isLibraryFilename(inName)) {
- return renameLibraryForCrazyLinker(inName);
- }
- return inName;
- }
-
- /**
- * Comparator used to sort jar entries from the input file.
- * Sorting is done based on the output filename (which maybe renamed).
- * Filenames are in natural string order, except that filenames matching
- * the meta-file pattern are always after other files. This is so the manifest
- * and signature are at the end of the file after any alignment file.
- */
- private static class EntryComparator implements Comparator<JarEntry> {
- private boolean mRename;
-
- public EntryComparator(boolean rename) {
- mRename = rename;
- }
-
- @Override
- public int compare(JarEntry j1, JarEntry j2) {
- String o1 = outputName(j1, mRename);
- String o2 = outputName(j2, mRename);
- boolean o1Matches = sMetaFilePattern.matcher(o1).matches();
- boolean o2Matches = sMetaFilePattern.matcher(o2).matches();
- if (o1Matches != o2Matches) {
- return o1Matches ? 1 : -1;
- } else {
- return o1.compareTo(o2);
- }
- }
- }
-
- // Build an ordered list of jar entries. The jar entries from the input are
- // sorted based on the output filenames (which maybe renamed). If |omitMetaFiles|
- // is true do not include the jar entries for the META-INF files.
- // Entries are ordered in the deterministic order used by SignApk.
- private static List<JarEntry> getOutputFileOrderEntries(
- JarFile jar, boolean omitMetaFiles, boolean rename) {
- List<JarEntry> entries = new ArrayList<JarEntry>();
- for (Enumeration<JarEntry> e = jar.entries(); e.hasMoreElements(); ) {
- JarEntry entry = e.nextElement();
- if (entry.isDirectory()) {
- continue;
- }
- if (omitMetaFiles && sMetaFilePattern.matcher(entry.getName()).matches()) {
- continue;
- }
- entries.add(entry);
- }
-
- // We sort the input entries by name. When present META-INF files
- // are sorted to the end.
- Collections.sort(entries, new EntryComparator(rename));
- return entries;
- }
-
- /**
- * Add a zero filled alignment file at this point in the zip file,
- * The added file will be added before |name| and after |prevName|.
- * The size of the alignment file is such that the location of the
- * file |name| will be on a LIBRARY_ALIGNMENT boundary.
- *
- * Note this arrangement is devised so that running SignApk and/or zipalign on the resulting
- * file will not alter the alignment.
- *
- * @param offset number of bytes into the output file at this point.
- * @param timestamp time in millis since the epoch to include in the header.
- * @param name the name of the library filename.
- * @param prevName the name of the previous file in the archive (or null).
- * @param out jar output stream to write the alignment file to.
- *
- * @throws IOException if the output file can not be written.
- */
- private static void addAlignmentFile(
- long offset, long timestamp, String name, String prevName,
- JarOutputStream out) throws IOException {
-
- // Compute the start and alignment of the library, as if it was next.
- int headerSize = JarFile.LOCHDR + name.length();
- long libOffset = offset + headerSize;
- int libNeeded = LIBRARY_ALIGNMENT - (int) (libOffset % LIBRARY_ALIGNMENT);
- if (libNeeded == LIBRARY_ALIGNMENT) {
- // Already aligned, no need to added alignment file.
- return;
- }
-
- // Check that there is not another file between the library and the
- // alignment file.
- String alignName = name.substring(0, name.length() - 2) + "align";
- if (prevName != null && prevName.compareTo(alignName) >= 0) {
- throw new UnsupportedOperationException(
- "Unable to insert alignment file, because there is "
- + "another file in front of the file to be aligned. "
- + "Other file: " + prevName + " Alignment file: " + alignName
- + " file: " + name);
- }
-
- // Compute the size of the alignment file header.
- headerSize = JarFile.LOCHDR + alignName.length();
- // We are going to add an alignment file of type STORED. This file
- // will itself induce a zipalign alignment adjustment.
- int extraNeeded =
- (ALIGNMENT - (int) ((offset + headerSize) % ALIGNMENT)) % ALIGNMENT;
- headerSize += extraNeeded;
-
- if (libNeeded < headerSize + 1) {
- // The header was bigger than the alignment that we need, add another page.
- libNeeded += LIBRARY_ALIGNMENT;
- }
- // Compute the size of the alignment file.
- libNeeded -= headerSize;
-
- // Build the header for the alignment file.
- byte[] zeroBuffer = new byte[libNeeded];
- JarEntry alignEntry = new JarEntry(alignName);
- alignEntry.setMethod(JarEntry.STORED);
- alignEntry.setSize(libNeeded);
- alignEntry.setTime(timestamp);
- CRC32 crc = new CRC32();
- crc.update(zeroBuffer);
- alignEntry.setCrc(crc.getValue());
-
- if (extraNeeded != 0) {
- alignEntry.setExtra(new byte[extraNeeded]);
- }
-
- // Output the alignment file.
- out.putNextEntry(alignEntry);
- out.write(zeroBuffer);
- out.closeEntry();
- out.flush();
- }
-
- // Make a JarEntry for the output file which corresponds to the input
- // file. The output file will be called |name|. The output file will always
- // be uncompressed (STORED). If the input is not STORED it is necessary to inflate
- // it to compute the CRC and size of the output entry.
- private static JarEntry makeStoredEntry(String name, JarEntry inEntry, JarFile in)
- throws IOException {
- JarEntry outEntry = new JarEntry(name);
- outEntry.setMethod(JarEntry.STORED);
-
- if (inEntry.getMethod() == JarEntry.STORED) {
- outEntry.setCrc(inEntry.getCrc());
- outEntry.setSize(inEntry.getSize());
- } else {
- // We are inflating the file. We need to compute the CRC and size.
- byte[] buffer = new byte[4096];
- CRC32 crc = new CRC32();
- int size = 0;
- int num;
- InputStream data = in.getInputStream(inEntry);
- while ((num = data.read(buffer)) > 0) {
- crc.update(buffer, 0, num);
- size += num;
- }
- data.close();
- outEntry.setCrc(crc.getValue());
- outEntry.setSize(size);
- }
- return outEntry;
- }
-
- /**
- * Copy the contents of the input APK file to the output APK file. If |rename| is
- * true then non-empty libraries (*.so) in the input will be renamed by prefixing
- * "crazy.". This is done to prevent the Android Package Manager extracting the
- * library. Note the crazy linker itself is not renamed, for bootstrapping reasons.
- * Empty libraries are not renamed (they are in the APK to workaround a bug where
- * the Android Package Manager fails to delete old versions when upgrading).
- * There must be exactly one "crazy" library in the output stream. The "crazy"
- * library will be uncompressed and page aligned in the output stream. Page
- * alignment is implemented by adding a zero filled file, regular alignment is
- * implemented by adding a zero filled extra field to the zip file header. If
- * |addAlignment| is true a page alignment file is added, otherwise the "crazy"
- * library must already be page aligned. Care is taken so that the output is generated
- * in the same way as SignApk. This is important so that running SignApk and
- * zipalign on the output does not break the page alignment. The archive may not
- * contain a "*.apk" as SignApk has special nested signing logic that we do not
- * support.
- *
- * @param in The input APK File.
- * @param out The output APK stream.
- * @param countOut Counting output stream (to measure the current offset).
- * @param addAlignment Whether to add the alignment file or just check.
- * @param rename Whether to rename libraries to be "crazy".
- *
- * @throws IOException if the output file can not be written.
- */
- private static void rezip(
- JarFile in, JarOutputStream out, CountingOutputStream countOut,
- boolean addAlignment, boolean rename) throws IOException {
-
- List<JarEntry> entries = getOutputFileOrderEntries(in, addAlignment, rename);
- long timestamp = System.currentTimeMillis();
- byte[] buffer = new byte[4096];
- boolean firstEntry = true;
- String prevName = null;
- int numCrazy = 0;
- for (JarEntry inEntry : entries) {
- // Rename files, if specied.
- String name = outputName(inEntry, rename);
- if (name.endsWith(".apk")) {
- throw new UnsupportedOperationException(
- "Nested APKs are not supported: " + name);
- }
-
- // Build the header.
- JarEntry outEntry = null;
- boolean isCrazy = isCrazyLibraryFilename(name);
- if (isCrazy) {
- // "crazy" libraries are alway output uncompressed (STORED).
- outEntry = makeStoredEntry(name, inEntry, in);
- numCrazy++;
- if (numCrazy > 1) {
- throw new UnsupportedOperationException(
- "Found more than one library\n"
- + "Multiple libraries are not supported for APKs that use "
- + "'load_library_from_zip'.\n"
- + "See crbug/388223.\n"
- + "Note, check that your build is clean.\n"
- + "An unclean build can incorrectly incorporate old "
- + "libraries in the APK.");
- }
- } else if (inEntry.getMethod() == JarEntry.STORED) {
- // Preserve the STORED method of the input entry.
- outEntry = new JarEntry(inEntry);
- outEntry.setExtra(null);
- } else {
- // Create a new entry so that the compressed len is recomputed.
- outEntry = new JarEntry(name);
- }
- outEntry.setTime(timestamp);
-
- // Compute and add alignment
- long offset = countOut.getCount();
- if (firstEntry) {
- // The first entry in a jar file has an extra field of
- // four bytes that you can't get rid of; any extra
- // data you specify in the JarEntry is appended to
- // these forced four bytes. This is JAR_MAGIC in
- // JarOutputStream; the bytes are 0xfeca0000.
- firstEntry = false;
- offset += 4;
- }
- if (outEntry.getMethod() == JarEntry.STORED) {
- if (isCrazy) {
- if (addAlignment) {
- addAlignmentFile(offset, timestamp, name, prevName, out);
- }
- // We check that we did indeed get to a page boundary.
- offset = countOut.getCount() + JarFile.LOCHDR + name.length();
- if ((offset % LIBRARY_ALIGNMENT) != 0) {
- throw new AssertionError(
- "Library was not page aligned when verifying page alignment. "
- + "Library name: " + name + " Expected alignment: "
- + LIBRARY_ALIGNMENT + "Offset: " + offset + " Error: "
- + (offset % LIBRARY_ALIGNMENT));
- }
- } else {
- // This is equivalent to zipalign.
- offset += JarFile.LOCHDR + name.length();
- int needed = (ALIGNMENT - (int) (offset % ALIGNMENT)) % ALIGNMENT;
- if (needed != 0) {
- outEntry.setExtra(new byte[needed]);
- }
- }
- }
- out.putNextEntry(outEntry);
-
- // Copy the data from the input to the output
- int num;
- InputStream data = in.getInputStream(inEntry);
- while ((num = data.read(buffer)) > 0) {
- out.write(buffer, 0, num);
- }
- data.close();
- out.closeEntry();
- out.flush();
- prevName = name;
- }
- if (numCrazy == 0) {
- throw new AssertionError("There was no crazy library in the archive");
- }
- }
-
- private static void usage() {
- System.err.println("Usage: prealignapk (addalignment|reorder) input.apk output.apk");
- System.err.println("\"crazy\" libraries are always inflated in the output");
- System.err.println(
- " renamealign - rename libraries with \"crazy.\" prefix and add alignment file");
- System.err.println(" align - add alignment file");
- System.err.println(" reorder - re-creates canonical ordering and checks alignment");
- System.exit(2);
- }
-
- public static void main(String[] args) throws IOException {
- if (args.length != 3) usage();
-
- boolean addAlignment = false;
- boolean rename = false;
- if (args[0].equals("renamealign")) {
- // Normal case. Before signing we rename the library and add an alignment file.
- addAlignment = true;
- rename = true;
- } else if (args[0].equals("align")) {
- // LGPL compliance case. Before signing, we add an alignment file to a
- // reconstructed APK which already contains the "crazy" library.
- addAlignment = true;
- rename = false;
- } else if (args[0].equals("reorder")) {
- // Normal case. After jarsigning we write the file in the canonical order and check.
- addAlignment = false;
- } else {
- usage();
- }
-
- String inputFilename = args[1];
- String outputFilename = args[2];
-
- JarFile inputJar = null;
- FileOutputStream outputFile = null;
-
- try {
- inputJar = new JarFile(new File(inputFilename), true);
- outputFile = new FileOutputStream(outputFilename);
-
- CountingOutputStream outCount = new CountingOutputStream(outputFile);
- JarOutputStream outputJar = new JarOutputStream(outCount);
-
- // Match the compression level used by SignApk.
- outputJar.setLevel(9);
-
- rezip(inputJar, outputJar, outCount, addAlignment, rename);
- outputJar.close();
- } finally {
- if (inputJar != null) inputJar.close();
- if (outputFile != null) outputFile.close();
- }
- }
-}
diff --git a/build/android/screenshot.py b/build/android/screenshot.py
deleted file mode 100755
index 097739f..0000000
--- a/build/android/screenshot.py
+++ /dev/null
@@ -1,98 +0,0 @@
-#!/usr/bin/env python
-
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Takes a screenshot or a screen video capture from an Android device."""
-
-import logging
-import optparse
-import os
-import sys
-
-from pylib import screenshot
-from pylib.device import device_errors
-from pylib.device import device_utils
-
-def _PrintMessage(heading, eol='\n'):
- sys.stdout.write('%s%s' % (heading, eol))
- sys.stdout.flush()
-
-
-def _CaptureScreenshot(device, host_file):
- host_file = device.TakeScreenshot(host_file)
- _PrintMessage('Screenshot written to %s' % os.path.abspath(host_file))
-
-
-def _CaptureVideo(device, host_file, options):
- size = tuple(map(int, options.size.split('x'))) if options.size else None
- recorder = screenshot.VideoRecorder(device,
- megabits_per_second=options.bitrate,
- size=size,
- rotate=options.rotate)
- try:
- recorder.Start()
- _PrintMessage('Recording. Press Enter to stop...', eol='')
- raw_input()
- finally:
- recorder.Stop()
- host_file = recorder.Pull(host_file)
- _PrintMessage('Video written to %s' % os.path.abspath(host_file))
-
-
-def main():
- # Parse options.
- parser = optparse.OptionParser(description=__doc__,
- usage='screenshot.py [options] [filename]')
- parser.add_option('-d', '--device', metavar='ANDROID_DEVICE', help='Serial '
- 'number of Android device to use.', default=None)
- parser.add_option('-f', '--file', help='Save result to file instead of '
- 'generating a timestamped file name.', metavar='FILE')
- parser.add_option('-v', '--verbose', help='Verbose logging.',
- action='store_true')
- video_options = optparse.OptionGroup(parser, 'Video capture')
- video_options.add_option('--video', help='Enable video capturing. Requires '
- 'Android KitKat or later', action='store_true')
- video_options.add_option('-b', '--bitrate', help='Bitrate in megabits/s, '
- 'from 0.1 to 100 mbps, %default mbps by default.',
- default=4, type='float')
- video_options.add_option('-r', '--rotate', help='Rotate video by 90 degrees.',
- default=False, action='store_true')
- video_options.add_option('-s', '--size', metavar='WIDTHxHEIGHT',
- help='Frame size to use instead of the device '
- 'screen size.', default=None)
- parser.add_option_group(video_options)
-
- (options, args) = parser.parse_args()
-
- if len(args) > 1:
- parser.error('Too many positional arguments.')
- host_file = args[0] if args else options.file
-
- if options.verbose:
- logging.getLogger().setLevel(logging.DEBUG)
-
- devices = device_utils.DeviceUtils.HealthyDevices()
- if options.device:
- device = next((d for d in devices if d == options.device), None)
- if not device:
- raise device_errors.DeviceUnreachableError(options.device)
- else:
- if len(devices) > 1:
- parser.error('Multiple devices are attached. '
- 'Please specify device serial number with --device.')
- elif len(devices) == 1:
- device = devices[0]
- else:
- raise device_errors.NoDevicesError()
-
- if options.video:
- _CaptureVideo(device, host_file, options)
- else:
- _CaptureScreenshot(device, host_file)
- return 0
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/build/android/setup.gyp b/build/android/setup.gyp
deleted file mode 100644
index 0e1c2c4..0000000
--- a/build/android/setup.gyp
+++ /dev/null
@@ -1,111 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-{
- 'conditions': [
- ['component == "shared_library"', {
- 'targets': [
- {
- # These libraries from the Android ndk are required to be packaged with
- # any APK that is built with them. build/java_apk.gypi expects any
- # libraries that should be packaged with the apk to be in
- # <(SHARED_LIB_DIR)
- 'target_name': 'copy_system_libraries',
- 'type': 'none',
- 'copies': [
- {
- 'destination': '<(SHARED_LIB_DIR)/',
- 'files': [
- '<(android_libcpp_libs_dir)/libc++_shared.so',
- ],
- },
- ],
- },
- ],
- }],
- ],
- 'targets': [
- {
- 'target_name': 'get_build_device_configurations',
- 'type': 'none',
- 'actions': [
- {
- 'action_name': 'get configurations',
- 'inputs': [
- 'gyp/util/build_device.py',
- 'gyp/get_device_configuration.py',
- ],
- 'outputs': [
- '<(build_device_config_path)',
- '<(build_device_config_path).fake',
- ],
- 'action': [
- 'python', 'gyp/get_device_configuration.py',
- '--output=<(build_device_config_path)',
- ],
- }
- ],
- },
- {
- # Target for creating common output build directories. Creating output
- # dirs beforehand ensures that build scripts can assume these folders to
- # exist and there are no race conditions resulting from build scripts
- # trying to create these directories.
- # The build/java.gypi target depends on this target.
- 'target_name': 'build_output_dirs',
- 'type': 'none',
- 'actions': [
- {
- 'action_name': 'create_java_output_dirs',
- 'variables' : {
- 'output_dirs' : [
- '<(PRODUCT_DIR)/apks',
- '<(PRODUCT_DIR)/lib.java',
- '<(PRODUCT_DIR)/test.lib.java',
- ]
- },
- 'inputs' : [],
- # By not specifying any outputs, we ensure that this command isn't
- # re-run when the output directories are touched (i.e. apks are
- # written to them).
- 'outputs': [''],
- 'action': [
- 'mkdir',
- '-p',
- '<@(output_dirs)',
- ],
- },
- ],
- }, # build_output_dirs
- {
- 'target_name': 'sun_tools_java',
- 'type': 'none',
- 'variables': {
- 'found_jar_path': '<(PRODUCT_DIR)/sun_tools_java/tools.jar',
- 'jar_path': '<(found_jar_path)',
- },
- 'includes': [
- '../../build/host_prebuilt_jar.gypi',
- ],
- 'actions': [
- {
- 'action_name': 'find_sun_tools_jar',
- 'variables' : {
- },
- 'inputs' : [
- 'gyp/find_sun_tools_jar.py',
- 'gyp/util/build_utils.py',
- ],
- 'outputs': [
- '<(found_jar_path)',
- ],
- 'action': [
- 'python', 'gyp/find_sun_tools_jar.py',
- '--output', '<(found_jar_path)',
- ],
- },
- ],
- }, # sun_tools_java
- ]
-}
-
diff --git a/build/android/strip_native_libraries.gypi b/build/android/strip_native_libraries.gypi
deleted file mode 100644
index bdffcfd..0000000
--- a/build/android/strip_native_libraries.gypi
+++ /dev/null
@@ -1,54 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included into an action to provide a rule that strips
-# native libraries.
-#
-# To use this, create a gyp target with the following form:
-# {
-# 'action_name': 'strip_native_libraries',
-# 'actions': [
-# 'variables': {
-# 'ordered_libraries_file': 'file generated by write_ordered_libraries'
-# 'input_paths': 'files to be added to the list of inputs'
-# 'stamp': 'file to touch when the action is complete'
-# 'stripped_libraries_dir': 'directory to store stripped libraries',
-# },
-# 'includes': [ '../../build/android/strip_native_libraries.gypi' ],
-# ],
-# },
-#
-
-{
- 'message': 'Stripping libraries for <(_target_name)',
- 'variables': {
- 'input_paths': [],
- },
- 'inputs': [
- '<(DEPTH)/build/android/gyp/util/build_utils.py',
- '<(DEPTH)/build/android/gyp/strip_library_for_device.py',
- '<(ordered_libraries_file)',
- '>@(input_paths)',
- ],
- 'outputs': [
- '<(stamp)',
- ],
- 'conditions': [
- ['component == "shared_library"', {
- # Add a fake output to force the build to always re-run this step. This
- # is required because the real inputs are not known at gyp-time and
- # changing base.so may not trigger changes to dependent libraries.
- 'outputs': [ '<(stamp).fake' ]
- }],
- ],
- 'action': [
- 'python', '<(DEPTH)/build/android/gyp/strip_library_for_device.py',
- '--android-strip=<(android_strip)',
- '--android-strip-arg=--strip-unneeded',
- '--stripped-libraries-dir=<(stripped_libraries_dir)',
- '--libraries-dir=<(SHARED_LIB_DIR),<(PRODUCT_DIR)',
- '--libraries=@FileArg(<(ordered_libraries_file):libraries)',
- '--stamp=<(stamp)',
- ],
-}
diff --git a/build/android/symbolize.py b/build/android/symbolize.py
deleted file mode 100755
index 56d3b19..0000000
--- a/build/android/symbolize.py
+++ /dev/null
@@ -1,88 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Symbolizes stack traces generated by Chromium for Android.
-
-Sample usage:
- adb logcat chromium:V | symbolize.py
-"""
-
-import os
-import re
-import sys
-
-from pylib import constants
-
-# Uses symbol.py from third_party/android_platform, not python's.
-sys.path.insert(0,
- os.path.join(constants.DIR_SOURCE_ROOT,
- 'third_party/android_platform/development/scripts'))
-import symbol
-
-# Sample output from base/debug/stack_trace_android.cc
-#00 0x693cd34f /path/to/some/libfoo.so+0x0007434f
-TRACE_LINE = re.compile(r'(?P<frame>\#[0-9]+ 0x[0-9a-f]{8,8}) '
- r'(?P<lib>[^+]+)\+0x(?P<addr>[0-9a-f]{8,8})')
-
-class Symbolizer(object):
- def __init__(self, output):
- self._output = output
-
- def write(self, data):
- while True:
- match = re.search(TRACE_LINE, data)
- if not match:
- self._output.write(data)
- break
-
- frame = match.group('frame')
- lib = match.group('lib')
- addr = match.group('addr')
-
- # TODO(scherkus): Doing a single lookup per line is pretty slow,
- # especially with larger libraries. Consider caching strategies such as:
- # 1) Have Python load the libraries and do symbol lookups instead of
- # calling out to addr2line each time.
- # 2) Have Python keep multiple addr2line instances open as subprocesses,
- # piping addresses and reading back symbols as we find them
- # 3) Read ahead the entire stack trace until we find no more, then batch
- # the symbol lookups.
- #
- # TODO(scherkus): These results are memoized, which could result in
- # incorrect lookups when running this script on long-lived instances
- # (e.g., adb logcat) when doing incremental development. Consider clearing
- # the cache when modification timestamp of libraries change.
- sym = symbol.SymbolInformation(lib, addr, False)[0][0]
-
- if not sym:
- post = match.end('addr')
- self._output.write(data[:post])
- data = data[post:]
- continue
-
- pre = match.start('frame')
- post = match.end('addr')
-
- self._output.write(data[:pre])
- self._output.write(frame)
- self._output.write(' ')
- self._output.write(sym)
-
- data = data[post:]
-
- def flush(self):
- self._output.flush()
-
-
-def main():
- symbolizer = Symbolizer(sys.stdout)
- for line in sys.stdin:
- symbolizer.write(line)
- symbolizer.flush()
-
-
-if __name__ == '__main__':
- main()
diff --git a/build/android/symbolize_test.py b/build/android/symbolize_test.py
deleted file mode 100755
index 826d852..0000000
--- a/build/android/symbolize_test.py
+++ /dev/null
@@ -1,130 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Unittest for symbolize.py.
-
-This test uses test libraries generated by the Android g++ toolchain.
-
-Should things break you can recreate the libraries and get the updated
-addresses and demangled names by running the following:
- cd test/symbolize/
- make
- nm -gC *.so
-"""
-
-import StringIO
-import unittest
-
-import symbolize
-
-LIB_A_PATH = '/build/android/tests/symbolize/liba.so'
-LIB_B_PATH = '/build/android/tests/symbolize/libb.so'
-
-def RunSymbolizer(text):
- output = StringIO.StringIO()
- s = symbolize.Symbolizer(output)
- s.write(text)
- return output.getvalue()
-
-
-class SymbolizerUnittest(unittest.TestCase):
- def testSingleLineNoMatch(self):
- # Leading '#' is required.
- expected = '00 0x00000000 ' + LIB_A_PATH + '+0x00000254\n'
- self.assertEqual(expected, RunSymbolizer(expected))
-
- # Whitespace should be exactly one space.
- expected = '#00 0x00000000 ' + LIB_A_PATH + '+0x00000254\n'
- self.assertEqual(expected, RunSymbolizer(expected))
- expected = '#00 0x00000000 ' + LIB_A_PATH + '+0x00000254\n'
- self.assertEqual(expected, RunSymbolizer(expected))
-
- # Decimal stack frame numbers are required.
- expected = '#0a 0x00000000 ' + LIB_A_PATH + '+0x00000254\n'
- self.assertEqual(expected, RunSymbolizer(expected))
-
- # Hexadecimal addresses are required.
- expected = '#00 0xghijklmn ' + LIB_A_PATH + '+0x00000254\n'
- self.assertEqual(expected, RunSymbolizer(expected))
- expected = '#00 0x00000000 ' + LIB_A_PATH + '+0xghijklmn\n'
- self.assertEqual(expected, RunSymbolizer(expected))
-
- # Addresses must be exactly 8 characters.
- expected = '#00 0x0000000 ' + LIB_A_PATH + '+0x00000254\n'
- self.assertEqual(expected, RunSymbolizer(expected))
- expected = '#00 0x000000000 ' + LIB_A_PATH + '+0x00000254\n'
- self.assertEqual(expected, RunSymbolizer(expected))
-
- expected = '#00 0x0000000 ' + LIB_A_PATH + '+0x0000254\n'
- self.assertEqual(expected, RunSymbolizer(expected))
- expected = '#00 0x000000000 ' + LIB_A_PATH + '+0x000000254\n'
- self.assertEqual(expected, RunSymbolizer(expected))
-
- # Addresses must be prefixed with '0x'.
- expected = '#00 00000000 ' + LIB_A_PATH + '+0x00000254\n'
- self.assertEqual(expected, RunSymbolizer(expected))
- expected = '#00 0x00000000 ' + LIB_A_PATH + '+00000254\n'
- self.assertEqual(expected, RunSymbolizer(expected))
-
- # Library name is required.
- expected = '#00 0x00000000\n'
- self.assertEqual(expected, RunSymbolizer(expected))
- expected = '#00 0x00000000 +0x00000254\n'
- self.assertEqual(expected, RunSymbolizer(expected))
-
- # Library name must be followed by offset with no spaces around '+'.
- expected = '#00 0x00000000 ' + LIB_A_PATH + ' +0x00000254\n'
- self.assertEqual(expected, RunSymbolizer(expected))
- expected = '#00 0x00000000 ' + LIB_A_PATH + '+ 0x00000254\n'
- self.assertEqual(expected, RunSymbolizer(expected))
- expected = '#00 0x00000000 ' + LIB_A_PATH + ' 0x00000254\n'
- self.assertEqual(expected, RunSymbolizer(expected))
- expected = '#00 0x00000000 ' + LIB_A_PATH + '+\n'
- self.assertEqual(expected, RunSymbolizer(expected))
-
- def testSingleLine(self):
- text = '#00 0x00000000 ' + LIB_A_PATH + '+0x00000254\n'
- expected = '#00 0x00000000 A::Bar(char const*)\n'
- actual = RunSymbolizer(text)
- self.assertEqual(expected, actual)
-
- def testSingleLineWithSurroundingText(self):
- text = 'LEFT #00 0x00000000 ' + LIB_A_PATH + '+0x00000254 RIGHT\n'
- expected = 'LEFT #00 0x00000000 A::Bar(char const*) RIGHT\n'
- actual = RunSymbolizer(text)
- self.assertEqual(expected, actual)
-
- def testMultipleLinesSameLibrary(self):
- text = '#00 0x00000000 ' + LIB_A_PATH + '+0x00000254\n'
- text += '#01 0x00000000 ' + LIB_A_PATH + '+0x00000234\n'
- expected = '#00 0x00000000 A::Bar(char const*)\n'
- expected += '#01 0x00000000 A::Foo(int)\n'
- actual = RunSymbolizer(text)
- self.assertEqual(expected, actual)
-
- def testMultipleLinesDifferentLibrary(self):
- text = '#00 0x00000000 ' + LIB_A_PATH + '+0x00000254\n'
- text += '#01 0x00000000 ' + LIB_B_PATH + '+0x00000234\n'
- expected = '#00 0x00000000 A::Bar(char const*)\n'
- expected += '#01 0x00000000 B::Baz(float)\n'
- actual = RunSymbolizer(text)
- self.assertEqual(expected, actual)
-
- def testMultipleLinesWithSurroundingTextEverywhere(self):
- text = 'TOP\n'
- text += 'LEFT #00 0x00000000 ' + LIB_A_PATH + '+0x00000254 RIGHT\n'
- text += 'LEFT #01 0x00000000 ' + LIB_B_PATH + '+0x00000234 RIGHT\n'
- text += 'BOTTOM\n'
- expected = 'TOP\n'
- expected += 'LEFT #00 0x00000000 A::Bar(char const*) RIGHT\n'
- expected += 'LEFT #01 0x00000000 B::Baz(float) RIGHT\n'
- expected += 'BOTTOM\n'
- actual = RunSymbolizer(text)
- self.assertEqual(expected, actual)
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/build/android/test_runner.gypi b/build/android/test_runner.gypi
deleted file mode 100644
index f92b7ce..0000000
--- a/build/android/test_runner.gypi
+++ /dev/null
@@ -1,81 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# Generates a script in the output bin directory which runs the test
-# target using the test runner script in build/android/pylib/test_runner.py.
-#
-# To use this, include this file in a gtest or instrumentation test target.
-# {
-# 'target_name': 'gtest',
-# 'type': 'none',
-# 'variables': {
-# 'test_type': 'gtest', # string
-# 'test_suite_name': 'gtest_suite' # string
-# 'isolate_file': 'path/to/gtest.isolate' # string
-# },
-# 'includes': ['path/to/this/gypi/file'],
-# }
-#
-# {
-# 'target_name': 'instrumentation_apk',
-# 'type': 'none',
-# 'variables': {
-# 'test_type': 'instrumentation', # string
-# 'apk_name': 'TestApk' # string
-# 'isolate_file': 'path/to/instrumentation_test.isolate' # string
-# },
-# 'includes': ['path/to/this/gypi/file'],
-# }
-#
-
-{
- 'variables': {
- 'variables': {
- 'isolate_file%': '',
- 'support_apk_path%': '',
- },
- 'test_runner_args': ['--output-directory', '<(PRODUCT_DIR)'],
- 'conditions': [
- ['test_type == "gtest"', {
- 'test_runner_args': ['--suite', '<(test_suite_name)'],
- 'script_name': 'run_<(test_suite_name)',
- }],
- ['test_type == "instrumentation"', {
- 'test_runner_args': ['--test-apk', '<(apk_name)'],
- 'script_name': 'run_<(_target_name)',
- 'conditions': [
- ['support_apk_path != ""', {
- 'test_runner_args': [
- '--support-apk',
- '<(support_apk_path)'
- ],
- }],
- ],
- }],
- ['isolate_file != ""', {
- 'test_runner_args': ['--isolate-file-path', '<(isolate_file)']
- }],
- ],
- },
- 'actions': [
- {
- 'action_name': 'create_test_runner_script_<(script_name)',
- 'message': 'Creating test runner script <(script_name)',
- 'variables': {
- 'script_output_path': '<(PRODUCT_DIR)/bin/<(script_name)',
- },
- 'inputs': [
- '<(DEPTH)/build/android/gyp/create_test_runner_script.py',
- ],
- 'outputs': [
- '<(script_output_path)'
- ],
- 'action': [
- 'python', '<(DEPTH)/build/android/gyp/create_test_runner_script.py',
- '--script-output-path=<(script_output_path)',
- '<(test_type)', '<@(test_runner_args)',
- ],
- },
- ],
-}
\ No newline at end of file
diff --git a/build/android/test_runner.py b/build/android/test_runner.py
deleted file mode 100755
index 1fc48ec..0000000
--- a/build/android/test_runner.py
+++ /dev/null
@@ -1,1067 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Runs all types of tests from one unified interface."""
-
-import argparse
-import collections
-import logging
-import os
-import shutil
-import signal
-import sys
-import threading
-import unittest
-
-from pylib import constants
-from pylib import forwarder
-from pylib import ports
-from pylib.base import base_test_result
-from pylib.base import environment_factory
-from pylib.base import test_dispatcher
-from pylib.base import test_instance_factory
-from pylib.base import test_run_factory
-from pylib.device import device_errors
-from pylib.device import device_utils
-from pylib.gtest import gtest_config
-# TODO(jbudorick): Remove this once we stop selectively enabling platform mode.
-from pylib.gtest import gtest_test_instance
-from pylib.gtest import setup as gtest_setup
-from pylib.gtest import test_options as gtest_test_options
-from pylib.linker import setup as linker_setup
-from pylib.host_driven import setup as host_driven_setup
-from pylib.instrumentation import setup as instrumentation_setup
-from pylib.instrumentation import test_options as instrumentation_test_options
-from pylib.junit import setup as junit_setup
-from pylib.junit import test_dispatcher as junit_dispatcher
-from pylib.monkey import setup as monkey_setup
-from pylib.monkey import test_options as monkey_test_options
-from pylib.perf import setup as perf_setup
-from pylib.perf import test_options as perf_test_options
-from pylib.perf import test_runner as perf_test_runner
-from pylib.results import json_results
-from pylib.results import report_results
-from pylib.uiautomator import setup as uiautomator_setup
-from pylib.uiautomator import test_options as uiautomator_test_options
-from pylib.utils import apk_helper
-from pylib.utils import base_error
-from pylib.utils import reraiser_thread
-from pylib.utils import run_tests_helper
-
-
-def AddCommonOptions(parser):
- """Adds all common options to |parser|."""
-
- group = parser.add_argument_group('Common Options')
-
- default_build_type = os.environ.get('BUILDTYPE', 'Debug')
-
- debug_or_release_group = group.add_mutually_exclusive_group()
- debug_or_release_group.add_argument(
- '--debug', action='store_const', const='Debug', dest='build_type',
- default=default_build_type,
- help=('If set, run test suites under out/Debug. '
- 'Default is env var BUILDTYPE or Debug.'))
- debug_or_release_group.add_argument(
- '--release', action='store_const', const='Release', dest='build_type',
- help=('If set, run test suites under out/Release. '
- 'Default is env var BUILDTYPE or Debug.'))
-
- group.add_argument('--build-directory', dest='build_directory',
- help=('Path to the directory in which build files are'
- ' located (should not include build type)'))
- group.add_argument('--output-directory', dest='output_directory',
- help=('Path to the directory in which build files are'
- ' located (must include build type). This will take'
- ' precedence over --debug, --release and'
- ' --build-directory'))
- group.add_argument('--num_retries', dest='num_retries', type=int, default=2,
- help=('Number of retries for a test before '
- 'giving up (default: %(default)s).'))
- group.add_argument('-v',
- '--verbose',
- dest='verbose_count',
- default=0,
- action='count',
- help='Verbose level (multiple times for more)')
- group.add_argument('--flakiness-dashboard-server',
- dest='flakiness_dashboard_server',
- help=('Address of the server that is hosting the '
- 'Chrome for Android flakiness dashboard.'))
- group.add_argument('--enable-platform-mode', action='store_true',
- help=('Run the test scripts in platform mode, which '
- 'conceptually separates the test runner from the '
- '"device" (local or remote, real or emulated) on '
- 'which the tests are running. [experimental]'))
- group.add_argument('-e', '--environment', default='local',
- choices=constants.VALID_ENVIRONMENTS,
- help='Test environment to run in (default: %(default)s).')
- group.add_argument('--adb-path',
- help=('Specify the absolute path of the adb binary that '
- 'should be used.'))
- group.add_argument('--json-results-file', dest='json_results_file',
- help='If set, will dump results in JSON form '
- 'to specified file.')
-
-def ProcessCommonOptions(args):
- """Processes and handles all common options."""
- run_tests_helper.SetLogLevel(args.verbose_count)
- constants.SetBuildType(args.build_type)
- if args.build_directory:
- constants.SetBuildDirectory(args.build_directory)
- if args.output_directory:
- constants.SetOutputDirectory(args.output_directory)
- if args.adb_path:
- constants.SetAdbPath(args.adb_path)
- # Some things such as Forwarder require ADB to be in the environment path.
- adb_dir = os.path.dirname(constants.GetAdbPath())
- if adb_dir and adb_dir not in os.environ['PATH'].split(os.pathsep):
- os.environ['PATH'] = adb_dir + os.pathsep + os.environ['PATH']
-
-
-def AddRemoteDeviceOptions(parser):
- group = parser.add_argument_group('Remote Device Options')
-
- group.add_argument('--trigger',
- help=('Only triggers the test if set. Stores test_run_id '
- 'in given file path. '))
- group.add_argument('--collect',
- help=('Only collects the test results if set. '
- 'Gets test_run_id from given file path.'))
- group.add_argument('--remote-device', action='append',
- help='Device type to run test on.')
- group.add_argument('--results-path',
- help='File path to download results to.')
- group.add_argument('--api-protocol',
- help='HTTP protocol to use. (http or https)')
- group.add_argument('--api-address',
- help='Address to send HTTP requests.')
- group.add_argument('--api-port',
- help='Port to send HTTP requests to.')
- group.add_argument('--runner-type',
- help='Type of test to run as.')
- group.add_argument('--runner-package',
- help='Package name of test.')
- group.add_argument('--device-type',
- choices=constants.VALID_DEVICE_TYPES,
- help=('Type of device to run on. iOS or android'))
- group.add_argument('--device-oem', action='append',
- help='Device OEM to run on.')
- group.add_argument('--remote-device-file',
- help=('File with JSON to select remote device. '
- 'Overrides all other flags.'))
- group.add_argument('--remote-device-timeout', type=int,
- help='Times to retry finding remote device')
- group.add_argument('--network-config', type=int,
- help='Integer that specifies the network environment '
- 'that the tests will be run in.')
-
- device_os_group = group.add_mutually_exclusive_group()
- device_os_group.add_argument('--remote-device-minimum-os',
- help='Minimum OS on device.')
- device_os_group.add_argument('--remote-device-os', action='append',
- help='OS to have on the device.')
-
- api_secret_group = group.add_mutually_exclusive_group()
- api_secret_group.add_argument('--api-secret', default='',
- help='API secret for remote devices.')
- api_secret_group.add_argument('--api-secret-file', default='',
- help='Path to file that contains API secret.')
-
- api_key_group = group.add_mutually_exclusive_group()
- api_key_group.add_argument('--api-key', default='',
- help='API key for remote devices.')
- api_key_group.add_argument('--api-key-file', default='',
- help='Path to file that contains API key.')
-
-
-def AddDeviceOptions(parser):
- """Adds device options to |parser|."""
- group = parser.add_argument_group(title='Device Options')
- group.add_argument('--tool',
- dest='tool',
- help=('Run the test under a tool '
- '(use --tool help to list them)'))
- group.add_argument('-d', '--device', dest='test_device',
- help=('Target device for the test suite '
- 'to run on.'))
-
-
-def AddGTestOptions(parser):
- """Adds gtest options to |parser|."""
-
- gtest_suites = list(gtest_config.STABLE_TEST_SUITES
- + gtest_config.EXPERIMENTAL_TEST_SUITES)
-
- group = parser.add_argument_group('GTest Options')
- group.add_argument('-s', '--suite', dest='suite_name',
- nargs='+', metavar='SUITE_NAME', required=True,
- help=('Executable name of the test suite to run. '
- 'Available suites include (but are not limited to): '
- '%s' % ', '.join('"%s"' % s for s in gtest_suites)))
- group.add_argument('--gtest_also_run_disabled_tests',
- '--gtest-also-run-disabled-tests',
- dest='run_disabled', action='store_true',
- help='Also run disabled tests if applicable.')
- group.add_argument('-a', '--test-arguments', dest='test_arguments',
- default='',
- help='Additional arguments to pass to the test.')
- group.add_argument('-t', dest='timeout', type=int, default=60,
- help='Timeout to wait for each test '
- '(default: %(default)s).')
- group.add_argument('--isolate_file_path',
- '--isolate-file-path',
- dest='isolate_file_path',
- help='.isolate file path to override the default '
- 'path')
- group.add_argument('--app-data-file', action='append', dest='app_data_files',
- help='A file path relative to the app data directory '
- 'that should be saved to the host.')
- group.add_argument('--app-data-file-dir',
- help='Host directory to which app data files will be'
- ' saved. Used with --app-data-file.')
- group.add_argument('--delete-stale-data', dest='delete_stale_data',
- action='store_true',
- help='Delete stale test data on the device.')
-
- filter_group = group.add_mutually_exclusive_group()
- filter_group.add_argument('-f', '--gtest_filter', '--gtest-filter',
- dest='test_filter',
- help='googletest-style filter string.')
- filter_group.add_argument('--gtest-filter-file', dest='test_filter_file',
- help='Path to file that contains googletest-style '
- 'filter strings. (Lines will be joined with '
- '":" to create a single filter string.)')
-
- AddDeviceOptions(parser)
- AddCommonOptions(parser)
- AddRemoteDeviceOptions(parser)
-
-
-def AddLinkerTestOptions(parser):
- group = parser.add_argument_group('Linker Test Options')
- group.add_argument('-f', '--gtest-filter', dest='test_filter',
- help='googletest-style filter string.')
- AddCommonOptions(parser)
- AddDeviceOptions(parser)
-
-
-def AddJavaTestOptions(argument_group):
- """Adds the Java test options to |option_parser|."""
-
- argument_group.add_argument(
- '-f', '--test-filter', dest='test_filter',
- help=('Test filter (if not fully qualified, will run all matches).'))
- argument_group.add_argument(
- '-A', '--annotation', dest='annotation_str',
- help=('Comma-separated list of annotations. Run only tests with any of '
- 'the given annotations. An annotation can be either a key or a '
- 'key-values pair. A test that has no annotation is considered '
- '"SmallTest".'))
- argument_group.add_argument(
- '-E', '--exclude-annotation', dest='exclude_annotation_str',
- help=('Comma-separated list of annotations. Exclude tests with these '
- 'annotations.'))
- argument_group.add_argument(
- '--screenshot', dest='screenshot_failures', action='store_true',
- help='Capture screenshots of test failures')
- argument_group.add_argument(
- '--save-perf-json', action='store_true',
- help='Saves the JSON file for each UI Perf test.')
- argument_group.add_argument(
- '--official-build', action='store_true', help='Run official build tests.')
- argument_group.add_argument(
- '--test_data', '--test-data', action='append', default=[],
- help=('Each instance defines a directory of test data that should be '
- 'copied to the target(s) before running the tests. The argument '
- 'should be of the form <target>:<source>, <target> is relative to '
- 'the device data directory, and <source> is relative to the '
- 'chromium build directory.'))
- argument_group.add_argument(
- '--disable-dalvik-asserts', dest='set_asserts', action='store_false',
- default=True, help='Removes the dalvik.vm.enableassertions property')
-
-
-
-def ProcessJavaTestOptions(args):
- """Processes options/arguments and populates |options| with defaults."""
-
- # TODO(jbudorick): Handle most of this function in argparse.
- if args.annotation_str:
- args.annotations = args.annotation_str.split(',')
- elif args.test_filter:
- args.annotations = []
- else:
- args.annotations = ['Smoke', 'SmallTest', 'MediumTest', 'LargeTest',
- 'EnormousTest', 'IntegrationTest']
-
- if args.exclude_annotation_str:
- args.exclude_annotations = args.exclude_annotation_str.split(',')
- else:
- args.exclude_annotations = []
-
-
-def AddInstrumentationTestOptions(parser):
- """Adds Instrumentation test options to |parser|."""
-
- parser.usage = '%(prog)s [options]'
-
- group = parser.add_argument_group('Instrumentation Test Options')
- AddJavaTestOptions(group)
-
- java_or_python_group = group.add_mutually_exclusive_group()
- java_or_python_group.add_argument(
- '-j', '--java-only', action='store_false',
- dest='run_python_tests', default=True, help='Run only the Java tests.')
- java_or_python_group.add_argument(
- '-p', '--python-only', action='store_false',
- dest='run_java_tests', default=True,
- help='Run only the host-driven tests.')
-
- group.add_argument('--host-driven-root',
- help='Root of the host-driven tests.')
- group.add_argument('-w', '--wait_debugger', dest='wait_for_debugger',
- action='store_true',
- help='Wait for debugger.')
- group.add_argument('--apk-under-test', dest='apk_under_test',
- help=('the name of the apk under test.'))
- group.add_argument('--test-apk', dest='test_apk', required=True,
- help=('The name of the apk containing the tests '
- '(without the .apk extension; '
- 'e.g. "ContentShellTest").'))
- group.add_argument('--support-apk', dest='test_support_apk_path',
- help=('The path to an optional support apk to be '
- 'installed alongside the test apk. The '
- 'path should be relative to the output '
- 'directory (--output-directory).'))
- group.add_argument('--coverage-dir',
- help=('Directory in which to place all generated '
- 'EMMA coverage files.'))
- group.add_argument('--device-flags', dest='device_flags', default='',
- help='The relative filepath to a file containing '
- 'command-line flags to set on the device')
- group.add_argument('--device-flags-file', default='',
- help='The relative filepath to a file containing '
- 'command-line flags to set on the device')
- group.add_argument('--isolate_file_path',
- '--isolate-file-path',
- dest='isolate_file_path',
- help='.isolate file path to override the default '
- 'path')
- group.add_argument('--delete-stale-data', dest='delete_stale_data',
- action='store_true',
- help='Delete stale test data on the device.')
-
- AddCommonOptions(parser)
- AddDeviceOptions(parser)
- AddRemoteDeviceOptions(parser)
-
-
-def ProcessInstrumentationOptions(args):
- """Processes options/arguments and populate |options| with defaults.
-
- Args:
- args: argparse.Namespace object.
-
- Returns:
- An InstrumentationOptions named tuple which contains all options relevant to
- instrumentation tests.
- """
-
- ProcessJavaTestOptions(args)
-
- if not args.host_driven_root:
- args.run_python_tests = False
-
- args.test_apk_path = os.path.join(
- constants.GetOutDirectory(),
- constants.SDK_BUILD_APKS_DIR,
- '%s.apk' % args.test_apk)
- args.test_apk_jar_path = os.path.join(
- constants.GetOutDirectory(),
- constants.SDK_BUILD_TEST_JAVALIB_DIR,
- '%s.jar' % args.test_apk)
-
- args.test_runner = apk_helper.GetInstrumentationName(args.test_apk_path)
-
- # TODO(jbudorick): Get rid of InstrumentationOptions.
- return instrumentation_test_options.InstrumentationOptions(
- args.tool,
- args.annotations,
- args.exclude_annotations,
- args.test_filter,
- args.test_data,
- args.save_perf_json,
- args.screenshot_failures,
- args.wait_for_debugger,
- args.coverage_dir,
- args.test_apk,
- args.test_apk_path,
- args.test_apk_jar_path,
- args.test_runner,
- args.test_support_apk_path,
- args.device_flags,
- args.isolate_file_path,
- args.set_asserts,
- args.delete_stale_data
- )
-
-
-def AddUIAutomatorTestOptions(parser):
- """Adds UI Automator test options to |parser|."""
-
- group = parser.add_argument_group('UIAutomator Test Options')
- AddJavaTestOptions(group)
- group.add_argument(
- '--package', required=True, choices=constants.PACKAGE_INFO.keys(),
- metavar='PACKAGE', help='Package under test.')
- group.add_argument(
- '--test-jar', dest='test_jar', required=True,
- help=('The name of the dexed jar containing the tests (without the '
- '.dex.jar extension). Alternatively, this can be a full path '
- 'to the jar.'))
-
- AddCommonOptions(parser)
- AddDeviceOptions(parser)
-
-
-def ProcessUIAutomatorOptions(args):
- """Processes UIAutomator options/arguments.
-
- Args:
- args: argparse.Namespace object.
-
- Returns:
- A UIAutomatorOptions named tuple which contains all options relevant to
- uiautomator tests.
- """
-
- ProcessJavaTestOptions(args)
-
- if os.path.exists(args.test_jar):
- # The dexed JAR is fully qualified, assume the info JAR lives along side.
- args.uiautomator_jar = args.test_jar
- else:
- args.uiautomator_jar = os.path.join(
- constants.GetOutDirectory(),
- constants.SDK_BUILD_JAVALIB_DIR,
- '%s.dex.jar' % args.test_jar)
- args.uiautomator_info_jar = (
- args.uiautomator_jar[:args.uiautomator_jar.find('.dex.jar')] +
- '_java.jar')
-
- return uiautomator_test_options.UIAutomatorOptions(
- args.tool,
- args.annotations,
- args.exclude_annotations,
- args.test_filter,
- args.test_data,
- args.save_perf_json,
- args.screenshot_failures,
- args.uiautomator_jar,
- args.uiautomator_info_jar,
- args.package,
- args.set_asserts)
-
-
-def AddJUnitTestOptions(parser):
- """Adds junit test options to |parser|."""
-
- group = parser.add_argument_group('JUnit Test Options')
- group.add_argument(
- '-s', '--test-suite', dest='test_suite', required=True,
- help=('JUnit test suite to run.'))
- group.add_argument(
- '-f', '--test-filter', dest='test_filter',
- help='Filters tests googletest-style.')
- group.add_argument(
- '--package-filter', dest='package_filter',
- help='Filters tests by package.')
- group.add_argument(
- '--runner-filter', dest='runner_filter',
- help='Filters tests by runner class. Must be fully qualified.')
- group.add_argument(
- '--sdk-version', dest='sdk_version', type=int,
- help='The Android SDK version.')
- AddCommonOptions(parser)
-
-
-def AddMonkeyTestOptions(parser):
- """Adds monkey test options to |parser|."""
-
- group = parser.add_argument_group('Monkey Test Options')
- group.add_argument(
- '--package', required=True, choices=constants.PACKAGE_INFO.keys(),
- metavar='PACKAGE', help='Package under test.')
- group.add_argument(
- '--event-count', default=10000, type=int,
- help='Number of events to generate (default: %(default)s).')
- group.add_argument(
- '--category', default='',
- help='A list of allowed categories.')
- group.add_argument(
- '--throttle', default=100, type=int,
- help='Delay between events (ms) (default: %(default)s). ')
- group.add_argument(
- '--seed', type=int,
- help=('Seed value for pseudo-random generator. Same seed value generates '
- 'the same sequence of events. Seed is randomized by default.'))
- group.add_argument(
- '--extra-args', default='',
- help=('String of other args to pass to the command verbatim.'))
-
- AddCommonOptions(parser)
- AddDeviceOptions(parser)
-
-def ProcessMonkeyTestOptions(args):
- """Processes all monkey test options.
-
- Args:
- args: argparse.Namespace object.
-
- Returns:
- A MonkeyOptions named tuple which contains all options relevant to
- monkey tests.
- """
- # TODO(jbudorick): Handle this directly in argparse with nargs='+'
- category = args.category
- if category:
- category = args.category.split(',')
-
- # TODO(jbudorick): Get rid of MonkeyOptions.
- return monkey_test_options.MonkeyOptions(
- args.verbose_count,
- args.package,
- args.event_count,
- category,
- args.throttle,
- args.seed,
- args.extra_args)
-
-def AddUirobotTestOptions(parser):
- """Adds uirobot test options to |option_parser|."""
- group = parser.add_argument_group('Uirobot Test Options')
-
- group.add_argument('--app-under-test', required=True,
- help='APK to run tests on.')
- group.add_argument(
- '--minutes', default=5, type=int,
- help='Number of minutes to run uirobot test [default: %(default)s].')
-
- AddCommonOptions(parser)
- AddDeviceOptions(parser)
- AddRemoteDeviceOptions(parser)
-
-def AddPerfTestOptions(parser):
- """Adds perf test options to |parser|."""
-
- group = parser.add_argument_group('Perf Test Options')
-
- class SingleStepAction(argparse.Action):
- def __call__(self, parser, namespace, values, option_string=None):
- if values and not namespace.single_step:
- parser.error('single step command provided, '
- 'but --single-step not specified.')
- elif namespace.single_step and not values:
- parser.error('--single-step specified, '
- 'but no single step command provided.')
- setattr(namespace, self.dest, values)
-
- step_group = group.add_mutually_exclusive_group(required=True)
- # TODO(jbudorick): Revise --single-step to use argparse.REMAINDER.
- # This requires removing "--" from client calls.
- step_group.add_argument(
- '--single-step', action='store_true',
- help='Execute the given command with retries, but only print the result '
- 'for the "most successful" round.')
- step_group.add_argument(
- '--steps',
- help='JSON file containing the list of commands to run.')
- step_group.add_argument(
- '--print-step',
- help='The name of a previously executed perf step to print.')
-
- group.add_argument(
- '--output-json-list',
- help='Write a simple list of names from --steps into the given file.')
- group.add_argument(
- '--collect-chartjson-data',
- action='store_true',
- help='Cache the chartjson output from each step for later use.')
- group.add_argument(
- '--output-chartjson-data',
- default='',
- help='Write out chartjson into the given file.')
- group.add_argument(
- '--flaky-steps',
- help=('A JSON file containing steps that are flaky '
- 'and will have its exit code ignored.'))
- group.add_argument(
- '--no-timeout', action='store_true',
- help=('Do not impose a timeout. Each perf step is responsible for '
- 'implementing the timeout logic.'))
- group.add_argument(
- '-f', '--test-filter',
- help=('Test filter (will match against the names listed in --steps).'))
- group.add_argument(
- '--dry-run', action='store_true',
- help='Just print the steps without executing.')
- # Uses 0.1 degrees C because that's what Android does.
- group.add_argument(
- '--max-battery-temp', type=int,
- help='Only start tests when the battery is at or below the given '
- 'temperature (0.1 C)')
- group.add_argument('single_step_command', nargs='*', action=SingleStepAction,
- help='If --single-step is specified, the command to run.')
- group.add_argument('--min-battery-level', type=int,
- help='Only starts tests when the battery is charged above '
- 'given level.')
- AddCommonOptions(parser)
- AddDeviceOptions(parser)
-
-
-def ProcessPerfTestOptions(args):
- """Processes all perf test options.
-
- Args:
- args: argparse.Namespace object.
-
- Returns:
- A PerfOptions named tuple which contains all options relevant to
- perf tests.
- """
- # TODO(jbudorick): Move single_step handling down into the perf tests.
- if args.single_step:
- args.single_step = ' '.join(args.single_step_command)
- # TODO(jbudorick): Get rid of PerfOptions.
- return perf_test_options.PerfOptions(
- args.steps, args.flaky_steps, args.output_json_list,
- args.print_step, args.no_timeout, args.test_filter,
- args.dry_run, args.single_step, args.collect_chartjson_data,
- args.output_chartjson_data, args.max_battery_temp, args.min_battery_level)
-
-
-def AddPythonTestOptions(parser):
- group = parser.add_argument_group('Python Test Options')
- group.add_argument(
- '-s', '--suite', dest='suite_name', metavar='SUITE_NAME',
- choices=constants.PYTHON_UNIT_TEST_SUITES.keys(),
- help='Name of the test suite to run.')
- AddCommonOptions(parser)
-
-
-def _RunGTests(args, devices):
- """Subcommand of RunTestsCommands which runs gtests."""
- exit_code = 0
- for suite_name in args.suite_name:
- # TODO(jbudorick): Either deprecate multi-suite or move its handling down
- # into the gtest code.
- gtest_options = gtest_test_options.GTestOptions(
- args.tool,
- args.test_filter,
- args.run_disabled,
- args.test_arguments,
- args.timeout,
- args.isolate_file_path,
- suite_name,
- args.app_data_files,
- args.app_data_file_dir,
- args.delete_stale_data)
- runner_factory, tests = gtest_setup.Setup(gtest_options, devices)
-
- results, test_exit_code = test_dispatcher.RunTests(
- tests, runner_factory, devices, shard=True, test_timeout=None,
- num_retries=args.num_retries)
-
- if test_exit_code and exit_code != constants.ERROR_EXIT_CODE:
- exit_code = test_exit_code
-
- report_results.LogFull(
- results=results,
- test_type='Unit test',
- test_package=suite_name,
- flakiness_server=args.flakiness_dashboard_server)
-
- if args.json_results_file:
- json_results.GenerateJsonResultsFile(results, args.json_results_file)
-
- return exit_code
-
-
-def _RunLinkerTests(args, devices):
- """Subcommand of RunTestsCommands which runs linker tests."""
- runner_factory, tests = linker_setup.Setup(args, devices)
-
- results, exit_code = test_dispatcher.RunTests(
- tests, runner_factory, devices, shard=True, test_timeout=60,
- num_retries=args.num_retries)
-
- report_results.LogFull(
- results=results,
- test_type='Linker test',
- test_package='ChromiumLinkerTest')
-
- if args.json_results_file:
- json_results.GenerateJsonResultsFile(results, args.json_results_file)
-
- return exit_code
-
-
-def _RunInstrumentationTests(args, devices):
- """Subcommand of RunTestsCommands which runs instrumentation tests."""
- logging.info('_RunInstrumentationTests(%s, %s)' % (str(args), str(devices)))
-
- instrumentation_options = ProcessInstrumentationOptions(args)
-
- if len(devices) > 1 and args.wait_for_debugger:
- logging.warning('Debugger can not be sharded, using first available device')
- devices = devices[:1]
-
- results = base_test_result.TestRunResults()
- exit_code = 0
-
- if args.run_java_tests:
- runner_factory, tests = instrumentation_setup.Setup(
- instrumentation_options, devices)
-
- test_results, exit_code = test_dispatcher.RunTests(
- tests, runner_factory, devices, shard=True, test_timeout=None,
- num_retries=args.num_retries)
-
- results.AddTestRunResults(test_results)
-
- if args.run_python_tests:
- runner_factory, tests = host_driven_setup.InstrumentationSetup(
- args.host_driven_root, args.official_build,
- instrumentation_options)
-
- if tests:
- test_results, test_exit_code = test_dispatcher.RunTests(
- tests, runner_factory, devices, shard=True, test_timeout=None,
- num_retries=args.num_retries)
-
- results.AddTestRunResults(test_results)
-
- # Only allow exit code escalation
- if test_exit_code and exit_code != constants.ERROR_EXIT_CODE:
- exit_code = test_exit_code
-
- if args.device_flags:
- args.device_flags = os.path.join(constants.DIR_SOURCE_ROOT,
- args.device_flags)
-
- report_results.LogFull(
- results=results,
- test_type='Instrumentation',
- test_package=os.path.basename(args.test_apk),
- annotation=args.annotations,
- flakiness_server=args.flakiness_dashboard_server)
-
- if args.json_results_file:
- json_results.GenerateJsonResultsFile(results, args.json_results_file)
-
- return exit_code
-
-
-def _RunUIAutomatorTests(args, devices):
- """Subcommand of RunTestsCommands which runs uiautomator tests."""
- uiautomator_options = ProcessUIAutomatorOptions(args)
-
- runner_factory, tests = uiautomator_setup.Setup(uiautomator_options)
-
- results, exit_code = test_dispatcher.RunTests(
- tests, runner_factory, devices, shard=True, test_timeout=None,
- num_retries=args.num_retries)
-
- report_results.LogFull(
- results=results,
- test_type='UIAutomator',
- test_package=os.path.basename(args.test_jar),
- annotation=args.annotations,
- flakiness_server=args.flakiness_dashboard_server)
-
- if args.json_results_file:
- json_results.GenerateJsonResultsFile(results, args.json_results_file)
-
- return exit_code
-
-
-def _RunJUnitTests(args):
- """Subcommand of RunTestsCommand which runs junit tests."""
- runner_factory, tests = junit_setup.Setup(args)
- results, exit_code = junit_dispatcher.RunTests(tests, runner_factory)
-
- report_results.LogFull(
- results=results,
- test_type='JUnit',
- test_package=args.test_suite)
-
- if args.json_results_file:
- json_results.GenerateJsonResultsFile(results, args.json_results_file)
-
- return exit_code
-
-
-def _RunMonkeyTests(args, devices):
- """Subcommand of RunTestsCommands which runs monkey tests."""
- monkey_options = ProcessMonkeyTestOptions(args)
-
- runner_factory, tests = monkey_setup.Setup(monkey_options)
-
- results, exit_code = test_dispatcher.RunTests(
- tests, runner_factory, devices, shard=False, test_timeout=None,
- num_retries=args.num_retries)
-
- report_results.LogFull(
- results=results,
- test_type='Monkey',
- test_package='Monkey')
-
- if args.json_results_file:
- json_results.GenerateJsonResultsFile(results, args.json_results_file)
-
- return exit_code
-
-
-def _RunPerfTests(args):
- """Subcommand of RunTestsCommands which runs perf tests."""
- perf_options = ProcessPerfTestOptions(args)
-
- # Just save a simple json with a list of test names.
- if perf_options.output_json_list:
- return perf_test_runner.OutputJsonList(
- perf_options.steps, perf_options.output_json_list)
-
- # Just print the results from a single previously executed step.
- if perf_options.print_step:
- return perf_test_runner.PrintTestOutput(
- perf_options.print_step, perf_options.output_chartjson_data)
-
- runner_factory, tests, devices = perf_setup.Setup(perf_options)
-
- # shard=False means that each device will get the full list of tests
- # and then each one will decide their own affinity.
- # shard=True means each device will pop the next test available from a queue,
- # which increases throughput but have no affinity.
- results, _ = test_dispatcher.RunTests(
- tests, runner_factory, devices, shard=False, test_timeout=None,
- num_retries=args.num_retries)
-
- report_results.LogFull(
- results=results,
- test_type='Perf',
- test_package='Perf')
-
- if args.json_results_file:
- json_results.GenerateJsonResultsFile(results, args.json_results_file)
-
- if perf_options.single_step:
- return perf_test_runner.PrintTestOutput('single_step')
-
- perf_test_runner.PrintSummary(tests)
-
- # Always return 0 on the sharding stage. Individual tests exit_code
- # will be returned on the print_step stage.
- return 0
-
-
-def _RunPythonTests(args):
- """Subcommand of RunTestsCommand which runs python unit tests."""
- suite_vars = constants.PYTHON_UNIT_TEST_SUITES[args.suite_name]
- suite_path = suite_vars['path']
- suite_test_modules = suite_vars['test_modules']
-
- sys.path = [suite_path] + sys.path
- try:
- suite = unittest.TestSuite()
- suite.addTests(unittest.defaultTestLoader.loadTestsFromName(m)
- for m in suite_test_modules)
- runner = unittest.TextTestRunner(verbosity=1+args.verbose_count)
- return 0 if runner.run(suite).wasSuccessful() else 1
- finally:
- sys.path = sys.path[1:]
-
-
-def _GetAttachedDevices(test_device=None):
- """Get all attached devices.
-
- Args:
- test_device: Name of a specific device to use.
-
- Returns:
- A list of attached devices.
- """
- attached_devices = device_utils.DeviceUtils.HealthyDevices()
- if test_device:
- test_device = [d for d in attached_devices if d == test_device]
- if not test_device:
- raise device_errors.DeviceUnreachableError(
- 'Did not find device %s among attached device. Attached devices: %s'
- % (test_device, ', '.join(attached_devices)))
- return test_device
-
- else:
- if not attached_devices:
- raise device_errors.NoDevicesError()
- return sorted(attached_devices)
-
-
-def RunTestsCommand(args, parser):
- """Checks test type and dispatches to the appropriate function.
-
- Args:
- args: argparse.Namespace object.
- parser: argparse.ArgumentParser object.
-
- Returns:
- Integer indicated exit code.
-
- Raises:
- Exception: Unknown command name passed in, or an exception from an
- individual test runner.
- """
- command = args.command
-
- ProcessCommonOptions(args)
-
- if args.enable_platform_mode:
- return RunTestsInPlatformMode(args, parser)
-
- if command in constants.LOCAL_MACHINE_TESTS:
- devices = []
- else:
- devices = _GetAttachedDevices(args.test_device)
-
- forwarder.Forwarder.RemoveHostLog()
- if not ports.ResetTestServerPortAllocation():
- raise Exception('Failed to reset test server port.')
-
- if command == 'gtest':
- if args.suite_name[0] in gtest_test_instance.BROWSER_TEST_SUITES:
- return RunTestsInPlatformMode(args, parser)
- return _RunGTests(args, devices)
- elif command == 'linker':
- return _RunLinkerTests(args, devices)
- elif command == 'instrumentation':
- return _RunInstrumentationTests(args, devices)
- elif command == 'uiautomator':
- return _RunUIAutomatorTests(args, devices)
- elif command == 'junit':
- return _RunJUnitTests(args)
- elif command == 'monkey':
- return _RunMonkeyTests(args, devices)
- elif command == 'perf':
- return _RunPerfTests(args)
- elif command == 'python':
- return _RunPythonTests(args)
- else:
- raise Exception('Unknown test type.')
-
-
-_SUPPORTED_IN_PLATFORM_MODE = [
- # TODO(jbudorick): Add support for more test types.
- 'gtest',
- 'instrumentation',
- 'uirobot',
-]
-
-
-def RunTestsInPlatformMode(args, parser):
-
- if args.command not in _SUPPORTED_IN_PLATFORM_MODE:
- parser.error('%s is not yet supported in platform mode' % args.command)
-
- with environment_factory.CreateEnvironment(args, parser.error) as env:
- with test_instance_factory.CreateTestInstance(args, parser.error) as test:
- with test_run_factory.CreateTestRun(
- args, env, test, parser.error) as test_run:
- results = test_run.RunTests()
-
- if args.environment == 'remote_device' and args.trigger:
- return 0 # Not returning results, only triggering.
-
- report_results.LogFull(
- results=results,
- test_type=test.TestType(),
- test_package=test_run.TestPackage(),
- annotation=getattr(args, 'annotations', None),
- flakiness_server=getattr(args, 'flakiness_dashboard_server', None))
-
- if args.json_results_file:
- json_results.GenerateJsonResultsFile(
- results, args.json_results_file)
-
- return 0 if results.DidRunPass() else constants.ERROR_EXIT_CODE
-
-
-CommandConfigTuple = collections.namedtuple(
- 'CommandConfigTuple',
- ['add_options_func', 'help_txt'])
-VALID_COMMANDS = {
- 'gtest': CommandConfigTuple(
- AddGTestOptions,
- 'googletest-based C++ tests'),
- 'instrumentation': CommandConfigTuple(
- AddInstrumentationTestOptions,
- 'InstrumentationTestCase-based Java tests'),
- 'uiautomator': CommandConfigTuple(
- AddUIAutomatorTestOptions,
- "Tests that run via Android's uiautomator command"),
- 'junit': CommandConfigTuple(
- AddJUnitTestOptions,
- 'JUnit4-based Java tests'),
- 'monkey': CommandConfigTuple(
- AddMonkeyTestOptions,
- "Tests based on Android's monkey"),
- 'perf': CommandConfigTuple(
- AddPerfTestOptions,
- 'Performance tests'),
- 'python': CommandConfigTuple(
- AddPythonTestOptions,
- 'Python tests based on unittest.TestCase'),
- 'linker': CommandConfigTuple(
- AddLinkerTestOptions,
- 'Linker tests'),
- 'uirobot': CommandConfigTuple(
- AddUirobotTestOptions,
- 'Uirobot test'),
-}
-
-
-def DumpThreadStacks(_signal, _frame):
- for thread in threading.enumerate():
- reraiser_thread.LogThreadStack(thread)
-
-
-def main():
- signal.signal(signal.SIGUSR1, DumpThreadStacks)
-
- parser = argparse.ArgumentParser()
- command_parsers = parser.add_subparsers(title='test types',
- dest='command')
-
- for test_type, config in sorted(VALID_COMMANDS.iteritems(),
- key=lambda x: x[0]):
- subparser = command_parsers.add_parser(
- test_type, usage='%(prog)s [options]', help=config.help_txt)
- config.add_options_func(subparser)
-
- args = parser.parse_args()
-
- try:
- return RunTestsCommand(args, parser)
- except base_error.BaseError as e:
- logging.exception('Error occurred.')
- if e.is_infra_error:
- return constants.INFRA_EXIT_CODE
- return constants.ERROR_EXIT_CODE
- except: # pylint: disable=W0702
- logging.exception('Unrecognized error occurred.')
- return constants.ERROR_EXIT_CODE
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/build/android/tests/symbolize/Makefile b/build/android/tests/symbolize/Makefile
deleted file mode 100644
index 5178a04..0000000
--- a/build/android/tests/symbolize/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-TOOLCHAIN=../../../../third_party/android_tools/ndk/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86_64/bin/arm-linux-androideabi-
-CXX=$(TOOLCHAIN)g++
-
-lib%.so: %.cc
- $(CXX) -nostdlib -g -fPIC -shared $< -o $@
-
-all: liba.so libb.so
diff --git a/build/android/tests/symbolize/a.cc b/build/android/tests/symbolize/a.cc
deleted file mode 100644
index f0c7ca4..0000000
--- a/build/android/tests/symbolize/a.cc
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-class A {
- public:
- A();
- void Foo(int i);
- void Bar(const char* c);
-};
-
-A::A() {}
-void A::Foo(int i) {}
-void A::Bar(const char* c) {}
diff --git a/build/android/tests/symbolize/b.cc b/build/android/tests/symbolize/b.cc
deleted file mode 100644
index db87520..0000000
--- a/build/android/tests/symbolize/b.cc
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-class B {
- public:
- B();
- void Baz(float f);
- void Qux(double d);
-};
-
-B::B() {}
-void B::Baz(float f) {}
-void B::Qux(double d) {}
diff --git a/build/android/tests/symbolize/liba.so b/build/android/tests/symbolize/liba.so
deleted file mode 100644
index 79cb739..0000000
--- a/build/android/tests/symbolize/liba.so
+++ /dev/null
Binary files differ
diff --git a/build/android/tests/symbolize/libb.so b/build/android/tests/symbolize/libb.so
deleted file mode 100644
index 7cf01d4..0000000
--- a/build/android/tests/symbolize/libb.so
+++ /dev/null
Binary files differ
diff --git a/build/android/tombstones.py b/build/android/tombstones.py
deleted file mode 100755
index dbfe3f7..0000000
--- a/build/android/tombstones.py
+++ /dev/null
@@ -1,252 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-#
-# Find the most recent tombstone file(s) on all connected devices
-# and prints their stacks.
-#
-# Assumes tombstone file was created with current symbols.
-
-import datetime
-import itertools
-import logging
-import multiprocessing
-import os
-import re
-import subprocess
-import sys
-import optparse
-
-from pylib.device import adb_wrapper
-from pylib.device import device_errors
-from pylib.device import device_utils
-from pylib.utils import run_tests_helper
-
-
-_TZ_UTC = {'TZ': 'UTC'}
-
-def _ListTombstones(device):
- """List the tombstone files on the device.
-
- Args:
- device: An instance of DeviceUtils.
-
- Yields:
- Tuples of (tombstone filename, date time of file on device).
- """
- try:
- lines = device.RunShellCommand(
- ['ls', '-a', '-l', '/data/tombstones'],
- as_root=True, check_return=True, env=_TZ_UTC, timeout=60)
- for line in lines:
- if 'tombstone' in line and not 'No such file or directory' in line:
- details = line.split()
- t = datetime.datetime.strptime(details[-3] + ' ' + details[-2],
- '%Y-%m-%d %H:%M')
- yield details[-1], t
- except device_errors.CommandFailedError:
- logging.exception('Could not retrieve tombstones.')
-
-
-def _GetDeviceDateTime(device):
- """Determine the date time on the device.
-
- Args:
- device: An instance of DeviceUtils.
-
- Returns:
- A datetime instance.
- """
- device_now_string = device.RunShellCommand(
- ['date'], check_return=True, env=_TZ_UTC)
- return datetime.datetime.strptime(
- device_now_string[0], '%a %b %d %H:%M:%S %Z %Y')
-
-
-def _GetTombstoneData(device, tombstone_file):
- """Retrieve the tombstone data from the device
-
- Args:
- device: An instance of DeviceUtils.
- tombstone_file: the tombstone to retrieve
-
- Returns:
- A list of lines
- """
- return device.ReadFile(
- '/data/tombstones/' + tombstone_file, as_root=True).splitlines()
-
-
-def _EraseTombstone(device, tombstone_file):
- """Deletes a tombstone from the device.
-
- Args:
- device: An instance of DeviceUtils.
- tombstone_file: the tombstone to delete.
- """
- return device.RunShellCommand(
- ['rm', '/data/tombstones/' + tombstone_file],
- as_root=True, check_return=True)
-
-
-def _DeviceAbiToArch(device_abi):
- # The order of this list is significant to find the more specific match (e.g.,
- # arm64) before the less specific (e.g., arm).
- arches = ['arm64', 'arm', 'x86_64', 'x86_64', 'x86', 'mips']
- for arch in arches:
- if arch in device_abi:
- return arch
- raise RuntimeError('Unknown device ABI: %s' % device_abi)
-
-def _ResolveSymbols(tombstone_data, include_stack, device_abi):
- """Run the stack tool for given tombstone input.
-
- Args:
- tombstone_data: a list of strings of tombstone data.
- include_stack: boolean whether to include stack data in output.
- device_abi: the default ABI of the device which generated the tombstone.
-
- Yields:
- A string for each line of resolved stack output.
- """
- # Check if the tombstone data has an ABI listed, if so use this in preference
- # to the device's default ABI.
- for line in tombstone_data:
- found_abi = re.search('ABI: \'(.+?)\'', line)
- if found_abi:
- device_abi = found_abi.group(1)
- arch = _DeviceAbiToArch(device_abi)
- if not arch:
- return
-
- stack_tool = os.path.join(os.path.dirname(__file__), '..', '..',
- 'third_party', 'android_platform', 'development',
- 'scripts', 'stack')
- proc = subprocess.Popen([stack_tool, '--arch', arch], stdin=subprocess.PIPE,
- stdout=subprocess.PIPE)
- output = proc.communicate(input='\n'.join(tombstone_data))[0]
- for line in output.split('\n'):
- if not include_stack and 'Stack Data:' in line:
- break
- yield line
-
-
-def _ResolveTombstone(tombstone):
- lines = []
- lines += [tombstone['file'] + ' created on ' + str(tombstone['time']) +
- ', about this long ago: ' +
- (str(tombstone['device_now'] - tombstone['time']) +
- ' Device: ' + tombstone['serial'])]
- logging.info('\n'.join(lines))
- logging.info('Resolving...')
- lines += _ResolveSymbols(tombstone['data'], tombstone['stack'],
- tombstone['device_abi'])
- return lines
-
-
-def _ResolveTombstones(jobs, tombstones):
- """Resolve a list of tombstones.
-
- Args:
- jobs: the number of jobs to use with multiprocess.
- tombstones: a list of tombstones.
- """
- if not tombstones:
- logging.warning('No tombstones to resolve.')
- return
- if len(tombstones) == 1:
- data = [_ResolveTombstone(tombstones[0])]
- else:
- pool = multiprocessing.Pool(processes=jobs)
- data = pool.map(_ResolveTombstone, tombstones)
- for tombstone in data:
- for line in tombstone:
- logging.info(line)
-
-
-def _GetTombstonesForDevice(device, options):
- """Returns a list of tombstones on a given device.
-
- Args:
- device: An instance of DeviceUtils.
- options: command line arguments from OptParse
- """
- ret = []
- all_tombstones = list(_ListTombstones(device))
- if not all_tombstones:
- logging.warning('No tombstones.')
- return ret
-
- # Sort the tombstones in date order, descending
- all_tombstones.sort(cmp=lambda a, b: cmp(b[1], a[1]))
-
- # Only resolve the most recent unless --all-tombstones given.
- tombstones = all_tombstones if options.all_tombstones else [all_tombstones[0]]
-
- device_now = _GetDeviceDateTime(device)
- try:
- for tombstone_file, tombstone_time in tombstones:
- ret += [{'serial': str(device),
- 'device_abi': device.product_cpu_abi,
- 'device_now': device_now,
- 'time': tombstone_time,
- 'file': tombstone_file,
- 'stack': options.stack,
- 'data': _GetTombstoneData(device, tombstone_file)}]
- except device_errors.CommandFailedError:
- for line in device.RunShellCommand(
- ['ls', '-a', '-l', '/data/tombstones'],
- as_root=True, check_return=True, env=_TZ_UTC, timeout=60):
- logging.info('%s: %s', str(device), line)
- raise
-
- # Erase all the tombstones if desired.
- if options.wipe_tombstones:
- for tombstone_file, _ in all_tombstones:
- _EraseTombstone(device, tombstone_file)
-
- return ret
-
-
-def main():
- custom_handler = logging.StreamHandler(sys.stdout)
- custom_handler.setFormatter(run_tests_helper.CustomFormatter())
- logging.getLogger().addHandler(custom_handler)
- logging.getLogger().setLevel(logging.INFO)
-
- parser = optparse.OptionParser()
- parser.add_option('--device',
- help='The serial number of the device. If not specified '
- 'will use all devices.')
- parser.add_option('-a', '--all-tombstones', action='store_true',
- help="""Resolve symbols for all tombstones, rather than just
- the most recent""")
- parser.add_option('-s', '--stack', action='store_true',
- help='Also include symbols for stack data')
- parser.add_option('-w', '--wipe-tombstones', action='store_true',
- help='Erase all tombstones from device after processing')
- parser.add_option('-j', '--jobs', type='int',
- default=4,
- help='Number of jobs to use when processing multiple '
- 'crash stacks.')
- options, _ = parser.parse_args()
-
- if options.device:
- devices = [device_utils.DeviceUtils(options.device)]
- else:
- devices = device_utils.DeviceUtils.HealthyDevices()
-
- # This must be done serially because strptime can hit a race condition if
- # used for the first time in a multithreaded environment.
- # http://bugs.python.org/issue7980
- tombstones = []
- for device in devices:
- tombstones += _GetTombstonesForDevice(device, options)
-
- _ResolveTombstones(options.jobs, tombstones)
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/build/android/update_verification.py b/build/android/update_verification.py
deleted file mode 100755
index 05d083b..0000000
--- a/build/android/update_verification.py
+++ /dev/null
@@ -1,108 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Runs semi-automated update testing on a non-rooted device.
-
-This script will help verify that app data is preserved during an update.
-To use this script first run it with the create_app_data option.
-
-./update_verification.py create_app_data --old-apk <path> --app-data <path>
-
-The script will then install the old apk, prompt you to create some app data
-(bookmarks, etc.), and then save the app data in the path you gave it.
-
-Next, once you have some app data saved, run this script with the test_update
-option.
-
-./update_verification.py test_update --old-apk <path> --new-apk <path>
---app-data <path>
-
-This will install the old apk, load the saved app data, install the new apk,
-and ask the user to verify that all of the app data was preserved.
-"""
-
-import argparse
-import logging
-import os
-import sys
-import time
-
-from pylib import constants
-from pylib.device import device_errors
-from pylib.device import device_utils
-from pylib.utils import apk_helper
-from pylib.utils import run_tests_helper
-
-def CreateAppData(device, old_apk, app_data, package_name):
- device.Install(old_apk)
- raw_input('Set the application state. Once ready, press enter and '
- 'select "Backup my data" on the device.')
- device.adb.Backup(app_data, packages=[package_name])
- logging.critical('Application data saved to %s' % app_data)
-
-def TestUpdate(device, old_apk, new_apk, app_data, package_name):
- device.Install(old_apk)
- device.adb.Restore(app_data)
- # Restore command is not synchronous
- raw_input('Select "Restore my data" on the device. Then press enter to '
- 'continue.')
- device_path = device.GetApplicationPaths(package_name)
- if not device_path:
- raise Exception('Expected package %s to already be installed. '
- 'Package name might have changed!' % package_name)
-
- logging.info('Verifying that %s can be overinstalled.', new_apk)
- device.adb.Install(new_apk, reinstall=True)
- logging.critical('Successfully updated to the new apk. Please verify that '
- 'the application data is preserved.')
-
-def main():
- parser = argparse.ArgumentParser(
- description="Script to do semi-automated upgrade testing.")
- parser.add_argument('-v', '--verbose', action='count',
- help='Print verbose log information.')
- command_parsers = parser.add_subparsers(dest='command')
-
- subparser = command_parsers.add_parser('create_app_data')
- subparser.add_argument('--old-apk', required=True,
- help='Path to apk to update from.')
- subparser.add_argument('--app-data', required=True,
- help='Path to where the app data backup should be '
- 'saved to.')
- subparser.add_argument('--package-name',
- help='Chrome apk package name.')
-
- subparser = command_parsers.add_parser('test_update')
- subparser.add_argument('--old-apk', required=True,
- help='Path to apk to update from.')
- subparser.add_argument('--new-apk', required=True,
- help='Path to apk to update to.')
- subparser.add_argument('--app-data', required=True,
- help='Path to where the app data backup is saved.')
- subparser.add_argument('--package-name',
- help='Chrome apk package name.')
-
- args = parser.parse_args()
- run_tests_helper.SetLogLevel(args.verbose)
-
- devices = device_utils.DeviceUtils.HealthyDevices()
- if not devices:
- raise device_errors.NoDevicesError()
- device = devices[0]
- logging.info('Using device %s for testing.' % str(device))
-
- package_name = (args.package_name if args.package_name
- else apk_helper.GetPackageName(args.old_apk))
- if args.command == 'create_app_data':
- CreateAppData(device, args.old_apk, args.app_data, package_name)
- elif args.command == 'test_update':
- TestUpdate(
- device, args.old_apk, args.new_apk, args.app_data, package_name)
- else:
- raise Exception('Unknown test command: %s' % args.command)
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/build/android/write_ordered_libraries.gypi b/build/android/write_ordered_libraries.gypi
deleted file mode 100644
index 1b52e71..0000000
--- a/build/android/write_ordered_libraries.gypi
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included into an action to provide a rule that
-# generates a json file with the list of dependent libraries needed for a given
-# shared library or executable.
-#
-# To use this, create a gyp target with the following form:
-# {
-# 'actions': [
-# 'variables': {
-# 'input_libraries': 'shared library or executable to process',
-# 'ordered_libraries_file': 'file to generate'
-# },
-# 'includes': [ '../../build/android/write_ordered_libraries.gypi' ],
-# ],
-# },
-#
-
-{
- 'action_name': 'ordered_libraries_<(_target_name)<(subtarget)',
- 'message': 'Writing dependency ordered libraries for <(_target_name)',
- 'variables': {
- 'input_libraries%': [],
- 'subtarget%': '',
- },
- 'inputs': [
- '<(DEPTH)/build/android/gyp/util/build_utils.py',
- '<(DEPTH)/build/android/gyp/write_ordered_libraries.py',
- '<@(input_libraries)',
- ],
- 'outputs': [
- '<(ordered_libraries_file)',
- ],
- 'action': [
- 'python', '<(DEPTH)/build/android/gyp/write_ordered_libraries.py',
- '--input-libraries=<(input_libraries)',
- '--libraries-dir=<(SHARED_LIB_DIR),<(PRODUCT_DIR)',
- '--readelf=<(android_readelf)',
- '--output=<(ordered_libraries_file)',
- ],
-}
diff --git a/build/android_sdk_extras.json b/build/android_sdk_extras.json
deleted file mode 100644
index 25b47c3..0000000
--- a/build/android_sdk_extras.json
+++ /dev/null
@@ -1,9 +0,0 @@
-[
- {
- "dir_name": "google",
- "version": "21.0.0",
- "zip": "google_google_play_services_21.0.0.zip",
- "package": "google_play_services",
- "package_id": "extra-google-google_play_services"
- }
-]
diff --git a/build/apk_browsertest.gypi b/build/apk_browsertest.gypi
deleted file mode 100644
index 316f52f..0000000
--- a/build/apk_browsertest.gypi
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included into a target to provide a rule
-# to build APK-based browser test suites.
-#
-# To use this, create a gyp target with the following form:
-# {
-# 'target_name': 'test_suite_name_apk',
-# 'type': 'none',
-# 'variables': {
-# 'test_suite_name': 'test_suite_name', # string
-# 'java_in_dir': 'path/to/java/dir',
-# },
-# 'includes': ['path/to/this/gypi/file'],
-# }
-#
-
-{
- 'dependencies': [
- '<(DEPTH)/base/base.gyp:base_java',
- '<(DEPTH)/build/android/pylib/device/commands/commands.gyp:chromium_commands',
- '<(DEPTH)/build/android/pylib/remote/device/dummy/dummy.gyp:remote_device_dummy_apk',
- '<(DEPTH)/testing/android/appurify_support.gyp:appurify_support_java',
- '<(DEPTH)/testing/android/native_test.gyp:native_test_java',
- '<(DEPTH)/tools/android/android_tools.gyp:android_tools',
- ],
- 'conditions': [
- ['OS == "android"', {
- 'variables': {
- # These are used to configure java_apk.gypi included below.
- 'apk_name': '<(test_suite_name)',
- 'intermediate_dir': '<(PRODUCT_DIR)/<(test_suite_name)_apk',
- 'final_apk_path': '<(intermediate_dir)/<(test_suite_name)-debug.apk',
- 'native_lib_target': 'lib<(test_suite_name)',
- # TODO(yfriedman, cjhopman): Support managed installs for gtests.
- 'gyp_managed_install': 0,
- },
- 'includes': [ 'java_apk.gypi' ],
- }], # 'OS == "android"
- ], # conditions
-}
diff --git a/build/apk_fake_jar.gypi b/build/apk_fake_jar.gypi
deleted file mode 100644
index 128b84c..0000000
--- a/build/apk_fake_jar.gypi
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included into a target to provide a rule
-# to build Java in a consistent manner.
-
-{
- 'all_dependent_settings': {
- 'variables': {
- 'input_jars_paths': ['>(apk_output_jar_path)'],
- 'library_dexed_jars_paths': ['>(apk_output_jar_path)'],
- },
- },
-}
diff --git a/build/apk_test.gypi b/build/apk_test.gypi
deleted file mode 100644
index e0d323f..0000000
--- a/build/apk_test.gypi
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included into a target to provide a rule
-# to build APK based test suites.
-#
-# To use this, create a gyp target with the following form:
-# {
-# 'target_name': 'test_suite_name_apk',
-# 'type': 'none',
-# 'variables': {
-# 'test_suite_name': 'test_suite_name', # string
-# 'input_jars_paths': ['/path/to/test_suite.jar', ... ], # list
-# },
-# 'includes': ['path/to/this/gypi/file'],
-# }
-#
-
-{
- 'dependencies': [
- '<(DEPTH)/base/base.gyp:base_java',
- '<(DEPTH)/build/android/pylib/device/commands/commands.gyp:chromium_commands',
- '<(DEPTH)/build/android/pylib/remote/device/dummy/dummy.gyp:remote_device_dummy_apk',
- '<(DEPTH)/testing/android/appurify_support.gyp:appurify_support_java',
- '<(DEPTH)/testing/android/on_device_instrumentation.gyp:reporter_java',
- '<(DEPTH)/tools/android/android_tools.gyp:android_tools',
- ],
- 'conditions': [
- ['OS == "android"', {
- 'variables': {
- # These are used to configure java_apk.gypi included below.
- 'test_type': 'gtest',
- 'apk_name': '<(test_suite_name)',
- 'intermediate_dir': '<(PRODUCT_DIR)/<(test_suite_name)_apk',
- 'final_apk_path': '<(intermediate_dir)/<(test_suite_name)-debug.apk',
- 'java_in_dir': '<(DEPTH)/testing/android/native_test/java',
- 'native_lib_target': 'lib<(test_suite_name)',
- # TODO(yfriedman, cjhopman): Support managed installs for gtests.
- 'gyp_managed_install': 0,
- },
- 'includes': [ 'java_apk.gypi', 'android/test_runner.gypi' ],
- }], # 'OS == "android"
- ], # conditions
-}
diff --git a/build/apply_locales.py b/build/apply_locales.py
deleted file mode 100755
index 6af7280..0000000
--- a/build/apply_locales.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2009 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# TODO: remove this script when GYP has for loops
-
-import sys
-import optparse
-
-def main(argv):
-
- parser = optparse.OptionParser()
- usage = 'usage: %s [options ...] format_string locale_list'
- parser.set_usage(usage.replace('%s', '%prog'))
- parser.add_option('-d', dest='dash_to_underscore', action="store_true",
- default=False,
- help='map "en-US" to "en" and "-" to "_" in locales')
-
- (options, arglist) = parser.parse_args(argv)
-
- if len(arglist) < 3:
- print 'ERROR: need string and list of locales'
- return 1
-
- str_template = arglist[1]
- locales = arglist[2:]
-
- results = []
- for locale in locales:
- # For Cocoa to find the locale at runtime, it needs to use '_' instead
- # of '-' (http://crbug.com/20441). Also, 'en-US' should be represented
- # simply as 'en' (http://crbug.com/19165, http://crbug.com/25578).
- if options.dash_to_underscore:
- if locale == 'en-US':
- locale = 'en'
- locale = locale.replace('-', '_')
- results.append(str_template.replace('ZZLOCALE', locale))
-
- # Quote each element so filename spaces don't mess up GYP's attempt to parse
- # it into a list.
- print ' '.join(["'%s'" % x for x in results])
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv))
diff --git a/build/branding_value.sh b/build/branding_value.sh
deleted file mode 100755
index 9fcb550..0000000
--- a/build/branding_value.sh
+++ /dev/null
@@ -1,51 +0,0 @@
-#!/bin/sh
-
-# Copyright (c) 2008 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This is a wrapper for fetching values from the BRANDING files. Pass the
-# value of GYP's branding variable followed by the key you want and the right
-# file is checked.
-#
-# branding_value.sh Chromium COPYRIGHT
-# branding_value.sh Chromium PRODUCT_FULLNAME
-#
-
-set -e
-
-if [ $# -ne 2 ] ; then
- echo "error: expect two arguments, branding and key" >&2
- exit 1
-fi
-
-BUILD_BRANDING=$1
-THE_KEY=$2
-
-pushd $(dirname "${0}") > /dev/null
-BUILD_DIR=$(pwd)
-popd > /dev/null
-
-TOP="${BUILD_DIR}/.."
-
-case ${BUILD_BRANDING} in
- Chromium)
- BRANDING_FILE="${TOP}/chrome/app/theme/chromium/BRANDING"
- ;;
- Chrome)
- BRANDING_FILE="${TOP}/chrome/app/theme/google_chrome/BRANDING"
- ;;
- *)
- echo "error: unknown branding: ${BUILD_BRANDING}" >&2
- exit 1
- ;;
-esac
-
-BRANDING_VALUE=$(sed -n -e "s/^${THE_KEY}=\(.*\)\$/\1/p" "${BRANDING_FILE}")
-
-if [ -z "${BRANDING_VALUE}" ] ; then
- echo "error: failed to find key '${THE_KEY}'" >&2
- exit 1
-fi
-
-echo "${BRANDING_VALUE}"
diff --git a/build/build-ctags.sh b/build/build-ctags.sh
deleted file mode 100755
index 61e017e..0000000
--- a/build/build-ctags.sh
+++ /dev/null
@@ -1,49 +0,0 @@
-#!/bin/bash
-
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-if [[ a"`ctags --version | head -1 | grep \"^Exuberant Ctags\"`" == "a" ]]; then
- cat <<EOF
- You must be using Exuberant Ctags, not just standard GNU ctags. If you are on
- Debian or a related flavor of Linux, you may want to try running
- apt-get install exuberant-ctags.
-EOF
- exit
-fi
-
-CHROME_SRC_DIR="$PWD"
-
-fail() {
- echo "Failed to create ctags for $1"
- exit 1
-}
-
-ctags_cmd() {
- echo "ctags --languages=C++ $1 --exclude=.git -R -f .tmp_tags"
-}
-
-build_dir() {
- local extraexcludes=""
- if [[ a"$1" == "a--extra-excludes" ]]; then
- extraexcludes="--exclude=third_party --exclude=build --exclude=out"
- shift
- fi
-
- cd "$CHROME_SRC_DIR/$1" || fail $1
- # Redirect error messages so they aren't seen because they are almost always
- # errors about components that you just happen to have not built (NaCl, for
- # example).
- $(ctags_cmd "$extraexcludes") 2> /dev/null || fail $1
- mv -f .tmp_tags tags
-}
-
-# We always build the top level but leave all submodules as optional.
-build_dir --extra-excludes "" "top level"
-
-# Build any other directies that are listed on the command line.
-for dir in $@; do
- build_dir "$1"
- shift
-done
diff --git a/build/build_config.h b/build/build_config.h
deleted file mode 100644
index d8c3db6..0000000
--- a/build/build_config.h
+++ /dev/null
@@ -1,168 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// This file adds defines about the platform we're currently building on.
-// Operating System:
-// OS_WIN / OS_MACOSX / OS_LINUX / OS_POSIX (MACOSX or LINUX) /
-// OS_NACL (NACL_SFI or NACL_NONSFI) / OS_NACL_SFI / OS_NACL_NONSFI
-// Compiler:
-// COMPILER_MSVC / COMPILER_GCC
-// Processor:
-// ARCH_CPU_X86 / ARCH_CPU_X86_64 / ARCH_CPU_X86_FAMILY (X86 or X86_64)
-// ARCH_CPU_32_BITS / ARCH_CPU_64_BITS
-
-#ifndef BUILD_BUILD_CONFIG_H_
-#define BUILD_BUILD_CONFIG_H_
-
-// A set of macros to use for platform detection.
-#if defined(__native_client__)
-// __native_client__ must be first, so that other OS_ defines are not set.
-#define OS_NACL 1
-// OS_NACL comes in two sandboxing technology flavors, SFI or Non-SFI.
-// PNaCl toolchain defines __native_client_nonsfi__ macro in Non-SFI build
-// mode, while it does not in SFI build mode.
-#if defined(__native_client_nonsfi__)
-#define OS_NACL_NONSFI
-#else
-#define OS_NACL_SFI
-#endif
-#elif defined(ANDROID)
-#define OS_ANDROID 1
-#elif defined(__APPLE__)
-// only include TargetConditions after testing ANDROID as some android builds
-// on mac don't have this header available and it's not needed unless the target
-// is really mac/ios.
-#include <TargetConditionals.h>
-#define OS_MACOSX 1
-#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
-#define OS_IOS 1
-#endif // defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
-#elif defined(__linux__)
-#define OS_LINUX 1
-// include a system header to pull in features.h for glibc/uclibc macros.
-#include <unistd.h>
-#if defined(__GLIBC__) && !defined(__UCLIBC__)
-// we really are using glibc, not uClibc pretending to be glibc
-#define LIBC_GLIBC 1
-#endif
-#elif defined(_WIN32)
-#define OS_WIN 1
-#define TOOLKIT_VIEWS 1
-#elif defined(__FreeBSD__)
-#define OS_FREEBSD 1
-#elif defined(__OpenBSD__)
-#define OS_OPENBSD 1
-#elif defined(__sun)
-#define OS_SOLARIS 1
-#elif defined(__QNXNTO__)
-#define OS_QNX 1
-#else
-#error Please add support for your platform in build/build_config.h
-#endif
-
-#if defined(USE_OPENSSL_CERTS) && defined(USE_NSS_CERTS)
-#error Cannot use both OpenSSL and NSS for certificates
-#endif
-
-// For access to standard BSD features, use OS_BSD instead of a
-// more specific macro.
-#if defined(OS_FREEBSD) || defined(OS_OPENBSD)
-#define OS_BSD 1
-#endif
-
-// For access to standard POSIXish features, use OS_POSIX instead of a
-// more specific macro.
-#if defined(OS_MACOSX) || defined(OS_LINUX) || defined(OS_FREEBSD) || \
- defined(OS_OPENBSD) || defined(OS_SOLARIS) || defined(OS_ANDROID) || \
- defined(OS_NACL) || defined(OS_QNX)
-#define OS_POSIX 1
-#endif
-
-// Use tcmalloc
-#if (defined(OS_WIN) || defined(OS_LINUX) || defined(OS_ANDROID)) && \
- !defined(NO_TCMALLOC)
-#define USE_TCMALLOC 1
-#endif
-
-// Compiler detection.
-#if defined(__GNUC__)
-#define COMPILER_GCC 1
-#elif defined(_MSC_VER)
-#define COMPILER_MSVC 1
-#else
-#error Please add support for your compiler in build/build_config.h
-#endif
-
-// Processor architecture detection. For more info on what's defined, see:
-// http://msdn.microsoft.com/en-us/library/b0084kay.aspx
-// http://www.agner.org/optimize/calling_conventions.pdf
-// or with gcc, run: "echo | gcc -E -dM -"
-#if defined(_M_X64) || defined(__x86_64__)
-#define ARCH_CPU_X86_FAMILY 1
-#define ARCH_CPU_X86_64 1
-#define ARCH_CPU_64_BITS 1
-#define ARCH_CPU_LITTLE_ENDIAN 1
-#elif defined(_M_IX86) || defined(__i386__)
-#define ARCH_CPU_X86_FAMILY 1
-#define ARCH_CPU_X86 1
-#define ARCH_CPU_32_BITS 1
-#define ARCH_CPU_LITTLE_ENDIAN 1
-#elif defined(__ARMEL__)
-#define ARCH_CPU_ARM_FAMILY 1
-#define ARCH_CPU_ARMEL 1
-#define ARCH_CPU_32_BITS 1
-#define ARCH_CPU_LITTLE_ENDIAN 1
-#elif defined(__aarch64__)
-#define ARCH_CPU_ARM_FAMILY 1
-#define ARCH_CPU_ARM64 1
-#define ARCH_CPU_64_BITS 1
-#define ARCH_CPU_LITTLE_ENDIAN 1
-#elif defined(__pnacl__)
-#define ARCH_CPU_32_BITS 1
-#define ARCH_CPU_LITTLE_ENDIAN 1
-#elif defined(__MIPSEL__)
-#if defined(__LP64__)
-#define ARCH_CPU_MIPS64_FAMILY 1
-#define ARCH_CPU_MIPS64EL 1
-#define ARCH_CPU_64_BITS 1
-#define ARCH_CPU_LITTLE_ENDIAN 1
-#else
-#define ARCH_CPU_MIPS_FAMILY 1
-#define ARCH_CPU_MIPSEL 1
-#define ARCH_CPU_32_BITS 1
-#define ARCH_CPU_LITTLE_ENDIAN 1
-#endif
-#else
-#error Please add support for your architecture in build/build_config.h
-#endif
-
-// Type detection for wchar_t.
-#if defined(OS_WIN)
-#define WCHAR_T_IS_UTF16
-#elif defined(OS_POSIX) && defined(COMPILER_GCC) && \
- defined(__WCHAR_MAX__) && \
- (__WCHAR_MAX__ == 0x7fffffff || __WCHAR_MAX__ == 0xffffffff)
-#define WCHAR_T_IS_UTF32
-#elif defined(OS_POSIX) && defined(COMPILER_GCC) && \
- defined(__WCHAR_MAX__) && \
- (__WCHAR_MAX__ == 0x7fff || __WCHAR_MAX__ == 0xffff)
-// On Posix, we'll detect short wchar_t, but projects aren't guaranteed to
-// compile in this mode (in particular, Chrome doesn't). This is intended for
-// other projects using base who manage their own dependencies and make sure
-// short wchar works for them.
-#define WCHAR_T_IS_UTF16
-#else
-#error Please add support for your compiler in build/build_config.h
-#endif
-
-#if defined(OS_ANDROID)
-// The compiler thinks std::string::const_iterator and "const char*" are
-// equivalent types.
-#define STD_STRING_ITERATOR_IS_CHAR_POINTER
-// The compiler thinks base::string16::const_iterator and "char16*" are
-// equivalent types.
-#define BASE_STRING16_ITERATOR_IS_CHAR16_POINTER
-#endif
-
-#endif // BUILD_BUILD_CONFIG_H_
diff --git a/build/check_return_value.py b/build/check_return_value.py
deleted file mode 100755
index c659d1e..0000000
--- a/build/check_return_value.py
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""This program wraps an arbitrary command and prints "1" if the command ran
-successfully."""
-
-import os
-import subprocess
-import sys
-
-devnull = open(os.devnull, 'wb')
-if not subprocess.call(sys.argv[1:], stdout=devnull, stderr=devnull):
- print 1
-else:
- print 0
diff --git a/build/check_sdk_extras_version.py b/build/check_sdk_extras_version.py
deleted file mode 100755
index 9b2f10d..0000000
--- a/build/check_sdk_extras_version.py
+++ /dev/null
@@ -1,131 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-'''Checks the status of an Android SDK package.
-
-Verifies the given package has been installed from the Android SDK Manager and
-that its version is at least the minimum version required by the project
-configuration.
-'''
-
-import argparse
-import json
-import os
-import re
-import sys
-
-
-COLORAMA_ROOT = os.path.join(os.path.dirname(__file__),
- os.pardir, 'third_party', 'colorama', 'src')
-
-sys.path.append(COLORAMA_ROOT)
-import colorama
-
-
-UDPATE_SCRIPT_PATH = 'build/install-android-sdks.sh'
-
-SDK_EXTRAS_JSON_FILE = os.path.join(os.path.dirname(__file__),
- 'android_sdk_extras.json')
-
-PACKAGE_VERSION_PATTERN = r'^Pkg\.Revision=(?P<version>\d+).*$'
-
-PKG_NOT_FOUND_MSG = ('Error while checking Android SDK extras versions. '
- 'Could not find the "{package_id}" package in '
- '{checked_location}. Please run {script} to download it.')
-UPDATE_NEEDED_MSG = ('Error while checking Android SDK extras versions. '
- 'Version {minimum_version} or greater is required for the '
- 'package "{package_id}". Version {actual_version} found. '
- 'Please run {script} to update it.')
-REQUIRED_VERSION_ERROR_MSG = ('Error while checking Android SDK extras '
- 'versions. '
- 'Could not retrieve the required version for '
- 'package "{package_id}".')
-
-
-def main():
- parser = argparse.ArgumentParser(description=__doc__)
- parser.add_argument('--package-id',
- help=('id of the package to check for. The list of '
- 'available packages and their ids can be obtained '
- 'by running '
- 'third_party/android_tools/sdk/tools/android list '
- 'sdk --extended'))
- parser.add_argument('--package-location',
- help='path to the package\'s expected install location.',
- metavar='DIR')
- parser.add_argument('--stamp',
- help=('if specified, a stamp file will be created at the '
- 'provided location.'),
- metavar='FILE')
-
- args = parser.parse_args()
-
- if not ShouldSkipVersionCheck():
- minimum_version = GetRequiredMinimumVersion(args.package_id)
- CheckPackageVersion(args.package_id, args.package_location, minimum_version)
-
- # Create the stamp file.
- if args.stamp:
- with open(args.stamp, 'a'):
- os.utime(args.stamp, None)
-
- sys.exit(0)
-
-def ExitError(msg):
- sys.exit(colorama.Fore.MAGENTA + colorama.Style.BRIGHT + msg +
- colorama.Style.RESET_ALL)
-
-
-def GetRequiredMinimumVersion(package_id):
- with open(SDK_EXTRAS_JSON_FILE, 'r') as json_file:
- packages = json.load(json_file)
-
- for package in packages:
- if package['package_id'] == package_id:
- return int(package['version'].split('.')[0])
-
- ExitError(REQUIRED_VERSION_ERROR_MSG.format(package_id=package_id))
-
-
-def CheckPackageVersion(pkg_id, location, minimum_version):
- version_file_path = os.path.join(location, 'source.properties')
- # Extracts the version of the package described by the property file. We only
- # care about the major version number here.
- version_pattern = re.compile(PACKAGE_VERSION_PATTERN, re.MULTILINE)
-
- if not os.path.isfile(version_file_path):
- ExitError(PKG_NOT_FOUND_MSG.format(
- package_id=pkg_id,
- checked_location=location,
- script=UDPATE_SCRIPT_PATH))
-
- with open(version_file_path, 'r') as f:
- match = version_pattern.search(f.read())
-
- if not match:
- ExitError(PKG_NOT_FOUND_MSG.format(
- package_id=pkg_id,
- checked_location=location,
- script=UDPATE_SCRIPT_PATH))
-
- pkg_version = int(match.group('version'))
- if pkg_version < minimum_version:
- ExitError(UPDATE_NEEDED_MSG.format(
- package_id=pkg_id,
- minimum_version=minimum_version,
- actual_version=pkg_version,
- script=UDPATE_SCRIPT_PATH))
-
- # Everything looks ok, print nothing.
-
-def ShouldSkipVersionCheck():
- '''
- Bots should not run the version check, since they download the sdk extras
- in a different way.
- '''
- return bool(os.environ.get('CHROME_HEADLESS'))
-
-if __name__ == '__main__':
- main()
diff --git a/build/chrome_settings.gypi b/build/chrome_settings.gypi
deleted file mode 100644
index e9c7535..0000000
--- a/build/chrome_settings.gypi
+++ /dev/null
@@ -1,30 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file contains settings for ../chrome/chrome.gyp that other gyp files
-# also use.
-{
- 'variables': {
- # TODO: remove this helper when we have loops in GYP
- 'apply_locales_cmd': ['python', '<(DEPTH)/build/apply_locales.py'],
-
- 'conditions': [
- ['OS=="mac"', {
- 'conditions': [
- ['branding=="Chrome"', {
- 'mac_bundle_id': 'com.google.Chrome',
- 'mac_creator': 'rimZ',
- # The policy .grd file also needs the bundle id.
- 'grit_defines': ['-D', 'mac_bundle_id=com.google.Chrome'],
- }, { # else: branding!="Chrome"
- 'mac_bundle_id': 'org.chromium.Chromium',
- 'mac_creator': 'Cr24',
- # The policy .grd file also needs the bundle id.
- 'grit_defines': ['-D', 'mac_bundle_id=org.chromium.Chromium'],
- }], # branding
- ], # conditions
- }], # OS=="mac"
- ], # conditions
- }, # variables
-}
diff --git a/build/clobber.py b/build/clobber.py
deleted file mode 100755
index 785011a..0000000
--- a/build/clobber.py
+++ /dev/null
@@ -1,110 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""This script provides methods for clobbering build directories."""
-
-import argparse
-import os
-import shutil
-import sys
-
-
-def extract_gn_build_commands(build_ninja_file):
- """Extracts from a build.ninja the commands to run GN.
-
- The commands to run GN are the gn rule and build.ninja build step at the
- top of the build.ninja file. We want to keep these when deleting GN builds
- since we want to preserve the command-line flags to GN.
-
- On error, returns the empty string."""
- result = ""
- with open(build_ninja_file, 'r') as f:
- # Read until the second blank line. The first thing GN writes to the file
- # is the "rule gn" and the second is the section for "build build.ninja",
- # separated by blank lines.
- num_blank_lines = 0
- while num_blank_lines < 2:
- line = f.readline()
- if len(line) == 0:
- return '' # Unexpected EOF.
- result += line
- if line[0] == '\n':
- num_blank_lines = num_blank_lines + 1
- return result
-
-
-def delete_build_dir(build_dir):
- # GN writes a build.ninja.d file. Note that not all GN builds have args.gn.
- build_ninja_d_file = os.path.join(build_dir, 'build.ninja.d')
- if not os.path.exists(build_ninja_d_file):
- shutil.rmtree(build_dir)
- return
-
- # GN builds aren't automatically regenerated when you sync. To avoid
- # messing with the GN workflow, erase everything but the args file, and
- # write a dummy build.ninja file that will automatically rerun GN the next
- # time Ninja is run.
- build_ninja_file = os.path.join(build_dir, 'build.ninja')
- build_commands = extract_gn_build_commands(build_ninja_file)
-
- try:
- gn_args_file = os.path.join(build_dir, 'args.gn')
- with open(gn_args_file, 'r') as f:
- args_contents = f.read()
- except IOError:
- args_contents = ''
-
- shutil.rmtree(build_dir)
-
- # Put back the args file (if any).
- os.mkdir(build_dir)
- if args_contents != '':
- with open(gn_args_file, 'w') as f:
- f.write(args_contents)
-
- # Write the build.ninja file sufficiently to regenerate itself.
- with open(os.path.join(build_dir, 'build.ninja'), 'w') as f:
- if build_commands != '':
- f.write(build_commands)
- else:
- # Couldn't parse the build.ninja file, write a default thing.
- f.write('''rule gn
-command = gn -q gen //out/%s/
-description = Regenerating ninja files
-
-build build.ninja: gn
-generator = 1
-depfile = build.ninja.d
-''' % (os.path.split(build_dir)[1]))
-
- # Write a .d file for the build which references a nonexistant file. This
- # will make Ninja always mark the build as dirty.
- with open(build_ninja_d_file, 'w') as f:
- f.write('build.ninja: nonexistant_file.gn\n')
-
-
-def clobber(out_dir):
- """Clobber contents of build directory.
-
- Don't delete the directory itself: some checkouts have the build directory
- mounted."""
- for f in os.listdir(out_dir):
- path = os.path.join(out_dir, f)
- if os.path.isfile(path):
- os.unlink(path)
- elif os.path.isdir(path):
- delete_build_dir(path)
-
-
-def main():
- parser = argparse.ArgumentParser()
- parser.add_argument('out_dir', help='The output directory to clobber')
- args = parser.parse_args()
- clobber(args.out_dir)
- return 0
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/build/common.croc b/build/common.croc
deleted file mode 100644
index fde7a8b..0000000
--- a/build/common.croc
+++ /dev/null
@@ -1,127 +0,0 @@
-# -*- python -*-
-# Crocodile config file for Chromium - settings common to all platforms
-#
-# This should be speicified before the platform-specific config, for example:
-# croc -c chrome_common.croc -c linux/chrome_linux.croc
-
-{
- # List of root directories, applied in order
- 'roots' : [
- # Sub-paths we specifically care about and want to call out
- {
- 'root' : '_/src',
- 'altname' : 'CHROMIUM',
- },
- ],
-
- # List of rules, applied in order
- # Note that any 'include':0 rules here will be overridden by the 'include':1
- # rules in the platform-specific configs.
- 'rules' : [
- # Don't scan for executable lines in uninstrumented C++ header files
- {
- 'regexp' : '.*\\.(h|hpp)$',
- 'add_if_missing' : 0,
- },
-
- # Groups
- {
- 'regexp' : '',
- 'group' : 'source',
- },
- {
- 'regexp' : '.*_(test|unittest|uitest|browsertest)\\.',
- 'group' : 'test',
- },
-
- # Languages
- {
- 'regexp' : '.*\\.(c|h)$',
- 'language' : 'C',
- },
- {
- 'regexp' : '.*\\.(cc|cpp|hpp)$',
- 'language' : 'C++',
- },
-
- # Files/paths to include. Specify these before the excludes, since rules
- # are in order.
- {
- 'regexp' : '^CHROMIUM/(base|media|net|printing|remoting|chrome|content|webkit/glue|native_client)/',
- 'include' : 1,
- },
- # Don't include subversion or mercurial SCM dirs
- {
- 'regexp' : '.*/(\\.svn|\\.hg)/',
- 'include' : 0,
- },
- # Don't include output dirs
- {
- 'regexp' : '.*/(Debug|Release|out|xcodebuild)/',
- 'include' : 0,
- },
- # Don't include third-party source
- {
- 'regexp' : '.*/third_party/',
- 'include' : 0,
- },
- # We don't run the V8 test suite, so we don't care about V8 coverage.
- {
- 'regexp' : '.*/v8/',
- 'include' : 0,
- },
- ],
-
- # Paths to add source from
- 'add_files' : [
- 'CHROMIUM'
- ],
-
- # Statistics to print
- 'print_stats' : [
- {
- 'stat' : 'files_executable',
- 'format' : '*RESULT FilesKnown: files_executable= %d files',
- },
- {
- 'stat' : 'files_instrumented',
- 'format' : '*RESULT FilesInstrumented: files_instrumented= %d files',
- },
- {
- 'stat' : '100.0 * files_instrumented / files_executable',
- 'format' : '*RESULT FilesInstrumentedPercent: files_instrumented_percent= %g percent',
- },
- {
- 'stat' : 'lines_executable',
- 'format' : '*RESULT LinesKnown: lines_known= %d lines',
- },
- {
- 'stat' : 'lines_instrumented',
- 'format' : '*RESULT LinesInstrumented: lines_instrumented= %d lines',
- },
- {
- 'stat' : 'lines_covered',
- 'format' : '*RESULT LinesCoveredSource: lines_covered_source= %d lines',
- 'group' : 'source',
- },
- {
- 'stat' : 'lines_covered',
- 'format' : '*RESULT LinesCoveredTest: lines_covered_test= %d lines',
- 'group' : 'test',
- },
- {
- 'stat' : '100.0 * lines_covered / lines_executable',
- 'format' : '*RESULT PercentCovered: percent_covered= %g percent',
- },
- {
- 'stat' : '100.0 * lines_covered / lines_executable',
- 'format' : '*RESULT PercentCoveredSource: percent_covered_source= %g percent',
- 'group' : 'source',
- },
- {
- 'stat' : '100.0 * lines_covered / lines_executable',
- 'format' : '*RESULT PercentCoveredTest: percent_covered_test= %g percent',
- 'group' : 'test',
- },
- ],
-}
diff --git a/build/common.gypi b/build/common.gypi
deleted file mode 100644
index 3a2df58..0000000
--- a/build/common.gypi
+++ /dev/null
@@ -1,6216 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# IMPORTANT:
-# Please don't directly include this file if you are building via gyp_chromium,
-# since gyp_chromium is automatically forcing its inclusion.
-{
- # Variables expected to be overriden on the GYP command line (-D) or by
- # ~/.gyp/include.gypi.
- 'variables': {
- # Putting a variables dict inside another variables dict looks kind of
- # weird. This is done so that 'host_arch', 'chromeos', etc are defined as
- # variables within the outer variables dict here. This is necessary
- # to get these variables defined for the conditions within this variables
- # dict that operate on these variables.
- 'variables': {
- 'variables': {
- 'variables': {
- 'variables': {
- # Whether we're building a ChromeOS build.
- 'chromeos%': 0,
-
- # Whether we're building the cast (chromecast) shell
- 'chromecast%': 0,
-
- # Whether or not we are using the Aura windowing framework.
- 'use_aura%': 0,
-
- # Whether or not we are building the Ash shell.
- 'use_ash%': 0,
-
- # Whether or not we are using CRAS, the ChromeOS Audio Server.
- 'use_cras%': 0,
-
- # Use a raw surface abstraction.
- 'use_ozone%': 0,
-
- # Configure the build for small devices. See crbug.com/318413
- 'embedded%': 0,
-
- 'conditions': [
- # Compute the architecture that we're building on.
- ['OS=="win" or OS=="ios"', {
- 'host_arch%': 'ia32',
- }, {
- 'host_arch%': '<!pymod_do_main(detect_host_arch)',
- }],
- ],
- },
- # Copy conditionally-set variables out one scope.
- 'chromeos%': '<(chromeos)',
- 'chromecast%': '<(chromecast)',
- 'use_aura%': '<(use_aura)',
- 'use_ash%': '<(use_ash)',
- 'use_cras%': '<(use_cras)',
- 'use_ozone%': '<(use_ozone)',
- 'embedded%': '<(embedded)',
- 'host_arch%': '<(host_arch)',
-
- # Whether we are using Views Toolkit
- 'toolkit_views%': 0,
-
- # Use the PCI lib to collect GPU information.
- 'use_libpci%': 1,
-
- # Use OpenSSL instead of NSS as the underlying SSL and crypto
- # implementation. Certificate verification will in most cases be
- # handled by the OS. If OpenSSL's struct X509 is used to represent
- # certificates, use_openssl_certs must be set.
- 'use_openssl%': 1,
-
- # Use OpenSSL for representing certificates. When targeting Android,
- # the platform certificate library is used for certificate
- # verification. On other targets, this flag also enables OpenSSL for
- # certificate verification, but this configuration is unsupported.
- 'use_openssl_certs%': 0,
-
- # Disable viewport meta tag by default.
- 'enable_viewport%': 0,
-
- # Enable HiDPI support.
- 'enable_hidpi%': 0,
-
- # Enable top chrome material design.
- 'enable_topchrome_md%' : 0,
-
- # Force building against pre-built sysroot image on linux. By default
- # the sysroot image is only used for Official builds or when cross
- # compiling to arm or mips.
- 'use_sysroot%': 0,
-
- # Override buildtype to select the desired build flavor.
- # Dev - everyday build for development/testing
- # Official - release build (generally implies additional processing)
- # TODO(mmoss) Once 'buildtype' is fully supported (e.g. Windows gyp
- # conversion is done), some of the things which are now controlled by
- # 'branding', such as symbol generation, will need to be refactored
- # based on 'buildtype' (i.e. we don't care about saving symbols for
- # non-Official # builds).
- 'buildtype%': 'Dev',
-
- # Override branding to select the desired branding flavor.
- 'branding%': 'Chromium',
-
- 'conditions': [
- # Windows and Linux (including Chrome OS) use Aura and Ash.
- ['OS=="win" or OS=="linux"', {
- 'use_ash%': 1,
- 'use_aura%': 1,
- }],
-
- ['chromecast==1 and OS!="android"', {
- 'embedded%': 1,
- 'use_ozone%': 1,
- }],
-
- # Ozone uses Aura.
- ['use_ozone==1', {
- 'use_aura%': 1,
- }],
-
- # Whether we're a traditional desktop unix.
- ['(OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris") and chromeos==0', {
- 'desktop_linux%': 1,
- }, {
- 'desktop_linux%': 0,
- }],
-
- # Embedded implies ozone.
- ['embedded==1', {
- 'use_ozone%': 1,
- }],
-
- ['OS=="android"', {
- 'target_arch%': 'arm',
- }, {
- # Default architecture we're building for is the architecture we're
- # building on, and possibly sub-architecture (for iOS builds).
- 'target_arch%': '<(host_arch)',
- }],
- ],
- },
- # Copy conditionally-set variables out one scope.
- 'chromeos%': '<(chromeos)',
- 'chromecast%': '<(chromecast)',
- 'desktop_linux%': '<(desktop_linux)',
- 'use_aura%': '<(use_aura)',
- 'use_ash%': '<(use_ash)',
- 'use_cras%': '<(use_cras)',
- 'use_ozone%': '<(use_ozone)',
- 'embedded%': '<(embedded)',
- 'use_libpci%': '<(use_libpci)',
- 'use_openssl%': '<(use_openssl)',
- 'use_openssl_certs%': '<(use_openssl_certs)',
- 'enable_viewport%': '<(enable_viewport)',
- 'enable_hidpi%': '<(enable_hidpi)',
- 'enable_topchrome_md%': '<(enable_topchrome_md)',
- 'buildtype%': '<(buildtype)',
- 'branding%': '<(branding)',
- 'branding_path_component%': '<(branding)',
- 'host_arch%': '<(host_arch)',
- 'target_arch%': '<(target_arch)',
-
- 'target_subarch%': '',
-
- # The channel to build on Android: stable, beta, dev, canary, or
- # default. "default" should be used on non-official builds.
- 'android_channel%': 'default',
-
- # Set ARM architecture version.
- 'arm_version%': 7,
-
- # Use aurax11 for clipboard implementation. This is true on linux_aura.
- 'use_clipboard_aurax11%': 0,
-
- # goma settings.
- # 1 to use goma.
- # If no gomadir is set, it uses the default gomadir.
- 'use_goma%': 0,
- 'gomadir%': '',
-
- # The system root for cross-compiles. Default: none.
- 'sysroot%': '',
- 'chroot_cmd%': '',
-
- # The system libdir used for this ABI.
- 'system_libdir%': 'lib',
-
- # Default MIPS arch variant. This is set in the conditions block
- # below for MIPS targets.
- 'mips_arch_variant%': '',
-
- # MIPS DSP ASE revision. Possible values are:
- # 0: unavailable
- # 1: revision 1
- # 2: revision 2
- 'mips_dsp_rev%': 0,
-
- 'conditions': [
- ['branding == "Chrome"', {
- 'branding_path_component%': 'google_chrome',
- }],
-
- ['branding == "Chromium"', {
- 'branding_path_component%': 'chromium',
- }],
-
- # Ash needs Aura.
- ['use_aura==0', {
- 'use_ash%': 0,
- }],
-
- # Set default value of toolkit_views based on OS.
- ['OS=="mac" or OS=="win" or chromeos==1 or use_aura==1', {
- 'toolkit_views%': 1,
- }, {
- 'toolkit_views%': 0,
- }],
-
- # Embedded builds use aura without ash or views.
- ['embedded==1', {
- 'use_aura%': 1,
- 'use_ash%': 0,
- 'toolkit_views%': 0,
- }],
-
- # Enable HiDPI on Mac OS, Windows and Linux (including Chrome OS).
- ['OS=="mac" or OS=="win" or OS=="linux"', {
- 'enable_hidpi%': 1,
- }],
-
- # Enable Top Chrome Material Design on Chrome OS, Windows, and Linux.
- ['chromeos==1 or OS=="win" or OS=="linux"', {
- 'enable_topchrome_md%': 1,
- }],
-
- # On iOS, use NSS rather than OpenSSL. See http://crbug.com/338886.
- ['OS=="ios"', {
- 'use_openssl%': 0,
- }],
-
- # Enable App Launcher everywhere but mobile.
- ['OS!="ios" and OS!="android"', {
- 'enable_app_list%': 1,
- }, {
- 'enable_app_list%': 0,
- }],
-
- ['use_aura==1 and OS!="android"', {
- 'use_default_render_theme%': 1,
- }, {
- 'use_default_render_theme%': 0,
- }],
-
- ['use_ozone==1', {
- 'use_ozone_evdev%': 1,
- }, {
- 'use_ozone_evdev%': 0,
- }],
-
- # Set default gomadir.
- ['OS=="win"', {
- 'gomadir': 'c:\\goma\\goma-win',
- }, {
- 'gomadir': '<!(/bin/echo -n ${HOME}/goma)',
- }],
-
- # Set the default "target_subarch" on iOS. Valid values are "arm32",
- # "arm64" and "both" (meaning a fat binary).
- ['OS=="ios"', {
- 'target_subarch%': 'arm64',
- }],
-
- # Set arch variants for MIPS platforms.
- ['target_arch=="mips64el"', {
- 'conditions': [
- ['OS=="android"', {
- 'mips_arch_variant%': 'r6',
- }, {
- 'mips_arch_variant%': 'r2',
- }],
- ],
- }],
-
- ['target_arch=="mipsel"', {
- 'mips_arch_variant%': 'r1',
- }],
-
- ['OS=="linux" and target_arch=="arm" and chromeos==0', {
- # sysroot needs to be an absolute path otherwise it generates
- # incorrect results when passed to pkg-config
- 'sysroot%': '<!(cd <(DEPTH) && pwd -P)/build/linux/debian_wheezy_arm-sysroot',
- }], # OS=="linux" and target_arch=="arm" and chromeos==0
-
- ['OS=="linux" and ((branding=="Chrome" and buildtype=="Official" and chromeos==0) or use_sysroot==1)' , {
- 'conditions': [
- ['target_arch=="x64"', {
- 'sysroot%': '<!(cd <(DEPTH) && pwd -P)/build/linux/debian_wheezy_amd64-sysroot',
- }],
- ['target_arch=="ia32"', {
- 'sysroot%': '<!(cd <(DEPTH) && pwd -P)/build/linux/debian_wheezy_i386-sysroot',
- }],
- ],
- }], # OS=="linux" and branding=="Chrome" and buildtype=="Official" and chromeos==0
-
- ['OS=="linux" and target_arch=="mipsel"', {
- 'sysroot%': '<!(cd <(DEPTH) && pwd -P)/mipsel-sysroot/sysroot',
- }],
- ],
- },
-
- # Copy conditionally-set variables out one scope.
- 'chromeos%': '<(chromeos)',
- 'chromecast%': '<(chromecast)',
- 'host_arch%': '<(host_arch)',
- 'target_arch%': '<(target_arch)',
- 'target_subarch%': '<(target_subarch)',
- 'mips_arch_variant%': '<(mips_arch_variant)',
- 'mips_dsp_rev%': '<(mips_dsp_rev)',
- 'toolkit_views%': '<(toolkit_views)',
- 'desktop_linux%': '<(desktop_linux)',
- 'use_aura%': '<(use_aura)',
- 'use_ash%': '<(use_ash)',
- 'use_cras%': '<(use_cras)',
- 'use_libpci%': '<(use_libpci)',
- 'use_ozone%': '<(use_ozone)',
- 'use_ozone_evdev%': '<(use_ozone_evdev)',
- 'use_clipboard_aurax11%': '<(use_clipboard_aurax11)',
- 'embedded%': '<(embedded)',
- 'use_openssl%': '<(use_openssl)',
- 'use_openssl_certs%': '<(use_openssl_certs)',
- 'enable_viewport%': '<(enable_viewport)',
- 'enable_hidpi%': '<(enable_hidpi)',
- 'enable_topchrome_md%': '<(enable_topchrome_md)',
- 'android_channel%': '<(android_channel)',
- 'use_goma%': '<(use_goma)',
- 'gomadir%': '<(gomadir)',
- 'enable_app_list%': '<(enable_app_list)',
- 'use_default_render_theme%': '<(use_default_render_theme)',
- 'buildtype%': '<(buildtype)',
- 'branding%': '<(branding)',
- 'branding_path_component%': '<(branding_path_component)',
- 'arm_version%': '<(arm_version)',
- 'sysroot%': '<(sysroot)',
- 'chroot_cmd%': '<(chroot_cmd)',
- 'system_libdir%': '<(system_libdir)',
-
- # Set to 1 to enable fast builds. Set to 2 for even faster builds
- # (it disables debug info for fastest compilation - only for use
- # on compile-only bots).
- 'fastbuild%': 0,
-
- # Set to 1 to not store any build metadata, e.g. ifdef out all __DATE__
- # and __TIME__. Set to 0 to reenable the use of these macros in the code
- # base. See http://crbug.com/314403.
- 'dont_embed_build_metadata%': 1,
-
- # Set to 1 to force Visual C++ to use legacy debug information format /Z7.
- # This is useful for parallel compilation tools which can't support /Zi.
- # Only used on Windows.
- 'win_z7%' : 0,
-
- # Set to 1 to enable dcheck in Release build.
- 'dcheck_always_on%': 0,
-
- # Set to 1 to make a build that disables unshipped tracing events.
- # Note: this setting is ignored if buildtype=="Official".
- 'tracing_like_official_build%': 0,
-
- # Disable image loader component extension by default.
- 'image_loader_extension%': 0,
-
- # Set NEON compilation flags.
- 'arm_neon%': 1,
-
- # Detect NEON support at run-time.
- 'arm_neon_optional%': 0,
-
- # Use libjpeg-turbo as the JPEG codec used by Chromium.
- 'use_libjpeg_turbo%': 1,
-
- # Use system libjpeg. Note that the system's libjepg will be used even if
- # use_libjpeg_turbo is set.
- 'use_system_libjpeg%': 0,
-
- # By default, component is set to static_library and it can be overriden
- # by the GYP command line or by ~/.gyp/include.gypi.
- 'component%': 'static_library',
-
- # /analyze is off by default on Windows because it is very slow and noisy.
- # Enable with GYP_DEFINES=win_analyze=1
- 'win_analyze%': 0,
-
- # Set to select the Title Case versions of strings in GRD files.
- 'use_titlecase_in_grd%': 0,
-
- # Use translations provided by volunteers at launchpad.net. This
- # currently only works on Linux.
- 'use_third_party_translations%': 0,
-
- # Remoting compilation is enabled by default. Set to 0 to disable.
- 'remoting%': 1,
-
- # Configuration policy is enabled by default. Set to 0 to disable.
- 'configuration_policy%': 1,
-
- # Variable safe_browsing is used to control the build time configuration
- # for safe browsing feature. Safe browsing can be compiled in 4 different
- # levels: 0 disables it, 1 enables it fully, and 2 enables only UI and
- # reporting features for use with Data Saver on Mobile, and 3 enables
- # extended mobile protection via an external API. When 3 is fully
- # deployed, it will replace 2.
- 'safe_browsing%': 1,
-
- # Web speech is enabled by default. Set to 0 to disable.
- 'enable_web_speech%': 1,
-
- # 'Ok Google' hotwording is disabled by default in open source builds. Set
- # to 1 to enable. (This will download a closed-source NaCl module at
- # startup.) Chrome-branded builds have this enabled by default.
- 'enable_hotwording%': 0,
-
- # Notifications are compiled in by default. Set to 0 to disable.
- 'notifications%' : 1,
-
- # Use dsymutil to generate real .dSYM files on Mac. The default is 0 for
- # regular builds and 1 for ASan builds.
- 'mac_want_real_dsym%': 'default',
-
- # If this is set, the clang plugins used on the buildbot will be used.
- # Run tools/clang/scripts/update.sh to make sure they are compiled.
- # This causes 'clang_chrome_plugins_flags' to be set.
- # Has no effect if 'clang' is not set as well.
- 'clang_use_chrome_plugins%': 1,
-
- # Enable building with ASAN (Clang's -fsanitize=address option).
- # -fsanitize=address only works with clang, but asan=1 implies clang=1
- # See https://sites.google.com/a/chromium.org/dev/developers/testing/addresssanitizer
- 'asan%': 0,
- 'asan_blacklist%': '<(PRODUCT_DIR)/../../tools/memory/asan/blacklist.txt',
- # Enable coverage gathering instrumentation in sanitizer tools. This flag
- # also controls coverage granularity (1 for function-level coverage, 2
- # for block-level coverage).
- 'sanitizer_coverage%': 0,
- # Deprecated, only works if |sanitizer_coverage| isn't set.
- # TODO(glider): remove this flag.
- 'asan_coverage%': 0,
- # Enable intra-object-overflow detection in ASan (experimental).
- 'asan_field_padding%': 0,
-
- # Enable Chromium overrides of the default configurations for various
- # dynamic tools (like ASan).
- 'use_sanitizer_options%': 0,
-
- # Enable building with SyzyAsan.
- # See https://code.google.com/p/sawbuck/wiki/SyzyASanHowTo
- 'syzyasan%': 0,
-
- # Enable crash reporting via Kasko.
- 'kasko%': 0,
-
- # Enable building with LSan (Clang's -fsanitize=leak option).
- # -fsanitize=leak only works with clang, but lsan=1 implies clang=1
- # See https://sites.google.com/a/chromium.org/dev/developers/testing/leaksanitizer
- 'lsan%': 0,
-
- # Enable building with TSan (Clang's -fsanitize=thread option).
- # -fsanitize=thread only works with clang, but tsan=1 implies clang=1
- # See http://clang.llvm.org/docs/ThreadSanitizer.html
- 'tsan%': 0,
- 'tsan_blacklist%': '<(PRODUCT_DIR)/../../tools/memory/tsan_v2/ignores.txt',
-
- # Enable building with MSan (Clang's -fsanitize=memory option).
- # MemorySanitizer only works with clang, but msan=1 implies clang=1
- # See http://clang.llvm.org/docs/MemorySanitizer.html
- 'msan%': 0,
- 'msan_blacklist%': '<(PRODUCT_DIR)/../../tools/msan/blacklist.txt',
- # Track where uninitialized memory originates from. From fastest to
- # slowest: 0 - no tracking, 1 - track only the initial allocation site, 2
- # - track the chain of stores leading from allocation site to use site.
- 'msan_track_origins%': 2,
-
- # Enable building with UBSan (Clang's -fsanitize=undefined option).
- # -fsanitize=undefined only works with clang, but ubsan=1 implies clang=1
- # See http://clang.llvm.org/docs/UsersManual.html
- 'ubsan%': 0,
- 'ubsan_blacklist%': '<(PRODUCT_DIR)/../../tools/ubsan/blacklist.txt',
- 'ubsan_vptr_blacklist%': '<(PRODUCT_DIR)/../../tools/ubsan/vptr_blacklist.txt',
-
- # Enable building with UBsan's vptr (Clang's -fsanitize=vptr option).
- # -fsanitize=vptr only works with clang, but ubsan_vptr=1 implies clang=1
- 'ubsan_vptr%': 0,
-
- # Use dynamic libraries instrumented by one of the sanitizers
- # instead of the standard system libraries. Set this flag to build the
- # libraries from source.
- 'use_instrumented_libraries%': 0,
-
- # Use dynamic libraries instrumented by one of the sanitizers
- # instead of the standard system libraries. Set this flag to download
- # prebuilt binaries from GCS.
- 'use_prebuilt_instrumented_libraries%': 0,
-
- # Use libc++ (third_party/libc++ and third_party/libc++abi) instead of
- # stdlibc++ as standard library. This is intended to use for instrumented
- # builds.
- 'use_custom_libcxx%': 0,
-
- # Use system libc++ instead of the default C++ library, usually libstdc++.
- # This is intended for iOS builds only.
- 'use_system_libcxx%': 0,
-
- # Use a modified version of Clang to intercept allocated types and sizes
- # for allocated objects. clang_type_profiler=1 implies clang=1.
- # See http://dev.chromium.org/developers/deep-memory-profiler/cpp-object-type-identifier
- # TODO(dmikurube): Support mac. See http://crbug.com/123758#c11
- 'clang_type_profiler%': 0,
-
- # Set to true to instrument the code with function call logger.
- # See src/third_party/cygprofile/cyg-profile.cc for details.
- 'order_profiling%': 0,
-
- # Use the provided profiled order file to link Chrome image with it.
- # This makes Chrome faster by better using CPU cache when executing code.
- # This is known as PGO (profile guided optimization).
- # See https://sites.google.com/a/google.com/chrome-msk/dev/boot-speed-up-effort
- 'order_text_section%' : "",
-
- # Set to 1 compile with -fPIC cflag on linux. This is a must for shared
- # libraries on linux x86-64 and arm, plus ASLR.
- 'linux_fpic%': 1,
-
- # Whether one-click signin is enabled or not.
- 'enable_one_click_signin%': 0,
-
- # Whether to back up data before sync.
- 'enable_pre_sync_backup%': 0,
-
- # Enable Chrome browser extensions
- 'enable_extensions%': 1,
-
- # Enable Google Now.
- 'enable_google_now%': 1,
-
- # Enable basic printing support and UI.
- 'enable_basic_printing%': 1,
-
- # Enable printing with print preview. It does not imply
- # enable_basic_printing. It's possible to build Chrome with preview only.
- 'enable_print_preview%': 1,
-
- # Set the version of CLD.
- # 0: Don't specify the version. This option is for the Finch testing.
- # 1: Use only CLD1.
- # 2: Use only CLD2.
- 'cld_version%': 2,
-
- # For CLD2, the size of the tables that should be included in the build
- # Only evaluated if cld_version == 2 or if building the CLD2 dynamic data
- # tool explicitly.
- # See third_party/cld_2/cld_2.gyp for more information.
- # 0: Small tables, lower accuracy
- # 2: Large tables, high accuracy
- 'cld2_table_size%': 2,
-
- # Enable spell checker.
- 'enable_spellcheck%': 1,
-
- # Use the operating system spellchecker, e.g. NSSpellChecker on Mac or
- # SpellCheckerSession on Android.
- 'use_platform_spellchecker%': 0,
-
- # Webrtc compilation is enabled by default. Set to 0 to disable.
- 'enable_webrtc%': 1,
-
- # Media router support is enabled by default. Set to 0 to disable.
- 'enable_media_router%': 1,
-
- # Enables use of the session service, which is enabled by default.
- # Support for disabling depends on the platform.
- 'enable_session_service%': 1,
-
- # Enables theme support, which is enabled by default. Support for
- # disabling depends on the platform.
- 'enable_themes%': 1,
-
- # Enables autofill dialog and associated features; disabled by default.
- 'enable_autofill_dialog%' : 0,
-
- # Defaults Wallet integration in Autofill dialog to use production
- # servers. Unofficial builds won't have the proper API keys.
- 'enable_prod_wallet_service%': 0,
-
- # Enables support for background apps.
- 'enable_background%': 1,
-
- # Enable the task manager by default.
- 'enable_task_manager%': 1,
-
- # Enables used resource whitelist generation; disabled by default.
- 'enable_resource_whitelist_generation%': 0,
-
- # Enable FILE support by default.
- 'disable_file_support%': 0,
-
- # Enable FTP support by default.
- 'disable_ftp_support%': 0,
-
- # Use native android functions in place of ICU. Not supported by most
- # components.
- 'use_icu_alternatives_on_android%': 0,
-
- # Use of precompiled headers on Windows.
- #
- # This variable may be explicitly set to 1 (enabled) or 0
- # (disabled) in ~/.gyp/include.gypi or via the GYP command line.
- # This setting will override the default.
- #
- # See
- # http://code.google.com/p/chromium/wiki/WindowsPrecompiledHeaders
- # for details.
- 'chromium_win_pch%': 0,
-
- # Clang stuff.
- 'make_clang_dir%': 'third_party/llvm-build/Release+Asserts',
- # Set this to true when building with Clang.
- # See http://code.google.com/p/chromium/wiki/Clang for details.
- # If this is set, clang is used as both host and target compiler in
- # cross-compile builds.
- 'clang%': 0,
-
- # Use experimental lld linker instead of the platform's default linker.
- 'use_lld%': 0,
-
- # Enable plugin installation by default.
- 'enable_plugin_installation%': 1,
-
- # Specifies whether to use canvas_skia.cc in place of platform
- # specific implementations of gfx::Canvas. Affects text drawing in the
- # Chrome UI.
- # TODO(asvitkine): Enable this on all platforms and delete this flag.
- # http://crbug.com/105550
- 'use_canvas_skia%': 0,
-
- # Set to "tsan", "memcheck", or "drmemory" to configure the build to work
- # with one of those tools.
- 'build_for_tool%': '',
-
- 'wix_path%': '<(DEPTH)/third_party/wix',
-
- # Supervised users are enabled by default.
- 'enable_supervised_users%': 1,
-
- # Platform sends memory pressure signals natively.
- 'native_memory_pressure_signals%': 0,
-
- 'enable_mdns%' : 0,
- 'enable_service_discovery%': 0,
- 'enable_wifi_bootstrapping%': 0,
- 'enable_hangout_services_extension%': 0,
-
- # Enable the Syzygy optimization step.
- 'syzygy_optimize%': 0,
-
- # Enable hole punching for the protected video.
- 'video_hole%': 0,
-
- # Automatically select platforms under ozone. Turn this off to
- # build only explicitly selected platforms.
- 'ozone_auto_platforms%': 1,
-
- # If this is set clang is used as host compiler, but not as target
- # compiler. Always do this by default.
- 'host_clang%': 1,
-
- # Variables to control Link-Time Optimization (LTO).
- # On Android, the variable use_lto enables LTO on code compiled with -Os,
- # and use_lto_o2 enables LTO on code compiled with -O2. On other
- # platforms, use_lto enables LTO in all translation units, and use_lto_o2
- # has no effect.
- #
- # On Linux and Android, when using LLVM LTO, the script
- # build/download_gold_plugin.py must be run to download a linker plugin.
- # On Mac, LLVM needs to be built from scratch using
- # tools/clang/scripts/update.py and the absolute path to
- # third_party/llvm-build/Release+Asserts/lib must be added to
- # $DYLD_LIBRARY_PATH to pick up the right version of the linker plugin.
- #
- # On Android, the variables must *not* be enabled at the same time.
- # In this case LTO would 'merge' the optimization flags at link-time
- # which would lead to all code be optimized with -O2. See crbug.com/407544
- 'use_lto%': 0,
- 'use_lto_o2%': 0,
-
- # Allowed level of identical code folding in the gold linker.
- 'gold_icf_level%': 'all',
-
- # Libxkbcommon usage.
- 'use_xkbcommon%': 0,
-
- # Control Flow Integrity for virtual calls and casts.
- # See http://clang.llvm.org/docs/ControlFlowIntegrity.html
- 'cfi_vptr%': 0,
-
- 'cfi_blacklist%': '<(PRODUCT_DIR)/../../tools/cfi/blacklist.txt',
-
- # Whether the entire browser uses toolkit-views on Mac instead of Cocoa.
- 'mac_views_browser%': 0,
-
- # By default, use ICU data file (icudtl.dat).
- 'icu_use_data_file_flag%': 1,
-
- # Turn on JNI generation optimizations by default.
- 'optimize_jni_generation%': 1,
-
- 'conditions': [
- # A flag for POSIX platforms
- ['OS=="win"', {
- 'os_posix%': 0,
- }, {
- 'os_posix%': 1,
- }],
-
- # A flag for BSD platforms
- ['OS=="freebsd" or OS=="openbsd"', {
- 'os_bsd%': 1,
- }, {
- 'os_bsd%': 0,
- }],
-
- # NSS usage.
- ['(OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris")', {
- 'use_nss_certs%': 1,
- }, {
- 'use_nss_certs%': 0,
- }],
-
- # libudev usage. This currently only affects the content layer.
- ['OS=="linux" and embedded==0', {
- 'use_udev%': 1,
- }, {
- 'use_udev%': 0,
- }],
-
- # Flags to use X11 on non-Mac POSIX platforms.
- ['OS=="win" or OS=="mac" or OS=="ios" or OS=="android" or use_ozone==1', {
- 'use_x11%': 0,
- }, {
- 'use_x11%': 1,
- }],
-
- # Flags to use glib.
- ['OS=="win" or OS=="mac" or OS=="ios" or OS=="android" or use_ozone==1', {
- 'use_glib%': 0,
- }, {
- 'use_glib%': 1,
- }],
-
- # Flags to use pango and cairo.
- ['OS=="win" or OS=="mac" or OS=="ios" or OS=="android" or embedded==1', {
- 'use_pango%': 0,
- 'use_cairo%': 0,
- }, {
- 'use_pango%': 1,
- 'use_cairo%': 1,
- }],
-
- # DBus usage.
- ['OS=="linux" and embedded==0', {
- 'use_dbus%': 1,
- }, {
- 'use_dbus%': 0,
- }],
-
- # We always use skia text rendering in Aura on Windows, since GDI
- # doesn't agree with our BackingStore.
- # TODO(beng): remove once skia text rendering is on by default.
- ['use_aura==1 and OS=="win"', {
- 'enable_skia_text%': 1,
- }],
-
- # A flag to enable or disable our compile-time dependency
- # on gnome-keyring. If that dependency is disabled, no gnome-keyring
- # support will be available. This option is useful
- # for Linux distributions and for Aura.
- ['OS!="linux" or chromeos==1', {
- 'use_gnome_keyring%': 0,
- }, {
- 'use_gnome_keyring%': 1,
- }],
-
- ['OS=="mac" or OS=="ios"', {
- # Mac and iOS want Title Case strings
- 'use_titlecase_in_grd%': 1,
- }],
-
- # Enable loader extensions on Chrome OS.
- ['chromeos==1', {
- 'image_loader_extension%': 1,
- }, {
- 'image_loader_extension%': 0,
- }],
-
- ['OS=="win" or OS=="mac" or (OS=="linux" and chromeos==0)', {
- 'enable_one_click_signin%': 1,
- 'enable_pre_sync_backup%': 1,
- }],
-
- ['OS=="android"', {
- 'enable_extensions%': 0,
- 'enable_google_now%': 0,
- 'cld_version%': 1,
- 'enable_spellcheck%': 0,
- 'enable_themes%': 0,
- 'remoting%': 0,
- 'arm_neon%': 0,
- 'arm_neon_optional%': 1,
- 'native_memory_pressure_signals%': 1,
- 'enable_basic_printing%': 1,
- 'enable_print_preview%': 0,
- 'enable_task_manager%':0,
- 'video_hole%': 1,
- }],
-
- # OSX has a built-in spellchecker can be utilized.
- ['OS=="mac"', {
- 'use_platform_spellchecker%': 1,
- }],
-
- # Android OS includes support for proprietary codecs regardless of
- # building Chromium or Google Chrome. We also ship Google Chrome and
- # Chromecast with proprietary codecs.
- ['OS=="android" or branding=="Chrome" or chromecast==1', {
- 'proprietary_codecs%': 1,
- }, {
- 'proprietary_codecs%': 0,
- }],
-
- ['OS=="mac" or OS=="ios"', {
- 'native_memory_pressure_signals%': 1,
- }],
-
- # Enable autofill dialog when not on iOS.
- ['OS!="ios"', {
- 'enable_autofill_dialog%': 1,
- }],
-
- ['buildtype=="Official"', {
- 'enable_prod_wallet_service%': 1,
- }],
-
- ['branding=="Chrome"', {
- 'enable_hotwording%': 1,
- }],
-
- ['OS=="android"', {
- 'enable_webrtc%': 1,
- }],
-
- ['OS=="ios"', {
- 'disable_ftp_support%': 1,
- 'enable_extensions%': 0,
- 'enable_google_now%': 0,
- 'cld_version%': 2,
- 'cld2_table_size%': 0,
- 'enable_basic_printing%': 0,
- 'enable_print_preview%': 0,
- 'enable_session_service%': 0,
- 'enable_spellcheck%': 0,
- 'enable_themes%': 0,
- 'enable_webrtc%': 0,
- 'notifications%': 0,
- 'remoting%': 0,
- 'safe_browsing%': 0,
- 'enable_supervised_users%': 0,
- 'enable_task_manager%': 0,
- 'use_system_libcxx%': 1,
- }],
-
- # Use GPU accelerated cross process image transport by default
- # on linux builds with the Aura window manager
- ['use_aura==1 and OS=="linux"', {
- 'ui_compositor_image_transport%': 1,
- }, {
- 'ui_compositor_image_transport%': 0,
- }],
-
- # Turn precompiled headers on by default.
- ['OS=="win" and buildtype!="Official"', {
- 'chromium_win_pch%': 1
- }],
-
- ['chromeos==1 or OS=="android" or OS=="ios" or desktop_linux==1', {
- 'enable_plugin_installation%': 0,
- }, {
- 'enable_plugin_installation%': 1,
- }],
-
- # Whether PPAPI is enabled.
- ['OS=="android" or OS=="ios" or (embedded==1 and chromecast==0)', {
- 'enable_plugins%': 0,
- }, {
- 'enable_plugins%': 1,
- }],
-
- # linux_use_bundled_gold: whether to use the gold linker binary checked
- # into third_party/binutils. Force this off via GYP_DEFINES when you
- # are using a custom toolchain and need to control -B in ldflags.
- # Do not use 32-bit gold on 32-bit hosts as it runs out address space
- # for component=static_library builds.
- ['(OS=="linux" or OS=="android") and (target_arch=="x64" or target_arch=="arm")', {
- 'linux_use_bundled_gold%': 1,
- }, {
- 'linux_use_bundled_gold%': 0,
- }],
-
- # linux_use_bundled_binutils: whether to use the binary binutils
- # checked into third_party/binutils. These are not multi-arch so cannot
- # be used except on x86 and x86-64 (the only two architectures which
- # are currently checke in). Force this off via GYP_DEFINES when you
- # are using a custom toolchain and need to control -B in cflags.
- ['OS=="linux" and (target_arch=="x64")', {
- 'linux_use_bundled_binutils%': 1,
- }, {
- 'linux_use_bundled_binutils%': 0,
- }],
-
- # linux_use_gold_flags: whether to use build flags that rely on gold.
- # On by default for x64 Linux.
- ['OS=="linux" and target_arch=="x64"', {
- 'linux_use_gold_flags%': 1,
- }, {
- 'linux_use_gold_flags%': 0,
- }],
-
- # linux_use_debug_fission: whether to use split DWARF debug info
- # files. This can reduce link time significantly, but is incompatible
- # with some utilities such as icecc and ccache. Requires gold and
- # gcc >= 4.8 or clang.
- # http://gcc.gnu.org/wiki/DebugFission
- ['OS=="linux" and target_arch=="x64"', {
- 'linux_use_debug_fission%': 1,
- }, {
- 'linux_use_debug_fission%': 0,
- }],
-
- ['OS=="android" or OS=="ios"', {
- 'enable_captive_portal_detection%': 0,
- 'enable_media_router%': 0,
- }, {
- 'enable_captive_portal_detection%': 1,
- 'enable_media_router%': 1,
- }],
-
- # Enable Skia UI text drawing incrementally on different platforms.
- # http://crbug.com/105550
- #
- # On Aura, this allows per-tile painting to be used in the browser
- # compositor.
- ['OS!="android" and OS!="ios"', {
- 'use_canvas_skia%': 1,
- }],
-
- ['chromeos==1', {
- 'enable_basic_printing%': 0,
- 'enable_print_preview%': 1,
- }],
-
- # Do not enable the Settings App on ChromeOS.
- ['enable_app_list==1 and chromeos==0', {
- 'enable_settings_app%': 1,
- }, {
- 'enable_settings_app%': 0,
- }],
-
- # Whether tests targets should be run, archived or just have the
- # dependencies verified. All the tests targets have the '_run' suffix,
- # e.g. base_unittests_run runs the target base_unittests. The test
- # target always calls tools/swarming_client/isolate.py. See the script's
- # --help for more information. Meant to be overriden with GYP_DEFINES.
- # TODO(maruel): Remove the conditions as more configurations are
- # supported.
- ['OS!="ios" and OS!="android" and chromeos==0', {
- 'test_isolation_mode%': 'check',
- }, {
- 'test_isolation_mode%': 'noop',
- }],
- # Whether Android build uses OpenMAX DL FFT.
- ['OS=="android" and ((target_arch=="arm" and arm_version >= 7) or target_arch=="ia32" or target_arch=="x64" or target_arch=="arm64" or target_arch=="mipsel")', {
- # Currently only supported on Android ARMv7+, ARM64, ia32, x64 and mipsel.
- # When enabled, this will also enable WebAudio support on
- # Android for these architectures. Default is enabled. Whether
- # WebAudio is actually available depends on runtime settings
- # and flags.
- 'use_openmax_dl_fft%': 1,
- }, {
- 'use_openmax_dl_fft%': 0,
- }],
- ['OS=="win" or OS=="linux"', {
- 'enable_mdns%' : 1,
- }],
-
- # Disable various features by default on embedded.
- ['embedded==1', {
- 'remoting%': 0,
- 'enable_basic_printing%': 0,
- 'enable_print_preview%': 0,
- }],
-
- ['OS=="win" or OS=="mac"', {
- 'enable_wifi_bootstrapping%' : 1,
- }],
-
- # Path to sas.dll, which provides the SendSAS function.
- # http://msdn.microsoft.com/en-us/library/windows/desktop/dd979761(v=vs.85).aspx
- ['target_arch=="x64"', {
- 'sas_dll_path%': '<(DEPTH)/third_party/platformsdk_win7/files/redist/amd64',
- }, {
- 'sas_dll_path%': '<(DEPTH)/third_party/platformsdk_win7/files/redist/x86',
- }],
-
- ['sysroot!=""', {
- 'pkg-config': '<(chroot_cmd) <(DEPTH)/build/linux/pkg-config-wrapper "<(sysroot)" "<(target_arch)" "<(system_libdir)"',
- }, {
- 'pkg-config': 'pkg-config'
- }],
- ],
-
- # WebVR support disabled until platform implementations have been added
- 'enable_webvr%': 0,
-
- # Setting this to '0' will cause V8's startup snapshot to be
- # embedded in the binary instead of being a external files.
- 'v8_use_external_startup_data%': 1,
-
- # Set this to 1 to enable use of concatenated impulse responses
- # for the HRTF panner in WebAudio.
- 'use_concatenated_impulse_responses': 1,
-
- # You can set the variable 'use_official_google_api_keys' to 1
- # to use the Google-internal file containing official API keys
- # for Google Chrome even in a developer build. Setting this
- # variable explicitly to 1 will cause your build to fail if the
- # internal file is missing.
- #
- # The variable is documented here, but not handled in this file;
- # see //google_apis/determine_use_official_keys.gypi for the
- # implementation.
- #
- # Set the variable to 0 to not use the internal file, even when
- # it exists in your checkout.
- #
- # Leave it unset in your include.gypi to have the variable
- # implicitly set to 1 if you have
- # src/google_apis/internal/google_chrome_api_keys.h in your
- # checkout, and implicitly set to 0 if not.
- #
- # Note that official builds always behave as if the variable
- # was explicitly set to 1, i.e. they always use official keys,
- # and will fail to build if the internal file is missing.
- #
- # NOTE: You MUST NOT explicitly set the variable to 2 in your
- # include.gypi or by other means. Due to subtleties of GYP, this
- # is not the same as leaving the variable unset, even though its
- # default value in
- # //google_apis/determine_use_official_keys.gypi is 2.
-
- # Set these to bake the specified API keys and OAuth client
- # IDs/secrets into your build.
- #
- # If you create a build without values baked in, you can instead
- # set environment variables to provide the keys at runtime (see
- # src/google_apis/google_api_keys.h for details). Features that
- # require server-side APIs may fail to work if no keys are
- # provided.
- #
- # Note that if you are building an official build or if
- # use_official_google_api_keys has been set to 1 (explicitly or
- # implicitly), these values will be ignored and the official
- # keys will be used instead.
- 'google_api_key%': '',
- 'google_default_client_id%': '',
- 'google_default_client_secret%': '',
- # Native Client is enabled by default.
- 'disable_nacl%': '0',
-
- # Sets the default version name and code for Android app, by default we
- # do a developer build.
- 'android_app_version_name%': 'Developer Build',
- 'android_app_version_code%': 1,
- },
-
- # Copy conditionally-set variables out one scope.
- 'branding%': '<(branding)',
- 'branding_path_component%': '<(branding_path_component)',
- 'buildtype%': '<(buildtype)',
- 'target_arch%': '<(target_arch)',
- 'target_subarch%': '<(target_subarch)',
- 'mips_arch_variant%': '<(mips_arch_variant)',
- 'mips_dsp_rev%': '<(mips_dsp_rev)',
- 'host_arch%': '<(host_arch)',
- 'toolkit_views%': '<(toolkit_views)',
- 'ui_compositor_image_transport%': '<(ui_compositor_image_transport)',
- 'use_aura%': '<(use_aura)',
- 'use_ash%': '<(use_ash)',
- 'use_cras%': '<(use_cras)',
- 'use_libpci%': '<(use_libpci)',
- 'use_openssl%': '<(use_openssl)',
- 'use_openssl_certs%': '<(use_openssl_certs)',
- 'use_nss_certs%': '<(use_nss_certs)',
- 'use_udev%': '<(use_udev)',
- 'os_bsd%': '<(os_bsd)',
- 'os_posix%': '<(os_posix)',
- 'use_dbus%': '<(use_dbus)',
- 'use_glib%': '<(use_glib)',
- 'use_pango%': '<(use_pango)',
- 'use_cairo%': '<(use_cairo)',
- 'use_ozone%': '<(use_ozone)',
- 'use_ozone_evdev%': '<(use_ozone_evdev)',
- 'use_xkbcommon%': '<(use_xkbcommon)',
- 'use_clipboard_aurax11%': '<(use_clipboard_aurax11)',
- 'desktop_linux%': '<(desktop_linux)',
- 'use_x11%': '<(use_x11)',
- 'use_gnome_keyring%': '<(use_gnome_keyring)',
- 'linux_fpic%': '<(linux_fpic)',
- 'chromeos%': '<(chromeos)',
- 'chromecast%': '<(chromecast)',
- 'enable_viewport%': '<(enable_viewport)',
- 'enable_hidpi%': '<(enable_hidpi)',
- 'enable_topchrome_md%': '<(enable_topchrome_md)',
- 'image_loader_extension%': '<(image_loader_extension)',
- 'fastbuild%': '<(fastbuild)',
- 'dont_embed_build_metadata%': '<(dont_embed_build_metadata)',
- 'win_z7%': '<(win_z7)',
- 'dcheck_always_on%': '<(dcheck_always_on)',
- 'tracing_like_official_build%': '<(tracing_like_official_build)',
- 'arm_version%': '<(arm_version)',
- 'arm_neon%': '<(arm_neon)',
- 'arm_neon_optional%': '<(arm_neon_optional)',
- 'sysroot%': '<(sysroot)',
- 'pkg-config%': '<(pkg-config)',
- 'chroot_cmd%': '<(chroot_cmd)',
- 'system_libdir%': '<(system_libdir)',
- 'component%': '<(component)',
- 'win_analyze%': '<(win_analyze)',
- 'enable_resource_whitelist_generation%': '<(enable_resource_whitelist_generation)',
- 'use_titlecase_in_grd%': '<(use_titlecase_in_grd)',
- 'use_third_party_translations%': '<(use_third_party_translations)',
- 'remoting%': '<(remoting)',
- 'enable_one_click_signin%': '<(enable_one_click_signin)',
- 'enable_pre_sync_backup%': '<(enable_pre_sync_backup)',
- 'enable_media_router%': '<(enable_media_router)',
- 'enable_webrtc%': '<(enable_webrtc)',
- 'chromium_win_pch%': '<(chromium_win_pch)',
- 'configuration_policy%': '<(configuration_policy)',
- 'safe_browsing%': '<(safe_browsing)',
- 'enable_web_speech%': '<(enable_web_speech)',
- 'enable_hotwording%': '<(enable_hotwording)',
- 'notifications%': '<(notifications)',
- 'clang_use_chrome_plugins%': '<(clang_use_chrome_plugins)',
- 'mac_want_real_dsym%': '<(mac_want_real_dsym)',
- 'asan%': '<(asan)',
- 'asan_blacklist%': '<(asan_blacklist)',
- 'asan_coverage%': '<(asan_coverage)',
- 'sanitizer_coverage%': '<(sanitizer_coverage)',
- 'asan_field_padding%': '<(asan_field_padding)',
- 'use_sanitizer_options%': '<(use_sanitizer_options)',
- 'syzyasan%': '<(syzyasan)',
- 'kasko%': '<(kasko)',
- 'syzygy_optimize%': '<(syzygy_optimize)',
- 'lsan%': '<(lsan)',
- 'msan%': '<(msan)',
- 'msan_blacklist%': '<(msan_blacklist)',
- 'msan_track_origins%': '<(msan_track_origins)',
- 'tsan%': '<(tsan)',
- 'tsan_blacklist%': '<(tsan_blacklist)',
- 'ubsan%': '<(ubsan)',
- 'ubsan_blacklist%': '<(ubsan_blacklist)',
- 'ubsan_vptr_blacklist%': '<(ubsan_vptr_blacklist)',
- 'ubsan_vptr%': '<(ubsan_vptr)',
- 'use_instrumented_libraries%': '<(use_instrumented_libraries)',
- 'use_prebuilt_instrumented_libraries%': '<(use_prebuilt_instrumented_libraries)',
- 'use_custom_libcxx%': '<(use_custom_libcxx)',
- 'use_system_libcxx%': '<(use_system_libcxx)',
- 'clang_type_profiler%': '<(clang_type_profiler)',
- 'order_profiling%': '<(order_profiling)',
- 'order_text_section%': '<(order_text_section)',
- 'enable_extensions%': '<(enable_extensions)',
- 'enable_plugin_installation%': '<(enable_plugin_installation)',
- 'enable_plugins%': '<(enable_plugins)',
- 'enable_session_service%': '<(enable_session_service)',
- 'enable_themes%': '<(enable_themes)',
- 'enable_autofill_dialog%': '<(enable_autofill_dialog)',
- 'enable_prod_wallet_service%': '<(enable_prod_wallet_service)',
- 'enable_background%': '<(enable_background)',
- 'linux_use_bundled_gold%': '<(linux_use_bundled_gold)',
- 'linux_use_bundled_binutils%': '<(linux_use_bundled_binutils)',
- 'linux_use_gold_flags%': '<(linux_use_gold_flags)',
- 'linux_use_debug_fission%': '<(linux_use_debug_fission)',
- 'use_canvas_skia%': '<(use_canvas_skia)',
- 'test_isolation_mode%': '<(test_isolation_mode)',
- 'enable_basic_printing%': '<(enable_basic_printing)',
- 'enable_print_preview%': '<(enable_print_preview)',
- 'enable_spellcheck%': '<(enable_spellcheck)',
- 'use_platform_spellchecker%': '<(use_platform_spellchecker)',
- 'enable_google_now%': '<(enable_google_now)',
- 'cld_version%': '<(cld_version)',
- 'cld2_table_size%': '<(cld2_table_size)',
- 'enable_captive_portal_detection%': '<(enable_captive_portal_detection)',
- 'disable_file_support%': '<(disable_file_support)',
- 'disable_ftp_support%': '<(disable_ftp_support)',
- 'use_icu_alternatives_on_android%': '<(use_icu_alternatives_on_android)',
- 'enable_task_manager%': '<(enable_task_manager)',
- 'sas_dll_path%': '<(sas_dll_path)',
- 'wix_path%': '<(wix_path)',
- 'use_libjpeg_turbo%': '<(use_libjpeg_turbo)',
- 'use_system_libjpeg%': '<(use_system_libjpeg)',
- 'android_channel%': '<(android_channel)',
- 'icu_use_data_file_flag%': '<(icu_use_data_file_flag)',
- 'gyp_managed_install%': 0,
- 'create_standalone_apk%': 1,
- 'enable_app_list%': '<(enable_app_list)',
- 'use_default_render_theme%': '<(use_default_render_theme)',
- 'enable_settings_app%': '<(enable_settings_app)',
- 'google_api_key%': '<(google_api_key)',
- 'google_default_client_id%': '<(google_default_client_id)',
- 'google_default_client_secret%': '<(google_default_client_secret)',
- 'enable_supervised_users%': '<(enable_supervised_users)',
- 'native_memory_pressure_signals%': '<(native_memory_pressure_signals)',
- 'enable_mdns%' : '<(enable_mdns)',
- 'enable_service_discovery%' : '<(enable_service_discovery)',
- 'enable_wifi_bootstrapping%': '<(enable_wifi_bootstrapping)',
- 'enable_hangout_services_extension%' : '<(enable_hangout_services_extension)',
- 'proprietary_codecs%': '<(proprietary_codecs)',
- 'use_goma%': '<(use_goma)',
- 'gomadir%': '<(gomadir)',
- 'use_lto%': '<(use_lto)',
- 'use_lto_o2%': '<(use_lto_o2)',
- 'gold_icf_level%': '<(gold_icf_level)',
- 'video_hole%': '<(video_hole)',
- 'v8_use_external_startup_data%': '<(v8_use_external_startup_data)',
- 'cfi_vptr%': '<(cfi_vptr)',
- 'cfi_blacklist%': '<(cfi_blacklist)',
- 'mac_views_browser%': '<(mac_views_browser)',
- 'android_app_version_name%': '<(android_app_version_name)',
- 'android_app_version_code%': '<(android_app_version_code)',
- 'enable_webvr%': '<(enable_webvr)',
-
- # Turns on compiler optimizations in V8 in Debug build.
- 'v8_optimized_debug%': 1,
-
- # Use system protobuf instead of bundled one.
- 'use_system_protobuf%': 0,
-
- # Use system yasm instead of bundled one.
- 'use_system_yasm%': 0,
-
- # Use system ICU instead of bundled one.
- 'use_system_icu%' : 0,
-
- # Default to enabled PIE; this is important for ASLR but we may need to be
- # able to turn it off for various reasons.
- 'linux_disable_pie%': 0,
-
- # The release channel that this build targets. This is used to restrict
- # channel-specific build options, like which installer packages to create.
- # The default is 'all', which does no channel-specific filtering.
- 'channel%': 'all',
-
- # Override chromium_mac_pch and set it to 0 to suppress the use of
- # precompiled headers on the Mac. Prefix header injection may still be
- # used, but prefix headers will not be precompiled. This is useful when
- # using distcc to distribute a build to compile slaves that don't
- # share the same compiler executable as the system driving the compilation,
- # because precompiled headers rely on pointers into a specific compiler
- # executable's image. Setting this to 0 is needed to use an experimental
- # Linux-Mac cross compiler distcc farm.
- 'chromium_mac_pch%': 1,
-
- # The default value for mac_strip in target_defaults. This cannot be
- # set there, per the comment about variable% in a target_defaults.
- 'mac_strip_release%': 0,
-
- # Set to 1 to enable java code coverage. Instruments classes during build
- # to produce .ec files during runtime.
- 'emma_coverage%': 0,
-
- # EMMA filter string consisting of a list of inclusion/exclusion patterns
- # separated with whitespace and/or comma. Only has effect if
- # 'emma_coverage=1'.
- 'emma_filter%': '',
-
- # Set to 1 to enable running Android lint on java/class files.
- 'android_lint%': 1,
-
- # Although base/allocator lets you select a heap library via an
- # environment variable, the libcmt shim it uses sometimes gets in
- # the way. To disable it entirely, and switch to normal msvcrt, do e.g.
- # 'win_use_allocator_shim': 0,
- # 'win_release_RuntimeLibrary': 2
- # to ~/.gyp/include.gypi, gclient runhooks --force, and do a release build.
- 'win_use_allocator_shim%': 1, # 1 = shim allocator via libcmt; 0 = msvcrt
-
- # TODO(bradnelson): eliminate this when possible.
- # To allow local gyp files to prevent release.vsprops from being included.
- # Yes(1) means include release.vsprops.
- # Once all vsprops settings are migrated into gyp, this can go away.
- 'msvs_use_common_release%': 1,
-
- # TODO(bradnelson): eliminate this when possible.
- # To allow local gyp files to override additional linker options for msvs.
- # Yes(1) means set use the common linker options.
- 'msvs_use_common_linker_extras%': 1,
-
- # TODO(sgk): eliminate this if possible.
- # It would be nicer to support this via a setting in 'target_defaults'
- # in chrome/app/locales/locales.gypi overriding the setting in the
- # 'Debug' configuration in the 'target_defaults' dict below,
- # but that doesn't work as we'd like.
- 'msvs_debug_link_incremental%': '2',
-
- # Needed for some of the largest modules.
- 'msvs_debug_link_nonincremental%': '1',
-
- # Turns on Use Library Dependency Inputs for linking chrome.dll on Windows
- # to get incremental linking to be faster in debug builds.
- 'incremental_chrome_dll%': '0',
-
- # Experimental setting to break chrome.dll into multiple pieces based on
- # process type.
- 'chrome_multiple_dll%': '0',
-
- # Experimental setting to optimize Chrome's DLLs with PGO.
- 'chrome_pgo_phase%': '0',
-
- # Whether the VS xtree header has been patched to disable warning 4702. If
- # it has, then we don't need to disable 4702 (unreachable code warning).
- # The patch is preapplied to the internal toolchain and hence all bots.
- 'msvs_xtree_patched%': '<!pymod_do_main(win_is_xtree_patched)',
-
- # Clang stuff.
- 'clang%': '<(clang)',
- 'host_clang%': '<(host_clang)',
- 'make_clang_dir%': '<(make_clang_dir)',
- 'use_lld%': '<(use_lld)',
-
- # Control which version of clang to use when building for iOS. If set to
- # '1', uses the version of clang that ships with Xcode. If set to '0', uses
- # the version of clang that ships with the Chromium source. This variable
- # is automatically set to '1' in Official builds.
- 'clang_xcode%': 0,
-
- # These two variables can be set in GYP_DEFINES while running
- # |gclient runhooks| to let clang run a plugin in every compilation.
- # Only has an effect if 'clang=1' is in GYP_DEFINES as well.
- # Example:
- # GYP_DEFINES='clang=1 clang_load=/abs/path/to/libPrintFunctionNames.dylib clang_add_plugin=print-fns' gclient runhooks
-
- 'clang_load%': '',
- 'clang_add_plugin%': '',
-
- # Tell ld64 to write map files describing binary layout. Useful
- # for looking at what contributes to binary size, e.g. with
- # https://github.com/nico/bloat
- 'mac_write_linker_maps%': 0,
-
- # The default type of gtest.
- 'gtest_target_type%': 'executable',
-
- # Enable sampling based profiler.
- # See http://google-perftools.googlecode.com/svn/trunk/doc/cpuprofile.html
- 'profiling%': '0',
- # Profile without optimizing out stack frames when profiling==1.
- 'profiling_full_stack_frames%': '0',
-
- # And if we want to dump symbols for Breakpad-enabled builds.
- 'linux_dump_symbols%': 0,
- # And if we want to strip the binary after dumping symbols.
- 'linux_strip_binary%': 0,
- # If we want stack unwind support for backtrace().
- 'debug_unwind_tables%': 1,
- 'release_unwind_tables%': 1,
-
- # Override where to find binutils
- 'binutils_version%': 0,
- 'binutils_dir%': '',
-
- # Enable TCMalloc.
- # Default of 'use_allocator' is set to 'none' if OS=='android' later.
- 'use_allocator%': 'tcmalloc',
-
- # Set to 1 to link against libgnome-keyring instead of using dlopen().
- 'linux_link_gnome_keyring%': 0,
- # Set to 1 to link against gsettings APIs instead of using dlopen().
- 'linux_link_gsettings%': 0,
-
- # Enable use of OpenMAX DL FFT routines.
- 'use_openmax_dl_fft%': '<(use_openmax_dl_fft)',
-
- # Enable new NPDevice API.
- 'enable_new_npdevice_api%': 0,
-
- # .gyp files or targets should set chromium_code to 1 if they build
- # Chromium-specific code, as opposed to external code. This variable is
- # used to control such things as the set of warnings to enable, and
- # whether warnings are treated as errors.
- 'chromium_code%': 0,
-
- # Disable fatal linker warnings, similarly to how we make it possible
- # to disable -Werror (e.g. for different toolchain versions).
- 'disable_fatal_linker_warnings%': 0,
-
- 'release_valgrind_build%': 0,
-
- # TODO(thakis): Make this a blacklist instead, http://crbug.com/101600
- 'enable_wexit_time_destructors%': 0,
-
- # Build libpeerconnection as a static library by default.
- 'libpeer_target_type%': 'static_library',
-
- # Set to 1 to compile with the OpenGL ES 2.0 conformance tests.
- 'internal_gles2_conform_tests%': 0,
-
- # Set to 1 to compile with the Khronos GL-CTS conformance tests.
- 'internal_khronos_glcts_tests%': 0,
-
- # Set to 1 to compile the filter fuzzer.
- 'internal_filter_fuzzer%': 0,
-
- # NOTE: When these end up in the Mac bundle, we need to replace '-' for '_'
- # so Cocoa is happy (http://crbug.com/20441).
- 'locales': [
- 'am', 'ar', 'bg', 'bn', 'ca', 'cs', 'da', 'de', 'el', 'en-GB',
- 'en-US', 'es-419', 'es', 'et', 'fa', 'fi', 'fil', 'fr', 'gu', 'he',
- 'hi', 'hr', 'hu', 'id', 'it', 'ja', 'kn', 'ko', 'lt', 'lv',
- 'ml', 'mr', 'ms', 'nb', 'nl', 'pl', 'pt-BR', 'pt-PT', 'ro', 'ru',
- 'sk', 'sl', 'sr', 'sv', 'sw', 'ta', 'te', 'th', 'tr', 'uk',
- 'vi', 'zh-CN', 'zh-TW',
- ],
-
- # Pseudo locales are special locales which are used for testing and
- # debugging. They don't get copied to the final app. For more info,
- # check out https://www.chromium.org/developers/testing/fake-bidi
- 'pseudo_locales': [
- 'fake-bidi',
- ],
-
- 'grit_defines': [],
-
- # If debug_devtools is set to 1, JavaScript files for DevTools are
- # stored as is and loaded from disk. Otherwise, a concatenated file
- # is stored in resources.pak. It is still possible to load JS files
- # from disk by passing --debug-devtools cmdline switch.
- 'debug_devtools%': 0,
-
- # The Java Bridge is not compiled in by default.
- 'java_bridge%': 0,
-
- # Code signing for iOS binaries. The bots need to be able to disable this.
- 'chromium_ios_signing%': 1,
-
- # This flag is only used when disable_nacl==0 and disables all those
- # subcomponents which would require the installation of a native_client
- # untrusted toolchain.
- 'disable_nacl_untrusted%': 0,
-
- # PNaCl toolchain does not support sanitizers. Disable by default.
- 'enable_nacl_nonsfi_test%': 0,
-
- # Disable Dart by default.
- 'enable_dart%': 0,
-
- # Copy out the setting of disable_nacl.
- 'disable_nacl%': '<(disable_nacl)',
-
- # Portable Native Client is enabled by default.
- 'disable_pnacl%': 0,
-
- # Whether to build full debug version for Debug configuration on Android.
- # Compared to full debug version, the default Debug configuration on Android
- # has no full v8 debug, has size optimization and linker gc section, so that
- # we can build a debug version with acceptable size and performance.
- 'android_full_debug%': 0,
-
- # Contains data about the attached devices for gyp_managed_install.
- 'build_device_config_path': '<(PRODUCT_DIR)/build_devices.cfg',
-
- 'sas_dll_exists': '<!pymod_do_main(dir_exists "<(sas_dll_path)")',
- 'wix_exists': '<!pymod_do_main(dir_exists "<(wix_path)")',
-
- 'windows_sdk_path%': 'C:/Program Files (x86)/Windows Kits/8.1',
- 'directx_sdk_default_path': '<(DEPTH)/third_party/directxsdk/files',
-
- # Whether we are using the rlz library or not. Platforms like Android send
- # rlz codes for searches but do not use the library.
- 'enable_rlz_support%': 0,
- 'enable_rlz%': 0,
-
- # Turns on the i18n support in V8.
- 'v8_enable_i18n_support': 1,
-
- # Compile d8 for the host toolset.
- 'v8_toolset_for_d8': 'host',
-
- # Use brlapi from brltty for braille display support.
- 'use_brlapi%': 0,
-
- # Relative path to icu.gyp from this file.
- 'icu_gyp_path': '../third_party/icu/icu.gyp',
-
- # IPC fuzzer is disabled by default.
- 'enable_ipc_fuzzer%': 0,
-
- # Force disable libstdc++ debug mode.
- 'disable_glibcxx_debug%': 0,
-
- # Set to 1 to compile with MSE support for MPEG2 TS
- 'enable_mpeg2ts_stream_parser%': 0,
-
- # Support ChromeOS touchpad gestures with ozone.
- 'use_evdev_gestures%': 0,
-
- # Default ozone platform (if no --ozone-platform flag).
- 'ozone_platform%': "",
-
- # Ozone platforms to include in the build.
- 'ozone_platform_caca%': 0,
- 'ozone_platform_cast%': 0,
- 'ozone_platform_drm%': 0,
- 'ozone_platform_egltest%': 0,
- 'ozone_platform_gbm%': 0,
- 'ozone_platform_ozonex%': 0,
- 'ozone_platform_test%': 0,
-
- # Experiment: http://crbug.com/426914
- 'envoy%': 0,
-
- # Used to set libjpeg_gyp_path. Chrome OS ui/gfx/gfx.gyp uses the IJG path
- # for robust login screen decoding.
- 'libjpeg_ijg_gyp_path': '<(DEPTH)/third_party/libjpeg/libjpeg.gyp',
- 'libjpeg_turbo_gyp_path': '<(DEPTH)/third_party/libjpeg_turbo/libjpeg.gyp',
-
- 'conditions': [
- ['buildtype=="Official"', {
- # Continue to embed build meta data in Official builds, basically the
- # time it was built.
- # TODO(maruel): This decision should be revisited because having an
- # official deterministic build has high value too but MSVC toolset can't
- # generate anything deterministic with WPO enabled AFAIK.
- 'dont_embed_build_metadata%': 0,
- }],
- # Enable the Syzygy optimization step for the official builds.
- ['OS=="win" and buildtype=="Official" and syzyasan!=1 and clang!=1', {
- 'syzygy_optimize%': 1,
- }, {
- 'syzygy_optimize%': 0,
- }],
- # Get binutils version so we can enable debug fission if we can.
- ['os_posix==1 and OS!="mac" and OS!="ios"', {
- 'conditions': [
- # compiler_version doesn't work with clang
- # TODO(mithro): Land https://codereview.chromium.org/199793014/ so
- # compiler_version works with clang.
- # TODO(glider): set clang to 1 earlier for ASan and TSan builds so
- # that it takes effect here.
- ['clang==0 and asan==0 and lsan==0 and tsan==0 and msan==0 and ubsan==0 and ubsan_vptr==0', {
- 'binutils_version%': '<!pymod_do_main(compiler_version target assembler)',
- }],
- # On Android we know the binutils version in the toolchain.
- ['OS=="android"', {
- 'binutils_version%': 222,
- }],
- ['host_arch=="x64"', {
- 'binutils_dir%': 'third_party/binutils/Linux_x64/Release/bin',
- }],
- ['host_arch=="ia32"', {
- 'binutils_dir%': 'third_party/binutils/Linux_ia32/Release/bin',
- }],
- # Our version of binutils in third_party/binutils
- ['linux_use_bundled_binutils==1', {
- 'binutils_version%': 224,
- }],
- ],
- }, {
- 'binutils_version%': 0,
- }],
- # The version of GCC in use, set later in platforms that use GCC and have
- # not explicitly chosen to build with clang. Currently, this means all
- # platforms except Windows, Mac and iOS.
- # TODO(glider): set clang to 1 earlier for ASan and TSan builds so that
- # it takes effect here.
- ['os_posix==1 and OS!="mac" and OS!="ios" and clang==0 and asan==0 and lsan==0 and tsan==0 and msan==0 and ubsan_vptr==0', {
- 'conditions': [
- ['OS=="android"', {
- 'host_gcc_version%': '<!pymod_do_main(compiler_version host compiler)',
- # We directly set the gcc version since we know what we use.
- 'gcc_version%': 49,
- }, {
- 'host_gcc_version%': '<!pymod_do_main(compiler_version host compiler)',
- 'gcc_version%': '<!pymod_do_main(compiler_version target compiler)',
- }],
- ],
- }, {
- 'host_gcc_version%': 0,
- 'gcc_version%': 0,
- }],
- ['OS=="win" and "<!pymod_do_main(dir_exists <(directx_sdk_default_path))"=="True"', {
- 'directx_sdk_path%': '<(directx_sdk_default_path)',
- }, {
- 'directx_sdk_path%': '$(DXSDK_DIR)',
- }],
- ['OS=="win"', {
- 'windows_driver_kit_path%': '$(WDK_DIR)',
- }],
- ['os_posix==1 and OS!="mac" and OS!="ios"', {
- 'conditions': [
- ['target_arch=="mipsel" or target_arch=="mips64el"', {
- 'werror%': '',
- 'disable_nacl%': 1,
- 'nacl_untrusted_build%': 0,
- 'use_allocator%': 'none',
- }],
- # Use a 64-bit linker to avoid running out of address space. The
- # buildbots should have a 64-bit kernel and a 64-bit libc installed.
- ['host_arch=="ia32" and target_arch=="ia32"', {
- # TODO(thestig) This is a horrible way to force the desired
- # configuration. Our gyp variable scoping is likely wrong and
- # needs to be cleaned up. The GN configuration should be changed
- # to match.
- 'binutils_version%': 224,
- 'linux_use_bundled_binutils%': '1',
- 'linux_use_bundled_gold%': '1',
- 'binutils_dir%': 'third_party/binutils/Linux_x64/Release/bin',
- }],
- # All Chrome builds have breakpad symbols, but only process the
- # symbols from official builds.
- ['(branding=="Chrome" and buildtype=="Official")', {
- 'linux_dump_symbols%': 1,
-
- # Omit unwind support in official release builds to save space. We
- # can use breakpad for these builds.
- 'release_unwind_tables%': 0,
- }],
- ],
- }], # os_posix==1 and OS!="mac" and OS!="ios"
- ['OS=="ios"', {
- 'disable_nacl%': 1,
- 'enable_background%': 0,
- 'icu_use_data_file_flag%': 1,
- 'enable_web_speech%': 0,
- 'use_system_libxml%': 1,
- 'use_system_sqlite%': 1,
- 'locales==': [
- 'ar', 'ca', 'cs', 'da', 'de', 'el', 'en-GB', 'en-US', 'es', 'es-MX',
- 'fi', 'fr', 'he', 'hi', 'hr', 'hu', 'id', 'it', 'ja', 'ko', 'ms',
- 'nb', 'nl', 'pl', 'pt', 'pt-PT', 'ro', 'ru', 'sk', 'sv', 'th', 'tr',
- 'uk', 'vi', 'zh-CN', 'zh-TW',
- ],
-
- # iOS SDK and deployment target support. The |ios_sdk| value is left
- # blank so that when it is set in the project files it will be the
- # "current" iOS SDK. Forcing a specific SDK even if it is "current"
- # causes Xcode to spit out a warning for every single project file for
- # not using the "current" SDK.
- 'ios_sdk%': '',
- 'ios_sdk_path%': '',
- 'ios_deployment_target%': '7.0',
-
- 'conditions': [
- # ios_product_name is set to the name of the .app bundle as it should
- # appear on disk.
- ['branding=="Chrome"', {
- 'ios_product_name%': 'Chrome',
- }, { # else: branding!="Chrome"
- 'ios_product_name%': 'Chromium',
- }],
- ['branding=="Chrome" and buildtype=="Official"', {
- 'ios_breakpad%': 1,
- }, { # else: branding!="Chrome" or buildtype!="Official"
- 'ios_breakpad%': 0,
- }],
- ],
- }], # OS=="ios"
- ['OS=="android"', {
- # Location of Android NDK.
- 'variables': {
- 'variables': {
- # Standard libraries can use the relative path to the NDK.
- 'android_ndk_root%': '../../third_party/android_tools/ndk/',
- # Unfortunately, it is required to use the absolute path to the SDK
- # because it us passed to ant which uses a different relative path
- # from GYP.
- 'android_sdk_root%': '<!(cd <(DEPTH) && pwd -P)/third_party/android_tools/sdk/',
- # Similarly, gdbserver and the Android toolchain need to use the
- # absolute path to the NDK because they are used at different levels
- # in the GYP files.
- 'android_ndk_absolute_root%': '<!(cd <(DEPTH) && pwd -P)/third_party/android_tools/ndk/',
- 'android_host_arch%': '<!(uname -m)',
- # Android API-level of the SDK used for compilation.
- 'android_sdk_version%': '22',
- 'android_sdk_build_tools_version%': '22.0.1',
- 'host_os%': "<!(uname -s | sed -e 's/Linux/linux/;s/Darwin/mac/')",
- },
- # Copy conditionally-set variables out one scope.
- 'android_ndk_root%': '<(android_ndk_root)',
- 'android_ndk_absolute_root%': '<(android_ndk_absolute_root)',
- 'android_sdk_root%': '<(android_sdk_root)',
- 'android_sdk_version%': '<(android_sdk_version)',
- 'android_libcpp_root': '<(android_ndk_root)/sources/cxx-stl/llvm-libc++',
- 'host_os%': '<(host_os)',
-
- 'android_sdk%': '<(android_sdk_root)/platforms/android-<(android_sdk_version)',
- # Android SDK build tools (e.g. dx, aidl)
- 'android_sdk_tools%': '<(android_sdk_root)/build-tools/<(android_sdk_build_tools_version)',
-
- # Android API level 16 is JB (Android 4.1) which is the minimum
- # platform requirement for Chrome on Android, we use it for native
- # code compilation.
- 'conditions': [
- ['target_arch == "ia32"', {
- 'android_app_abi%': 'x86',
- 'android_gdbserver%': '<(android_ndk_absolute_root)/prebuilt/android-x86/gdbserver/gdbserver',
- 'android_ndk_sysroot%': '<(android_ndk_root)/platforms/android-16/arch-x86',
- 'android_ndk_lib_dir%': 'usr/lib',
- 'android_toolchain%': '<(android_ndk_absolute_root)/toolchains/x86-4.9/prebuilt/<(host_os)-<(android_host_arch)/bin',
- }],
- ['target_arch == "x64"', {
- 'android_app_abi%': 'x86_64',
- 'android_gdbserver%': '<(android_ndk_absolute_root)/prebuilt/android-x86_64/gdbserver/gdbserver',
- 'android_ndk_sysroot%': '<(android_ndk_root)/platforms/android-21/arch-x86_64',
- 'android_ndk_lib_dir%': 'usr/lib64',
- 'android_toolchain%': '<(android_ndk_absolute_root)/toolchains/x86_64-4.9/prebuilt/<(host_os)-<(android_host_arch)/bin',
- }],
- ['target_arch=="arm"', {
- 'conditions': [
- ['arm_version<7', {
- 'android_app_abi%': 'armeabi',
- }, {
- 'android_app_abi%': 'armeabi-v7a',
- }],
- ],
- 'android_gdbserver%': '<(android_ndk_absolute_root)/prebuilt/android-arm/gdbserver/gdbserver',
- 'android_ndk_sysroot%': '<(android_ndk_root)/platforms/android-16/arch-arm',
- 'android_ndk_lib_dir%': 'usr/lib',
- 'android_toolchain%': '<(android_ndk_absolute_root)/toolchains/arm-linux-androideabi-4.9/prebuilt/<(host_os)-<(android_host_arch)/bin',
- }],
- ['target_arch == "arm64"', {
- 'android_app_abi%': 'arm64-v8a',
- 'android_gdbserver%': '<(android_ndk_absolute_root)/prebuilt/android-arm64/gdbserver/gdbserver',
- 'android_ndk_sysroot%': '<(android_ndk_root)/platforms/android-21/arch-arm64',
- 'android_ndk_lib_dir%': 'usr/lib',
- 'android_toolchain%': '<(android_ndk_absolute_root)/toolchains/aarch64-linux-android-4.9/prebuilt/<(host_os)-<(android_host_arch)/bin',
- }],
- ['target_arch == "mipsel"', {
- 'android_app_abi%': 'mips',
- 'android_gdbserver%': '<(android_ndk_absolute_root)/prebuilt/android-mips/gdbserver/gdbserver',
- 'android_ndk_sysroot%': '<(android_ndk_root)/platforms/android-16/arch-mips',
- 'android_ndk_lib_dir%': 'usr/lib',
- 'android_toolchain%': '<(android_ndk_absolute_root)/toolchains/mipsel-linux-android-4.9/prebuilt/<(host_os)-<(android_host_arch)/bin',
- }],
- ['target_arch == "mips64el"', {
- 'android_app_abi%': 'mips64',
- 'android_gdbserver%': '<(android_ndk_absolute_root)/prebuilt/android-mips64/gdbserver/gdbserver',
- 'android_ndk_sysroot%': '<(android_ndk_root)/platforms/android-21/arch-mips64',
- 'android_ndk_lib_dir%': 'usr/lib64',
- 'android_toolchain%': '<(android_ndk_absolute_root)/toolchains/mips64el-linux-android-4.9/prebuilt/<(host_os)-<(android_host_arch)/bin',
- }],
- ],
- },
- # Copy conditionally-set variables out one scope.
- 'android_app_abi%': '<(android_app_abi)',
- 'android_gdbserver%': '<(android_gdbserver)',
- 'android_ndk_root%': '<(android_ndk_root)',
- 'android_ndk_sysroot%': '<(android_ndk_sysroot)',
- 'android_sdk_root%': '<(android_sdk_root)',
- 'android_sdk_version%': '<(android_sdk_version)',
- 'android_toolchain%': '<(android_toolchain)',
-
- 'android_ndk_include': '<(android_ndk_sysroot)/usr/include',
- 'android_ndk_lib': '<(android_ndk_sysroot)/<(android_ndk_lib_dir)',
- 'android_sdk_tools%': '<(android_sdk_tools)',
- 'android_aapt_path%': '<(android_sdk_tools)/aapt',
- 'android_sdk%': '<(android_sdk)',
- 'android_sdk_jar%': '<(android_sdk)/android.jar',
-
- 'android_libcpp_root': '<(android_libcpp_root)',
- 'android_libcpp_include': '<(android_libcpp_root)/libcxx/include',
- 'android_libcpp_libs_dir%': '<(android_libcpp_root)/libs/<(android_app_abi)',
- 'host_os%': '<(host_os)',
-
- # Location of the "objcopy" binary, used by both gyp and scripts.
- 'android_objcopy%' : '<!(/bin/echo -n <(android_toolchain)/*-objcopy)',
-
- # Location of the "strip" binary, used by both gyp and scripts.
- 'android_strip%' : '<!(/bin/echo -n <(android_toolchain)/*-strip)',
-
- # Location of the "readelf" binary.
- 'android_readelf%' : '<!(/bin/echo -n <(android_toolchain)/*-readelf)',
-
- # Determines whether we should optimize JNI generation at the cost of
- # breaking assumptions in the build system that when inputs have changed
- # the outputs should always change as well. This is meant purely for
- # developer builds, to avoid spurious re-linking of native files.
- 'optimize_jni_generation%': '<(optimize_jni_generation)',
-
- # Use OpenSSL's struct X509 to represent certificates.
- 'use_openssl_certs%': 1,
-
- 'proprietary_codecs%': '<(proprietary_codecs)',
- 'safe_browsing%': 2,
- 'enable_web_speech%': 0,
- 'java_bridge%': 1,
- 'build_ffmpegsumo%': 0,
- 'use_allocator%': 'none',
-
- # Disable Native Client.
- 'disable_nacl%': 1,
-
- # Android does not support background apps.
- 'enable_background%': 0,
-
- # Sessions are store separately in the Java side.
- 'enable_session_service%': 0,
-
- 'p2p_apis%' : 0,
-
- 'gtest_target_type%': 'shared_library',
- }], # OS=="android"
- ['embedded==1', {
- 'use_system_fontconfig%': 0,
- }, {
- 'use_system_fontconfig%': 1,
- }],
- ['chromecast==1', {
- 'enable_mpeg2ts_stream_parser%': 1,
- 'ffmpeg_branding%': 'ChromeOS',
- 'ozone_platform_ozonex%': 1,
- 'use_custom_freetype%': 0,
- 'use_playready%': 0,
- 'conditions': [
- ['target_arch=="arm"', {
- 'arm_arch%': '',
- 'arm_tune%': 'cortex-a9',
- 'arm_thumb%': 1,
- 'video_hole%': 1,
- }],
- ],
- }],
- ['chromecast==1 and OS!="android"', {
- 'ozone_platform_cast%': 1
- }],
- ['OS=="linux" and target_arch!="mipsel"', {
- 'clang%': 1,
- }], # OS=="mac"
- ['OS=="mac"', {
- 'conditions': [
- # All Chrome builds have breakpad symbols, but only process the
- # symbols from official builds.
- ['(branding=="Chrome" and buildtype=="Official")', {
- 'mac_strip_release%': 1,
- }],
- ],
- }], # OS=="mac"
- ['OS=="mac" or OS=="ios"', {
- 'clang%': 1,
-
- 'variables': {
- # Mac OS X SDK and deployment target support. The SDK identifies
- # the version of the system headers that will be used, and
- # corresponds to the MAC_OS_X_VERSION_MAX_ALLOWED compile-time
- # macro. "Maximum allowed" refers to the operating system version
- # whose APIs are available in the headers. The deployment target
- # identifies the minimum system version that the built products are
- # expected to function on. It corresponds to the
- # MAC_OS_X_VERSION_MIN_REQUIRED compile-time macro. To ensure these
- # macros are available, #include <AvailabilityMacros.h>. Additional
- # documentation on these macros is available at
- # http://developer.apple.com/mac/library/technotes/tn2002/tn2064.html#SECTION3
- # Chrome normally builds with the Mac OS X 10.6 SDK and sets the
- # deployment target to 10.6. Other projects, such as O3D, may
- # override these defaults.
-
- # Normally, mac_sdk_min is used to find an SDK that Xcode knows
- # about that is at least the specified version. In official builds,
- # the SDK must match mac_sdk_min exactly. If the SDK is installed
- # someplace that Xcode doesn't know about, set mac_sdk_path to the
- # path to the SDK; when set to a non-empty string, SDK detection
- # based on mac_sdk_min will be bypassed entirely.
- 'conditions': [
- ['OS=="ios"', {
- 'mac_sdk_min%': '10.8',
- }, { # else OS!="ios"
- 'mac_sdk_min%': '10.6',
- }],
- ],
- 'mac_sdk_path%': '',
-
- 'mac_deployment_target%': '10.6',
- },
-
- 'mac_sdk_min': '<(mac_sdk_min)',
- 'mac_sdk_path': '<(mac_sdk_path)',
- 'mac_deployment_target': '<(mac_deployment_target)',
-
- # Compile in Breakpad support by default so that it can be
- # tested, even if it is not enabled by default at runtime.
- 'mac_breakpad_compiled_in%': 1,
- 'conditions': [
- # mac_product_name is set to the name of the .app bundle as it should
- # appear on disk. This duplicates data from
- # chrome/app/theme/chromium/BRANDING and
- # chrome/app/theme/google_chrome/BRANDING, but is necessary to get
- # these names into the build system.
- ['branding=="Chrome"', {
- 'mac_product_name%': 'Google Chrome',
- }, { # else: branding!="Chrome"
- 'mac_product_name%': 'Chromium',
- }],
- # Official mac builds require a specific OS X SDK, but iOS and
- # non-official mac builds do not.
- ['branding=="Chrome" and buildtype=="Official" and OS=="mac"', {
- 'mac_sdk%': '<!(python <(DEPTH)/build/mac/find_sdk.py --verify <(mac_sdk_min) --sdk_path=<(mac_sdk_path))',
- }, {
- 'mac_sdk%': '<!(python <(DEPTH)/build/mac/find_sdk.py <(mac_sdk_min))',
- }],
- ['branding=="Chrome" and buildtype=="Official"', {
- # Enable uploading crash dumps.
- 'mac_breakpad_uploads%': 1,
- # Enable dumping symbols at build time for use by Mac Breakpad.
- 'mac_breakpad%': 1,
- # Enable Keystone auto-update support.
- 'mac_keystone%': 1,
- }, { # else: branding!="Chrome" or buildtype!="Official"
- 'mac_breakpad_uploads%': 0,
- 'mac_breakpad%': 0,
- 'mac_keystone%': 0,
- }],
- ],
- }], # OS=="mac" or OS=="ios"
- ['OS=="win"', {
- 'conditions': [
- # This is the architecture convention used in WinSDK paths.
- ['target_arch=="ia32"', {
- 'winsdk_arch%': 'x86',
- },{
- 'winsdk_arch%': '<(target_arch)',
- }],
- ['component=="shared_library" or MSVS_VERSION == "2015"', {
- # TODO(scottmg): The allocator shimming doesn't work on the 2015 CRT
- # and we are hoping to be able to remove it if an additional feature
- # lands in the 2015 CRT API. For now, don't shim and revisit once
- # VS2015 is RTM: http://crbug.com/481611.
- 'win_use_allocator_shim%': 0,
- }],
- ['component=="static_library"', {
- # Turn on multiple dll by default on Windows when in static_library.
- 'chrome_multiple_dll%': 1,
- }],
- ['asan==1 or syzyasan==1', {
- 'win_use_allocator_shim%': 0,
- }],
- ['syzyasan==1', {
- 'kasko%': 1,
- }],
- ['component=="shared_library" and "<(GENERATOR)"=="ninja"', {
- # Only enabled by default for ninja because it's buggy in VS.
- # Not enabled for component=static_library because some targets
- # are too large and the toolchain fails due to the size of the
- # .obj files.
- 'incremental_chrome_dll%': 1,
- }],
- # Don't do incremental linking for large modules on 32-bit or when
- # component=static_library as the toolchain fails due to the size of
- # the .ilk files.
- ['MSVS_OS_BITS==32 or component=="static_library"', {
- 'msvs_large_module_debug_link_mode%': '1', # No
- },{
- 'msvs_large_module_debug_link_mode%': '2', # Yes
- }],
- ],
- 'nacl_win64_defines': [
- # This flag is used to minimize dependencies when building
- # Native Client loader for 64-bit Windows.
- 'NACL_WIN64',
- ],
- # Need to include allocator target, but exclude tcmalloc files.
- 'use_allocator%': 'winheap',
- }],
-
- ['os_posix==1 and chromeos==0 and OS!="android" and OS!="ios" and embedded==0', {
- 'use_cups%': 1,
- }, {
- 'use_cups%': 0,
- }],
-
- ['enable_plugins==1 and (OS=="linux" or OS=="mac" or OS=="win") and chromecast==0', {
- 'enable_pepper_cdms%': 1,
- }, {
- 'enable_pepper_cdms%': 0,
- }],
-
- ['OS=="android" or chromecast==1', {
- 'enable_browser_cdms%': 1,
- }, {
- 'enable_browser_cdms%': 0,
- }],
-
- # Native Client glibc toolchain is enabled
- # by default except on arm, mips and mips64.
- ['target_arch=="arm" or target_arch=="mipsel" or target_arch=="mips64el"', {
- 'disable_glibc%': 1,
- }, {
- 'disable_glibc%': 0,
- }],
-
- # Set the relative path from this file to the GYP file of the JPEG
- # library used by Chromium.
- ['use_system_libjpeg==1 or use_libjpeg_turbo==0', {
- # Configuration for using the system libjeg is here.
- 'libjpeg_gyp_path': '<(libjpeg_ijg_gyp_path)',
- }, {
- 'libjpeg_gyp_path': '<(libjpeg_turbo_gyp_path)',
- }],
-
- # Options controlling the use of GConf (the classic GNOME configuration
- # system) and GIO, which contains GSettings (the new GNOME config system).
- ['chromeos==1 or embedded==1', {
- 'use_gconf%': 0,
- 'use_gio%': 0,
- }, {
- 'use_gconf%': 1,
- 'use_gio%': 1,
- }],
-
- # Set up -D and -E flags passed into grit.
- ['branding=="Chrome"', {
- # TODO(mmoss) The .grd files look for _google_chrome, but for
- # consistency they should look for google_chrome_build like C++.
- 'grit_defines': ['-D', '_google_chrome',
- '-E', 'CHROMIUM_BUILD=google_chrome'],
- }, {
- 'grit_defines': ['-D', '_chromium',
- '-E', 'CHROMIUM_BUILD=chromium'],
- }],
- ['chromeos==1', {
- 'grit_defines': ['-D', 'chromeos', '-D', 'scale_factors=2x'],
- }],
- ['desktop_linux==1', {
- 'grit_defines': ['-D', 'desktop_linux'],
- }],
- ['toolkit_views==1', {
- 'grit_defines': ['-D', 'toolkit_views'],
- }],
- ['use_aura==1', {
- 'grit_defines': ['-D', 'use_aura'],
- }],
- ['use_ash==1', {
- 'grit_defines': ['-D', 'use_ash'],
- }],
- ['use_nss_certs==1', {
- 'grit_defines': ['-D', 'use_nss_certs'],
- }],
- ['use_ozone==1', {
- 'grit_defines': ['-D', 'use_ozone'],
- }],
- ['image_loader_extension==1', {
- 'grit_defines': ['-D', 'image_loader_extension'],
- }],
- ['remoting==1', {
- 'grit_defines': ['-D', 'remoting'],
- }],
- ['use_titlecase_in_grd==1', {
- 'grit_defines': ['-D', 'use_titlecase'],
- }],
- ['use_third_party_translations==1', {
- 'grit_defines': ['-D', 'use_third_party_translations'],
- 'locales': [
- 'ast', 'bs', 'ca@valencia', 'en-AU', 'eo', 'eu', 'gl', 'hy', 'ia',
- 'ka', 'ku', 'kw', 'ms', 'ug'
- ],
- }],
- ['OS=="android"', {
- 'grit_defines': [
- '-t', 'android',
- '-E', 'ANDROID_JAVA_TAGGED_ONLY=true',
- '--no-output-all-resource-defines',
- ],
- }],
- ['OS=="mac" or OS=="ios"', {
- 'grit_defines': ['-D', 'scale_factors=2x'],
- }],
- ['OS == "ios"', {
- 'variables': {
- 'enable_coverage%': 0,
- },
- 'grit_defines': [
- '-t', 'ios',
- '--no-output-all-resource-defines',
- ],
- # iOS uses a whitelist to filter resources.
- 'grit_whitelist%': '<(DEPTH)/build/ios/grit_whitelist.txt',
-
- # Enable host builds when generating with ninja-ios.
- 'conditions': [
- ['"<(GENERATOR)"=="ninja"', {
- 'host_os%': "mac",
- }],
-
- # Use the version of clang shipped with Xcode when building official
- # version of Chrome for iOS.
- #
- # TODO(eugenebut): Remove enable_coverage check once
- # libclang_rt.profile_ios.a is bundled with Chromium's clang.
- # http://crbug.com/450379
- #
- # TODO(sdefresne): Remove xcodebuild version check onces clang ToT
- # supports "nullable" and related. https://crbug.com/499448
- ['buildtype=="Official" or enable_coverage or '
- '<!(xcodebuild -version|awk \'/Xcode/{print ($2 >= 7.0)}\')==1', {
- 'clang_xcode%': 1,
- }],
- ],
- }],
- ['enable_extensions==1', {
- 'grit_defines': ['-D', 'enable_extensions'],
- }],
- ['enable_plugins!=0', {
- 'grit_defines': ['-D', 'enable_plugins'],
- }],
- ['enable_basic_printing==1 or enable_print_preview==1', {
- 'grit_defines': ['-D', 'enable_printing'],
- }],
- ['enable_print_preview==1', {
- 'grit_defines': ['-D', 'enable_print_preview'],
- }],
- ['enable_themes==1', {
- 'grit_defines': ['-D', 'enable_themes'],
- }],
- ['enable_app_list==1', {
- 'grit_defines': ['-D', 'enable_app_list'],
- }],
- ['enable_settings_app==1', {
- 'grit_defines': ['-D', 'enable_settings_app'],
- }],
- ['enable_google_now==1', {
- 'grit_defines': ['-D', 'enable_google_now'],
- }],
- ['use_concatenated_impulse_responses==1', {
- 'grit_defines': ['-D', 'use_concatenated_impulse_responses'],
- }],
- ['enable_media_router==1', {
- 'grit_defines': ['-D', 'enable_media_router'],
- }],
- ['enable_webrtc==1', {
- 'grit_defines': ['-D', 'enable_webrtc'],
- }],
- ['enable_hangout_services_extension==1', {
- 'grit_defines': ['-D', 'enable_hangout_services_extension'],
- }],
- ['enable_task_manager==1', {
- 'grit_defines': ['-D', 'enable_task_manager'],
- }],
- ['notifications==1', {
- 'grit_defines': ['-D', 'enable_notifications'],
- }],
- ['enable_wifi_bootstrapping==1', {
- 'grit_defines': ['-D', 'enable_wifi_bootstrapping'],
- }],
- ['mac_views_browser==1', {
- 'grit_defines': ['-D', 'mac_views_browser'],
- }],
- ['enable_resource_whitelist_generation==1 and OS!="win"', {
- 'grit_rc_header_format': ['-h', '#define {textual_id} _Pragma("whitelisted_resource_{numeric_id}") {numeric_id}'],
- }],
- ['enable_resource_whitelist_generation==1 and OS=="win"', {
- 'grit_rc_header_format': ['-h', '#define {textual_id} __pragma(message("whitelisted_resource_{numeric_id}")) {numeric_id}'],
- }],
- ['enable_mdns==1 or OS=="mac"', {
- 'grit_defines': ['-D', 'enable_service_discovery'],
- 'enable_service_discovery%': 1
- }],
- ['clang_use_chrome_plugins==1', {
- 'variables': {
- 'conditions': [
- ['OS!="win"', {
- 'variables': {
- 'conditions': [
- ['OS=="mac" or OS=="ios"', {
- 'clang_lib_path%': '<!(cd <(DEPTH) && pwd -P)/third_party/llvm-build/Release+Asserts/lib/libFindBadConstructs.dylib',
- }, { # OS != "mac" or OS != "ios"
- 'clang_lib_path%': '<!(cd <(DEPTH) && pwd -P)/third_party/llvm-build/Release+Asserts/lib/libFindBadConstructs.so',
- }],
- ],
- },
- 'clang_dynlib_flags%': '-Xclang -load -Xclang <(clang_lib_path) ',
- }, { # OS == "win"
- # On Windows, the plugin is built directly into clang, so there's
- # no need to load it dynamically.
- 'clang_dynlib_flags%': '',
- }],
- # https://crbug.com/441916
- ['OS=="android" or OS=="linux" or OS=="mac"', {
- 'clang_plugin_args%': '-Xclang -plugin-arg-find-bad-constructs -Xclang check-templates ',
- }, { # OS != "linux"
- 'clang_plugin_args%': ''
- }],
- ],
- },
- # If you change these, also change build/config/clang/BUILD.gn.
- 'clang_chrome_plugins_flags%':
- '<(clang_dynlib_flags)'
- '-Xclang -add-plugin -Xclang find-bad-constructs <(clang_plugin_args)',
- }],
- ['asan==1 or msan==1 or lsan==1 or tsan==1', {
- 'clang%': 1,
- 'use_allocator%': 'none',
- 'use_sanitizer_options%': 1,
- }],
-
- ['OS=="linux" and asan==0 and msan==0 and lsan==0 and tsan==0', {
- # PNaCl toolchain Non-SFI build only supports linux OS build.
- # Also, it does not support sanitizers.
- 'enable_nacl_nonsfi_test%': 1,
- }],
- ['asan==1 and OS=="linux" and chromeos==0', {
- 'use_custom_libcxx%': 1,
- }],
- ['ubsan==1', {
- 'clang%': 1,
- }],
- ['ubsan_vptr==1', {
- 'clang%': 1,
- }],
- ['asan==1 and OS=="mac"', {
- 'mac_strip_release': 1,
- }],
- ['tsan==1', {
- 'use_custom_libcxx%': 1,
- }],
- ['msan==1', {
- # Use a just-built, MSan-instrumented libc++ instead of the system-wide
- # libstdc++. This is required to avoid false positive reports whenever
- # the C++ standard library is used.
- 'use_custom_libcxx%': 1,
- # Running the V8-generated code on an ARM simulator is a powerful hack
- # that allows the tool to see the memory accesses from JITted code.
- # Without this flag, JS code causes false positive reports from MSan.
- 'v8_target_arch': 'arm64',
- }],
-
- ['OS=="linux" and clang_type_profiler==1', {
- 'clang%': 1,
- 'clang_use_chrome_plugins%': 0,
- 'conditions': [
- ['host_arch=="x64"', {
- 'make_clang_dir%': 'third_party/llvm-allocated-type/Linux_x64',
- }],
- ['host_arch=="ia32"', {
- # 32-bit Clang is unsupported. It may not build. Put your 32-bit
- # Clang in this directory at your own risk if needed for some
- # purpose (e.g. to compare 32-bit and 64-bit behavior like memory
- # usage). Any failure by this compiler should not close the tree.
- 'make_clang_dir%': 'third_party/llvm-allocated-type/Linux_ia32',
- }],
- ],
- }],
-
- # On valgrind bots, override the optimizer settings so we don't inline too
- # much and make the stacks harder to figure out.
- #
- # TODO(rnk): Kill off variables that no one else uses and just implement
- # them under a build_for_tool== condition.
- ['build_for_tool=="memcheck" or build_for_tool=="tsan"', {
- # gcc flags
- 'mac_debug_optimization': '1',
- 'mac_release_optimization': '1',
- 'release_optimize': '1',
- 'no_gc_sections': 1,
- 'debug_extra_cflags': '-g -fno-inline -fno-omit-frame-pointer '
- '-fno-builtin -fno-optimize-sibling-calls',
- 'release_extra_cflags': '-g -fno-inline -fno-omit-frame-pointer '
- '-fno-builtin -fno-optimize-sibling-calls',
-
- # MSVS flags for TSan on Pin and Windows.
- 'win_debug_RuntimeChecks': '0',
- 'win_debug_disable_iterator_debugging': '1',
- 'win_debug_Optimization': '1',
- 'win_debug_InlineFunctionExpansion': '0',
- 'win_release_InlineFunctionExpansion': '0',
- 'win_release_OmitFramePointers': '0',
-
- 'use_allocator': 'tcmalloc',
- 'release_valgrind_build': 1,
- 'werror': '',
- 'component': 'static_library',
- 'use_system_zlib': 0,
- }],
-
- # Build tweaks for DrMemory.
- # TODO(rnk): Combine with tsan config to share the builder.
- # http://crbug.com/108155
- ['build_for_tool=="drmemory"', {
- # These runtime checks force initialization of stack vars which blocks
- # DrMemory's uninit detection.
- 'win_debug_RuntimeChecks': '0',
- # Iterator debugging is slow.
- 'win_debug_disable_iterator_debugging': '1',
- # Try to disable optimizations that mess up stacks in a release build.
- # DrM-i#1054 (https://github.com/DynamoRIO/drmemory/issues/1054)
- # /O2 and /Ob0 (disable inline) cannot be used together because of a
- # compiler bug, so we use /Ob1 instead.
- 'win_release_InlineFunctionExpansion': '1',
- 'win_release_OmitFramePointers': '0',
- # Ditto for debug, to support bumping win_debug_Optimization.
- 'win_debug_InlineFunctionExpansion': 0,
- 'win_debug_OmitFramePointers': 0,
- # Keep the code under #ifndef NVALGRIND.
- 'release_valgrind_build': 1,
- }],
-
- # RLZ library is used on Win, Mac, iOS and ChromeOS.
- ['OS=="win" or OS=="mac" or OS=="ios" or chromeos==1', {
- 'enable_rlz_support%': 1,
- 'conditions': [
- # RLZ is enabled for "Chrome" builds.
- ['branding=="Chrome"', {
- 'enable_rlz%': 1,
- }],
- ],
- }],
-
- # Set default compiler flags depending on ARM version.
- ['arm_version==6', {
- 'arm_arch%': 'armv6',
- 'arm_tune%': '',
- 'arm_fpu%': 'vfp',
- 'arm_float_abi%': 'softfp',
- 'arm_thumb%': 0,
- }],
- ['arm_version==7', {
- 'arm_arch%': 'armv7-a',
- 'arm_tune%': 'generic-armv7-a',
- 'conditions': [
- ['arm_neon==1', {
- 'arm_fpu%': 'neon',
- }, {
- 'arm_fpu%': 'vfpv3-d16',
- }],
- ['OS=="android"', {
- 'arm_float_abi%': 'softfp',
- }, {
- 'arm_float_abi%': 'hard',
- }],
- ],
- 'arm_thumb%': 1,
- }],
-
- # Set default compiler flags for MIPS floating-point support.
- ['target_arch=="mipsel"', {
- 'mips_float_abi%': 'hard',
- }],
- ['target_arch=="mipsel" and mips_arch_variant=="r2"', {
- 'mips_fpu_mode%': 'fp32',
- }],
-
- # Enable brlapi by default for chromeos.
- [ 'chromeos==1', {
- 'use_brlapi%': 1,
- }],
-
- ['use_ozone==1 and ozone_auto_platforms==1', {
- # Use test as the default platform.
- 'ozone_platform%': 'test',
-
- # Build all platforms whose deps are in install-build-deps.sh.
- # Only these platforms will be compile tested by buildbots.
- 'ozone_platform_drm%': 1,
- 'ozone_platform_test%': 1,
- 'ozone_platform_egltest%': 1,
- }],
-
- ['desktop_linux==1 and use_aura==1 and use_x11==1', {
- 'use_clipboard_aurax11%': 1,
- }],
-
- ['OS=="win" and use_goma==1', {
- # goma doesn't support pch yet.
- 'chromium_win_pch': 0,
- # goma doesn't support PDB yet, so win_z7=1 or fastbuild=1.
- 'conditions': [
- ['win_z7==0 and fastbuild==0', {
- 'fastbuild': 1,
- }],
- ],
- }],
-
- ['OS=="win" and (clang==1 or asan==1)', {
- 'chromium_win_pch': 0,
- }],
-
- ['host_clang==1', {
- 'host_cc': '<(make_clang_dir)/bin/clang',
- 'host_cxx': '<(make_clang_dir)/bin/clang++',
- }, {
- 'host_cc': '<!(which gcc)',
- 'host_cxx': '<!(which g++)',
- }],
-
- # The seccomp-bpf sandbox is only supported on five architectures
- # currently.
- # Do not disable seccomp_bpf anywhere without talking to
- # security@chromium.org!
- ['((OS=="linux" or OS=="android") and '
- '(target_arch=="ia32" or target_arch=="x64" or '
- 'target_arch=="arm" or target_arch=="mipsel" or '
- 'target_arch=="arm64"))', {
- 'use_seccomp_bpf%': 1,
- }, {
- 'use_seccomp_bpf%': 0,
- }],
-
- ['cfi_vptr==1', {
- 'use_lto%': 1,
- }],
-
- ['branding=="Chrome" and buildtype=="Official"', {
- 'enable_hangout_services_extension%': 1,
- }, {
- 'enable_hangout_services_extension%': 0,
- }],
- ],
-
- # The path to the ANGLE library.
- 'angle_path': '<(DEPTH)/third_party/angle',
-
- # List of default apps to install in new profiles. The first list contains
- # the source files as found in svn. The second list, used only for linux,
- # contains the destination location for each of the files. When a crx
- # is added or removed from the list, the chrome/browser/resources/
- # default_apps/external_extensions.json file must also be updated.
- #
- # README: GN version of these is in the target //chrome:default_apps
- # (there's no global variable like in GYP). Be sure to update that target
- # if you change these lists!
- 'default_apps_list': [
- 'browser/resources/default_apps/external_extensions.json',
- 'browser/resources/default_apps/gmail.crx',
- 'browser/resources/default_apps/search.crx',
- 'browser/resources/default_apps/youtube.crx',
- 'browser/resources/default_apps/drive.crx',
- 'browser/resources/default_apps/docs.crx',
- ],
- 'default_apps_list_linux_dest': [
- '<(PRODUCT_DIR)/default_apps/external_extensions.json',
- '<(PRODUCT_DIR)/default_apps/gmail.crx',
- '<(PRODUCT_DIR)/default_apps/search.crx',
- '<(PRODUCT_DIR)/default_apps/youtube.crx',
- '<(PRODUCT_DIR)/default_apps/drive.crx',
- '<(PRODUCT_DIR)/default_apps/docs.crx',
- ],
-
- # Whether to allow building of the GPU-related isolates.
- 'archive_gpu_tests%': 0,
-
- # Whether to allow building of chromoting related isolates.
- 'archive_chromoting_tests%': 0,
- },
- 'target_defaults': {
- 'variables': {
- # The condition that operates on chromium_code is in a target_conditions
- # section, and will not have access to the default fallback value of
- # chromium_code at the top of this file, or to the chromium_code
- # variable placed at the root variables scope of .gyp files, because
- # those variables are not set at target scope. As a workaround,
- # if chromium_code is not set at target scope, define it in target scope
- # to contain whatever value it has during early variable expansion.
- # That's enough to make it available during target conditional
- # processing.
- 'chromium_code%': '<(chromium_code)',
-
- 'component%': '<(component)',
-
- 'chromecast%': '<(chromecast)',
-
- # See http://msdn.microsoft.com/en-us/library/aa652360(VS.71).aspx
- 'win_release_Optimization%': '2', # 2 = /O2
- 'win_debug_Optimization%': '0', # 0 = /Od
-
- # See http://msdn.microsoft.com/en-us/library/2kxx5t2c(v=vs.80).aspx
- # Tri-state: blank is default, 1 on, 0 off
- 'win_release_OmitFramePointers%': '0',
- # Tri-state: blank is default, 1 on, 0 off
- 'win_debug_OmitFramePointers%': '',
-
- # See http://msdn.microsoft.com/en-us/library/8wtf2dfz(VS.71).aspx
- 'win_debug_RuntimeChecks%': '3', # 3 = all checks enabled, 0 = off
-
- # See http://msdn.microsoft.com/en-us/library/47238hez(VS.71).aspx
- 'win_debug_InlineFunctionExpansion%': '', # empty = default, 0 = off,
- 'win_release_InlineFunctionExpansion%': '2', # 1 = only __inline, 2 = max
-
- # VS inserts quite a lot of extra checks to algorithms like
- # std::partial_sort in Debug build which make them O(N^2)
- # instead of O(N*logN). This is particularly slow under memory
- # tools like ThreadSanitizer so we want it to be disablable.
- # See http://msdn.microsoft.com/en-us/library/aa985982(v=VS.80).aspx
- 'win_debug_disable_iterator_debugging%': '0',
-
- # An application manifest fragment to declare compatibility settings for
- # 'executable' targets. Ignored in other target type.
- 'win_exe_compatibility_manifest%':
- '<(DEPTH)\\build\\win\\compatibility.manifest',
-
- 'release_extra_cflags%': '',
- 'debug_extra_cflags%': '',
-
- 'release_valgrind_build%': '<(release_valgrind_build)',
-
- # the non-qualified versions are widely assumed to be *nix-only
- 'win_release_extra_cflags%': '',
- 'win_debug_extra_cflags%': '',
-
- # TODO(thakis): Make this a blacklist instead, http://crbug.com/101600
- 'enable_wexit_time_destructors%': '<(enable_wexit_time_destructors)',
-
- # Only used by Windows build for now. Can be used to build into a
- # differet output directory, e.g., a build_dir_prefix of VS2010_ would
- # output files in src/build/VS2010_{Debug,Release}.
- 'build_dir_prefix%': '',
-
- # Targets are by default not nacl untrusted code.
- 'nacl_untrusted_build%': 0,
-
- 'pnacl_compile_flags': [
- # pnacl uses the clang compiler so we need to suppress all the
- # same warnings as we do for clang.
- # TODO(sbc): Remove these if/when they are removed from the clang
- # build.
- '-Wno-unused-function',
- '-Wno-char-subscripts',
- '-Wno-c++11-extensions',
- '-Wno-unnamed-type-template-args',
- ],
-
- # By default, Android targets have their exported JNI symbols stripped,
- # so we test the manual JNI registration code paths that are required
- # when using the crazy linker. To allow use of native JNI exports (lazily
- # resolved by the JVM), targets can enable this variable, which will stop
- # the stripping from happening. Only targets which do not need to be
- # compatible with the crazy linker are permitted to set this.
- 'use_native_jni_exports%': 0,
-
- 'conditions': [
- ['OS=="win" and component=="shared_library"', {
- # See http://msdn.microsoft.com/en-us/library/aa652367.aspx
- 'win_release_RuntimeLibrary%': '2', # 2 = /MD (nondebug DLL)
- 'win_debug_RuntimeLibrary%': '3', # 3 = /MDd (debug DLL)
- }, {
- # See http://msdn.microsoft.com/en-us/library/aa652367.aspx
- 'win_release_RuntimeLibrary%': '0', # 0 = /MT (nondebug static)
- 'win_debug_RuntimeLibrary%': '1', # 1 = /MTd (debug static)
- }],
- ['OS=="ios"', {
- # See http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Optimize-Options.html
- 'mac_release_optimization%': 's', # Use -Os unless overridden
- 'mac_debug_optimization%': '0', # Use -O0 unless overridden
- }, {
- # See http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Optimize-Options.html
- 'mac_release_optimization%': '2', # Use -O2 unless overridden
- 'mac_debug_optimization%': '0', # Use -O0 unless overridden
- }],
- ['OS=="android"', {
- 'host_os%': '<(host_os)', # See comment above chromium_code.
- }],
- ],
- 'clang_warning_flags': [
- '-Wheader-hygiene',
-
- # Don't die on dtoa code that uses a char as an array index.
- # This is required solely for base/third_party/dmg_fp/dtoa.cc.
- '-Wno-char-subscripts',
-
- # TODO(thakis): This used to be implied by -Wno-unused-function,
- # which we no longer use. Check if it makes sense to remove
- # this as well. http://crbug.com/316352
- '-Wno-unneeded-internal-declaration',
-
- # Warns on switches on enums that cover all enum values but
- # also contain a default: branch. Chrome is full of that.
- '-Wno-covered-switch-default',
-
- # Warns when a const char[] is converted to bool.
- '-Wstring-conversion',
-
- # C++11-related flags:
-
- # This warns on using ints as initializers for floats in
- # initializer lists (e.g. |int a = f(); CGSize s = { a, a };|),
- # which happens in several places in chrome code. Not sure if
- # this is worth fixing.
- '-Wno-c++11-narrowing',
-
- # Clang considers the `register` keyword as deprecated, but e.g.
- # code generated by flex (used in angle) contains that keyword.
- # http://crbug.com/255186
- '-Wno-deprecated-register',
-
- # TODO(hans): Get this cleaned up, http://crbug.com/428099
- '-Wno-inconsistent-missing-override',
-
- # TODO(thakis): Enable this, crbug.com/507717
- '-Wno-shift-negative-value',
- ],
- },
- 'includes': [ 'set_clang_warning_flags.gypi', ],
- 'defines': [
- # Don't use deprecated V8 APIs anywhere.
- 'V8_DEPRECATION_WARNINGS',
- ],
- 'include_dirs': [
- '<(SHARED_INTERMEDIATE_DIR)',
- ],
- 'conditions': [
- ['OS=="mac"', {
- # When compiling Objective C, warns if a method is used whose
- # availability is newer than the deployment target.
- 'xcode_settings': { 'WARNING_CFLAGS': ['-Wpartial-availability']},
- }],
- ['(OS=="mac" or OS=="ios") and asan==1', {
- 'dependencies': [
- '<(DEPTH)/build/mac/asan.gyp:asan_dynamic_runtime',
- ],
- }],
- ['OS=="win" and asan==1 and component=="shared_library"', {
- 'dependencies': [
- '<(DEPTH)/build/win/asan.gyp:asan_dynamic_runtime',
- ],
- }],
- ['OS=="linux" and use_allocator!="none" and clang_type_profiler==1', {
- 'cflags_cc!': ['-fno-rtti'],
- 'cflags_cc+': [
- '-frtti',
- '-gline-tables-only',
- '-fintercept-allocation-functions',
- ],
- 'defines': ['TYPE_PROFILING'],
- 'dependencies': [
- '<(DEPTH)/base/allocator/allocator.gyp:type_profiler',
- ],
- }],
- ['branding=="Chrome"', {
- 'defines': ['GOOGLE_CHROME_BUILD'],
- }, { # else: branding!="Chrome"
- 'defines': ['CHROMIUM_BUILD'],
- }],
- ['OS=="mac" and component=="shared_library"', {
- 'xcode_settings': {
- 'DYLIB_INSTALL_NAME_BASE': '@rpath',
- 'LD_RUNPATH_SEARCH_PATHS': [
- # For unbundled binaries.
- '@loader_path/.',
- # For bundled binaries, to get back from Binary.app/Contents/MacOS.
- '@loader_path/../../..',
- ],
- },
- }],
- ['clang==1 or host_clang==1', {
- # This is here so that all files get recompiled after a clang roll and
- # when turning clang on or off.
- # (defines are passed via the command line, and build systems rebuild
- # things when their commandline changes). Nothing should ever read this
- # define.
- 'defines': ['CR_CLANG_REVISION=<!(python <(DEPTH)/tools/clang/scripts/update.py --print-revision)'],
- }],
- ['enable_rlz==1', {
- 'defines': ['ENABLE_RLZ'],
- }],
- ['component=="shared_library"', {
- 'defines': ['COMPONENT_BUILD'],
- }],
- ['ui_compositor_image_transport==1', {
- 'defines': ['UI_COMPOSITOR_IMAGE_TRANSPORT'],
- }],
- ['use_aura==1', {
- 'defines': ['USE_AURA=1'],
- }],
- ['use_ash==1', {
- 'defines': ['USE_ASH=1'],
- }],
- ['use_pango==1', {
- 'defines': ['USE_PANGO=1'],
- }],
- ['use_cairo==1', {
- 'defines': ['USE_CAIRO=1'],
- }],
- ['use_cras==1', {
- 'defines': ['USE_CRAS=1'],
- }],
- ['use_ozone==1', {
- 'defines': ['USE_OZONE=1'],
- }],
- ['use_default_render_theme==1', {
- 'defines': ['USE_DEFAULT_RENDER_THEME=1'],
- }],
- ['use_libjpeg_turbo==1', {
- 'defines': ['USE_LIBJPEG_TURBO=1'],
- }],
- ['use_x11==1', {
- 'defines': ['USE_X11=1'],
- }],
- ['use_clipboard_aurax11==1', {
- 'defines': ['USE_CLIPBOARD_AURAX11=1'],
- }],
- ['enable_one_click_signin==1', {
- 'defines': ['ENABLE_ONE_CLICK_SIGNIN'],
- }],
- ['enable_pre_sync_backup==1', {
- 'defines': ['ENABLE_PRE_SYNC_BACKUP'],
- }],
- ['image_loader_extension==1', {
- 'defines': ['IMAGE_LOADER_EXTENSION=1'],
- }],
- ['profiling==1', {
- 'defines': ['ENABLE_PROFILING=1'],
- }],
- ['remoting==1', {
- 'defines': ['ENABLE_REMOTING=1'],
- }],
- ['enable_webrtc==1', {
- 'defines': ['ENABLE_WEBRTC=1'],
- }],
- ['enable_media_router==1', {
- 'defines': ['ENABLE_MEDIA_ROUTER=1'],
- }],
- ['proprietary_codecs==1', {
- 'defines': ['USE_PROPRIETARY_CODECS'],
- 'conditions': [
- ['enable_mpeg2ts_stream_parser==1', {
- 'defines': ['ENABLE_MPEG2TS_STREAM_PARSER'],
- }],
- ],
- }],
- ['enable_viewport==1', {
- 'defines': ['ENABLE_VIEWPORT'],
- }],
- ['enable_pepper_cdms==1', {
- 'defines': ['ENABLE_PEPPER_CDMS'],
- }],
- ['enable_browser_cdms==1', {
- 'defines': ['ENABLE_BROWSER_CDMS'],
- }],
- ['configuration_policy==1', {
- 'defines': ['ENABLE_CONFIGURATION_POLICY'],
- }],
- ['notifications==1', {
- 'defines': ['ENABLE_NOTIFICATIONS'],
- }],
- ['enable_hidpi==1', {
- 'defines': ['ENABLE_HIDPI=1'],
- }],
- ['enable_topchrome_md==1', {
- 'defines': ['ENABLE_TOPCHROME_MD=1'],
- }],
- ['native_memory_pressure_signals==1', {
- 'defines': ['SYSTEM_NATIVELY_SIGNALS_MEMORY_PRESSURE'],
- }],
- ['use_udev==1', {
- 'defines': ['USE_UDEV'],
- }],
- ['fastbuild!=0', {
- 'xcode_settings': {
- 'GCC_GENERATE_DEBUGGING_SYMBOLS': 'NO',
- },
- 'conditions': [
- ['OS=="win" and fastbuild==2', {
- # Completely disable debug information.
- 'msvs_settings': {
- 'VCLinkerTool': {
- 'GenerateDebugInformation': 'false',
- },
- 'VCCLCompilerTool': {
- 'DebugInformationFormat': '0',
- },
- },
- }],
- ['OS=="win" and fastbuild==1', {
- 'msvs_settings': {
- 'VCLinkerTool': {
- # This tells the linker to generate .pdbs, so that
- # we can get meaningful stack traces.
- 'GenerateDebugInformation': 'true',
- },
- 'VCCLCompilerTool': {
- # No debug info to be generated by compiler.
- 'DebugInformationFormat': '0',
- },
- },
- }],
- ['(OS=="android" or OS=="linux") and fastbuild==2', {
- 'variables': { 'debug_extra_cflags': '-g0', },
- }],
- ['(OS=="android" or OS=="linux") and fastbuild==1', {
- # TODO(thakis): Change this to -g1 once http://crbug.com/456947 is
- # fixed.
- 'variables': { 'debug_extra_cflags': '-g0', },
- }],
- # Android builds symbols on release by default, disable them.
- ['OS=="android" and fastbuild==2', {
- 'variables': { 'release_extra_cflags': '-g0', },
- }],
- ['OS=="android" and fastbuild==1', {
- # TODO(thakis): Change this to -g1 once http://crbug.com/456947 is
- # fixed.
- 'variables': { 'release_extra_cflags': '-g0', },
- }],
- ],
- }], # fastbuild!=0
- ['dont_embed_build_metadata==1', {
- 'defines': [
- 'DONT_EMBED_BUILD_METADATA',
- ],
- }], # dont_embed_build_metadata==1
- ['dcheck_always_on!=0', {
- 'defines': ['DCHECK_ALWAYS_ON=1'],
- }], # dcheck_always_on!=0
- ['tracing_like_official_build!=0', {
- 'defines': ['TRACING_IS_OFFICIAL_BUILD=1'],
- }], # tracing_like_official_build!=0
- ['OS=="win"', {
- 'defines': ['NO_TCMALLOC'],
- 'conditions': [
- ['win_use_allocator_shim==1', {
- 'defines': ['ALLOCATOR_SHIM'],
- }],
- ],
- }],
- ['asan==1', {
- 'defines': [
- 'ADDRESS_SANITIZER',
- 'MEMORY_TOOL_REPLACES_ALLOCATOR',
- 'MEMORY_SANITIZER_INITIAL_SIZE',
- ],
- }],
- ['syzyasan==1', {
- # SyzyAsan needs /PROFILE turned on to produce appropriate pdbs.
- 'msvs_settings': {
- 'VCLinkerTool': {
- 'Profile': 'true',
- },
- },
- 'defines': [
- 'SYZYASAN',
- 'MEMORY_TOOL_REPLACES_ALLOCATOR',
- 'MEMORY_SANITIZER_INITIAL_SIZE',
- ],
- }],
- ['kasko==1', {
- 'defines': [
- 'KASKO',
- ],
- 'include_dirs': [
- '<(DEPTH)/third_party/kasko/include',
- ],
- }],
- ['OS=="win"', {
- 'defines': [
- '__STD_C',
- '_CRT_SECURE_NO_DEPRECATE',
- '_SCL_SECURE_NO_DEPRECATE',
- # This define is required to pull in the new Win8 interfaces from
- # system headers like ShObjIdl.h.
- 'NTDDI_VERSION=0x06030000',
- # This is required for ATL to use XP-safe versions of its functions.
- '_USING_V110_SDK71_',
- ],
- 'include_dirs': [
- '<(DEPTH)/third_party/wtl/include',
- ],
- 'conditions': [
- ['win_z7!=0', {
- 'msvs_settings': {
- # Generates debug info when win_z7=1
- # even if fastbuild=1 (that makes GenerateDebugInformation false).
- 'VCLinkerTool': {
- 'GenerateDebugInformation': 'true',
- },
- 'VCCLCompilerTool': {
- 'DebugInformationFormat': '1',
- }
- }
- }], # win_z7!=0
- ['win_analyze', {
- 'defines!': [
- # This is prohibited when running /analyze.
- '_USING_V110_SDK71_',
- ],
- 'msvs_settings': {
- 'VCCLCompilerTool': {
- # Set WarnAsError to false to disable this setting for most
- # projects so that compilation continues.
- 'WarnAsError': 'false',
- # When win_analyze is specified add the /analyze switch.
- # Also add /WX- to force-disable WarnAsError for projects that
- # override WarnAsError.
- # Also, disable various noisy warnings that have low value.
- 'AdditionalOptions': [
- '/analyze:WX-',
- '/wd6011', # Dereferencing NULL pointer
- '/wd6312', # Possible infinite loop: use of the constant
- # EXCEPTION_CONTINUE_EXECUTION in the exception-filter
- '/wd6326', # Potential comparison of constant with constant
- '/wd28159', # Consider using 'GetTickCount64'
- '/wd28204', # Inconsistent SAL annotations
- '/wd28251', # Inconsistent SAL annotations
- '/wd28252', # Inconsistent SAL annotations
- '/wd28253', # Inconsistent SAL annotations
- '/wd28196', # The precondition is not satisfied
- '/wd28301', # Inconsistent SAL annotations
- '/wd6340', # Sign mismatch in function parameter
- '/wd28182', # Dereferencing NULL pointer
- # C6285 is ~16% of raw warnings and has low value
- '/wd6285', # non-zero constant || non-zero constant
- # C6334 is ~80% of raw warnings and has low value
- '/wd6334', # sizeof applied to an expression with an operator
- ],
- },
- },
- }], # win_analyze
- ],
- }], # OS==win
- ['chromecast==1', {
- 'defines': [
- 'LOG_DISABLED=0',
- ],
- 'conditions': [
- ['use_playready==1', {
- 'defines': [
- 'PLAYREADY_CDM_AVAILABLE',
- ],
- }],
- ],
- }],
- ['enable_task_manager==1', {
- 'defines': [
- 'ENABLE_TASK_MANAGER=1',
- ],
- }],
- ['enable_extensions==1', {
- 'defines': [
- 'ENABLE_EXTENSIONS=1',
- ],
- }],
- ['OS=="win" and branding=="Chrome"', {
- 'defines': ['ENABLE_SWIFTSHADER'],
- }],
- ['enable_dart==1', {
- 'defines': ['WEBKIT_USING_DART=1'],
- }],
- ['enable_plugin_installation==1', {
- 'defines': ['ENABLE_PLUGIN_INSTALLATION=1'],
- }],
- ['enable_plugins==1', {
- 'defines': ['ENABLE_PLUGINS=1'],
- }],
- ['enable_session_service==1', {
- 'defines': ['ENABLE_SESSION_SERVICE=1'],
- }],
- ['enable_themes==1', {
- 'defines': ['ENABLE_THEMES=1'],
- }],
- ['enable_autofill_dialog==1', {
- 'defines': ['ENABLE_AUTOFILL_DIALOG=1'],
- }],
- ['enable_prod_wallet_service==1', {
- # In GN, this is set on the autofill tagets only. See
- # //components/autofill/core/browser:wallet_service
- 'defines': ['ENABLE_PROD_WALLET_SERVICE=1'],
- }],
- ['enable_background==1', {
- 'defines': ['ENABLE_BACKGROUND=1'],
- }],
- ['enable_google_now==1', {
- 'defines': ['ENABLE_GOOGLE_NOW=1'],
- }],
- ['cld_version!=0', {
- 'defines': ['CLD_VERSION=<(cld_version)'],
- }],
- ['enable_basic_printing==1 or enable_print_preview==1', {
- # Convenience define for ENABLE_BASIC_PRINTING || ENABLE_PRINT_PREVIEW.
- 'defines': ['ENABLE_PRINTING=1'],
- }],
- ['enable_basic_printing==1', {
- # Enable basic printing support and UI.
- 'defines': ['ENABLE_BASIC_PRINTING=1'],
- }],
- ['enable_print_preview==1', {
- # Enable printing with print preview.
- # Can be defined without ENABLE_BASIC_PRINTING.
- 'defines': ['ENABLE_PRINT_PREVIEW=1'],
- }],
- ['enable_spellcheck==1', {
- 'defines': ['ENABLE_SPELLCHECK=1'],
- }],
- ['use_platform_spellchecker', {
- 'defines': ['USE_PLATFORM_SPELLCHECKER=1'],
- }],
- ['enable_captive_portal_detection==1', {
- 'defines': ['ENABLE_CAPTIVE_PORTAL_DETECTION=1'],
- }],
- ['enable_app_list==1', {
- 'defines': ['ENABLE_APP_LIST=1'],
- }],
- ['enable_settings_app==1', {
- 'defines': ['ENABLE_SETTINGS_APP=1'],
- }],
- ['disable_file_support==1', {
- 'defines': ['DISABLE_FILE_SUPPORT=1'],
- }],
- ['disable_ftp_support==1', {
- 'defines': ['DISABLE_FTP_SUPPORT=1'],
- }],
- ['enable_supervised_users==1', {
- 'defines': ['ENABLE_SUPERVISED_USERS=1'],
- }],
- ['enable_mdns==1', {
- 'defines': ['ENABLE_MDNS=1'],
- }],
- ['enable_service_discovery==1', {
- 'defines' : [ 'ENABLE_SERVICE_DISCOVERY=1' ],
- }],
- ['enable_wifi_bootstrapping==1', {
- 'defines' : [ 'ENABLE_WIFI_BOOTSTRAPPING=1' ],
- }],
- ['enable_hangout_services_extension==1', {
- 'defines': ['ENABLE_HANGOUT_SERVICES_EXTENSION=1'],
- }],
- ['enable_ipc_fuzzer==1', {
- 'defines': ['ENABLE_IPC_FUZZER=1'],
- }],
- ['video_hole==1', {
- 'defines': ['VIDEO_HOLE=1'],
- }],
- ['v8_use_external_startup_data==1', {
- 'defines': ['V8_USE_EXTERNAL_STARTUP_DATA'],
- }],
- ['enable_webvr==1', {
- 'defines': ['ENABLE_WEBVR'],
- }],
-
- # SAFE_BROWSING_SERVICE - browser manages a safe-browsing service.
- # SAFE_BROWSING_DB_LOCAL - service manages a local database.
- # SAFE_BROWSING_DB_REMOTE - service talks via API to a database
- # SAFE_BROWSING_CSD - enable client-side phishing detection.
- ['safe_browsing==1', {
- 'defines': [
- # TODO(nparker): Remove existing uses of FULL_SAFE_BROWSING
- 'FULL_SAFE_BROWSING',
- 'SAFE_BROWSING_CSD',
- 'SAFE_BROWSING_DB_LOCAL',
- 'SAFE_BROWSING_SERVICE',
- ],
- }],
- ['safe_browsing==2', {
- 'defines': [
- # TODO(nparker): Remove existing uses of MOBILE_SAFE_BROWSING
- 'MOBILE_SAFE_BROWSING',
- 'SAFE_BROWSING_SERVICE',
- ],
- }],
- ['safe_browsing==3', {
- 'defines': [
- # TODO(nparker): Remove existing uses of MOBILE_SAFE_BROWSING
- 'MOBILE_SAFE_BROWSING',
- 'SAFE_BROWSING_DB_REMOTE',
- 'SAFE_BROWSING_SERVICE',
- ],
- }],
- ], # conditions for 'target_defaults'
- 'target_conditions': [
- ['<(use_libpci)==1', {
- 'defines': ['USE_LIBPCI=1'],
- }],
- ['<(use_openssl)==1', {
- 'defines': ['USE_OPENSSL=1'],
- }],
- ['<(use_openssl_certs)==1', {
- 'defines': ['USE_OPENSSL_CERTS=1'],
- }],
- ['>(nacl_untrusted_build)==1', {
- 'defines': [
- 'USE_OPENSSL=1',
- 'USE_OPENSSL_CERTS=1',
- ],
- }],
- ['<(use_glib)==1 and >(nacl_untrusted_build)==0', {
- 'defines': ['USE_GLIB=1'],
- }],
- ['<(use_nss_certs)==1 and >(nacl_untrusted_build)==0', {
- 'defines': ['USE_NSS_CERTS=1'],
- }],
- ['<(chromeos)==1 and >(nacl_untrusted_build)==0', {
- 'defines': ['OS_CHROMEOS=1'],
- }],
- ['enable_wexit_time_destructors==1 and OS!="win"', {
- # TODO: Enable on Windows too, http://crbug.com/404525
- 'variables': { 'clang_warning_flags': ['-Wexit-time-destructors']},
- }],
- ['chromium_code==0', {
- 'variables': {
- 'clang_warning_flags': [
- # TODO(mgiuca): Move this suppression into individual third-party
- # libraries as required. http://crbug.com/505301.
- '-Wno-overloaded-virtual',
- # Lots of third-party libraries have unused variables. Instead of
- # suppressing them individually, we just blanket suppress them here.
- '-Wno-unused-variable',
- ],
- },
- 'conditions': [
- [ 'os_posix==1 and OS!="mac" and OS!="ios"', {
- # We don't want to get warnings from third-party code,
- # so remove any existing warning-enabling flags like -Wall.
- 'cflags!': [
- '-Wall',
- '-Wextra',
- ],
- 'cflags_cc': [
- # Don't warn about hash_map in third-party code.
- '-Wno-deprecated',
- ],
- 'cflags': [
- # Don't warn about printf format problems.
- # This is off by default in gcc but on in Ubuntu's gcc(!).
- '-Wno-format',
- ],
- 'cflags_cc!': [
- # Necessary because llvm.org/PR10448 is WONTFIX (crbug.com/90453).
- '-Wsign-compare',
- ]
- }],
- # TODO: Fix all warnings on chromeos too.
- [ 'os_posix==1 and OS!="mac" and OS!="ios" and (clang!=1 or chromeos==1)', {
- 'cflags!': [
- '-Werror',
- ],
- }],
- [ 'os_posix==1 and os_bsd!=1 and OS!="mac" and OS!="android"', {
- 'cflags': [
- # Don't warn about ignoring the return value from e.g. close().
- # This is off by default in some gccs but on by default in others.
- # BSD systems do not support this option, since they are usually
- # using gcc 4.2.1, which does not have this flag yet.
- '-Wno-unused-result',
- ],
- }],
- [ 'OS=="win"', {
- 'defines': [
- '_CRT_SECURE_NO_DEPRECATE',
- '_CRT_NONSTDC_NO_WARNINGS',
- '_CRT_NONSTDC_NO_DEPRECATE',
- '_SCL_SECURE_NO_DEPRECATE',
- ],
- 'msvs_disabled_warnings': [
- 4800,
- ],
- 'msvs_settings': {
- 'VCCLCompilerTool': {
- 'WarningLevel': '3',
- 'WarnAsError': 'true',
- 'Detect64BitPortabilityProblems': 'false',
- },
- },
- 'conditions': [
- ['buildtype=="Official"', {
- 'msvs_settings': {
- 'VCCLCompilerTool': { 'WarnAsError': 'false' },
- }
- }],
- [ 'component=="shared_library"', {
- # TODO(darin): Unfortunately, some third_party code depends on base.
- 'msvs_disabled_warnings': [
- 4251, # class 'std::xx' needs to have dll-interface.
- ],
- }],
- ],
- }],
-
- [ 'OS=="mac" or OS=="ios"', {
- 'xcode_settings': {
- 'WARNING_CFLAGS!': ['-Wall', '-Wextra'],
- },
- 'conditions': [
- ['buildtype=="Official"', {
- 'xcode_settings': {
- 'GCC_TREAT_WARNINGS_AS_ERRORS': 'NO', # -Werror
- },
- }],
- ],
- }],
- [ 'OS=="ios"', {
- 'xcode_settings': {
- # TODO(ios): Fix remaining warnings in third-party code, then
- # remove this; the Mac cleanup didn't get everything that's
- # flagged in an iOS build.
- 'GCC_TREAT_WARNINGS_AS_ERRORS': 'NO',
- 'RUN_CLANG_STATIC_ANALYZER': 'NO',
- # Several internal ios directories generate numerous warnings for
- # -Wobjc-missing-property-synthesis.
- 'CLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS': 'NO',
- },
- }],
- ],
- }, {
- 'includes': [
- # Rules for excluding e.g. foo_win.cc from the build on non-Windows.
- 'filename_rules.gypi',
- ],
- # In Chromium code, we define __STDC_foo_MACROS in order to get the
- # C99 macros on Mac and Linux.
- 'defines': [
- '__STDC_CONSTANT_MACROS',
- '__STDC_FORMAT_MACROS',
- ],
- 'conditions': [
- ['OS=="win"', {
- # turn on warnings for signed/unsigned mismatch on chromium code.
- 'msvs_settings': {
- 'VCCLCompilerTool': {
- 'AdditionalOptions': ['/we4389'],
- },
- },
- }],
- ['OS=="win" and component=="shared_library"', {
- 'msvs_disabled_warnings': [
- 4251, # class 'std::xx' needs to have dll-interface.
- ],
- }],
- ],
- }],
- ], # target_conditions for 'target_defaults'
- 'default_configuration': 'Debug',
- 'configurations': {
- # VCLinkerTool LinkIncremental values below:
- # 0 == default
- # 1 == /INCREMENTAL:NO
- # 2 == /INCREMENTAL
- # Debug links incremental, Release does not.
- #
- # Abstract base configurations to cover common attributes.
- #
- 'Common_Base': {
- 'abstract': 1,
- 'msvs_configuration_attributes': {
- 'OutputDirectory': '<(DEPTH)\\build\\<(build_dir_prefix)$(ConfigurationName)',
- 'IntermediateDirectory': '$(OutDir)\\obj\\$(ProjectName)',
- 'CharacterSet': '1',
- },
- 'msvs_settings':{
- 'VCCLCompilerTool': {
- 'AdditionalOptions': [
- '/bigobj',
- ],
- },
- 'VCLinkerTool': {
- # Add the default import libs.
- 'AdditionalDependencies': [
- 'kernel32.lib',
- 'gdi32.lib',
- 'winspool.lib',
- 'comdlg32.lib',
- 'advapi32.lib',
- 'shell32.lib',
- 'ole32.lib',
- 'oleaut32.lib',
- 'user32.lib',
- 'uuid.lib',
- 'odbc32.lib',
- 'odbccp32.lib',
- 'delayimp.lib',
- 'credui.lib',
- 'netapi32.lib',
- ],
- 'AdditionalOptions': [
- # Suggested by Microsoft Devrel to avoid
- # LINK : fatal error LNK1248: image size (80000000) exceeds maximum allowable size (80000000)
- # which started happening more regularly after VS2013 Update 4.
- # Needs to be a bit lower for VS2015, or else errors out.
- '/maxilksize:0x7ff00000',
- ],
- },
- },
- },
- 'x86_Base': {
- 'abstract': 1,
- 'msvs_settings': {
- 'VCLinkerTool': {
- 'MinimumRequiredVersion': '5.01', # XP.
- 'TargetMachine': '1',
- },
- 'VCLibrarianTool': {
- 'TargetMachine': '1',
- },
- },
- 'msvs_configuration_platform': 'Win32',
- },
- 'x64_Base': {
- 'abstract': 1,
- 'msvs_configuration_platform': 'x64',
- 'msvs_settings': {
- 'VCLinkerTool': {
- # Make sure to understand http://crbug.com/361720 if you want to
- # increase this.
- 'MinimumRequiredVersion': '5.02', # Server 2003.
- 'TargetMachine': '17', # x86 - 64
- 'AdditionalLibraryDirectories!':
- ['<(windows_sdk_path)/Lib/win8/um/x86'],
- 'AdditionalLibraryDirectories':
- ['<(windows_sdk_path)/Lib/win8/um/x64'],
- # Doesn't exist x64 SDK. Should use oleaut32 in any case.
- 'IgnoreDefaultLibraryNames': [ 'olepro32.lib' ],
- },
- 'VCLibrarianTool': {
- 'AdditionalLibraryDirectories!':
- ['<(windows_sdk_path)/Lib/win8/um/x86'],
- 'AdditionalLibraryDirectories':
- ['<(windows_sdk_path)/Lib/win8/um/x64'],
- 'TargetMachine': '17', # x64
- },
- },
- },
- 'Debug_Base': {
- 'abstract': 1,
- 'defines': [
- 'DYNAMIC_ANNOTATIONS_ENABLED=1',
- 'WTF_USE_DYNAMIC_ANNOTATIONS=1',
- ],
- 'xcode_settings': {
- 'GCC_OPTIMIZATION_LEVEL': '<(mac_debug_optimization)',
- 'OTHER_CFLAGS': [
- '<@(debug_extra_cflags)',
- ],
- },
- 'msvs_settings': {
- 'VCCLCompilerTool': {
- 'Optimization': '<(win_debug_Optimization)',
- 'PreprocessorDefinitions': ['_DEBUG'],
- 'BasicRuntimeChecks': '<(win_debug_RuntimeChecks)',
- 'RuntimeLibrary': '<(win_debug_RuntimeLibrary)',
- 'conditions': [
- # According to MSVS, InlineFunctionExpansion=0 means
- # "default inlining", not "/Ob0".
- # Thus, we have to handle InlineFunctionExpansion==0 separately.
- ['win_debug_InlineFunctionExpansion==0', {
- 'AdditionalOptions': ['/Ob0'],
- }],
- ['win_debug_InlineFunctionExpansion!=""', {
- 'InlineFunctionExpansion':
- '<(win_debug_InlineFunctionExpansion)',
- }],
- ['win_debug_disable_iterator_debugging==1', {
- 'PreprocessorDefinitions': ['_HAS_ITERATOR_DEBUGGING=0'],
- }],
-
- # if win_debug_OmitFramePointers is blank, leave as default
- ['win_debug_OmitFramePointers==1', {
- 'OmitFramePointers': 'true',
- }],
- ['win_debug_OmitFramePointers==0', {
- 'OmitFramePointers': 'false',
- # The above is not sufficient (http://crbug.com/106711): it
- # simply eliminates an explicit "/Oy", but both /O2 and /Ox
- # perform FPO regardless, so we must explicitly disable.
- # We still want the false setting above to avoid having
- # "/Oy /Oy-" and warnings about overriding.
- 'AdditionalOptions': ['/Oy-'],
- }],
- ],
- 'AdditionalOptions': [ '<@(win_debug_extra_cflags)', ],
- },
- 'VCLinkerTool': {
- 'LinkIncremental': '<(msvs_debug_link_incremental)',
- # ASLR makes debugging with windbg difficult because Chrome.exe and
- # Chrome.dll share the same base name. As result, windbg will
- # name the Chrome.dll module like chrome_<base address>, where
- # <base address> typically changes with each launch. This in turn
- # means that breakpoints in Chrome.dll don't stick from one launch
- # to the next. For this reason, we turn ASLR off in debug builds.
- # Note that this is a three-way bool, where 0 means to pick up
- # the default setting, 1 is off and 2 is on.
- 'RandomizedBaseAddress': 1,
- },
- 'VCResourceCompilerTool': {
- 'PreprocessorDefinitions': ['_DEBUG'],
- },
- },
- 'conditions': [
- ['OS=="linux" or OS=="android"', {
- 'target_conditions': [
- ['_toolset=="target"', {
- 'cflags': [
- '<@(debug_extra_cflags)',
- ],
- }],
- ],
- }],
- ['OS=="linux" and target_arch!="ia32" and disable_glibcxx_debug==0', {
- # Enable libstdc++ debugging facilities to help catch problems
- # early, see http://crbug.com/65151 .
- # TODO(phajdan.jr): Should we enable this for all of POSIX?
- 'defines': ['_GLIBCXX_DEBUG=1',],
- }],
- ['release_valgrind_build==0', {
- 'xcode_settings': {
- 'OTHER_CFLAGS': [
- '-fstack-protector-all', # Implies -fstack-protector
- ],
- },
- }],
- ['clang==1', {
- 'cflags': [
- # Allow comparing the address of references and 'this' against 0
- # in debug builds. Technically, these can never be null in
- # well-defined C/C++ and Clang can optimize such checks away in
- # release builds, but they may be used in asserts in debug builds.
- '-Wno-undefined-bool-conversion',
- '-Wno-tautological-undefined-compare',
- ],
- 'xcode_settings': {
- 'OTHER_CFLAGS': [
- '-Wno-undefined-bool-conversion',
- '-Wno-tautological-undefined-compare',
- ],
- },
- 'msvs_settings': {
- 'VCCLCompilerTool': {
- 'AdditionalOptions': [
- '-Wno-undefined-bool-conversion',
- '-Wno-tautological-undefined-compare',
- ],
- },
- },
- }],
- ],
- },
- 'Release_Base': {
- 'abstract': 1,
- 'defines': [
- 'NDEBUG',
- ],
- 'xcode_settings': {
- 'DEAD_CODE_STRIPPING': 'YES', # -Wl,-dead_strip
- 'GCC_OPTIMIZATION_LEVEL': '<(mac_release_optimization)',
- 'OTHER_CFLAGS': [ '<@(release_extra_cflags)', ],
- },
- 'msvs_settings': {
- 'VCCLCompilerTool': {
- 'RuntimeLibrary': '<(win_release_RuntimeLibrary)',
- 'conditions': [
- # In official builds, each target will self-select
- # an optimization level.
- ['buildtype!="Official"', {
- 'Optimization': '<(win_release_Optimization)',
- },
- ],
- # According to MSVS, InlineFunctionExpansion=0 means
- # "default inlining", not "/Ob0".
- # Thus, we have to handle InlineFunctionExpansion==0 separately.
- ['win_release_InlineFunctionExpansion==0', {
- 'AdditionalOptions': ['/Ob0'],
- }],
- ['win_release_InlineFunctionExpansion!=""', {
- 'InlineFunctionExpansion':
- '<(win_release_InlineFunctionExpansion)',
- }],
-
- # if win_release_OmitFramePointers is blank, leave as default
- ['win_release_OmitFramePointers==1', {
- 'OmitFramePointers': 'true',
- }],
- ['win_release_OmitFramePointers==0', {
- 'OmitFramePointers': 'false',
- # The above is not sufficient (http://crbug.com/106711): it
- # simply eliminates an explicit "/Oy", but both /O2 and /Ox
- # perform FPO regardless, so we must explicitly disable.
- # We still want the false setting above to avoid having
- # "/Oy /Oy-" and warnings about overriding.
- 'AdditionalOptions': ['/Oy-'],
- }],
- ['asan==0', {
- # Put data in separate COMDATs. This allows the linker
- # to put bit-identical constants at the same address even if
- # they're unrelated constants, which saves binary size.
- # This optimization can't be used when ASan is enabled because
- # it is not compatible with the ASan ODR checker.
- 'AdditionalOptions': ['/Gw'],
- }],
- ],
- 'AdditionalOptions': [
- '/d2Zi+', # Improve debugging of Release builds.
- '/Zc:inline', # Remove unreferenced COMDAT (faster links).
- '<@(win_release_extra_cflags)',
- ],
- },
- 'VCLinkerTool': {
- # LinkIncremental is a tri-state boolean, where 0 means default
- # (i.e., inherit from parent solution), 1 means false, and
- # 2 means true.
- 'LinkIncremental': '1',
- # This corresponds to the /PROFILE flag which ensures the PDB
- # file contains FIXUP information (growing the PDB file by about
- # 5%) but does not otherwise alter the output binary. This
- # information is used by the Syzygy optimization tool when
- # decomposing the release image.
- 'Profile': 'true',
- },
- },
- 'conditions': [
- ['msvs_use_common_release', {
- 'includes': ['release.gypi'],
- }],
- ['release_valgrind_build==0 and tsan==0', {
- 'defines': [
- 'NVALGRIND',
- 'DYNAMIC_ANNOTATIONS_ENABLED=0',
- ],
- }, {
- 'defines': [
- 'MEMORY_TOOL_REPLACES_ALLOCATOR',
- 'MEMORY_SANITIZER_INITIAL_SIZE',
- 'DYNAMIC_ANNOTATIONS_ENABLED=1',
- 'WTF_USE_DYNAMIC_ANNOTATIONS=1',
- ],
- }],
- ['OS=="win"', {
- 'defines': ['NO_TCMALLOC'],
- }],
- # _FORTIFY_SOURCE isn't really supported by Clang now, see
- # http://llvm.org/bugs/show_bug.cgi?id=16821.
- # It seems to work fine with Ubuntu 12 headers though, so use it
- # in official builds.
- ['os_posix==1 and (asan!=1 and msan!=1 and tsan!=1 and lsan!=1 and ubsan!=1) and (OS!="linux" or clang!=1 or buildtype=="Official")', {
- 'target_conditions': [
- ['chromium_code==1', {
- # Non-chromium code is not guaranteed to compile cleanly
- # with _FORTIFY_SOURCE. Also, fortified build may fail
- # when optimizations are disabled, so only do that for Release
- # build.
- 'defines': [
- '_FORTIFY_SOURCE=2',
- ],
- }],
- ],
- }],
- ['OS=="linux" or OS=="android"', {
- 'target_conditions': [
- ['_toolset=="target"', {
- 'cflags': [
- '<@(release_extra_cflags)',
- ],
- 'conditions': [
- ['enable_resource_whitelist_generation==1', {
- 'cflags': [
- '-Wunknown-pragmas -Wno-error=unknown-pragmas',
- ],
- }],
- ],
- }],
- ],
- }],
- ['OS=="ios"', {
- 'defines': [
- 'NS_BLOCK_ASSERTIONS=1',
- ],
- }],
- ],
- },
- #
- # Concrete configurations
- #
- 'Debug': {
- 'inherit_from': ['Common_Base', 'x86_Base', 'Debug_Base'],
- },
- 'Release': {
- 'inherit_from': ['Common_Base', 'x86_Base', 'Release_Base'],
- },
- 'conditions': [
- [ 'OS=="ios"', {
- 'Profile': {
- 'inherit_from': ['Common_Base', 'x86_Base', 'Release_Base'],
- 'target_conditions': [
- [ '_type=="executable"', {
- # To get a real .dSYM bundle produced by dsymutil, set the
- # debug information format to dwarf-with-dsym. Since
- # strip_from_xcode will not be used, set Xcode to do the
- # stripping as well.
- 'xcode_settings': {
- 'DEBUG_INFORMATION_FORMAT': 'dwarf-with-dsym',
- 'DEPLOYMENT_POSTPROCESSING': 'YES',
- 'STRIP_INSTALLED_PRODUCT': 'YES',
- },
- }],
- ],
- },
- }],
- [ 'OS=="win"', {
- # TODO(bradnelson): add a gyp mechanism to make this more graceful.
- 'Debug_x64': {
- 'inherit_from': ['Common_Base', 'x64_Base', 'Debug_Base'],
- },
- 'Release_x64': {
- 'inherit_from': ['Common_Base', 'x64_Base', 'Release_Base'],
- },
- }],
- ],
- },
- },
- 'conditions': [
- ['os_posix==1', {
- 'target_defaults': {
- 'ldflags': [
- '-Wl,-z,now',
- '-Wl,-z,relro',
- ],
- # TODO(glider): enable the default options on other systems.
- 'conditions': [
- ['use_sanitizer_options==1 and ((OS=="linux" and (chromeos==0 or target_arch!="ia32")) or OS=="mac")', {
- 'dependencies': [
- '<(DEPTH)/build/sanitizers/sanitizers.gyp:sanitizer_options',
- ],
- }],
- ],
- },
- }],
- # TODO(jochen): Enable this on chromeos on arm. http://crbug.com/356580
- ['os_posix==1 and disable_fatal_linker_warnings==0 and use_evdev_gestures==0 and (chromeos==0 or target_arch!="arm")', {
- 'target_defaults': {
- 'ldflags': [
- '-Wl,--fatal-warnings',
- ],
- },
- }],
- # -Wl,-z,-defs doesn't work with the sanitiziers, http://crbug.com/452065
- ['(OS=="linux" or OS=="android") and asan==0 and msan==0 and tsan==0 and ubsan==0 and ubsan_vptr==0', {
- 'target_defaults': {
- 'ldflags': [
- '-Wl,-z,defs',
- ],
- },
- }],
- ['os_posix==1 and chromeos==0', {
- # Chrome OS enables -fstack-protector-strong via its build wrapper,
- # and we want to avoid overriding this, so stack-protector is only
- # enabled when not building on Chrome OS.
- # TODO(phajdan.jr): Use -fstack-protector-strong when our gcc
- # supports it.
- 'target_defaults': {
- 'cflags': [
- '-fstack-protector',
- '--param=ssp-buffer-size=4',
- ],
- },
- }],
- ['os_posix==1 and OS=="linux"', {
- 'defines': [
- '_LARGEFILE_SOURCE',
- '_LARGEFILE64_SOURCE',
- '_FILE_OFFSET_BITS=64',
- ],
- }],
- ['os_posix==1 and OS!="mac" and OS!="ios"', {
- 'target_defaults': {
- # Enable -Werror by default, but put it in a variable so it can
- # be disabled in ~/.gyp/include.gypi on the valgrind builders.
- 'variables': {
- 'werror%': '-Werror',
- 'libraries_for_target%': '',
- },
- 'defines': [
- '_FILE_OFFSET_BITS=64',
- ],
- 'cflags': [
- '<(werror)', # See note above about the werror variable.
- '-pthread',
- '-fno-strict-aliasing', # See http://crbug.com/32204
- '-Wall',
- # Don't warn about unused function params. We use those everywhere.
- '-Wno-unused-parameter',
- # Don't warn about the "struct foo f = {0};" initialization pattern.
- '-Wno-missing-field-initializers',
- # Don't export any symbols (for example, to plugins we dlopen()).
- # Note: this is *required* to make some plugins work.
- '-fvisibility=hidden',
- '-pipe',
- ],
- 'cflags_cc': [
- '-fno-exceptions',
- '-fno-rtti',
- '-fno-threadsafe-statics',
- # Make inline functions have hidden visiblity by default.
- # Surprisingly, not covered by -fvisibility=hidden.
- '-fvisibility-inlines-hidden',
- # GCC turns on -Wsign-compare for C++ under -Wall, but clang doesn't,
- # so we specify it explicitly. (llvm.org/PR10448, crbug.com/90453)
- '-Wsign-compare',
- ],
- 'ldflags': [
- '-pthread', '-Wl,-z,noexecstack',
- ],
- 'libraries' : [
- '<(libraries_for_target)',
- ],
- 'configurations': {
- 'Debug_Base': {
- 'variables': {
- 'debug_optimize%': '0',
- },
- 'defines': [
- '_DEBUG',
- ],
- 'cflags': [
- '-O>(debug_optimize)',
- '-g',
- ],
- 'conditions' : [
- ['OS=="android" and target_arch!="mipsel" and target_arch!="mips64el"', {
- # TODO(jdduke) Re-enable on mips after resolving linking
- # issues with libc++ (crbug.com/456380).
- 'ldflags': [
- # Warn in case of text relocations.
- '-Wl,--warn-shared-textrel',
- ],
- }],
- ['OS=="android" and android_full_debug==0', {
- # Some configurations are copied from Release_Base to reduce
- # the binary size.
- 'variables': {
- 'debug_optimize%': 's',
- },
- 'cflags': [
- '-fdata-sections',
- '-ffunction-sections',
- ],
- 'ldflags': [
- '-Wl,-O1',
- '-Wl,--as-needed',
- ],
- }],
- ['OS=="android" and android_full_debug==0 and target_arch!="arm64"', {
- # We don't omit frame pointers on arm64 since they are required
- # to correctly unwind stackframes which contain system library
- # function frames (crbug.com/391706).
- 'cflags': [
- '-fomit-frame-pointer',
- ],
- }],
- ['OS=="linux" and target_arch=="ia32"', {
- 'ldflags': [
- '-Wl,--no-as-needed',
- ],
- }],
- ['debug_unwind_tables==1', {
- 'cflags': ['-funwind-tables'],
- }, {
- 'cflags': ['-fno-unwind-tables', '-fno-asynchronous-unwind-tables'],
- 'defines': ['NO_UNWIND_TABLES'],
- }],
- # TODO(mostynb): shuffle clang/gcc_version/binutils_version
- # definitions in to the right scope to use them when setting
- # linux_use_debug_fission, so it can be used here alone.
- ['linux_use_debug_fission==1 and linux_use_gold_flags==1 and (clang==1 or gcc_version>=48) and binutils_version>=223', {
- 'cflags': ['-gsplit-dwarf'],
- }],
- ],
- },
- 'Release_Base': {
- 'variables': {
- 'release_optimize%': '2',
- # Binaries become big and gold is unable to perform GC
- # and remove unused sections for some of test targets
- # on 32 bit platform.
- # (This is currently observed only in chromeos valgrind bots)
- # The following flag is to disable --gc-sections linker
- # option for these bots.
- 'no_gc_sections%': 0,
-
- # TODO(bradnelson): reexamine how this is done if we change the
- # expansion of configurations
- 'release_valgrind_build%': 0,
- },
- 'cflags': [
- '-O<(release_optimize)',
- # Don't emit the GCC version ident directives, they just end up
- # in the .comment section taking up binary size.
- '-fno-ident',
- # Put data and code in their own sections, so that unused symbols
- # can be removed at link time with --gc-sections.
- '-fdata-sections',
- '-ffunction-sections',
- ],
- 'ldflags': [
- # Specifically tell the linker to perform optimizations.
- # See http://lwn.net/Articles/192624/ .
- '-Wl,-O1',
- '-Wl,--as-needed',
- ],
- 'conditions' : [
- ['no_gc_sections==0', {
- 'ldflags': [
- '-Wl,--gc-sections',
- ],
- }],
- ['OS=="android" and target_arch!="arm64"', {
- # We don't omit frame pointers on arm64 since they are required
- # to correctly unwind stackframes which contain system library
- # function frames (crbug.com/391706).
- 'cflags': [
- '-fomit-frame-pointer',
- ]
- }],
- ['OS=="android" and target_arch!="mipsel" and target_arch!="mips64el"', {
- # TODO(jdduke) Re-enable on mips after resolving linking
- # issues with libc++ (crbug.com/456380).
- 'ldflags': [
- # Warn in case of text relocations.
- '-Wl,--warn-shared-textrel',
- ],
- }],
- ['OS=="android"', {
- 'variables': {
- 'release_optimize%': 's',
- },
- }],
- ['profiling==1', {
- 'cflags': [
- '-fno-omit-frame-pointer',
- '-g',
- ],
- 'conditions' : [
- ['profiling_full_stack_frames==1', {
- 'cflags': [
- '-fno-inline',
- '-fno-optimize-sibling-calls',
- ],
- }],
- ],
- }],
- ['release_unwind_tables==1', {
- 'cflags': ['-funwind-tables'],
- }, {
- 'cflags': ['-fno-unwind-tables', '-fno-asynchronous-unwind-tables'],
- 'defines': ['NO_UNWIND_TABLES'],
- }],
- ],
- },
- },
- 'conditions': [
- ['target_arch=="ia32"', {
- 'target_conditions': [
- ['_toolset=="target"', {
- 'asflags': [
- # Needed so that libs with .s files (e.g. libicudata.a)
- # are compatible with the general 32-bit-ness.
- '-32',
- ],
- # All floating-point computations on x87 happens in 80-bit
- # precision. Because the C and C++ language standards allow
- # the compiler to keep the floating-point values in higher
- # precision than what's specified in the source and doing so
- # is more efficient than constantly rounding up to 64-bit or
- # 32-bit precision as specified in the source, the compiler,
- # especially in the optimized mode, tries very hard to keep
- # values in x87 floating-point stack (in 80-bit precision)
- # as long as possible. This has important side effects, that
- # the real value used in computation may change depending on
- # how the compiler did the optimization - that is, the value
- # kept in 80-bit is different than the value rounded down to
- # 64-bit or 32-bit. There are possible compiler options to
- # make this behavior consistent (e.g. -ffloat-store would keep
- # all floating-values in the memory, thus force them to be
- # rounded to its original precision) but they have significant
- # runtime performance penalty.
- #
- # -mfpmath=sse -msse2 makes the compiler use SSE instructions
- # which keep floating-point values in SSE registers in its
- # native precision (32-bit for single precision, and 64-bit
- # for double precision values). This means the floating-point
- # value used during computation does not change depending on
- # how the compiler optimized the code, since the value is
- # always kept in its specified precision.
- #
- # Refer to http://crbug.com/348761 for rationale behind SSE2
- # being a minimum requirement for 32-bit Linux builds and
- # http://crbug.com/313032 for an example where this has "bit"
- # us in the past.
- 'cflags': [
- '-msse2',
- '-mfpmath=sse',
- '-mmmx', # Allows mmintrin.h for MMX intrinsics.
- '-m32',
- ],
- 'ldflags': [
- '-m32',
- ],
- 'conditions': [
- # Use gold linker for Android ia32 target.
- ['OS=="android"', {
- 'ldflags': [
- '-fuse-ld=gold',
- ],
- }],
- ],
- }],
- ],
- }],
- ['target_arch=="x64"', {
- 'target_conditions': [
- ['_toolset=="target"', {
- 'conditions': [
- # Use gold linker for Android x64 target.
- ['OS=="android"', {
- 'ldflags': [
- '-fuse-ld=gold',
- ],
- }],
- ],
- 'cflags': [
- '-m64',
- '-march=x86-64',
- ],
- 'ldflags': [
- '-m64',
- ],
- }],
- ],
- }],
- ['target_arch=="arm"', {
- 'target_conditions': [
- ['_toolset=="target"', {
- 'conditions': [
- ['clang==0', {
- 'cflags_cc': [
- # The codesourcery arm-2009q3 toolchain warns at that the ABI
- # has changed whenever it encounters a varargs function. This
- # silences those warnings, as they are not helpful and
- # clutter legitimate warnings.
- '-Wno-abi',
- ],
- }],
- ['clang==1 and arm_arch!="" and OS!="android"', {
- 'cflags': [
- '-target arm-linux-gnueabihf',
- ],
- 'ldflags': [
- '-target arm-linux-gnueabihf',
- ],
- }],
- ['arm_arch!=""', {
- 'cflags': [
- '-march=<(arm_arch)',
- ],
- 'conditions': [
- ['use_lto==1 or use_lto_o2==1', {
- 'ldflags': [
- '-march=<(arm_arch)',
- ],
- }],
- ],
- }],
- ['clang==1 and OS!="android"', {
- 'cflags': [
- # We need to disable clang's builtin assembler as it can't
- # handle several asm files, crbug.com/124610
- '-no-integrated-as',
- ],
- }],
- ['arm_tune!=""', {
- 'cflags': [
- '-mtune=<(arm_tune)',
- ],
- 'conditions': [
- ['use_lto==1 or use_lto_o2==1', {
- 'ldflags': [
- '-mtune=<(arm_tune)',
- ],
- }],
- ],
- }],
- ['arm_fpu!=""', {
- 'cflags': [
- '-mfpu=<(arm_fpu)',
- ],
- 'conditions': [
- ['use_lto==1 or use_lto_o2==1', {
- 'ldflags': [
- '-mfpu=<(arm_fpu)',
- ],
- }],
- ],
- }],
- ['arm_float_abi!=""', {
- 'cflags': [
- '-mfloat-abi=<(arm_float_abi)',
- ],
- 'conditions': [
- ['use_lto==1 or use_lto_o2==1', {
- 'ldflags': [
- '-mfloat-abi=<(arm_float_abi)',
- ],
- }],
- ],
- }],
- ['arm_thumb==1', {
- 'cflags': [
- '-mthumb',
- ],
- 'conditions': [
- ['use_lto==1 or use_lto_o2==1', {
- 'ldflags': [
- '-mthumb',
- ],
- }],
- ],
- }],
- ['OS=="android"', {
- # Most of the following flags are derived from what Android
- # uses by default when building for arm, reference for which
- # can be found in the following file in the Android NDK:
- # toolchains/arm-linux-androideabi-4.9/setup.mk
- 'cflags': [
- # The tree-sra optimization (scalar replacement for
- # aggregates enabling subsequent optimizations) leads to
- # invalid code generation when using the Android NDK's
- # compiler (r5-r7). This can be verified using
- # webkit_unit_tests' WTF.Checked_int8_t test.
- '-fno-tree-sra',
- # The following option is disabled to improve binary
- # size and performance in gcc 4.9.
- '-fno-caller-saves',
- '-Wno-psabi',
- ],
- # Android now supports .relro sections properly.
- # NOTE: While these flags enable the generation of .relro
- # sections, the generated libraries can still be loaded on
- # older Android platform versions.
- 'ldflags': [
- '-Wl,-z,relro',
- '-Wl,-z,now',
- '-fuse-ld=gold',
- ],
- 'conditions': [
- ['gcc_version==48 and clang==0', {
- 'cflags': [
- # The following 5 options are disabled to save on
- # binary size in GCC 4.8.
- '-fno-partial-inlining',
- '-fno-early-inlining',
- '-fno-tree-copy-prop',
- '-fno-tree-loop-optimize',
- '-fno-move-loop-invariants',
- ],
- }],
- ['arm_thumb==1', {
- 'cflags': [ '-mthumb-interwork' ],
- }],
- ['profiling==1', {
- 'cflags': [
- # Thumb code with frame pointer makes chrome crash
- # early.
- '-marm',
- '-mapcs-frame', # Required by -fno-omit-frame-pointer.
- # The perf report sometimes incorrectly attributes
- # code from tail calls.
- '-fno-optimize-sibling-calls',
- ],
- 'cflags!': [
- '-fomit-frame-pointer',
- ],
- }],
- ['clang==1', {
- 'cflags!': [
- # Clang does not support the following options.
- '-mapcs-frame',
- '-mthumb-interwork',
- '-finline-limit=64',
- '-fno-tree-sra',
- '-fno-caller-saves',
- '-Wno-psabi',
- ],
- 'cflags': [
- # TODO(hans) Enable integrated-as (crbug.com/124610).
- '-no-integrated-as',
- '-B<(android_toolchain)', # Else /usr/bin/as gets picked up.
- ],
- }],
- ['clang==1 and linux_use_bundled_gold==0', {
- 'ldflags': [
- # Let clang find the ld.gold in the NDK.
- '--gcc-toolchain=<(android_toolchain)/..',
- ],
- }],
- ['asan==1', {
- 'cflags': [
- '-marm', # Required for frame pointer based stack traces.
- ],
- }],
- ],
- }],
- ['chromecast==1', {
- 'cflags': [
- # We set arm_arch to "" so that -march compiler option
- # is not set. Otherwise a gcc bug that would complain
- # about it conflicting with '-mcpu=cortex-a9'. The flag
- # '-march=armv7-a' is actually redundant anyway because
- # it is enabled by default when we built the toolchain.
- # And using '-mcpu=cortex-a9' should be sufficient.
- '-mcpu=cortex-a9',
- '-funwind-tables',
- # Breakpad requires symbols with debugging information
- '-g',
- ],
- 'ldflags': [
- # We want to statically link libstdc++/libgcc_s.
- '-static-libstdc++',
- '-static-libgcc',
- ],
- 'cflags!': [
- # Some components in Chromium (e.g. v8, skia, ffmpeg)
- # define their own cflags for arm builds that could
- # conflict with the flags we set here (e.g.
- # '-mcpu=cortex-a9'). Remove these flags explicitly.
- '-march=armv7-a',
- '-mtune=cortex-a8',
- ],
- }],
- ],
- }],
- ],
- }],
- ['target_arch=="arm64"', {
- 'target_conditions': [
- ['_toolset=="target"', {
- 'conditions': [
- ['OS=="android"', {
- 'cflags!': [
- '-fstack-protector', # stack protector is always enabled on arm64.
- ],
- }],
- ],
- }],
- ],
- }],
- ['target_arch=="mipsel"', {
- 'target_conditions': [
- ['_toolset=="target"', {
- 'conditions': [
- ['mips_arch_variant=="r6"', {
- 'conditions': [
- ['clang==1', {
- 'cflags': [ '-target mipsel-linux-gnu', '-march=mips32r6', ],
- 'ldflags': [ '-target mipsel-linux-gnu', ],
- }, { # clang==0
- 'cflags': ['-mips32r6', '-Wa,-mips32r6', ],
- }],
- ['clang==0 and OS=="android"', {
- 'ldflags': ['-mips32r6', '-Wl,-melf32ltsmip',],
- }],
- ],
- }],
- ['mips_arch_variant=="r2"', {
- 'conditions': [
- ['mips_float_abi=="hard" and mips_fpu_mode!=""', {
- 'cflags': ['-m<(mips_fpu_mode)'],
- }],
- ['clang==1', {
- 'conditions': [
- ['OS=="android"', {
- 'cflags': [ '-target mipsel-linux-android', '-march=mipsel', '-mcpu=mips32r2'],
- 'ldflags': [ '-target mipsel-linux-android', ],
- }, {
- 'cflags': [ '-target mipsel-linux-gnu', '-march=mipsel', '-mcpu=mips32r2'],
- 'ldflags': [ '-target mipsel-linux-gnu', ],
- }],
- ],
- }, { # clang==0
- 'cflags': ['-mips32r2', '-Wa,-mips32r2', ],
- }],
- ],
- }],
- ['mips_arch_variant=="r1"', {
- 'conditions': [
- ['clang==1', {
- 'conditions': [
- ['OS=="android"', {
- 'cflags': [ '-target mipsel-linux-android', '-march=mipsel', '-mcpu=mips32'],
- 'ldflags': [ '-target mipsel-linux-android', ],
- }, {
- 'cflags': [ '-target mipsel-linux-gnu', '-march=mipsel', '-mcpu=mips32'],
- 'ldflags': [ '-target mipsel-linux-gnu', ],
- }],
- ],
- }, { # clang==0
- 'cflags': ['-mips32', '-Wa,-mips32', ],
- }],
- ],
- }],
- ['clang==1', {
- 'cflags!': [
- # Clang does not support the following options.
- '-finline-limit=64',
- ],
- 'cflags': [
- # TODO(gordanac) Enable integrated-as.
- '-no-integrated-as',
- ],
- }],
- ['clang==1 and OS=="android"', {
- 'cflags': [
- '-B<(android_toolchain)', # Else /usr/bin/as gets picked up.
- ],
- 'ldflags': [
- # Let clang find the ld in the NDK.
- '--gcc-toolchain=<(android_toolchain)/..',
- ],
- }],
- ['mips_dsp_rev==1', {
- 'cflags': ['-mdsp'],
- }],
- ['mips_dsp_rev==2', {
- 'cflags': ['-mdspr2'],
- }],
- ],
- 'cflags': [
- '-m<(mips_float_abi)-float'
- ],
- 'ldflags': [
- '-Wl,--no-keep-memory'
- ],
- 'cflags_cc': [
- '-Wno-uninitialized',
- ],
- }],
- ],
- }],
- ['target_arch=="mips64el"', {
- 'target_conditions': [
- ['_toolset=="target"', {
- 'conditions': [
- ['mips_arch_variant=="r6"', {
- 'cflags': ['-mips64r6', '-Wa,-mips64r6'],
- 'ldflags': ['-mips64r6'],
- }],
- ['mips_arch_variant=="r2"', {
- 'cflags': ['-mips64r2', '-Wa,-mips64r2'],
- 'ldflags': ['-mips64r2'],
- }],
- ],
- 'cflags_cc': [
- '-Wno-uninitialized',
- ],
- }],
- ],
- }],
- ['linux_fpic==1', {
- 'cflags': [
- '-fPIC',
- ],
- 'ldflags': [
- '-fPIC',
- ],
- }],
- ['sysroot!=""', {
- 'target_conditions': [
- ['_toolset=="target"', {
- 'cflags': [
- '--sysroot=<(sysroot)',
- ],
- 'ldflags': [
- '--sysroot=<(sysroot)',
- '<!(<(DEPTH)/build/linux/sysroot_ld_path.sh <(sysroot))',
- ],
- }]]
- }],
- ['clang==1', {
- 'cflags': [
- # TODO(thakis): Remove, http://crbug.com/263960
- '-Wno-reserved-user-defined-literal',
- ],
- 'cflags_cc': [
- # gnu++11 instead of c++11 is needed because some code uses
- # typeof() (a GNU extension).
- # TODO(thakis): Eventually switch this to c++11 instead,
- # http://crbug.com/427584
- '-std=gnu++11',
- ],
- }],
- ['clang==0 and host_clang==1', {
- 'target_conditions': [
- ['_toolset=="host"', {
- 'cflags_cc': [ '-std=gnu++11', ],
- }],
- ],
- }],
- ['clang==1 and clang_use_chrome_plugins==1', {
- 'cflags': [
- '<@(clang_chrome_plugins_flags)',
- ],
- }],
- ['clang==1 and clang_load!=""', {
- 'cflags': [
- '-Xclang', '-load', '-Xclang', '<(clang_load)',
- ],
- }],
- ['clang==1 and clang_add_plugin!=""', {
- 'cflags': [
- '-Xclang', '-add-plugin', '-Xclang', '<(clang_add_plugin)',
- ],
- }],
- ['clang==1 and target_arch=="ia32"', {
- 'cflags': [
- # Else building libyuv gives clang's register allocator issues,
- # see llvm.org/PR15798 / crbug.com/233709
- '-momit-leaf-frame-pointer',
- # Align the stack on 16-byte boundaries, http://crbug.com/418554.
- '-mstack-alignment=16',
- '-mstackrealign',
- ],
- }],
- ['clang==1 and "<(GENERATOR)"=="ninja"', {
- 'cflags': [
- # See http://crbug.com/110262
- '-fcolor-diagnostics',
- ],
- }],
- # Common options for AddressSanitizer, LeakSanitizer,
- # ThreadSanitizer and MemorySanitizer.
- ['asan==1 or lsan==1 or tsan==1 or msan==1 or ubsan==1 or ubsan_vptr==1', {
- 'target_conditions': [
- ['_toolset=="target"', {
- 'cflags': [
- '-fno-omit-frame-pointer',
- '-gline-tables-only',
- ],
- 'cflags!': [
- '-fomit-frame-pointer',
- ],
- }],
- ],
- }],
- ['asan==1 or lsan==1 or tsan==1 or msan==1', {
- 'target_conditions': [
- ['_toolset=="target"', {
- 'ldflags!': [
- # Functions interposed by the sanitizers can make ld think
- # that some libraries aren't needed when they actually are,
- # http://crbug.com/234010. As workaround, disable --as-needed.
- '-Wl,--as-needed',
- ],
- 'defines': [
- 'MEMORY_TOOL_REPLACES_ALLOCATOR',
- 'MEMORY_SANITIZER_INITIAL_SIZE',
- ],
- }],
- ],
- }],
- ['asan==1', {
- 'target_conditions': [
- ['_toolset=="target"', {
- 'cflags': [
- '-fsanitize=address',
- # TODO(earthdok): Re-enable. http://crbug.com/427202
- #'-fsanitize-blacklist=<(asan_blacklist)',
- ],
- 'ldflags': [
- '-fsanitize=address',
- ],
- }],
- ],
- 'conditions': [
- ['OS=="mac"', {
- 'cflags': [
- '-mllvm -asan-globals=0', # http://crbug.com/352073
- ],
- }],
- ],
- }],
- ['ubsan==1', {
- 'target_conditions': [
- ['_toolset=="target"', {
- 'cflags': [
- # FIXME: work on enabling more flags and getting rid of false
- # positives. http://crbug.com/174801.
- '-fsanitize=bounds',
- '-fsanitize=float-divide-by-zero',
- '-fsanitize=integer-divide-by-zero',
- '-fsanitize=null',
- '-fsanitize=object-size',
- '-fsanitize=return',
- '-fsanitize=returns-nonnull-attribute',
- '-fsanitize=shift-exponent',
- '-fsanitize=signed-integer-overflow',
- '-fsanitize=unreachable',
- '-fsanitize=vla-bound',
- '-fsanitize-blacklist=<(ubsan_blacklist)',
- # Employ the experimental PBQP register allocator to avoid
- # slow compilation on files with too many basic blocks.
- # See http://crbug.com/426271.
- '-mllvm -regalloc=pbqp',
- # Speculatively use coalescing to slightly improve the code
- # generated by PBQP regallocator. May increase compile time.
- '-mllvm -pbqp-coalescing',
- ],
- 'cflags_cc!': [
- '-fno-rtti',
- ],
- 'cflags!': [
- '-fno-rtti',
- ],
- 'ldflags': [
- '-fsanitize=undefined',
- ],
- 'defines': [
- 'UNDEFINED_SANITIZER',
- ],
- }],
- ],
- }],
- ['ubsan_vptr==1', {
- 'target_conditions': [
- ['_toolset=="target"', {
- 'cflags': [
- '-fsanitize=vptr',
- '-fsanitize-blacklist=<(ubsan_vptr_blacklist)',
- ],
- 'cflags_cc!': [
- '-fno-rtti',
- ],
- 'cflags!': [
- '-fno-rtti',
- ],
- 'ldflags': [
- '-fsanitize=vptr',
- ],
- 'defines': [
- 'UNDEFINED_SANITIZER',
- ],
- }],
- ],
- }],
- ['asan_coverage!=0 and sanitizer_coverage==0', {
- 'target_conditions': [
- ['_toolset=="target"', {
- 'cflags': [
- '-fsanitize-coverage=<(asan_coverage)',
- ],
- 'defines': [
- 'SANITIZER_COVERAGE',
- ],
- }],
- ],
- }],
- ['sanitizer_coverage!=0', {
- 'target_conditions': [
- ['_toolset=="target"', {
- 'cflags': [
- '-fsanitize-coverage=<(sanitizer_coverage)',
- ],
- 'defines': [
- 'SANITIZER_COVERAGE',
- ],
- }],
- ],
- }],
- ['asan_field_padding!=0', {
- 'target_conditions': [
- ['_toolset=="target"', {
- 'cflags': [
- '-fsanitize-address-field-padding=<(asan_field_padding)',
- ],
- }],
- ],
- }],
- ['lsan==1', {
- 'target_conditions': [
- ['_toolset=="target"', {
- 'cflags': [
- '-fsanitize=leak',
- ],
- 'ldflags': [
- '-fsanitize=leak',
- ],
- 'defines': [
- 'LEAK_SANITIZER',
- 'WTF_USE_LEAK_SANITIZER=1',
- ],
- }],
- ],
- }],
- ['tsan==1', {
- 'target_conditions': [
- ['_toolset=="target"', {
- 'cflags': [
- '-fsanitize=thread',
- '-fsanitize-blacklist=<(tsan_blacklist)',
- ],
- 'ldflags': [
- '-fsanitize=thread',
- ],
- 'defines': [
- 'THREAD_SANITIZER',
- 'DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL=1',
- 'WTF_USE_DYNAMIC_ANNOTATIONS_NOIMPL=1',
- ],
- }],
- ],
- }],
- ['msan==1', {
- 'target_conditions': [
- ['_toolset=="target"', {
- 'cflags': [
- '-fsanitize=memory',
- '-fsanitize-memory-track-origins=<(msan_track_origins)',
- '-fsanitize-blacklist=<(msan_blacklist)',
- ],
- 'ldflags': [
- '-fsanitize=memory',
- ],
- 'defines': [
- 'MEMORY_SANITIZER',
- ],
- }],
- ],
- }],
- ['use_instrumented_libraries==1', {
- 'dependencies': [
- '<(DEPTH)/third_party/instrumented_libraries/instrumented_libraries.gyp:instrumented_libraries',
- ],
- }],
- ['use_prebuilt_instrumented_libraries==1', {
- 'dependencies': [
- '<(DEPTH)/third_party/instrumented_libraries/instrumented_libraries.gyp:prebuilt_instrumented_libraries',
- ],
- }],
- ['use_custom_libcxx==1', {
- 'dependencies': [
- '<(DEPTH)/buildtools/third_party/libc++/libc++.gyp:libcxx_proxy',
- ],
- }],
- ['order_profiling!=0 and (chromeos==1 or OS=="linux" or OS=="android")', {
- 'target_conditions' : [
- # crazy_linker has an upstream gyp file we can't edit, and we
- # don't want to instrument it.
- ['_toolset=="target" and _target_name!="crazy_linker"', {
- 'cflags': [
- '-finstrument-functions',
- # Allow mmx intrinsics to inline, so that the
- #0 compiler can expand the intrinsics.
- '-finstrument-functions-exclude-file-list=mmintrin.h',
- ],
- }],
- ['_toolset=="target" and OS=="android"', {
- 'cflags': [
- # Avoids errors with current NDK:
- # "third_party/android_tools/ndk/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/include/arm_neon.h:3426:3: error: argument must be a constant"
- '-finstrument-functions-exclude-file-list=arm_neon.h,SaturatedArithmeticARM.h',
- ],
- }],
- ],
- }],
- ['linux_dump_symbols==1', {
- 'cflags': [ '-g' ],
- 'conditions': [
- ['OS=="linux" and host_arch=="ia32" and linux_use_bundled_gold==0', {
- 'target_conditions': [
- ['_toolset=="target"', {
- 'ldflags': [
- # Attempt to use less memory to prevent the linker from
- # running out of address space. Considering installing a
- # 64-bit kernel and switching to a 64-bit linker.
- '-Wl,--no-keep-memory',
- ],
- }],
- ],
- }],
- ],
- }],
- ['use_allocator!="tcmalloc"', {
- 'defines': ['NO_TCMALLOC'],
- }],
- ['linux_use_gold_flags==1', {
- # Newer gccs and clangs support -fuse-ld, use the flag to force gold
- # selection.
- # gcc -- http://gcc.gnu.org/onlinedocs/gcc-4.8.0/gcc/Optimize-Options.html
- 'ldflags': [ '-fuse-ld=gold', ],
-
- 'target_conditions': [
- ['_toolset=="target"', {
- 'ldflags': [
- # Experimentation found that using four linking threads
- # saved ~20% of link time.
- # https://groups.google.com/a/chromium.org/group/chromium-dev/browse_thread/thread/281527606915bb36
- # Only apply this to the target linker, since the host
- # linker might not be gold, but isn't used much anyway.
- # TODO(raymes): Disable threading because gold is frequently
- # crashing on the bots: crbug.com/161942.
- # '-Wl,--threads',
- # '-Wl,--thread-count=4',
- ],
- 'conditions': [
- # TODO(thestig): Enable this for disabled cases.
- [ 'buildtype!="Official" and chromeos==0 and release_valgrind_build==0 and asan==0 and lsan==0 and tsan==0 and msan==0 and ubsan==0 and ubsan_vptr==0', {
- 'ldflags': [
- '-Wl,--detect-odr-violations',
- ],
- }],
- ],
- }],
- ],
- 'conditions': [
- ['release_valgrind_build==0 and order_profiling==0 and asan==0 and msan==0 and lsan==0 and tsan==0', {
- 'target_conditions': [
- ['_toolset=="target"', {
- 'ldflags': [
- '-Wl,--icf=<(gold_icf_level)',
- ],
- }],
- ],
- }],
- ],
- }],
- ['linux_use_bundled_binutils==1', {
- 'cflags': [
- '-B<!(cd <(DEPTH) && pwd -P)/<(binutils_dir)',
- ],
- }],
- ['linux_use_bundled_gold==1 and '
- 'not (clang==0 and (use_lto==1 or use_lto_o2==1))', {
- # Put our binutils, which contains gold in the search path. We pass
- # the path to gold to the compiler. gyp leaves unspecified what the
- # cwd is when running the compiler, so the normal gyp path-munging
- # fails us. This hack gets the right path.
- #
- # Disabled when using GCC LTO because GCC also uses the -B search
- # path at link time to find "as", and our bundled "as" can only
- # target x86.
- 'ldflags': [
- '-B<!(cd <(DEPTH) && pwd -P)/<(binutils_dir)',
- ],
- }],
- # Some binutils 2.23 releases may or may not have new dtags enabled,
- # but they are all compatible with --disable-new-dtags,
- # because the new dynamic tags are not created by default.
- ['binutils_version>=223', {
- # Newer binutils don't set DT_RPATH unless you disable "new" dtags
- # and the new DT_RUNPATH doesn't work without --no-as-needed flag.
- # FIXME(mithro): Figure out the --as-needed/--no-as-needed flags
- # inside this file to allow usage of --no-as-needed and removal of
- # this flag.
- 'ldflags': [
- '-Wl,--disable-new-dtags',
- ],
- }],
- ['gcc_version>=47 and clang==0', {
- 'target_conditions': [
- ['_toolset=="target"', {
- 'cflags_cc': [
- '-std=gnu++11',
- # See comment for -Wno-c++11-narrowing.
- '-Wno-narrowing',
- # TODO(thakis): Remove, http://crbug.com/263960
- '-Wno-literal-suffix',
- ],
- }],
- ],
- }],
- ['host_gcc_version>=47 and clang==0 and host_clang==0', {
- 'target_conditions': [
- ['_toolset=="host"', {
- 'cflags_cc': [
- '-std=gnu++11',
- # See comment for -Wno-c++11-narrowing.
- '-Wno-narrowing',
- # TODO(thakis): Remove, http://crbug.com/263960
- '-Wno-literal-suffix',
- ],
- }],
- ],
- }],
- ],
- },
- }],
- # FreeBSD-specific options; note that most FreeBSD options are set above,
- # with Linux.
- ['OS=="freebsd"', {
- 'target_defaults': {
- 'ldflags': [
- '-Wl,--no-keep-memory',
- ],
- },
- }],
- # Android-specific options; note that most are set above with Linux.
- ['OS=="android"', {
- 'variables': {
- # This is a unique identifier for a given build. It's used for
- # identifying various build artifacts corresponding to a particular
- # build of chrome (e.g. where to find archived symbols).
- 'chrome_build_id%': '',
- 'conditions': [
- # Figure this out early since it needs symbols from libgcc.a, so it
- # has to be before that in the set of libraries.
- ['component=="shared_library"', {
- 'android_libcpp_library': 'c++_shared',
- }, {
- 'android_libcpp_library': 'c++_static',
- }],
- ],
-
- # Placing this variable here prevents from forking libvpx, used
- # by remoting. Remoting is off, so it needn't built,
- # so forking it's deps seems like overkill.
- # But this variable need defined to properly run gyp.
- # A proper solution is to have an OS==android conditional
- # in third_party/libvpx/libvpx.gyp to define it.
- 'libvpx_path': 'lib/linux/arm',
- },
- 'target_defaults': {
- 'variables': {
- 'release_extra_cflags%': '',
- 'conditions': [
- # If we're using the components build, append "cr" to all shared
- # libraries to avoid naming collisions with android system library
- # versions with the same name (e.g. skia, icu).
- ['component=="shared_library"', {
- 'android_product_extension': 'cr.so',
- }, {
- 'android_product_extension': 'so',
- } ],
- ],
- },
- 'target_conditions': [
- ['_type=="shared_library"', {
- 'product_extension': '<(android_product_extension)',
- }],
-
- # Settings for building device targets using Android's toolchain.
- # These are based on the setup.mk file from the Android NDK.
- #
- # The NDK Android executable link step looks as follows:
- # $LDFLAGS
- # $(TARGET_CRTBEGIN_DYNAMIC_O) <-- crtbegin.o
- # $(PRIVATE_OBJECTS) <-- The .o that we built
- # $(PRIVATE_STATIC_LIBRARIES) <-- The .a that we built
- # $(TARGET_LIBGCC) <-- libgcc.a
- # $(PRIVATE_SHARED_LIBRARIES) <-- The .so that we built
- # $(PRIVATE_LDLIBS) <-- System .so
- # $(TARGET_CRTEND_O) <-- crtend.o
- #
- # For now the above are approximated for executables by adding
- # crtbegin.o to the end of the ldflags and 'crtend.o' to the end
- # of 'libraries'.
- #
- # The NDK Android shared library link step looks as follows:
- # $LDFLAGS
- # $(PRIVATE_OBJECTS) <-- The .o that we built
- # -l,--whole-archive
- # $(PRIVATE_WHOLE_STATIC_LIBRARIES)
- # -l,--no-whole-archive
- # $(PRIVATE_STATIC_LIBRARIES) <-- The .a that we built
- # $(TARGET_LIBGCC) <-- libgcc.a
- # $(PRIVATE_SHARED_LIBRARIES) <-- The .so that we built
- # $(PRIVATE_LDLIBS) <-- System .so
- #
- # For now, assume that whole static libraries are not needed.
- #
- # For both executables and shared libraries, add the proper
- # libgcc.a to the start of libraries which puts it in the
- # proper spot after .o and .a files get linked in.
- #
- # TODO: The proper thing to do longer-tem would be proper gyp
- # support for a custom link command line.
- ['_toolset=="target"', {
- 'cflags!': [
- '-pthread', # Not supported by Android toolchain.
- ],
- 'cflags': [
- '-ffunction-sections',
- '-funwind-tables',
- '-g',
- '-fstack-protector',
- '-fno-short-enums',
- '-finline-limit=64',
- '<@(release_extra_cflags)',
- '--sysroot=<(android_ndk_sysroot)',
- # NOTE: The libc++ header include paths below are specified in
- # cflags rather than include_dirs because they need to come
- # after include_dirs.
- # The include ordering here is important; change with caution.
- '-isystem<(android_libcpp_include)',
- '-isystem<(android_ndk_root)/sources/cxx-stl/llvm-libc++abi/libcxxabi/include',
- '-isystem<(android_ndk_root)/sources/android/support/include',
- ],
- 'defines': [
- 'ANDROID',
- '__GNU_SOURCE=1', # Necessary for clone()
- 'CHROME_BUILD_ID="<(chrome_build_id)"',
- # The NDK has these things, but doesn't define the constants
- # to say that it does. Define them here instead.
- 'HAVE_SYS_UIO_H',
- ],
- 'ldflags!': [
- '-pthread', # Not supported by Android toolchain.
- ],
- 'ldflags': [
- '-Wl,--build-id=sha1',
- '-Wl,--no-undefined',
- '--sysroot=<(android_ndk_sysroot)',
- '-nostdlib',
- '-L<(android_libcpp_libs_dir)',
- # Don't allow visible symbols from libgcc or libc++ to be
- # re-exported.
- '-Wl,--exclude-libs=libgcc.a',
- '-Wl,--exclude-libs=libc++_static.a',
- # Don't allow visible symbols from libraries that contain
- # assembly code with symbols that aren't hidden properly.
- # http://crbug.com/448386
- '-Wl,--exclude-libs=libcommon_audio.a',
- '-Wl,--exclude-libs=libcommon_audio_neon.a',
- '-Wl,--exclude-libs=libcommon_audio_sse2.a',
- '-Wl,--exclude-libs=libiSACFix.a',
- '-Wl,--exclude-libs=libisac_neon.a',
- '-Wl,--exclude-libs=libopus.a',
- '-Wl,--exclude-libs=libvpx.a',
- ],
- 'libraries': [
- '-l<(android_libcpp_library)',
- '-latomic',
- # Manually link the libgcc.a that the cross compiler uses.
- '<!(<(android_toolchain)/*-gcc -print-libgcc-file-name)',
- '-lc',
- '-ldl',
- '-lm',
- ],
- 'conditions': [
- ['component=="static_library"', {
- 'target_conditions': [
- ['use_native_jni_exports==0', {
- # Use a linker version script to strip JNI exports from
- # binaries which have not specifically asked to use them.
- 'ldflags': [
- '-Wl,--version-script=<!(cd <(DEPTH) && pwd -P)/build/android/android_no_jni_exports.lst',
- ],
- }],
- ],
- }],
- ['clang==1', {
- 'libraries!': [
- # Clang with libc++ does not require an explicit atomic
- # library reference.
- '-latomic',
- ],
- 'cflags': [
- # Work around incompatibilities between bionic and clang
- # headers.
- '-D__compiler_offsetof=__builtin_offsetof',
- '-Dnan=__builtin_nan',
- ],
- 'conditions': [
- ['target_arch=="arm"', {
- 'cflags': [
- '-target arm-linux-androideabi',
- ],
- 'ldflags': [
- '-target arm-linux-androideabi',
- ],
- }],
- ['target_arch=="ia32"', {
- 'cflags': [
- '-target x86-linux-androideabi',
- ],
- 'ldflags': [
- '-target x86-linux-androideabi',
- ],
- }],
- # Place holder for x64 support, not tested.
- # TODO: Enable clang support for Android x64. http://crbug.com/346626
- ['target_arch=="x64"', {
- 'cflags': [
- '-target x86_64-linux-androideabi',
- ],
- 'ldflags': [
- '-target x86_64-linux-androideabi',
- ],
- }],
- ],
- }],
- ['asan==1', {
- 'cflags': [
- # Android build relies on -Wl,--gc-sections removing
- # unreachable code. ASan instrumentation for globals inhibits
- # this and results in a library with unresolvable relocations.
- # TODO(eugenis): find a way to reenable this.
- '-mllvm -asan-globals=0',
- ],
- }],
- ['target_arch == "arm" and order_profiling==0', {
- 'ldflags': [
- # Enable identical code folding to reduce size.
- '-Wl,--icf=<(gold_icf_level)',
- ],
- }],
- ['target_arch=="ia32"', {
- # The x86 toolchain currently has problems with stack-protector.
- 'cflags!': [
- '-fstack-protector',
- ],
- 'cflags': [
- '-fno-stack-protector',
- ],
- }],
- ],
- 'target_conditions': [
- ['_type=="executable"', {
- # Force android tools to export the "main" symbol so they can be
- # loaded on ICS using the run_pie wrapper. See crbug.com/373219.
- # TODO(primiano): remove -fvisibility and -rdynamic flags below
- # when ICS support will be dropped.
- 'cflags': [
- '-fPIE',
- '-fvisibility=default',
- ],
- 'ldflags': [
- '-Bdynamic',
- '-Wl,--gc-sections',
- '-Wl,-z,nocopyreloc',
- '-pie',
- '-rdynamic',
- # crtbegin_dynamic.o should be the last item in ldflags.
- '<(android_ndk_lib)/crtbegin_dynamic.o',
- ],
- 'libraries': [
- # crtend_android.o needs to be the last item in libraries.
- # Do not add any libraries after this!
- '<(android_ndk_lib)/crtend_android.o',
- ],
- }],
- ['_type=="shared_library" or _type=="loadable_module"', {
- 'ldflags': [
- '-Wl,-shared,-Bsymbolic',
- # crtbegin_so.o should be the last item in ldflags.
- '<(android_ndk_lib)/crtbegin_so.o',
- ],
- 'libraries': [
- # crtend_so.o needs to be the last item in libraries.
- # Do not add any libraries after this!
- '<(android_ndk_lib)/crtend_so.o',
- ],
- }],
- ],
- }],
- # Settings for building host targets using the system toolchain.
- ['_toolset=="host"', {
- 'cflags!': [
- # Due to issues in Clang build system, using ASan on 32-bit
- # binaries on x86_64 host is problematic.
- # TODO(eugenis): re-enable.
- '-fsanitize=address',
- ],
- 'ldflags!': [
- '-fsanitize=address',
- '-Wl,-z,noexecstack',
- '-Wl,--gc-sections',
- '-Wl,-O1',
- '-Wl,--as-needed',
- '-Wl,--warn-shared-textrel',
- '-Wl,--fatal-warnings',
- ],
- }],
- # Settings for building host targets on mac.
- ['_toolset=="host" and host_os=="mac"', {
- 'ldflags!': [
- '-Wl,-z,now',
- '-Wl,-z,relro',
- ],
- }],
- ],
- },
- }],
- ['OS=="solaris"', {
- 'cflags!': ['-fvisibility=hidden'],
- 'cflags_cc!': ['-fvisibility-inlines-hidden'],
- }],
- ['OS=="mac" or OS=="ios"', {
- 'target_defaults': {
- 'mac_bundle': 0,
- 'xcode_settings': {
- 'ALWAYS_SEARCH_USER_PATHS': 'NO',
- # Don't link in libarclite_macosx.a, see http://crbug.com/156530.
- 'CLANG_LINK_OBJC_RUNTIME': 'NO', # -fno-objc-link-runtime
- 'COPY_PHASE_STRIP': 'NO',
- 'GCC_C_LANGUAGE_STANDARD': 'c99', # -std=c99
- 'GCC_CW_ASM_SYNTAX': 'NO', # No -fasm-blocks
- 'GCC_ENABLE_CPP_EXCEPTIONS': 'NO', # -fno-exceptions
- 'GCC_ENABLE_CPP_RTTI': 'NO', # -fno-rtti
- 'GCC_ENABLE_PASCAL_STRINGS': 'NO', # No -mpascal-strings
- # GCC_INLINES_ARE_PRIVATE_EXTERN maps to -fvisibility-inlines-hidden
- 'GCC_INLINES_ARE_PRIVATE_EXTERN': 'YES',
- 'GCC_OBJC_CALL_CXX_CDTORS': 'YES', # -fobjc-call-cxx-cdtors
- 'GCC_SYMBOLS_PRIVATE_EXTERN': 'YES', # -fvisibility=hidden
- 'GCC_THREADSAFE_STATICS': 'NO', # -fno-threadsafe-statics
- 'GCC_TREAT_WARNINGS_AS_ERRORS': 'YES', # -Werror
- 'GCC_VERSION': '4.2',
- 'GCC_WARN_ABOUT_MISSING_NEWLINE': 'YES', # -Wnewline-eof
- 'USE_HEADERMAP': 'NO',
- 'WARNING_CFLAGS': [
- '-Wall',
- '-Wendif-labels',
- '-Wextra',
- # Don't warn about unused function parameters.
- '-Wno-unused-parameter',
- # Don't warn about the "struct foo f = {0};" initialization
- # pattern.
- '-Wno-missing-field-initializers',
- ],
- 'conditions': [
- ['chromium_mac_pch', {'GCC_PRECOMPILE_PREFIX_HEADER': 'YES'},
- {'GCC_PRECOMPILE_PREFIX_HEADER': 'NO'}
- ],
- # Note that the prebuilt Clang binaries should not be used for iOS
- # development except for ASan builds.
- ['clang==1', {
- 'CLANG_CXX_LANGUAGE_STANDARD': 'c++11', # -std=c++11
- # Warn if automatic synthesis is triggered with
- # the -Wobjc-missing-property-synthesis flag.
- 'CLANG_WARN_OBJC_MISSING_PROPERTY_SYNTHESIS': 'YES',
- 'GCC_VERSION': 'com.apple.compilers.llvm.clang.1_0',
- 'WARNING_CFLAGS': [
- # This warns on selectors from Cocoa headers (-length, -set).
- # cfe-dev is currently discussing the merits of this warning.
- # TODO(thakis): Reevaluate what to do with this, based one
- # cfe-dev discussion.
- '-Wno-selector-type-mismatch',
- ],
- 'conditions': [
- ['clang_xcode==0', {
- 'CC': '$(SOURCE_ROOT)/<(clang_dir)/clang',
- 'LDPLUSPLUS': '$(SOURCE_ROOT)/<(clang_dir)/clang++',
- }],
- ],
- }],
- ['clang==1 and clang_xcode==0 and clang_use_chrome_plugins==1', {
- 'OTHER_CFLAGS': [
- '<@(clang_chrome_plugins_flags)',
- ],
- }],
- ['clang==1 and clang_xcode==0 and clang_load!=""', {
- 'OTHER_CFLAGS': [
- '-Xclang', '-load', '-Xclang', '<(clang_load)',
- ],
- }],
- ['clang==1 and clang_xcode==0 and clang_add_plugin!=""', {
- 'OTHER_CFLAGS': [
- '-Xclang', '-add-plugin', '-Xclang', '<(clang_add_plugin)',
- ],
- }],
- ['clang==1 and "<(GENERATOR)"=="ninja"', {
- 'OTHER_CFLAGS': [
- # See http://crbug.com/110262
- '-fcolor-diagnostics',
- ],
- }],
- ['OS=="ios" and target_subarch!="arm32" and \
- "<(GENERATOR)"=="xcode"', {
- 'OTHER_CFLAGS': [
- # TODO(ios): when building Chrome for iOS on 64-bit platform
- # with Xcode, the -Wshorted-64-to-32 warning is automatically
- # enabled. This cause failures when compiling protobuf code,
- # so disable the warning. http://crbug.com/359107
- '-Wno-shorten-64-to-32',
- ],
- }],
- ],
- },
- 'conditions': [
- ['clang==1', {
- 'variables': {
- 'clang_dir': '../third_party/llvm-build/Release+Asserts/bin',
- },
- }],
- ['asan==1', {
- 'xcode_settings': {
- 'OTHER_CFLAGS': [
- '-fsanitize=address',
- '-mllvm -asan-globals=0', # http://crbug.com/352073
- '-gline-tables-only',
- ],
- },
- }],
- ['asan_coverage!=0 and sanitizer_coverage==0', {
- 'target_conditions': [
- ['_toolset=="target"', {
- 'cflags': [
- '-fsanitize-coverage=<(asan_coverage)',
- ],
- 'defines': [
- 'SANITIZER_COVERAGE',
- ],
- }],
- ],
- }],
- ['sanitizer_coverage!=0', {
- 'target_conditions': [
- ['_toolset=="target"', {
- 'cflags': [
- '-fsanitize-coverage=<(sanitizer_coverage)',
- ],
- 'defines': [
- 'SANITIZER_COVERAGE',
- ],
- }],
- ],
- }],
- ],
- 'target_conditions': [
- ['_type!="static_library"', {
- 'xcode_settings': {'OTHER_LDFLAGS': ['-Wl,-search_paths_first']},
- 'conditions': [
- ['asan==1', {
- 'xcode_settings': {
- 'OTHER_LDFLAGS': [
- '-fsanitize=address',
- ],
- },
- }],
- ['mac_write_linker_maps==1', {
- 'xcode_settings': {
- 'OTHER_LDFLAGS': [
- '-Wl,-map,>(_target_name).map',
- ],
- },
- }],
- ],
- }],
- ['_mac_bundle', {
- 'xcode_settings': {'OTHER_LDFLAGS': ['-Wl,-ObjC']},
- 'target_conditions': [
- ['_type=="executable"', {
- 'conditions': [
- ['asan==1', {
- 'postbuilds': [
- {
- 'variables': {
- # Define copy_asan_dylib_path in a variable ending in
- # _path so that gyp understands it's a path and
- # performs proper relativization during dict merging.
- 'copy_asan_dylib_path':
- 'mac/copy_asan_runtime_dylib.sh',
- },
- 'postbuild_name': 'Copy ASan runtime dylib',
- 'action': [
- '<(copy_asan_dylib_path)',
- ],
- },
- ],
- }],
- ],
- }],
- ],
- }],
- ], # target_conditions
- }, # target_defaults
- }], # OS=="mac" or OS=="ios"
- ['OS=="mac"', {
- 'target_defaults': {
- 'defines': [
- # Prevent Mac OS X AssertMacros.h from defining macros that collide
- # with common names, like 'check', 'require', and 'verify'.
- # (Included by system header. Also exists on iOS but not included.)
- # http://opensource.apple.com/source/CarbonHeaders/CarbonHeaders-18.1/AssertMacros.h
- '__ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORE=0',
- ],
- 'variables': {
- # These should end with %, but there seems to be a bug with % in
- # variables that are intended to be set to different values in
- # different targets, like these.
- 'mac_pie': 1, # Most executables can be position-independent.
- # Strip debugging symbols from the target.
- 'mac_strip': '<(mac_strip_release)',
- 'conditions': [
- ['asan==1', {
- 'conditions': [
- ['mac_want_real_dsym=="default"', {
- 'mac_real_dsym': 1,
- }, {
- 'mac_real_dsym': '<(mac_want_real_dsym)'
- }],
- ],
- }, {
- 'conditions': [
- ['mac_want_real_dsym=="default"', {
- 'mac_real_dsym': 0, # Fake .dSYMs are fine in most cases.
- }, {
- 'mac_real_dsym': '<(mac_want_real_dsym)'
- }],
- ],
- }],
- ],
- },
- 'configurations': {
- 'Release_Base': {
- 'conditions': [
- ['branding=="Chrome" and buildtype=="Official"', {
- 'xcode_settings': {
- 'OTHER_CFLAGS': [
- # The Google Chrome Framework dSYM generated by dsymutil has
- # grown larger than 4GB, which dsymutil can't handle. Reduce
- # the amount of debug symbols.
- '-fno-standalone-debug', # See http://crbug.com/479841
- ]
- },
- }],
- ],
- }, # configuration "Release"
- }, # configurations
- 'xcode_settings': {
- 'GCC_DYNAMIC_NO_PIC': 'NO', # No -mdynamic-no-pic
- # (Equivalent to -fPIC)
- # MACOSX_DEPLOYMENT_TARGET maps to -mmacosx-version-min
- 'MACOSX_DEPLOYMENT_TARGET': '<(mac_deployment_target)',
- # Keep pch files below xcodebuild/.
- 'SHARED_PRECOMPS_DIR': '$(CONFIGURATION_BUILD_DIR)/SharedPrecompiledHeaders',
- 'OTHER_CFLAGS': [
- # Someday this can be replaced by an 'GCC_STRICT_ALIASING': 'NO'
- # xcode_setting, but not until all downstream projects' mac bots are
- # using xcode >= 4.6, because that's when the default value of the
- # flag in the compiler switched. Pre-4.6, the value 'NO' for that
- # setting is a no-op as far as xcode is concerned, but the compiler
- # behaves differently based on whether -fno-strict-aliasing is
- # specified or not.
- '-fno-strict-aliasing', # See http://crbug.com/32204.
- ],
- },
- 'target_conditions': [
- ['_type=="executable"', {
- 'postbuilds': [
- {
- # Arranges for data (heap) pages to be protected against
- # code execution when running on Mac OS X 10.7 ("Lion"), and
- # ensures that the position-independent executable (PIE) bit
- # is set for ASLR when running on Mac OS X 10.5 ("Leopard").
- 'variables': {
- # Define change_mach_o_flags in a variable ending in _path
- # so that GYP understands it's a path and performs proper
- # relativization during dict merging.
- 'change_mach_o_flags_path':
- 'mac/change_mach_o_flags_from_xcode.sh',
- 'change_mach_o_flags_options%': [
- ],
- 'target_conditions': [
- ['mac_pie==0 or release_valgrind_build==1', {
- # Don't enable PIE if it's unwanted. It's unwanted if
- # the target specifies mac_pie=0 or if building for
- # Valgrind, because Valgrind doesn't understand slide.
- # See the similar mac_pie/release_valgrind_build check
- # below.
- 'change_mach_o_flags_options': [
- '--no-pie',
- ],
- }],
- ],
- },
- 'postbuild_name': 'Change Mach-O Flags',
- 'action': [
- '<(change_mach_o_flags_path)',
- '>@(change_mach_o_flags_options)',
- ],
- },
- ],
- 'target_conditions': [
- ['mac_pie==1 and release_valgrind_build==0', {
- # Turn on position-independence (ASLR) for executables. When
- # PIE is on for the Chrome executables, the framework will
- # also be subject to ASLR.
- # Don't do this when building for Valgrind, because Valgrind
- # doesn't understand slide. TODO: Make Valgrind on Mac OS X
- # understand slide, and get rid of the Valgrind check.
- 'xcode_settings': {
- 'OTHER_LDFLAGS': [
- '-Wl,-pie', # Position-independent executable (MH_PIE)
- ],
- },
- }],
- ],
- }],
- ['(_type=="executable" or _type=="shared_library" or \
- _type=="loadable_module") and mac_strip!=0', {
- 'target_conditions': [
- ['mac_real_dsym == 1', {
- # To get a real .dSYM bundle produced by dsymutil, set the
- # debug information format to dwarf-with-dsym. Since
- # strip_from_xcode will not be used, set Xcode to do the
- # stripping as well.
- 'configurations': {
- 'Release_Base': {
- 'xcode_settings': {
- 'DEBUG_INFORMATION_FORMAT': 'dwarf-with-dsym',
- 'DEPLOYMENT_POSTPROCESSING': 'YES',
- 'STRIP_INSTALLED_PRODUCT': 'YES',
- 'conditions': [
- # Only strip non-ASan builds.
- ['asan==0', {
- 'target_conditions': [
- ['_type=="shared_library" or _type=="loadable_module"', {
- # The Xcode default is to strip debugging symbols
- # only (-S). Local symbols should be stripped as
- # well, which will be handled by -x. Xcode will
- # continue to insert -S when stripping even when
- # additional flags are added with STRIPFLAGS.
- 'STRIPFLAGS': '-x',
- }], # _type=="shared_library" or _type=="loadable_module"
- ], # target_conditions
- }, { # asan != 0
- 'STRIPFLAGS': '-S',
- }],
- ],
- }, # xcode_settings
- }, # configuration "Release"
- }, # configurations
- }, { # mac_real_dsym != 1
- # To get a fast fake .dSYM bundle, use a post-build step to
- # produce the .dSYM and strip the executable. strip_from_xcode
- # only operates in the Release configuration.
- 'postbuilds': [
- {
- 'variables': {
- # Define strip_from_xcode in a variable ending in _path
- # so that gyp understands it's a path and performs proper
- # relativization during dict merging.
- 'strip_from_xcode_path': 'mac/strip_from_xcode',
- },
- 'postbuild_name': 'Strip If Needed',
- 'action': ['<(strip_from_xcode_path)'],
- },
- ], # postbuilds
- }], # mac_real_dsym
- ], # target_conditions
- }], # (_type=="executable" or _type=="shared_library" or
- # _type=="loadable_module") and mac_strip!=0
- ], # target_conditions
- }, # target_defaults
- }], # OS=="mac"
- ['OS=="ios"', {
- 'includes': [
- 'ios/coverage.gypi',
- ],
- 'target_defaults': {
- 'xcode_settings' : {
- 'CLANG_CXX_LANGUAGE_STANDARD': 'c++11',
-
- 'conditions': [
- # Older Xcodes do not support -Wno-deprecated-register, so pass an
- # additional flag to suppress the "unknown compiler option" error.
- # Restrict this flag to builds that are either compiling with Xcode
- # or compiling with Xcode's Clang. This will allow Ninja builds to
- # continue failing on unknown compiler options.
- # TODO(rohitrao): This flag is temporary and should be removed as
- # soon as the iOS bots are updated to use Xcode 5.1.
- ['clang_xcode==1', {
- 'WARNING_CFLAGS': [
- '-Wno-unknown-warning-option',
- # It's not possible to achieve nullability completeness before
- # all builders are running Xcode 7. crbug.com/499809
- '-Wno-nullability-completeness',
- ],
- }],
-
- # Limit the valid architectures depending on "target_subarch".
- # This need to include the "arm" architectures but also the "x86"
- # ones (they are used when building for the simulator).
- ['target_subarch=="arm32"', {
- 'VALID_ARCHS': ['armv7', 'i386'],
- }],
- ['target_subarch=="arm64"', {
- 'VALID_ARCHS': ['arm64', 'x86_64'],
- }],
- ['target_subarch=="both"', {
- 'VALID_ARCHS': ['arm64', 'armv7', 'x86_64', 'i386'],
- }],
- ['use_system_libcxx==1', {
- 'target_conditions': [
- # Only use libc++ when building target for iOS not when building
- # tools for the host (OS X) as Mac targets OS X SDK 10.6 which
- # does not support libc++.
- ['_toolset=="target"', {
- 'CLANG_CXX_LIBRARY': 'libc++', # -stdlib=libc++
- }]
- ],
- }, {
- # The default for deployment target of 7.0+ is libc++, so force
- # the old behavior unless libc++ is enabled.
- 'CLANG_CXX_LIBRARY': 'libstdc++', # -stdlib=libstdc++
- }],
- ],
- },
- 'target_conditions': [
- ['_toolset=="host"', {
- 'xcode_settings': {
- 'SDKROOT': 'macosx<(mac_sdk)', # -isysroot
- 'MACOSX_DEPLOYMENT_TARGET': '<(mac_deployment_target)',
- 'VALID_ARCHS': [
- 'x86_64',
- ],
- 'ARCHS': [
- 'x86_64',
- ],
- },
- }],
- ['_toolset=="target"', {
- 'xcode_settings': {
- # This section should be for overriding host settings. But,
- # since we can't negate the iphone deployment target above, we
- # instead set it here for target only.
- 'IPHONEOS_DEPLOYMENT_TARGET': '<(ios_deployment_target)',
- 'ARCHS': ['$(ARCHS_STANDARD_INCLUDING_64_BIT)'],
- },
- }],
- ['_type=="executable"', {
- 'configurations': {
- 'Release_Base': {
- 'xcode_settings': {
- 'DEPLOYMENT_POSTPROCESSING': 'YES',
- 'STRIP_INSTALLED_PRODUCT': 'YES',
- },
- },
- 'Debug_Base': {
- 'xcode_settings': {
- # Remove dSYM to reduce build time.
- 'DEBUG_INFORMATION_FORMAT': 'dwarf',
- },
- },
- },
- 'xcode_settings': {
- 'conditions': [
- ['chromium_ios_signing', {
- # iOS SDK wants everything for device signed.
- 'CODE_SIGN_IDENTITY[sdk=iphoneos*]': 'iPhone Developer',
- }, {
- 'CODE_SIGNING_REQUIRED': 'NO',
- 'CODE_SIGN_IDENTITY[sdk=iphoneos*]': '',
- }],
- ],
- },
- }],
- ], # target_conditions
- }, # target_defaults
- }], # OS=="ios"
- ['OS=="win"', {
- 'target_defaults': {
- 'defines': [
- '_WIN32_WINNT=0x0603',
- 'WINVER=0x0603',
- 'WIN32',
- '_WINDOWS',
- 'NOMINMAX',
- 'PSAPI_VERSION=1',
- '_CRT_RAND_S',
- 'CERT_CHAIN_PARA_HAS_EXTRA_FIELDS',
- 'WIN32_LEAN_AND_MEAN',
- '_ATL_NO_OPENGL',
- '_SECURE_ATL',
- # _HAS_EXCEPTIONS must match ExceptionHandling in msvs_settings.
- '_HAS_EXCEPTIONS=0',
- # Silence some warnings; we can't switch the the 'recommended'
- # versions as they're not available on old OSs.
- '_WINSOCK_DEPRECATED_NO_WARNINGS',
- ],
- 'conditions': [
- ['buildtype=="Official"', {
- # In official builds, targets can self-select an optimization
- # level by defining a variable named 'optimize', and setting it
- # to one of
- # - "size", optimizes for minimal code size - the default.
- # - "speed", optimizes for speed over code size.
- # - "max", whole program optimization and link-time code
- # generation. This is very expensive and should be used
- # sparingly.
- 'variables': {
- 'optimize%': 'size',
- },
- 'msvs_settings': {
- 'VCLinkerTool': {
- # Set /LTCG for the official builds.
- 'LinkTimeCodeGeneration': '1',
- 'AdditionalOptions': [
- # Set the number of LTCG code-gen threads to eight.
- # The default is four. This gives a 5-10% link speedup.
- '/cgthreads:8',
- ],
- },
- },
- 'target_conditions': [
- ['optimize=="size"', {
- 'msvs_settings': {
- 'VCCLCompilerTool': {
- # 1, optimizeMinSpace, Minimize Size (/O1)
- 'Optimization': '1',
- # 2, favorSize - Favor small code (/Os)
- 'FavorSizeOrSpeed': '2',
- },
- },
- },
- ],
- # This config is used to avoid a problem in ffmpeg, see
- # http://crbug.com/264459.
- ['optimize=="size_no_ltcg"', {
- 'msvs_settings': {
- 'VCCLCompilerTool': {
- # 1, optimizeMinSpace, Minimize Size (/O1)
- 'Optimization': '1',
- # 2, favorSize - Favor small code (/Os)
- 'FavorSizeOrSpeed': '2',
- },
- },
- },
- ],
- ['optimize=="speed"', {
- 'msvs_settings': {
- 'VCCLCompilerTool': {
- # 2, optimizeMaxSpeed, Maximize Speed (/O2)
- 'Optimization': '2',
- # 1, favorSpeed - Favor fast code (/Ot)
- 'FavorSizeOrSpeed': '1',
- },
- },
- },
- ],
- ['optimize=="max"', {
- # Disable Warning 4702 ("Unreachable code") for the WPO/PGO
- # builds. Probably anything that this would catch that
- # wouldn't be caught in a normal build isn't going to
- # actually be a bug, so the incremental value of C4702 for
- # PGO builds is likely very small.
- 'msvs_disabled_warnings': [
- 4702
- ],
- 'msvs_settings': {
- 'VCCLCompilerTool': {
- # 2, optimizeMaxSpeed, Maximize Speed (/O2)
- 'Optimization': '2',
- # 1, favorSpeed - Favor fast code (/Ot)
- 'FavorSizeOrSpeed': '1',
- # This implies link time code generation.
- 'WholeProgramOptimization': 'true',
- },
- },
- },
- ],
- ],
- },
- ],
- ['msvs_xtree_patched!=1', {
- # If xtree hasn't been patched, then we disable C4702. Otherwise,
- # it's enabled. This will generally only be true for system-level
- # installed Express users.
- 'msvs_disabled_warnings': [
- 4702,
- ],
- }],
- ],
- 'msvs_system_include_dirs': [
- '<(windows_sdk_path)/Include/shared',
- '<(windows_sdk_path)/Include/um',
- '<(windows_sdk_path)/Include/winrt',
- '$(VSInstallDir)/VC/atlmfc/include',
- ],
- 'msvs_cygwin_shell': 0,
- 'msvs_disabled_warnings': [
- # C4091: 'typedef ': ignored on left of 'X' when no variable is
- # declared.
- # This happens in a number of Windows headers. Dumb.
- 4091,
-
- # C4127: conditional expression is constant
- # This warning can in theory catch dead code and other problems, but
- # triggers in far too many desirable cases where the conditional
- # expression is either set by macros or corresponds some legitimate
- # compile-time constant expression (due to constant template args,
- # conditionals comparing the sizes of different types, etc.). Some of
- # these can be worked around, but it's not worth it.
- 4127,
-
- # C4351: new behavior: elements of array 'array' will be default
- # initialized
- # This is a silly "warning" that basically just alerts you that the
- # compiler is going to actually follow the language spec like it's
- # supposed to, instead of not following it like old buggy versions
- # did. There's absolutely no reason to turn this on.
- 4351,
-
- # C4355: 'this': used in base member initializer list
- # It's commonly useful to pass |this| to objects in a class'
- # initializer list. While this warning can catch real bugs, most of
- # the time the constructors in question don't attempt to call methods
- # on the passed-in pointer (until later), and annotating every legit
- # usage of this is simply more hassle than the warning is worth.
- 4355,
-
- # C4503: 'identifier': decorated name length exceeded, name was
- # truncated
- # This only means that some long error messages might have truncated
- # identifiers in the presence of lots of templates. It has no effect
- # on program correctness and there's no real reason to waste time
- # trying to prevent it.
- 4503,
-
- # Warning C4589 says: "Constructor of abstract class ignores
- # initializer for virtual base class." Disable this warning because it
- # is flaky in VS 2015 RTM. It triggers on compiler generated
- # copy-constructors in some cases.
- 4589,
-
- # C4611: interaction between 'function' and C++ object destruction is
- # non-portable
- # This warning is unavoidable when using e.g. setjmp/longjmp. MSDN
- # suggests using exceptions instead of setjmp/longjmp for C++, but
- # Chromium code compiles without exception support. We therefore have
- # to use setjmp/longjmp for e.g. JPEG decode error handling, which
- # means we have to turn off this warning (and be careful about how
- # object destruction happens in such cases).
- 4611,
-
- # TODO(maruel): These warnings are level 4. They will be slowly
- # removed as code is fixed.
- 4100, # Unreferenced formal parameter
- 4121, # Alignment of a member was sensitive to packing
- 4244, # Conversion from 'type1' to 'type2', possible loss of data
- 4481, # Nonstandard extension used: override specifier 'keyword'
- 4505, # Unreferenced local function has been removed
- 4510, # Default constructor could not be generated
- 4512, # Assignment operator could not be generated
- 4610, # Object can never be instantiated
- 4838, # Narrowing conversion. Doesn't seem to be very useful.
- 4996, # 'X': was declared deprecated (for GetVersionEx).
-
- # These are variable shadowing warnings that are new in VS2015. We
- # should work through these at some point -- they may be removed from
- # the RTM release in the /W4 set.
- 4456, 4457, 4458, 4459,
- ],
- 'msvs_settings': {
- 'VCCLCompilerTool': {
- 'AdditionalOptions': ['/MP'],
- 'MinimalRebuild': 'false',
- 'BufferSecurityCheck': 'true',
- 'EnableFunctionLevelLinking': 'true',
- 'RuntimeTypeInfo': 'false',
- 'WarningLevel': '4',
- 'WarnAsError': 'true',
- 'DebugInformationFormat': '3',
- # ExceptionHandling must match _HAS_EXCEPTIONS above.
- 'ExceptionHandling': '0',
- },
- 'VCLibrarianTool': {
- 'AdditionalOptions': ['/ignore:4221'],
- 'AdditionalLibraryDirectories': [
- '<(windows_sdk_path)/Lib/win8/um/x86',
- ],
- },
- 'VCLinkerTool': {
- 'AdditionalDependencies': [
- 'wininet.lib',
- 'dnsapi.lib',
- 'version.lib',
- 'msimg32.lib',
- 'ws2_32.lib',
- 'usp10.lib',
- 'psapi.lib',
- 'dbghelp.lib',
- 'winmm.lib',
- 'shlwapi.lib',
- ],
- 'AdditionalLibraryDirectories': [
- '<(windows_sdk_path)/Lib/win8/um/x86',
- ],
- 'GenerateDebugInformation': 'true',
- 'MapFileName': '$(OutDir)\\$(TargetName).map',
- 'ImportLibrary': '$(OutDir)\\lib\\$(TargetName).lib',
- 'FixedBaseAddress': '1',
- # SubSystem values:
- # 0 == not set
- # 1 == /SUBSYSTEM:CONSOLE
- # 2 == /SUBSYSTEM:WINDOWS
- # Most of the executables we'll ever create are tests
- # and utilities with console output.
- 'SubSystem': '1',
- },
- 'VCMIDLTool': {
- 'GenerateStublessProxies': 'true',
- 'TypeLibraryName': '$(InputName).tlb',
- 'OutputDirectory': '$(IntDir)',
- 'HeaderFileName': '$(InputName).h',
- 'DLLDataFileName': '$(InputName).dlldata.c',
- 'InterfaceIdentifierFileName': '$(InputName)_i.c',
- 'ProxyFileName': '$(InputName)_p.c',
- },
- 'VCResourceCompilerTool': {
- 'Culture' : '1033',
- 'AdditionalIncludeDirectories': [
- '<(DEPTH)',
- '<(SHARED_INTERMEDIATE_DIR)',
- ],
- },
- 'target_conditions': [
- ['_type=="executable"', {
- 'VCManifestTool': {
- 'EmbedManifest': 'true',
- },
- }],
- ['_type=="executable" and ">(win_exe_compatibility_manifest)"!=""', {
- 'VCManifestTool': {
- 'AdditionalManifestFiles': [
- '>(win_exe_compatibility_manifest)',
- ],
- },
- }],
- ],
- 'conditions': [
- # Building with Clang on Windows is a work in progress and very
- # experimental. See crbug.com/82385.
- # Keep this in sync with the similar blocks in build/config/compiler/BUILD.gn
- ['clang==1', {
- 'VCCLCompilerTool': {
- 'AdditionalOptions': [
- # Many files use intrinsics without including this header.
- # TODO(hans): Fix those files, or move this to sub-GYPs.
- '/FIIntrin.h',
-
- # TODO(hans): Make this list shorter eventually, http://crbug.com/504657
- '-Qunused-arguments', # http://crbug.com/504658
- '-Wno-microsoft', # http://crbug.com/505296
- '-Wno-switch', # http://crbug.com/505308
- '-Wno-unknown-pragmas', # http://crbug.com/505314
- '-Wno-unused-function', # http://crbug.com/505316
- '-Wno-unused-value', # http://crbug.com/505318
- '-Wno-unused-local-typedef', # http://crbug.com/411648
- ],
- },
- }],
- ['clang==1 and target_arch=="ia32"', {
- 'VCCLCompilerTool': {
- 'WarnAsError': 'false',
- 'AdditionalOptions': [
- '/fallback',
- ],
- },
- }],
- ['clang==1 and clang_use_chrome_plugins==1', {
- 'VCCLCompilerTool': {
- 'AdditionalOptions': [
- '<@(clang_chrome_plugins_flags)',
- ],
- },
- }],
- ['clang==1 and MSVS_VERSION == "2013"', {
- 'VCCLCompilerTool': {
- 'AdditionalOptions': [
- '-fmsc-version=1800',
- ],
- },
- }],
- ['clang==1 and MSVS_VERSION == "2015"', {
- 'VCCLCompilerTool': {
- 'AdditionalOptions': [
- '-fmsc-version=1900',
- ],
- },
- }],
- ['clang==1 and "<!(python <(DEPTH)/build/win/use_ansi_codes.py)"=="True"', {
- 'VCCLCompilerTool': {
- 'AdditionalOptions': [
- # cmd.exe doesn't understand ANSI escape codes by default,
- # so only enable them if something emulating them is around.
- '-fansi-escape-codes',
- # Also see http://crbug.com/110262
- '-fcolor-diagnostics',
- ],
- },
- }],
- ],
- },
- },
- }],
- ['disable_nacl==1', {
- 'target_defaults': {
- 'defines': [
- 'DISABLE_NACL',
- ],
- },
- }],
- ['OS=="win" and msvs_use_common_linker_extras', {
- 'target_defaults': {
- 'msvs_settings': {
- 'VCLinkerTool': {
- 'DelayLoadDLLs': [
- 'dbghelp.dll',
- 'dwmapi.dll',
- 'shell32.dll',
- 'uxtheme.dll',
- ],
- },
- },
- 'configurations': {
- 'x86_Base': {
- 'msvs_settings': {
- 'VCLinkerTool': {
- 'AdditionalOptions': [
- '/safeseh',
- '/dynamicbase',
- '/ignore:4199',
- '/ignore:4221',
- '/nxcompat',
- ],
- },
- 'conditions': [
- ['syzyasan==0', {
- 'VCLinkerTool': {
- 'AdditionalOptions': ['/largeaddressaware'],
- },
- }],
- ['asan==1', {
- # TODO(asan/win): Move this down into the general
- # win-target_defaults section once the 64-bit asan runtime
- # exists. See crbug.com/345874.
- 'VCCLCompilerTool': {
- 'AdditionalOptions': [
- '-fsanitize=address',
- '-fsanitize-blacklist=<(PRODUCT_DIR)/../../tools/memory/asan/blacklist_win.txt',
- ],
- 'AdditionalIncludeDirectories': [
- # MSVC needs to be able to find the sanitizer headers when
- # invoked via /fallback. This is critical for using macros
- # like ASAN_UNPOISON_MEMORY_REGION in files where we fall
- # back.
- '<(DEPTH)/<(make_clang_dir)/lib/clang/<!(python <(DEPTH)/tools/clang/scripts/update.py --print-clang-version)/include_sanitizer',
- ],
- },
- 'VCLinkerTool': {
- 'AdditionalLibraryDirectories': [
- # TODO(hans): If make_clang_dir is absolute, this breaks.
- '<(DEPTH)/<(make_clang_dir)/lib/clang/<!(python <(DEPTH)/tools/clang/scripts/update.py --print-clang-version)/lib/windows',
- ],
- },
- 'target_conditions': [
- ['component=="shared_library"', {
- 'VCLinkerTool': {
- 'AdditionalDependencies': [
- 'clang_rt.asan_dynamic-i386.lib',
- 'clang_rt.asan_dynamic_runtime_thunk-i386.lib',
- ],
- },
- }],
- ['_type=="executable" and component=="static_library"', {
- 'VCLinkerTool': {
- 'AdditionalDependencies': [
- 'clang_rt.asan-i386.lib',
- ],
- },
- }],
- ['(_type=="shared_library" or _type=="loadable_module") and component=="static_library"', {
- 'VCLinkerTool': {
- 'AdditionalDependencies': [
- 'clang_rt.asan_dll_thunk-i386.lib',
- ],
- },
- }],
- ],
- }],
- ['sanitizer_coverage!=0', {
- # TODO(asan/win): Move this down into the general
- # win-target_defaults section once the 64-bit asan runtime
- # exists. See crbug.com/345874.
- 'VCCLCompilerTool': {
- 'AdditionalOptions': [
- '-fsanitize-coverage=<(sanitizer_coverage)',
- ],
- },
- }],
- ],
- },
- 'conditions': [
- ['sanitizer_coverage!=0', {
- # TODO(asan/win): Move this down into the general
- # win-target_defaults section once the 64-bit asan runtime
- # exists. See crbug.com/345874.
- 'defines': [
- 'SANITIZER_COVERAGE',
- ],
- }],
- ],
- },
- 'x64_Base': {
- 'msvs_settings': {
- 'VCLinkerTool': {
- 'AdditionalOptions': [
- # safeseh is not compatible with x64
- '/dynamicbase',
- '/ignore:4199',
- '/ignore:4221',
- '/nxcompat',
- ],
- },
- },
- },
- },
- },
- }],
- ['enable_new_npdevice_api==1', {
- 'target_defaults': {
- 'defines': [
- 'ENABLE_NEW_NPDEVICE_API',
- ],
- },
- }],
- # Don't warn about the "typedef 'foo' locally defined but not used"
- # for gcc 4.8 and higher.
- # TODO: remove this flag once all builds work. See crbug.com/227506
- ['gcc_version>=48 and clang==0', {
- 'target_defaults': {
- 'cflags': [
- '-Wno-unused-local-typedefs',
- ],
- },
- }],
- ['gcc_version>=48 and clang==0 and host_clang==1', {
- 'target_defaults': {
- 'target_conditions': [
- ['_toolset=="host"', { 'cflags!': [ '-Wno-unused-local-typedefs' ]}],
- ],
- },
- }],
- ['clang==1 and ((OS!="mac" and OS!="ios") or clang_xcode==0) '
- 'and OS!="win"', {
- 'make_global_settings': [
- ['CC', '<(make_clang_dir)/bin/clang'],
- ['CXX', '<(make_clang_dir)/bin/clang++'],
- ['CC.host', '$(CC)'],
- ['CXX.host', '$(CXX)'],
- ],
- }],
- ['clang==1 and OS=="win"', {
- 'make_global_settings': [
- # On Windows, gyp's ninja generator only looks at CC.
- ['CC', '<(make_clang_dir)/bin/clang-cl'],
- ],
- }],
- ['use_lld==1 and OS=="win"', {
- 'make_global_settings': [
- # Limited to Windows because -flavor link2 is the driver that is
- # compatible with link.exe.
- ['LD', '<(make_clang_dir)/bin/lld -flavor link2'],
- ],
- }],
- ['OS=="android" and clang==0', {
- # Hardcode the compiler names in the Makefile so that
- # it won't depend on the environment at make time.
- 'make_global_settings': [
- ['CC', '<!(/bin/echo -n <(android_toolchain)/*-gcc)'],
- ['CXX', '<!(/bin/echo -n <(android_toolchain)/*-g++)'],
- ['CC.host', '<(host_cc)'],
- ['CXX.host', '<(host_cxx)'],
- ],
- }],
- ['OS=="linux" and target_arch=="mipsel" and clang==0', {
- 'make_global_settings': [
- ['CC', '<(sysroot)/../bin/mipsel-linux-gnu-gcc'],
- ['CXX', '<(sysroot)/../bin/mipsel-linux-gnu-g++'],
- ['CC.host', '<(host_cc)'],
- ['CXX.host', '<(host_cxx)'],
- ],
- }],
- ['OS=="linux" and target_arch=="arm" and host_arch!="arm" and chromeos==0 and clang==0', {
- # Set default ARM cross compiling on linux. These can be overridden
- # using CC/CXX/etc environment variables.
- 'make_global_settings': [
- ['CC', '<!(which arm-linux-gnueabihf-gcc)'],
- ['CXX', '<!(which arm-linux-gnueabihf-g++)'],
- ['CC.host', '<(host_cc)'],
- ['CXX.host', '<(host_cxx)'],
- ],
- }],
-
- # TODO(yyanagisawa): supports GENERATOR==make
- # make generator doesn't support CC_wrapper without CC
- # in make_global_settings yet.
- ['use_goma==1 and ("<(GENERATOR)"=="ninja" or clang==1)', {
- 'make_global_settings': [
- ['CC_wrapper', '<(gomadir)/gomacc'],
- ['CXX_wrapper', '<(gomadir)/gomacc'],
- ['CC.host_wrapper', '<(gomadir)/gomacc'],
- ['CXX.host_wrapper', '<(gomadir)/gomacc'],
- ],
- }],
- ['use_lto==1', {
- 'target_defaults': {
- 'target_conditions': [
- ['_toolset=="target"', {
- 'cflags': [
- '-flto',
- ],
- 'xcode_settings': {
- 'LLVM_LTO': 'YES',
- },
- }],
- # Work-around for http://openradar.appspot.com/20356002
- ['_toolset=="target" and _type!="static_library"', {
- 'xcode_settings': {
- 'OTHER_LDFLAGS': [
- '-Wl,-all_load',
- ],
- },
- }],
- ],
- },
- }],
- ['use_lto==1 and clang==0', {
- 'target_defaults': {
- 'target_conditions': [
- ['_toolset=="target"', {
- 'cflags': [
- '-ffat-lto-objects',
- ],
- }],
- ],
- },
- }],
- ['use_lto==1 and clang==1', {
- 'target_defaults': {
- 'target_conditions': [
- ['_toolset=="target"', {
- 'arflags': [
- '--plugin', '../../<(make_clang_dir)/lib/LLVMgold.so',
- ],
- }],
- ],
- },
- }],
- # Apply a lower LTO optimization level in non-official builds.
- ['use_lto==1 and clang==1 and buildtype!="Official"', {
- 'target_defaults': {
- 'target_conditions': [
- ['_toolset=="target"', {
- 'ldflags': [
- '-Wl,--plugin-opt,O1',
- ],
- }],
- ['_toolset=="target" and _type!="static_library"', {
- 'xcode_settings': {
- 'OTHER_LDFLAGS': [
- '-Wl,-mllvm,-O1',
- ],
- },
- }],
- ],
- },
- }],
- ['use_lto==1 and clang==1 and target_arch=="arm"', {
- 'target_defaults': {
- 'target_conditions': [
- ['_toolset=="target"', {
- # Without this flag, LTO produces a .text section that is larger
- # than the maximum call displacement, preventing the linker from
- # relocating calls (http://llvm.org/PR22999).
- 'ldflags': [
- '-Wl,-plugin-opt,-function-sections',
- ],
- }],
- ],
- },
- }],
- ['(use_lto==1 or use_lto_o2==1) and clang==0', {
- 'target_defaults': {
- 'target_conditions': [
- ['_toolset=="target"', {
- 'ldflags': [
- '-flto=32',
- ],
- }],
- ],
- },
- }],
- ['(use_lto==1 or use_lto_o2==1) and clang==1', {
- 'target_defaults': {
- 'target_conditions': [
- ['_toolset=="target"', {
- 'ldflags': [
- '-flto',
- ],
- }],
- ],
- },
- }],
- ['cfi_vptr==1', {
- 'target_defaults': {
- 'target_conditions': [
- ['_toolset=="target"', {
- 'cflags': [
- '-fsanitize=cfi-vcall',
- '-fsanitize=cfi-derived-cast',
- '-fsanitize=cfi-unrelated-cast',
- '-fsanitize-blacklist=<(cfi_blacklist)',
- ],
- 'ldflags': [
- '-fsanitize=cfi-vcall',
- '-fsanitize=cfi-derived-cast',
- '-fsanitize=cfi-unrelated-cast',
- ],
- 'xcode_settings': {
- 'OTHER_CFLAGS': [
- '-fsanitize=cfi-vcall',
- '-fsanitize=cfi-derived-cast',
- '-fsanitize=cfi-unrelated-cast',
- '-fsanitize-blacklist=<(cfi_blacklist)',
- ],
- },
- 'msvs_settings': {
- 'VCCLCompilerTool': {
- 'AdditionalOptions': [
- '-fsanitize=cfi-vcall',
- '-fsanitize=cfi-derived-cast',
- '-fsanitize=cfi-unrelated-cast',
- '-fsanitize-blacklist=<(cfi_blacklist)',
- ],
- },
- },
- }],
- ['_toolset=="target" and _type!="static_library"', {
- 'xcode_settings': {
- 'OTHER_LDFLAGS': [
- '-fsanitize=cfi-vcall',
- '-fsanitize=cfi-derived-cast',
- '-fsanitize=cfi-unrelated-cast',
- ],
- },
- }],
- ],
- },
- }],
- ],
- 'xcode_settings': {
- # DON'T ADD ANYTHING NEW TO THIS BLOCK UNLESS YOU REALLY REALLY NEED IT!
- # This block adds *project-wide* configuration settings to each project
- # file. It's almost always wrong to put things here. Specify your
- # custom xcode_settings in target_defaults to add them to targets instead.
-
- 'conditions': [
- # In an Xcode Project Info window, the "Base SDK for All Configurations"
- # setting sets the SDK on a project-wide basis. In order to get the
- # configured SDK to show properly in the Xcode UI, SDKROOT must be set
- # here at the project level.
- ['OS=="mac"', {
- 'conditions': [
- ['mac_sdk_path==""', {
- 'SDKROOT': 'macosx<(mac_sdk)', # -isysroot
- }, {
- 'SDKROOT': '<(mac_sdk_path)', # -isysroot
- }],
- ],
- }],
- ['OS=="ios"', {
- 'conditions': [
- ['ios_sdk_path==""', {
- 'conditions': [
- # TODO(justincohen): Ninja only supports simulator for now.
- ['"<(GENERATOR)"=="xcode"', {
- 'SDKROOT': 'iphoneos<(ios_sdk)', # -isysroot
- }, {
- 'SDKROOT': 'iphonesimulator<(ios_sdk)', # -isysroot
- }],
- ],
- }, {
- 'SDKROOT': '<(ios_sdk_path)', # -isysroot
- }],
- ],
- }],
- ['OS=="ios"', {
- # Target both iPhone and iPad.
- 'TARGETED_DEVICE_FAMILY': '1,2',
- }, { # OS!="ios"
- 'conditions': [
- ['target_arch=="x64"', {
- 'ARCHS': [
- 'x86_64'
- ],
- }],
- ['target_arch=="ia32"', {
- 'ARCHS': [
- 'i386'
- ],
- }],
- ],
- }],
- ],
-
- # The Xcode generator will look for an xcode_settings section at the root
- # of each dict and use it to apply settings on a file-wide basis. Most
- # settings should not be here, they should be in target-specific
- # xcode_settings sections, or better yet, should use non-Xcode-specific
- # settings in target dicts. SYMROOT is a special case, because many other
- # Xcode variables depend on it, including variables such as
- # PROJECT_DERIVED_FILE_DIR. When a source group corresponding to something
- # like PROJECT_DERIVED_FILE_DIR is added to a project, in order for the
- # files to appear (when present) in the UI as actual files and not red
- # red "missing file" proxies, the correct path to PROJECT_DERIVED_FILE_DIR,
- # and therefore SYMROOT, needs to be set at the project level.
- 'SYMROOT': '<(DEPTH)/xcodebuild',
- },
-}
diff --git a/build/common_untrusted.gypi b/build/common_untrusted.gypi
deleted file mode 100644
index bcc3686..0000000
--- a/build/common_untrusted.gypi
+++ /dev/null
@@ -1,40 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This GYP file should be included for every target in Chromium that is built
-# using the NaCl toolchain.
-{
- 'includes': [
- '../native_client/build/untrusted.gypi',
- ],
- 'target_defaults': {
- 'conditions': [
- # TODO(bradnelson): Drop this once the nacl side does the same.
- ['target_arch=="x64"', {
- 'variables': {
- 'enable_x86_32': 0,
- },
- }],
- ['target_arch=="ia32" and OS!="win"', {
- 'variables': {
- 'enable_x86_64': 0,
- },
- }],
- ['target_arch=="arm"', {
- 'variables': {
- 'clang': 1,
- },
- 'defines': [
- # Needed by build/build_config.h processor architecture detection.
- '__ARMEL__',
- # Needed by base/third_party/nspr/prtime.cc.
- '__arm__',
- # Disable ValGrind. The assembly code it generates causes the build
- # to fail.
- 'NVALGRIND',
- ],
- }],
- ],
- },
-}
diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn
index 09527af..d01496f 100644
--- a/build/config/BUILDCONFIG.gn
+++ b/build/config/BUILDCONFIG.gn
@@ -308,11 +308,6 @@
_shared_library_configs += _windows_linker_configs
} else if (is_mac) {
_shared_library_configs += [ "//build/config/mac:mac_dynamic_flags" ]
-} else if (is_android) {
- # Strip native JNI exports from shared libraries by default. Binaries that
- # want this can remove this config.
- _shared_library_configs +=
- [ "//build/config/android:hide_native_jni_exports" ]
}
set_defaults("shared_library") {
configs = _shared_library_configs
@@ -337,11 +332,7 @@
if (is_win) {
# On windows we use the same toolchain for host and target by default.
- if (is_clang) {
- host_toolchain = "//build/toolchain/win:clang_$current_cpu"
- } else {
- host_toolchain = "//build/toolchain/win:$current_cpu"
- }
+ host_toolchain = "//build/toolchain/win:$current_cpu"
set_default_toolchain("$host_toolchain")
} else if (is_android) {
if (host_os == "linux") {
diff --git a/build/config/android/BUILD.gn b/build/config/android/BUILD.gn
index 5492693..0cc38b7 100644
--- a/build/config/android/BUILD.gn
+++ b/build/config/android/BUILD.gn
@@ -25,8 +25,3 @@
cflags = [ "-fPIE" ]
ldflags = [ "-pie" ]
}
-
-config("hide_native_jni_exports") {
- ldflags = [ "-Wl,--version-script=" +
- rebase_path("//build/android/android_no_jni_exports.lst") ]
-}
diff --git a/build/config/android/OWNERS b/build/config/android/OWNERS
deleted file mode 100644
index 3759e93..0000000
--- a/build/config/android/OWNERS
+++ /dev/null
@@ -1 +0,0 @@
-cjhopman@chromium.org
diff --git a/build/config/android/config.gni b/build/config/android/config.gni
index 35ffcccf..fdabcb5 100644
--- a/build/config/android/config.gni
+++ b/build/config/android/config.gni
@@ -5,46 +5,16 @@
# This file contains common system config stuff for the Android build.
if (is_android) {
- has_chrome_android_internal =
- exec_script("//build/dir_exists.py",
- [ rebase_path("//clank", root_build_dir) ],
- "string") == "True"
-
- if (has_chrome_android_internal) {
- import("//clank/config.gni")
- }
-
if (!defined(default_android_sdk_root)) {
default_android_sdk_root = "//third_party/android_tools/sdk"
default_android_sdk_version = "22"
default_android_sdk_build_tools_version = "22.0.1"
}
- if (!defined(google_play_services_library)) {
- google_play_services_library =
- "//third_party/android_tools:google_play_services_default_java"
- }
-
declare_args() {
android_sdk_root = default_android_sdk_root
android_sdk_version = default_android_sdk_version
android_sdk_build_tools_version = default_android_sdk_build_tools_version
-
- android_default_keystore_path =
- "//build/android/ant/chromium-debug.keystore"
- android_default_keystore_name = "chromiumdebugkey"
- android_default_keystore_password = "chromium"
-
- # This is a unique identifier for a given build. It's used for
- # identifying various build artifacts corresponding to a particular build of
- # chrome (e.g. where to find archived symbols).
- android_chrome_build_id = "\"\""
-
- # Set to true to run findbugs on JAR targets.
- run_findbugs = false
-
- # Set to true to enable the Errorprone compiler
- use_errorprone_java_compiler = false
}
# Host stuff -----------------------------------------------------------------
diff --git a/build/config/android/internal_rules.gni b/build/config/android/internal_rules.gni
deleted file mode 100644
index ab154b4..0000000
--- a/build/config/android/internal_rules.gni
+++ /dev/null
@@ -1,1596 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/config/android/config.gni")
-
-assert(is_android)
-
-rebased_android_sdk = rebase_path(android_sdk, root_build_dir)
-rebased_android_sdk_root = rebase_path(android_sdk_root, root_build_dir)
-rebased_android_sdk_build_tools =
- rebase_path(android_sdk_build_tools, root_build_dir)
-
-android_sdk_jar = "$android_sdk/android.jar"
-rebased_android_sdk_jar = rebase_path(android_sdk_jar, root_build_dir)
-android_aapt_path = "$rebased_android_sdk_build_tools/aapt"
-
-template("android_lint") {
- set_sources_assignment_filter([])
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
-
- jar_path = invoker.jar_path
- android_manifest = invoker.android_manifest
- java_files = invoker.java_files
- base_path = "$target_gen_dir/$target_name"
-
- action(target_name) {
- script = "//build/android/gyp/lint.py"
- result_path = base_path + "/result.xml"
- config_path = base_path + "/config.xml"
- suppressions_file = "//build/android/lint/suppressions.xml"
- inputs = [
- suppressions_file,
- android_manifest,
- jar_path,
- ] + java_files
-
- outputs = [
- config_path,
- result_path,
- ]
-
- rebased_java_files = rebase_path(java_files, root_build_dir)
-
- args = [
- "--lint-path=$rebased_android_sdk_root/tools/lint",
- "--config-path",
- rebase_path(suppressions_file, root_build_dir),
- "--manifest-path",
- rebase_path(android_manifest, root_build_dir),
- "--product-dir=.",
- "--jar-path",
- rebase_path(jar_path, root_build_dir),
- "--processed-config-path",
- rebase_path(config_path, root_build_dir),
- "--result-path",
- rebase_path(result_path, root_build_dir),
- "--java-files=$rebased_java_files",
- "--enable",
- ]
-
- if (defined(invoker.deps)) {
- deps = invoker.deps
- }
- if (defined(invoker.public_deps)) {
- public_deps = invoker.public_deps
- }
- if (defined(invoker.data_deps)) {
- data_deps = invoker.data_deps
- }
- }
-}
-
-template("findbugs") {
- jar_path = invoker.jar_path
-
- build_config = invoker.build_config
-
- action(target_name) {
- script = "//build/android/findbugs_diff.py"
- depfile = "$target_gen_dir/$target_name.d"
- result_path = "$target_gen_dir/$target_name/result.xml"
- exclusions_file = "//build/android/findbugs_filter/findbugs_exclude.xml"
-
- rebased_build_config = rebase_path(build_config, root_build_dir)
-
- if (defined(invoker.deps)) {
- deps = invoker.deps
- }
-
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
-
- inputs = [
- "//build/android/pylib/utils/findbugs.py",
- exclusions_file,
- jar_path,
- ]
-
- outputs = [
- depfile,
- result_path,
- ]
-
- args = [
- "--depfile",
- rebase_path(depfile, root_build_dir),
- "--exclude",
- rebase_path(exclusions_file, root_build_dir),
- "--auxclasspath-gyp",
- "@FileArg($rebased_build_config:javac:classpath)",
- "--output-file",
- rebase_path(result_path, root_build_dir),
- rebase_path(jar_path, root_build_dir),
- ]
- }
-}
-
-template("dex") {
- set_sources_assignment_filter([])
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
-
- assert(defined(invoker.output))
- action(target_name) {
- script = "//build/android/gyp/dex.py"
- depfile = "$target_gen_dir/$target_name.d"
- if (defined(invoker.sources)) {
- sources = invoker.sources
- }
- outputs = [
- depfile,
- invoker.output,
- ]
- if (defined(invoker.inputs)) {
- inputs = invoker.inputs
- }
-
- if (defined(invoker.deps)) {
- deps = invoker.deps
- }
-
- rebased_output = rebase_path(invoker.output, root_build_dir)
-
- args = [
- "--depfile",
- rebase_path(depfile, root_build_dir),
- "--android-sdk-tools",
- rebased_android_sdk_build_tools,
- "--dex-path",
- rebased_output,
- ]
-
- if (defined(invoker.no_locals) && invoker.no_locals) {
- args += [ "--no-locals=1" ]
- }
-
- if (defined(invoker.args)) {
- args += invoker.args
- }
-
- if (defined(invoker.sources)) {
- args += rebase_path(invoker.sources, root_build_dir)
- }
- }
-}
-
-# Creates a zip archive of the inputs.
-# If base_dir is provided, the archive paths will be relative to it.
-template("zip") {
- set_sources_assignment_filter([])
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
-
- assert(defined(invoker.inputs))
- assert(defined(invoker.output))
-
- rebase_inputs = rebase_path(invoker.inputs, root_build_dir)
- rebase_output = rebase_path(invoker.output, root_build_dir)
- action(target_name) {
- script = "//build/android/gn/zip.py"
- depfile = "$target_gen_dir/$target_name.d"
- inputs = invoker.inputs
- outputs = [
- depfile,
- invoker.output,
- ]
- args = [
- "--depfile",
- rebase_path(depfile, root_build_dir),
- "--inputs=$rebase_inputs",
- "--output=$rebase_output",
- ]
- if (defined(invoker.base_dir)) {
- args += [
- "--base-dir",
- rebase_path(invoker.base_dir, root_build_dir),
- ]
- }
-
- if (defined(invoker.deps)) {
- deps = invoker.deps
- }
- if (defined(invoker.public_deps)) {
- public_deps = invoker.public_deps
- }
- if (defined(invoker.data_deps)) {
- data_deps = invoker.data_deps
- }
-
- if (defined(invoker.visibility)) {
- visibility = invoker.visibility
- }
- }
-}
-
-# Write the target's .build_config file. This is a json file that contains a
-# dictionary of information about how to build this target (things that
-# require knowledge about this target's dependencies and cannot be calculated
-# at gn-time). There is a special syntax to add a value in that dictionary to
-# an action/action_foreachs args:
-# --python-arg=@FileArg($rebased_build_config_path:key0:key1)
-# At runtime, such an arg will be replaced by the value in the build_config.
-# See build/android/gyp/write_build_config.py and
-# build/android/gyp/util/build_utils.py:ExpandFileArgs
-template("write_build_config") {
- set_sources_assignment_filter([])
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
-
- assert(defined(invoker.type))
- assert(defined(invoker.build_config))
-
- type = invoker.type
- build_config = invoker.build_config
-
- assert(type == "android_apk" || type == "java_library" ||
- type == "android_resources" || type == "deps_dex")
-
- action(target_name) {
- if (defined(invoker.visibility)) {
- visibility = invoker.visibility
- }
-
- script = "//build/android/gyp/write_build_config.py"
- depfile = "$target_gen_dir/$target_name.d"
- inputs = []
-
- deps = []
- if (defined(invoker.deps)) {
- deps += invoker.deps
- }
-
- possible_deps_configs = []
- foreach(d, deps) {
- dep_gen_dir = get_label_info(d, "target_gen_dir")
- dep_name = get_label_info(d, "name")
- possible_deps_configs += [ "$dep_gen_dir/$dep_name.build_config" ]
- }
- rebase_possible_deps_configs =
- rebase_path(possible_deps_configs, root_build_dir)
-
- outputs = [
- depfile,
- build_config,
- ]
-
- args = [
- "--type",
- type,
- "--depfile",
- rebase_path(depfile, root_build_dir),
- "--possible-deps-configs=$rebase_possible_deps_configs",
- "--build-config",
- rebase_path(build_config, root_build_dir),
- ]
-
- is_java_library = type == "java_library"
- is_apk = type == "android_apk"
- is_android_resources = type == "android_resources"
- is_deps_dex = type == "deps_dex"
-
- supports_android = is_apk || is_android_resources || is_deps_dex ||
- (is_java_library && defined(invoker.supports_android) &&
- invoker.supports_android)
- requires_android = is_apk || is_android_resources || is_deps_dex ||
- (is_java_library && defined(invoker.requires_android) &&
- invoker.requires_android)
-
- assert(!requires_android || supports_android,
- "requires_android requires" + " supports_android")
-
- # Mark these variables as used.
- assert(is_java_library || true)
- assert(is_apk || true)
- assert(is_android_resources || true)
- assert(is_deps_dex || true)
-
- if (is_java_library || is_apk) {
- args += [
- "--jar-path",
- rebase_path(invoker.jar_path, root_build_dir),
- ]
- }
-
- if (is_apk || is_deps_dex || (is_java_library && supports_android)) {
- args += [
- "--dex-path",
- rebase_path(invoker.dex_path, root_build_dir),
- ]
- }
- if (supports_android) {
- args += [ "--supports-android" ]
- }
- if (requires_android) {
- args += [ "--requires-android" ]
- }
- if (defined(invoker.bypass_platform_checks) &&
- invoker.bypass_platform_checks) {
- args += [ "--bypass-platform-checks" ]
- }
-
- if (defined(invoker.apk_under_test)) {
- deps += [ invoker.apk_under_test ]
- apk_under_test_gen_dir =
- get_label_info(invoker.apk_under_test, "target_gen_dir")
- apk_under_test_name = get_label_info(invoker.apk_under_test, "name")
- apk_under_test_config =
- "$apk_under_test_gen_dir/$apk_under_test_name.build_config"
- args += [
- "--tested-apk-config",
- rebase_path(apk_under_test_config, root_build_dir),
- ]
- }
-
- if (is_android_resources || is_apk) {
- assert(defined(invoker.resources_zip))
- args += [
- "--resources-zip",
- rebase_path(invoker.resources_zip, root_build_dir),
- ]
- if (defined(invoker.android_manifest)) {
- inputs += [ invoker.android_manifest ]
- args += [
- "--android-manifest",
- rebase_path(invoker.android_manifest, root_build_dir),
- ]
- } else {
- assert(!is_apk, "apk build configs require an android_manifest")
- }
- if (defined(invoker.custom_package)) {
- args += [
- "--package-name",
- invoker.custom_package,
- ]
- }
- if (defined(invoker.r_text)) {
- args += [
- "--r-text",
- rebase_path(invoker.r_text, root_build_dir),
- ]
- }
- }
-
- if (is_apk) {
- if (defined(invoker.native_libs)) {
- inputs += invoker.native_libs
- rebased_native_libs = rebase_path(invoker.native_libs, root_build_dir)
- rebased_android_readelf = rebase_path(android_readelf, root_build_dir)
- args += [
- "--native-libs=$rebased_native_libs",
- "--readelf-path=$rebased_android_readelf",
- ]
- }
- }
-
- if (defined(invoker.srcjar)) {
- args += [
- "--srcjar",
- rebase_path(invoker.srcjar, root_build_dir),
- ]
- }
- }
-}
-
-template("process_java_prebuilt") {
- set_sources_assignment_filter([])
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
-
- _input_jar_path = invoker.input_jar_path
- _output_jar_path = invoker.output_jar_path
- _jar_toc_path = _output_jar_path + ".TOC"
-
- assert(invoker.build_config != "")
-
- if (defined(invoker.proguard_preprocess) && invoker.proguard_preprocess) {
- _proguard_jar_path = "$android_sdk_root/tools/proguard/lib/proguard.jar"
- _proguard_config_path = invoker.proguard_config
- _build_config = invoker.build_config
- _rebased_build_config = rebase_path(_build_config, root_build_dir)
- _output_jar_target = "${target_name}__proguard_process"
- action(_output_jar_target) {
- script = "//build/android/gyp/proguard.py"
- inputs = [
- android_sdk_jar,
- _proguard_jar_path,
- _build_config,
- _input_jar_path,
- _proguard_config_path,
- ]
- depfile = "${target_gen_dir}/${target_name}.d"
- outputs = [
- depfile,
- _output_jar_path,
- ]
- args = [
- "--depfile",
- rebase_path(depfile, root_build_dir),
- "--proguard-path",
- rebase_path(_proguard_jar_path, root_build_dir),
- "--input-path",
- rebase_path(_input_jar_path, root_build_dir),
- "--output-path",
- rebase_path(_output_jar_path, root_build_dir),
- "--proguard-config",
- rebase_path(_proguard_config_path, root_build_dir),
- "--classpath",
- rebased_android_sdk_jar,
- "--classpath=@FileArg($_rebased_build_config:javac:classpath)",
- ]
-
- if (defined(invoker.deps)) {
- deps = invoker.deps
- }
- if (defined(invoker.public_deps)) {
- public_deps = invoker.public_deps
- }
- if (defined(invoker.data_deps)) {
- data_deps = invoker.data_deps
- }
- }
- } else {
- _output_jar_target = "${target_name}__copy_jar"
- copy(_output_jar_target) {
- sources = [
- _input_jar_path,
- ]
- outputs = [
- _output_jar_path,
- ]
-
- if (defined(invoker.deps)) {
- deps = invoker.deps
- }
- if (defined(invoker.public_deps)) {
- public_deps = invoker.public_deps
- }
- if (defined(invoker.data_deps)) {
- data_deps = invoker.data_deps
- }
- }
- }
-
- action("${target_name}__jar_toc") {
- script = "//build/android/gyp/jar_toc.py"
- depfile = "$target_gen_dir/$target_name.d"
- outputs = [
- depfile,
- _jar_toc_path,
- _jar_toc_path + ".md5.stamp",
- ]
- inputs = [
- _output_jar_path,
- ]
- args = [
- "--depfile",
- rebase_path(depfile, root_build_dir),
- "--jar-path",
- rebase_path(_output_jar_path, root_build_dir),
- "--toc-path",
- rebase_path(_jar_toc_path, root_build_dir),
- ]
- public_deps = [
- ":$_output_jar_target",
- ]
- }
-
- group(target_name) {
- if (defined(invoker.visibility)) {
- visibility = invoker.visibility
- }
- public_deps = [
- ":${target_name}__jar_toc",
- ":$_output_jar_target",
- ]
- }
-}
-
-template("finalize_apk") {
- action(target_name) {
- script = "//build/android/gyp/finalize_apk.py"
- depfile = "$target_gen_dir/$target_name.d"
-
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
-
- sources = [
- invoker.input_apk_path,
- ]
- inputs = [
- invoker.keystore_path,
- ]
- outputs = [
- depfile,
- invoker.output_apk_path,
- ]
-
- args = [
- "--depfile",
- rebase_path(depfile, root_build_dir),
- "--zipalign-path",
- rebase_path(zipalign_path, root_build_dir),
- "--unsigned-apk-path",
- rebase_path(invoker.input_apk_path, root_build_dir),
- "--final-apk-path",
- rebase_path(invoker.output_apk_path, root_build_dir),
- "--key-path",
- rebase_path(invoker.keystore_path, root_build_dir),
- "--key-name",
- invoker.keystore_name,
- "--key-passwd",
- invoker.keystore_password,
- ]
- if (defined(invoker.rezip_apk) && invoker.rezip_apk) {
- _rezip_jar_path = "$root_build_dir/lib.java/rezip_apk.jar"
- inputs += [ _rezip_jar_path ]
- args += [
- "--load-library-from-zip=1",
- "--rezip-apk-jar-path",
- rebase_path(_rezip_jar_path, root_build_dir),
- ]
- }
-
- if (defined(invoker.deps)) {
- deps = invoker.deps
- }
- if (defined(invoker.public_deps)) {
- public_deps = invoker.public_deps
- }
- if (defined(invoker.data_deps)) {
- data_deps = invoker.data_deps
- }
- }
-}
-
-# Packages resources, assets, dex, and native libraries into an apk. Signs and
-# zipaligns the apk.
-template("create_apk") {
- set_sources_assignment_filter([])
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
-
- _android_manifest = invoker.android_manifest
- _base_path = invoker.base_path
- _final_apk_path = invoker.apk_path
-
- if (defined(invoker.resources_zip)) {
- _resources_zip = invoker.resources_zip
- }
- if (defined(invoker.dex_path)) {
- _dex_path = invoker.dex_path
- }
- _load_library_from_apk = invoker.load_library_from_apk
-
- _package_deps = []
- if (defined(invoker.deps)) {
- _package_deps = invoker.deps
- }
-
- _native_libs_dir = "//build/android/empty/res"
- if (defined(invoker.native_libs_dir)) {
- _native_libs_dir = invoker.native_libs_dir
- }
-
- if (defined(invoker.asset_location)) {
- _asset_location = invoker.asset_location
- }
-
- _version_code = invoker.version_code
- _version_name = invoker.version_name
-
- _base_apk_path = _base_path + ".apk_intermediates"
-
- _resource_packaged_apk_path = _base_apk_path + ".ap_"
- _packaged_apk_path = _base_apk_path + ".unfinished.apk"
- _shared_resources =
- defined(invoker.shared_resources) && invoker.shared_resources
-
- _configuration_name = "Release"
- if (is_debug) {
- _configuration_name = "Debug"
- }
-
- _keystore_path = invoker.keystore_path
- _keystore_name = invoker.keystore_name
- _keystore_password = invoker.keystore_password
-
- _split_densities = []
- if (defined(invoker.create_density_splits) && invoker.create_density_splits) {
- _split_densities = [
- "hdpi",
- "xhdpi",
- "xxhdpi",
- "xxxhdpi",
- "tvdpi",
- ]
- }
-
- _split_languages = []
- if (defined(invoker.language_splits)) {
- _split_languages = invoker.language_splits
- }
-
- _package_resources_target_name = "${target_name}__package_resources"
- action(_package_resources_target_name) {
- deps = _package_deps
-
- script = "//build/android/gyp/package_resources.py"
- depfile = "${target_gen_dir}/${target_name}.d"
- inputs = [
- _android_manifest,
- ]
- if (defined(_resources_zip)) {
- inputs += [ _resources_zip ]
- }
- outputs = [
- depfile,
- _resource_packaged_apk_path,
- ]
-
- args = [
- "--depfile",
- rebase_path(depfile, root_build_dir),
- "--android-sdk",
- rebased_android_sdk,
- "--aapt-path",
- android_aapt_path,
- "--configuration-name=$_configuration_name",
- "--android-manifest",
- rebase_path(_android_manifest, root_build_dir),
- "--version-code",
- _version_code,
- "--version-name",
- _version_name,
- "--apk-path",
- rebase_path(_resource_packaged_apk_path, root_build_dir),
- ]
-
- if (defined(_asset_location)) {
- args += [
- "--asset-dir",
- rebase_path(_asset_location, root_build_dir),
- ]
- }
- if (defined(_resources_zip)) {
- args += [
- "--resource-zips",
- rebase_path(_resources_zip, root_build_dir),
- ]
- }
- if (_shared_resources) {
- args += [ "--shared-resources" ]
- }
- if (_split_densities != []) {
- args += [ "--create-density-splits" ]
- foreach(_density, _split_densities) {
- outputs += [ "${_resource_packaged_apk_path}_${_density}" ]
- }
- }
- if (_split_languages != []) {
- args += [ "--language-splits=$_split_languages" ]
- foreach(_language, _split_languages) {
- outputs += [ "${_resource_packaged_apk_path}_${_language}" ]
- }
- }
- if (defined(invoker.extensions_to_not_compress)) {
- args += [
- "--no-compress",
- invoker.extensions_to_not_compress,
- ]
- }
- }
-
- package_target = "${target_name}__package"
- action(package_target) {
- script = "//build/android/gyp/ant.py"
- _ant_script = "//build/android/ant/apk-package.xml"
-
- deps = [
- ":${_package_resources_target_name}",
- ]
- if (defined(invoker.deps)) {
- deps += invoker.deps
- }
- depfile = "$target_gen_dir/$target_name.d"
-
- inputs = [
- _resource_packaged_apk_path,
- _ant_script,
- ]
- if (defined(_dex_path)) {
- inputs += [ _dex_path ]
- }
-
- outputs = [
- depfile,
- _packaged_apk_path,
- ]
-
- _rebased_emma_jar = ""
- _rebased_resource_packaged_apk_path =
- rebase_path(_resource_packaged_apk_path, root_build_dir)
- _rebased_packaged_apk_path = rebase_path(_packaged_apk_path, root_build_dir)
- _rebased_native_libs_dir = rebase_path(_native_libs_dir, root_build_dir)
- args = [
- "--depfile",
- rebase_path(depfile, root_build_dir),
- "--",
- "-quiet",
- "-DANDROID_SDK_ROOT=$rebased_android_sdk_root",
- "-DANDROID_SDK_TOOLS=$rebased_android_sdk_build_tools",
- "-DRESOURCE_PACKAGED_APK_NAME=$_rebased_resource_packaged_apk_path",
- "-DCONFIGURATION_NAME=$_configuration_name",
- "-DNATIVE_LIBS_DIR=$_rebased_native_libs_dir",
- "-DOUT_DIR=",
- "-DUNSIGNED_APK_PATH=$_rebased_packaged_apk_path",
- "-DEMMA_INSTRUMENT=0",
- "-DEMMA_DEVICE_JAR=$_rebased_emma_jar",
- "-Dbasedir=.",
- "-buildfile",
- rebase_path(_ant_script, root_build_dir),
- ]
- if (defined(_dex_path)) {
- _rebased_dex_path = rebase_path(_dex_path, root_build_dir)
- args += [
- "-DDEX_FILE_PATH=$_rebased_dex_path",
- "-DHAS_CODE=true",
- ]
- } else {
- args += [ "-DHAS_CODE=false" ]
- }
- }
-
- _finalize_apk_rule_name = "${target_name}__finalize"
- finalize_apk(_finalize_apk_rule_name) {
- input_apk_path = _packaged_apk_path
- output_apk_path = _final_apk_path
- keystore_path = _keystore_path
- keystore_name = _keystore_name
- keystore_password = _keystore_password
- rezip_apk = _load_library_from_apk
-
- public_deps = [
- # Generator of the _packaged_apk_path this target takes as input.
- ":$package_target",
- ]
- }
-
- _final_deps = [ ":${_finalize_apk_rule_name}" ]
-
- template("finalize_split") {
- finalize_apk(target_name) {
- _config = invoker.split_config
- _type = invoker.split_type
- input_apk_path = "${_resource_packaged_apk_path}_${_config}"
- _output_paths = process_file_template(
- [ _final_apk_path ],
- "{{source_dir}}/{{source_name_part}}-${_type}-${_config}.apk")
- output_apk_path = _output_paths[0]
- keystore_path = _keystore_path
- keystore_name = _keystore_name
- keystore_password = _keystore_password
- deps = [
- ":${_package_resources_target_name}",
- ]
- }
- }
-
- foreach(_split, _split_densities) {
- _split_rule = "${target_name}__finalize_${_split}_split"
- finalize_split(_split_rule) {
- split_type = "density"
- split_config = _split
- }
- _final_deps += [ ":$_split_rule" ]
- }
- foreach(_split, _split_languages) {
- _split_rule = "${target_name}__finalize_${_split}_split"
- finalize_split(_split_rule) {
- split_type = "lang"
- split_config = _split
- }
- _final_deps += [ ":$_split_rule" ]
- }
-
- group(target_name) {
- public_deps = _final_deps
- }
-}
-
-template("java_prebuilt_impl") {
- set_sources_assignment_filter([])
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
- _supports_android =
- defined(invoker.supports_android) && invoker.supports_android
-
- assert(defined(invoker.jar_path))
- _base_path = "${target_gen_dir}/$target_name"
- _jar_path = _base_path + ".jar"
- _build_config = _base_path + ".build_config"
-
- if (_supports_android) {
- _dex_path = _base_path + ".dex.jar"
- }
- _deps = []
- if (defined(invoker.deps)) {
- _deps = invoker.deps
- }
- _jar_deps = []
- if (defined(invoker.jar_dep)) {
- _jar_deps = [ invoker.jar_dep ]
- }
-
- _template_name = target_name
-
- build_config_target_name = "${_template_name}__build_config"
- process_jar_target_name = "${_template_name}__process_jar"
- if (_supports_android) {
- dex_target_name = "${_template_name}__dex"
- }
-
- write_build_config(build_config_target_name) {
- type = "java_library"
- supports_android = _supports_android
- requires_android =
- defined(invoker.requires_android) && invoker.requires_android
-
- deps = _deps
- build_config = _build_config
- jar_path = _jar_path
- if (_supports_android) {
- dex_path = _dex_path
- }
- }
-
- process_java_prebuilt(process_jar_target_name) {
- visibility = [ ":$_template_name" ]
- if (_supports_android) {
- visibility += [ ":$dex_target_name" ]
- }
-
- if (defined(invoker.proguard_preprocess) && invoker.proguard_preprocess) {
- proguard_preprocess = true
- proguard_config = invoker.proguard_config
- }
-
- build_config = _build_config
- input_jar_path = invoker.jar_path
- output_jar_path = _jar_path
-
- deps = [ ":$build_config_target_name" ] + _deps + _jar_deps
- }
-
- if (_supports_android) {
- dex(dex_target_name) {
- sources = [
- _jar_path,
- ]
- output = _dex_path
- deps = [ ":$process_jar_target_name" ] + _deps + _jar_deps
- }
- }
-
- group(target_name) {
- deps = [
- ":$process_jar_target_name",
- ]
- if (defined(invoker.data_deps)) {
- data_deps = invoker.data_deps
- }
- if (_supports_android) {
- deps += [ ":$dex_target_name" ]
- }
- }
-}
-
-# Compiles and jars a set of java files.
-#
-# Outputs:
-# $jar_path.jar
-# $jar_path.jar.TOC
-#
-# Variables
-# java_files: List of .java files to compile.
-# java_deps: List of java dependencies. These should all have a .jar output
-# at "${target_gen_dir}/${target_name}.jar.
-# chromium_code: If true, enable extra warnings.
-# srcjar_deps: List of srcjar dependencies. The .java files contained in the
-# dependencies srcjar outputs will be compiled and added to the output jar.
-# jar_path: Use this to explicitly set the output jar path. Defaults to
-# "${target_gen_dir}/${target_name}.jar.
-template("compile_java") {
- set_sources_assignment_filter([])
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
-
- assert(defined(invoker.java_files))
- assert(defined(invoker.build_config))
- assert(defined(invoker.jar_path))
-
- _java_files = invoker.java_files
- _final_jar_path = invoker.jar_path
- _intermediate_jar_path = "$target_gen_dir/$target_name.initial.jar"
-
- _build_config = invoker.build_config
-
- _jar_excluded_patterns = []
- if (defined(invoker.jar_excluded_patterns)) {
- _jar_excluded_patterns += invoker.jar_excluded_patterns
- }
-
- _chromium_code = false
- if (defined(invoker.chromium_code)) {
- _chromium_code = invoker.chromium_code
- }
-
- _supports_android = true
- if (defined(invoker.supports_android)) {
- _supports_android = invoker.supports_android
- }
-
- _enable_errorprone = use_errorprone_java_compiler
- if (defined(invoker.enable_errorprone)) {
- _enable_errorprone = invoker.enable_errorprone
- }
-
- _manifest_entries = []
- if (defined(invoker.manifest_entries)) {
- _manifest_entries = invoker.manifest_entries
- }
-
- _srcjar_deps = []
- if (defined(invoker.srcjar_deps)) {
- _srcjar_deps += invoker.srcjar_deps
- }
-
- _java_srcjars = []
- if (defined(invoker.srcjars)) {
- _java_srcjars = invoker.srcjars
- }
- foreach(dep, _srcjar_deps) {
- _dep_gen_dir = get_label_info(dep, "target_gen_dir")
- _dep_name = get_label_info(dep, "name")
- _java_srcjars += [ "$_dep_gen_dir/$_dep_name.srcjar" ]
- }
-
- # Mark srcjar_deps as used.
- assert(_srcjar_deps == [] || true)
-
- _system_jars = []
- if (defined(invoker.android) && invoker.android) {
- _system_jars += [ android_sdk_jar ]
- }
-
- _rebased_build_config = rebase_path(_build_config, root_build_dir)
- _rebased_jar_path = rebase_path(_intermediate_jar_path, root_build_dir)
-
- javac_target_name = "${target_name}__javac"
- finish_target_name = "${target_name}__finish"
- final_target_name = target_name
-
- action(javac_target_name) {
- script = "//build/android/gyp/javac.py"
- depfile = "$target_gen_dir/$target_name.d"
- deps = _srcjar_deps
- if (defined(invoker.deps)) {
- deps += invoker.deps
- }
-
- outputs = [
- depfile,
- _intermediate_jar_path,
- _intermediate_jar_path + ".md5.stamp",
- ]
- sources = _java_files + _java_srcjars
- inputs = _system_jars + [ _build_config ]
-
- _rebased_system_jars = rebase_path(_system_jars, root_build_dir)
- _rebased_java_srcjars = rebase_path(_java_srcjars, root_build_dir)
- _rebased_depfile = rebase_path(depfile, root_build_dir)
- args = [
- "--depfile=$_rebased_depfile",
- "--classpath=$_rebased_system_jars",
- "--classpath=@FileArg($_rebased_build_config:javac:classpath)",
- "--jar-path=$_rebased_jar_path",
- "--java-srcjars=$_rebased_java_srcjars",
- "--java-srcjars=@FileArg($_rebased_build_config:javac:srcjars)",
- "--jar-excluded-classes=$_jar_excluded_patterns",
- ]
- if (_supports_android) {
- _rebased_android_sdk_jar = rebase_path(android_sdk_jar, root_build_dir)
- args += [ "--bootclasspath=$_rebased_android_sdk_jar" ]
- }
- foreach(e, _manifest_entries) {
- args += [ "--manifest-entry=" + e ]
- }
- if (_chromium_code) {
- args += [ "--chromium-code=1" ]
- }
- if (_enable_errorprone) {
- deps += [ "//third_party/errorprone:chromium_errorprone" ]
- args += [
- "--use-errorprone-path",
- "bin/chromium_errorprone",
- ]
- }
- args += rebase_path(_java_files, root_build_dir)
- }
-
- process_java_prebuilt(finish_target_name) {
- visibility = [ ":$final_target_name" ]
-
- build_config = _build_config
- input_jar_path = _intermediate_jar_path
- output_jar_path = _final_jar_path
- if (defined(invoker.proguard_preprocess) && invoker.proguard_preprocess) {
- proguard_preprocess = invoker.proguard_preprocess
- proguard_config = invoker.proguard_config
- }
- deps = [
- ":$javac_target_name",
- ]
- }
-
- group(final_target_name) {
- if (defined(invoker.visibility)) {
- visibility = invoker.visibility
- }
- public_deps = [
- ":$finish_target_name",
- ]
- }
-}
-
-template("java_library_impl") {
- set_sources_assignment_filter([])
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
-
- assert(
- defined(invoker.java_files) || defined(invoker.DEPRECATED_java_in_dir) ||
- defined(invoker.srcjars) || defined(invoker.srcjar_deps))
- _base_path = "$target_gen_dir/$target_name"
- _jar_path = _base_path + ".jar"
- if (defined(invoker.jar_path)) {
- _jar_path = invoker.jar_path
- }
- _template_name = target_name
-
- _final_deps = []
- _final_datadeps = []
- if (defined(invoker.datadeps)) {
- _final_datadeps = invoker.datadeps
- }
-
- _supports_android =
- defined(invoker.supports_android) && invoker.supports_android
- _requires_android =
- defined(invoker.requires_android) && invoker.requires_android
-
- if (_supports_android) {
- _dex_path = _base_path + ".dex.jar"
- if (defined(invoker.dex_path)) {
- _dex_path = invoker.dex_path
- }
- }
-
- # Define build_config_deps which will be a list of targets required to
- # build the _build_config.
- if (defined(invoker.override_build_config)) {
- _build_config = invoker.override_build_config
-
- # When a custom build config file is specified, we need to use the deps
- # supplied by the invoker any time we reference the build config file.
- assert(defined(invoker.deps),
- "If you specify a build config file for " +
- "java_library_impl($target_name), you should " +
- "also specify the target that made it in the deps")
- build_config_deps = invoker.deps
- } else {
- _build_config = _base_path + ".build_config"
- build_config_target_name = "${_template_name}__build_config"
- build_config_deps = [ ":$build_config_target_name" ]
-
- write_build_config(build_config_target_name) {
- type = "java_library"
- supports_android = _supports_android
- requires_android = _requires_android
- bypass_platform_checks = defined(invoker.bypass_platform_checks) &&
- invoker.bypass_platform_checks
-
- deps = []
- if (defined(invoker.deps)) {
- deps += invoker.deps
- }
-
- build_config = _build_config
- jar_path = _jar_path
- if (_supports_android) {
- dex_path = _dex_path
- }
- }
- }
-
- _chromium_code = true
- if (defined(invoker.chromium_code)) {
- _chromium_code = invoker.chromium_code
- }
-
- _srcjar_deps = []
- if (defined(invoker.srcjar_deps)) {
- _srcjar_deps = invoker.srcjar_deps
- }
-
- _srcjars = []
- if (defined(invoker.srcjars)) {
- _srcjars = invoker.srcjars
- }
-
- _java_files = []
- if (defined(invoker.java_files)) {
- _java_files = invoker.java_files
- } else if (defined(invoker.DEPRECATED_java_in_dir)) {
- _src_dir = invoker.DEPRECATED_java_in_dir + "/src"
- _src_dir_exists = exec_script("//build/dir_exists.py",
- [ rebase_path(_src_dir, root_build_dir) ],
- "string")
- assert(_src_dir_exists == "False",
- "In GN, java_in_dir should be the fully specified java directory " +
- "(i.e. including the trailing \"/src\")")
-
- _java_files_build_rel = exec_script(
- "//build/android/gyp/find.py",
- [
- "--pattern",
- "*.java",
- rebase_path(invoker.DEPRECATED_java_in_dir, root_build_dir),
- ],
- "list lines")
- _java_files = rebase_path(_java_files_build_rel, ".", root_build_dir)
- }
- assert(_java_files != [] || _srcjar_deps != [] || _srcjars != [])
-
- _compile_java_target = "${_template_name}__compile_java"
- _final_deps += [ ":$_compile_java_target" ]
- compile_java(_compile_java_target) {
- jar_path = _jar_path
- build_config = _build_config
- java_files = _java_files
- srcjar_deps = _srcjar_deps
- srcjars = _srcjars
- chromium_code = _chromium_code
- android = _requires_android
-
- if (defined(invoker.enable_errorprone)) {
- enable_errorprone = invoker.enable_errorprone
- }
- if (defined(invoker.jar_excluded_patterns)) {
- jar_excluded_patterns = invoker.jar_excluded_patterns
- }
- if (defined(invoker.proguard_preprocess)) {
- proguard_preprocess = invoker.proguard_preprocess
- }
- if (defined(invoker.proguard_config)) {
- proguard_config = invoker.proguard_config
- }
- if (defined(invoker.dist_jar_path)) {
- dist_jar_path = invoker.dist_jar_path
- }
- if (defined(invoker.manifest_entries)) {
- manifest_entries = invoker.manifest_entries
- }
-
- supports_android = _supports_android
- deps = build_config_deps
- }
-
- if (defined(invoker.main_class)) {
- _final_deps += [ ":${_template_name}__binary_script" ]
- action("${_template_name}__binary_script") {
- script = "//build/android/gyp/create_java_binary_script.py"
- depfile = "$target_gen_dir/$target_name.d"
- java_script = "$root_build_dir/bin/$_template_name"
- inputs = [
- _build_config,
- ]
- outputs = [
- depfile,
- java_script,
- ]
- _rebased_build_config = rebase_path(_build_config, root_build_dir)
- args = [
- "--depfile",
- rebase_path(depfile, root_build_dir),
- "--output",
- rebase_path(java_script, root_build_dir),
- "--classpath=@FileArg($_rebased_build_config:java:full_classpath)",
- "--jar-path",
- rebase_path(_jar_path, root_build_dir),
- "--main-class",
- invoker.main_class,
- ]
-
- deps = build_config_deps
- }
- }
-
- if (_supports_android) {
- if (defined(invoker.chromium_code) && invoker.chromium_code) {
- _android_manifest = "//build/android/AndroidManifest.xml"
- if (defined(invoker.android_manifest)) {
- _android_manifest = invoker.android_manifest
- }
-
- _final_datadeps += [ ":${_template_name}__lint" ]
- android_lint("${_template_name}__lint") {
- android_manifest = _android_manifest
- jar_path = _jar_path
- java_files = _java_files
- deps = [
- ":$_compile_java_target",
- ]
- if (defined(invoker.deps)) {
- deps += invoker.deps
- }
- }
-
- if (run_findbugs) {
- _final_datadeps += [ ":${_template_name}__findbugs" ]
- findbugs("${_template_name}__findbugs") {
- build_config = _build_config
- jar_path = _jar_path
- deps = build_config_deps
- }
- }
- }
-
- _final_deps += [ ":${_template_name}__dex" ]
- dex("${_template_name}__dex") {
- sources = [
- _jar_path,
- ]
- output = _dex_path
- deps = [
- ":$_compile_java_target",
- ]
- }
- }
-
- group(target_name) {
- if (defined(invoker.visibility)) {
- visibility = invoker.visibility
- }
- public_deps = _final_deps
- data_deps = _final_datadeps
- }
-}
-
-# Runs process_resources.py
-template("process_resources") {
- set_sources_assignment_filter([])
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
-
- zip_path = invoker.zip_path
- srcjar_path = invoker.srcjar_path
- r_text_path = invoker.r_text_path
- build_config = invoker.build_config
- resource_dirs = invoker.resource_dirs
- android_manifest = invoker.android_manifest
-
- non_constant_id = true
- if (defined(invoker.generate_constant_ids) && invoker.generate_constant_ids) {
- non_constant_id = false
- }
-
- action(target_name) {
- if (defined(invoker.visibility)) {
- visibility = invoker.visibility
- }
-
- script = "//build/android/gyp/process_resources.py"
-
- depfile = "$target_gen_dir/$target_name.d"
- outputs = [
- depfile,
- zip_path,
- srcjar_path,
- r_text_path,
- ]
-
- sources_build_rel = exec_script("//build/android/gyp/find.py",
- rebase_path(resource_dirs, root_build_dir),
- "list lines")
- sources = rebase_path(sources_build_rel, ".", root_build_dir)
-
- inputs = [
- build_config,
- android_manifest,
- ]
-
- rebase_resource_dirs = rebase_path(resource_dirs, root_build_dir)
- rebase_build_config = rebase_path(build_config, root_build_dir)
- args = [
- "--depfile",
- rebase_path(depfile, root_build_dir),
- "--android-sdk",
- rebase_path(android_sdk, root_build_dir),
- "--aapt-path",
- android_aapt_path,
- "--android-manifest",
- rebase_path(android_manifest, root_build_dir),
- "--resource-dirs=$rebase_resource_dirs",
- "--srcjar-out",
- rebase_path(srcjar_path, root_build_dir),
- "--resource-zip-out",
- rebase_path(zip_path, root_build_dir),
- "--r-text-out",
- rebase_path(r_text_path, root_build_dir),
- "--dependencies-res-zips=@FileArg($rebase_build_config:resources:dependency_zips)",
- "--extra-res-packages=@FileArg($rebase_build_config:resources:extra_package_names)",
- "--extra-r-text-files=@FileArg($rebase_build_config:resources:extra_r_text_files)",
- ]
-
- if (non_constant_id) {
- args += [ "--non-constant-id" ]
- }
-
- if (defined(invoker.custom_package)) {
- args += [
- "--custom-package",
- invoker.custom_package,
- ]
- }
-
- if (defined(invoker.v14_skip) && invoker.v14_skip) {
- args += [ "--v14-skip" ]
- }
-
- if (defined(invoker.shared_resources) && invoker.shared_resources) {
- args += [ "--shared-resources" ]
- }
-
- if (defined(invoker.include_all_resources) &&
- invoker.include_all_resources) {
- args += [ "--include-all-resources" ]
- }
-
- if (defined(invoker.all_resources_zip_path)) {
- all_resources_zip = invoker.all_resources_zip_path
- outputs += [ all_resources_zip ]
- args += [
- "--all-resources-zip-out",
- rebase_path(all_resources_zip, root_build_dir),
- ]
- }
-
- if (defined(invoker.args)) {
- args += invoker.args
- }
- if (defined(invoker.deps)) {
- deps = invoker.deps
- }
- }
-}
-
-template("copy_ex") {
- set_sources_assignment_filter([])
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
-
- action(target_name) {
- if (defined(invoker.visibility)) {
- visibility = invoker.visibility
- }
-
- script = "//build/android/gyp/copy_ex.py"
-
- if (defined(invoker.deps)) {
- deps = invoker.deps
- }
-
- sources = []
- if (defined(invoker.sources)) {
- sources += invoker.sources
- }
-
- inputs = []
- if (defined(invoker.inputs)) {
- inputs += invoker.inputs
- }
-
- depfile = "$target_gen_dir/$target_name.d"
- outputs = [
- depfile,
- ]
-
- args = [
- "--depfile",
- rebase_path(depfile, root_build_dir),
- "--dest",
- rebase_path(invoker.dest, root_build_dir),
- ]
- rebased_sources = rebase_path(sources, root_build_dir)
- args += [ "--files=$rebased_sources" ]
-
- if (defined(invoker.clear_dir) && invoker.clear_dir) {
- args += [ "--clear" ]
- }
-
- if (defined(invoker.args)) {
- args += invoker.args
- }
- }
-}
-
-# Produces a single .dex.jar out of a set of Java dependencies.
-template("deps_dex") {
- set_sources_assignment_filter([])
- build_config = "$target_gen_dir/${target_name}.build_config"
- build_config_target_name = "${target_name}__build_config"
-
- write_build_config(build_config_target_name) {
- type = "deps_dex"
- deps = invoker.deps
-
- build_config = build_config
- dex_path = invoker.dex_path
- }
-
- rebased_build_config = rebase_path(build_config, root_build_dir)
- dex(target_name) {
- inputs = [
- build_config,
- ]
- output = invoker.dex_path
- dex_arg_key = "${rebased_build_config}:final_dex:dependency_dex_files"
- args = [ "--inputs=@FileArg($dex_arg_key)" ]
- if (defined(invoker.excluded_jars)) {
- excluded_jars = rebase_path(invoker.excluded_jars, root_build_dir)
- args += [ "--excluded-paths=${excluded_jars}" ]
- }
- deps = [
- ":$build_config_target_name",
- ]
- }
-}
-
-# Creates an AndroidManifest.xml for an APK split.
-template("generate_split_manifest") {
- assert(defined(invoker.main_manifest))
- assert(defined(invoker.out_manifest))
- assert(defined(invoker.split_name))
-
- action(target_name) {
- depfile = "$target_gen_dir/$target_name.d"
- if (defined(invoker.deps)) {
- deps = invoker.deps
- }
- args = [
- "--main-manifest",
- rebase_path(invoker.main_manifest, root_build_dir),
- "--out-manifest",
- rebase_path(invoker.out_manifest, root_build_dir),
- "--split",
- invoker.split_name,
- ]
- if (defined(invoker.version_code)) {
- args += [
- "--version-code",
- invoker.version_code,
- ]
- }
- if (defined(invoker.version_name)) {
- args += [
- "--version-name",
- invoker.version_name,
- ]
- }
- if (defined(invoker.has_code)) {
- args += [
- "--has-code",
- invoker.has_code,
- ]
- }
- args += [
- "--depfile",
- rebase_path(depfile, root_build_dir),
- ]
-
- script = "//build/android/gyp/generate_split_manifest.py"
- outputs = [
- depfile,
- invoker.out_manifest,
- ]
- inputs = [
- invoker.main_manifest,
- ]
- }
-}
-
-# Generates a script in the output bin directory which runs the test
-# target using the test runner script in build/android/test_runner.py.
-template("test_runner_script") {
- testonly = true
- _test_name = invoker.test_name
- _test_type = invoker.test_type
-
- action(target_name) {
- script = "//build/android/gyp/create_test_runner_script.py"
- depfile = "$target_gen_dir/$target_name.d"
-
- test_runner_args = [
- _test_type,
- "--output-directory",
- rebase_path(root_build_dir, root_build_dir),
- ]
- if (_test_type == "gtest") {
- assert(defined(invoker.test_suite))
- test_runner_args += [
- "--suite",
- invoker.test_suite,
- ]
- } else if (_test_type == "instrumentation") {
- assert(defined(invoker.test_apk))
- test_runner_args += [
- "--test-apk",
- invoker.test_apk,
- ]
- if (defined(invoker.support_apk_path)) {
- test_runner_args += [
- "--support-apk",
- rebase_path(invoker.support_apk_path, root_build_dir),
- ]
- }
- } else {
- assert(false, "Invalid test type: $_test_type.")
- }
-
- if (defined(invoker.isolate_file)) {
- test_runner_args += [
- "--isolate-file-path",
- rebase_path(invoker.isolate_file, root_build_dir),
- ]
- }
-
- generated_script = "$root_build_dir/bin/run_${_test_name}"
- outputs = [
- depfile,
- generated_script,
- ]
- args = [
- "--depfile",
- rebase_path(depfile, root_build_dir),
- "--script-output-path",
- rebase_path(generated_script, root_build_dir),
- ]
- args += test_runner_args
- }
-}
diff --git a/build/config/android/rules.gni b/build/config/android/rules.gni
deleted file mode 100644
index 3c8640b..0000000
--- a/build/config/android/rules.gni
+++ /dev/null
@@ -1,2238 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//base/android/linker/config.gni")
-import("//build/config/android/config.gni")
-import("//build/config/android/internal_rules.gni")
-import("//third_party/android_platform/config.gni")
-import("//tools/grit/grit_rule.gni")
-
-assert(is_android)
-
-# Declare a jni target
-#
-# This target generates the native jni bindings for a set of .java files.
-#
-# See base/android/jni_generator/jni_generator.py for more info about the
-# format of generating JNI bindings.
-#
-# Variables
-# sources: list of .java files to generate jni for
-# jni_package: subdirectory path for generated bindings
-#
-# Example
-# generate_jni("foo_jni") {
-# sources = [
-# "android/java/src/org/chromium/foo/Foo.java",
-# "android/java/src/org/chromium/foo/FooUtil.java",
-# ]
-# jni_package = "foo"
-# }
-template("generate_jni") {
- set_sources_assignment_filter([])
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
-
- assert(defined(invoker.sources))
- assert(defined(invoker.jni_package))
- jni_package = invoker.jni_package
- base_output_dir = "${target_gen_dir}/${target_name}"
- package_output_dir = "${base_output_dir}/${jni_package}"
- jni_output_dir = "${package_output_dir}/jni"
-
- jni_generator_include = "//base/android/jni_generator/jni_generator_helper.h"
-
- foreach_target_name = "${target_name}__jni_gen"
- action_foreach(foreach_target_name) {
- script = "//base/android/jni_generator/jni_generator.py"
- depfile = "$target_gen_dir/$target_name.{{source_name_part}}.d"
- sources = invoker.sources
- outputs = [
- depfile,
- "${jni_output_dir}/{{source_name_part}}_jni.h",
- ]
-
- args = [
- "--depfile",
- rebase_path(depfile, root_build_dir),
- "--input_file={{source}}",
- "--optimize_generation=1",
- "--ptr_type=long",
- "--output_dir",
- rebase_path(jni_output_dir, root_build_dir),
- "--includes",
- rebase_path(jni_generator_include, jni_output_dir),
- "--native_exports_optional",
- ]
- if (defined(invoker.jni_generator_jarjar_file)) {
- args += [
- "--jarjar",
- rebase_path(jni_generator_jarjar_file, root_build_dir),
- ]
- }
- }
-
- config("jni_includes_${target_name}") {
- # TODO(cjhopman): #includes should probably all be relative to
- # base_output_dir. Remove that from this config once the includes are
- # updated.
- include_dirs = [
- base_output_dir,
- package_output_dir,
- ]
- }
-
- group(target_name) {
- deps = [
- ":$foreach_target_name",
- ]
- public_configs = [ ":jni_includes_${target_name}" ]
-
- if (defined(invoker.deps)) {
- deps += invoker.deps
- }
- if (defined(invoker.public_deps)) {
- public_deps = invoker.public_deps
- }
-
- if (defined(invoker.visibility)) {
- visibility = invoker.visibility
- }
- }
-}
-
-# Declare a jni target for a prebuilt jar
-#
-# This target generates the native jni bindings for a set of classes in a .jar.
-#
-# See base/android/jni_generator/jni_generator.py for more info about the
-# format of generating JNI bindings.
-#
-# Variables
-# classes: list of .class files in the jar to generate jni for. These should
-# include the full path to the .class file.
-# jni_package: subdirectory path for generated bindings
-# jar_file: the path to the .jar. If not provided, will default to the sdk's
-# android.jar
-#
-# deps, public_deps: As normal
-#
-# Example
-# generate_jar_jni("foo_jni") {
-# classes = [
-# "android/view/Foo.class",
-# ]
-# jni_package = "foo"
-# }
-template("generate_jar_jni") {
- set_sources_assignment_filter([])
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
-
- assert(defined(invoker.classes))
- assert(defined(invoker.jni_package))
-
- if (defined(invoker.jar_file)) {
- jar_file = invoker.jar_file
- } else {
- jar_file = android_sdk_jar
- }
-
- jni_package = invoker.jni_package
- base_output_dir = "${root_gen_dir}/${target_name}/${jni_package}"
- jni_output_dir = "${base_output_dir}/jni"
-
- jni_generator_include = "//base/android/jni_generator/jni_generator_helper.h"
-
- # TODO(cjhopman): make jni_generator.py support generating jni for multiple
- # .class files from a .jar.
- jni_actions = []
- foreach(class, invoker.classes) {
- _classname_list = []
- _classname_list = process_file_template([ class ], "{{source_name_part}}")
- classname = _classname_list[0]
- jni_target_name = "${target_name}__jni_${classname}"
- jni_actions += [ ":$jni_target_name" ]
- action(jni_target_name) {
- # The sources aren't compiled so don't check their dependencies.
- check_includes = false
- depfile = "$target_gen_dir/$target_name.d"
- script = "//base/android/jni_generator/jni_generator.py"
- sources = [
- jar_file,
- ]
- outputs = [
- depfile,
- "${jni_output_dir}/${classname}_jni.h",
- ]
-
- args = [
- "--depfile",
- rebase_path(depfile, root_build_dir),
- "--jar_file",
- rebase_path(jar_file, root_build_dir),
- "--input_file",
- class,
- "--optimize_generation=1",
- "--ptr_type=long",
- "--output_dir",
- rebase_path(jni_output_dir, root_build_dir),
- "--includes",
- rebase_path(jni_generator_include, jni_output_dir),
- "--native_exports_optional",
- ]
- }
- }
-
- config("jni_includes_${target_name}") {
- include_dirs = [ base_output_dir ]
- }
-
- group(target_name) {
- deps = jni_actions
- if (defined(invoker.deps)) {
- deps += invoker.deps
- }
- if (defined(invoker.public_deps)) {
- public_deps = invoker.public_deps
- }
- public_configs = [ ":jni_includes_${target_name}" ]
- }
-}
-
-# Declare a target for c-preprocessor-generated java files
-#
-# NOTE: For generating Java conterparts to enums prefer using the java_cpp_enum
-# rule instead.
-#
-# This target generates java files using the host C pre-processor. Each file in
-# sources will be compiled using the C pre-processor. If include_path is
-# specified, it will be passed (with --I) to the pre-processor.
-#
-# This target will create a single .srcjar. Adding this target to an
-# android_library target's srcjar_deps will make the generated java files be
-# included in that library's final outputs.
-#
-# Variables
-# sources: list of files to be processed by the C pre-processor. For each
-# file in sources, there will be one .java file in the final .srcjar. For a
-# file named FooBar.template, a java file will be created with name
-# FooBar.java.
-# inputs: additional compile-time dependencies. Any files
-# `#include`-ed in the templates should be listed here.
-# package_name: this will be the subdirectory for each .java file in the
-# .srcjar.
-#
-# Example
-# java_cpp_template("foo_generated_enum") {
-# sources = [
-# "android/java/templates/Foo.template",
-# ]
-# inputs = [
-# "android/java/templates/native_foo_header.h",
-# ]
-#
-# package_name = "org/chromium/base/library_loader"
-# include_path = "android/java/templates"
-# }
-template("java_cpp_template") {
- set_sources_assignment_filter([])
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
-
- assert(defined(invoker.sources))
- package_name = invoker.package_name + ""
-
- if (defined(invoker.include_path)) {
- include_path = invoker.include_path + ""
- } else {
- include_path = "//"
- }
-
- apply_gcc_target_name = "${target_name}__apply_gcc"
- zip_srcjar_target_name = "${target_name}__zip_srcjar"
- final_target_name = target_name
-
- action_foreach(apply_gcc_target_name) {
- visibility = [ ":$zip_srcjar_target_name" ]
- script = "//build/android/gyp/gcc_preprocess.py"
- if (defined(invoker.inputs)) {
- inputs = invoker.inputs + []
- }
- depfile = "${target_gen_dir}/${target_name}_{{source_name_part}}.d"
-
- sources = invoker.sources
-
- if (defined(invoker.deps)) {
- deps = invoker.deps
- }
- if (defined(invoker.public_deps)) {
- public_deps = invoker.public_deps
- }
- if (defined(invoker.data_deps)) {
- data_deps = invoker.data_deps
- }
-
- gen_dir =
- "${target_gen_dir}/${target_name}/java_cpp_template/${package_name}"
- gcc_template_output_pattern = "${gen_dir}/{{source_name_part}}.java"
-
- outputs = [
- depfile,
- gcc_template_output_pattern,
- ]
-
- args = [
- "--depfile",
- rebase_path(depfile, root_build_dir),
- "--include-path",
- rebase_path(include_path, root_build_dir),
- "--output",
- rebase_path(gen_dir, root_build_dir) + "/{{source_name_part}}.java",
- "--template={{source}}",
- ]
-
- if (defined(invoker.defines)) {
- foreach(def, invoker.defines) {
- args += [
- "--defines",
- def,
- ]
- }
- }
- }
-
- apply_gcc_outputs = get_target_outputs(":$apply_gcc_target_name")
- base_gen_dir = get_label_info(":$apply_gcc_target_name", "target_gen_dir")
-
- srcjar_path = "${target_gen_dir}/${target_name}.srcjar"
- zip(zip_srcjar_target_name) {
- visibility = [ ":$final_target_name" ]
- inputs = apply_gcc_outputs
- output = srcjar_path
- base_dir = base_gen_dir
- deps = [
- ":$apply_gcc_target_name",
- ]
- }
-
- group(final_target_name) {
- if (defined(invoker.visibility)) {
- visibility = invoker.visibility
- }
- deps = [
- ":$zip_srcjar_target_name",
- ]
- }
-}
-
-# Declare a target for generating Java classes from C++ enums.
-#
-# This target generates Java files from C++ enums using a script.
-#
-# This target will create a single .srcjar. Adding this target to an
-# android_library target's srcjar_deps will make the generated java files be
-# included in that library's final outputs.
-#
-# Variables
-# sources: list of files to be processed by the script. For each annotated
-# enum contained in the sources files the script will generate a .java
-# file with the same name as the name of the enum.
-#
-# outputs: list of outputs, relative to the output_dir. These paths are
-# verified at build time by the script. To get the list programatically run:
-# python build/android/gyp/java_cpp_enum.py \
-# --print_output_only . path/to/header/file.h
-#
-# Example
-# java_cpp_enum("foo_generated_enum") {
-# sources = [
-# "src/native_foo_header.h",
-# ]
-# outputs = [
-# "org/chromium/FooEnum.java",
-# ]
-# }
-template("java_cpp_enum") {
- set_sources_assignment_filter([])
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
-
- assert(defined(invoker.sources))
- assert(defined(invoker.outputs))
-
- generate_enum_target_name = "${target_name}__generate_enum"
- zip_srcjar_target_name = "${target_name}__zip_srcjar"
- final_target_name = target_name
-
- action(generate_enum_target_name) {
- visibility = [ ":$zip_srcjar_target_name" ]
-
- # The sources aren't compiled so don't check their dependencies.
- check_includes = false
-
- sources = invoker.sources
- script = "//build/android/gyp/java_cpp_enum.py"
- gen_dir = "${target_gen_dir}/${target_name}/enums"
- outputs =
- get_path_info(rebase_path(invoker.outputs, ".", gen_dir), "abspath")
-
- args = []
- foreach(output, rebase_path(outputs, root_build_dir)) {
- args += [
- "--assert_file",
- output,
- ]
- }
- args += [ rebase_path(gen_dir, root_build_dir) ]
- args += rebase_path(invoker.sources, root_build_dir)
- }
-
- generate_enum_outputs = get_target_outputs(":$generate_enum_target_name")
- base_gen_dir = get_label_info(":$generate_enum_target_name", "target_gen_dir")
-
- srcjar_path = "${target_gen_dir}/${target_name}.srcjar"
- zip(zip_srcjar_target_name) {
- visibility = [ ":$final_target_name" ]
- inputs = generate_enum_outputs
- output = srcjar_path
- base_dir = base_gen_dir
- deps = [
- ":$generate_enum_target_name",
- ]
- }
-
- group(final_target_name) {
- if (defined(invoker.visibility)) {
- visibility = invoker.visibility
- }
- deps = [
- ":$zip_srcjar_target_name",
- ]
- }
-}
-
-# Declare a target for processing Android resources as Jinja templates.
-#
-# This takes an Android resource directory where each resource is a Jinja
-# template, processes each template, then packages the results in a zip file
-# which can be consumed by an android resources, library, or apk target.
-#
-# If this target is included in the deps of an android resources/library/apk,
-# the resources will be included with that target.
-#
-# Variables
-# resources: The list of resources files to process.
-# res_dir: The resource directory containing the resources.
-# variables: (Optional) A list of variables to make available to the template
-# processing environment, e.g. ["name=foo", "color=red"].
-#
-# Example
-# jinja_template_resources("chrome_shell_template_resources") {
-# res_dir = "shell/res_template"
-# resources = ["shell/res_template/xml/syncable.xml"]
-# variables = ["color=red"]
-# }
-template("jinja_template_resources") {
- set_sources_assignment_filter([])
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
-
- assert(defined(invoker.resources))
- assert(defined(invoker.res_dir))
-
- _base_path = "$target_gen_dir/$target_name"
- _resources_zip = _base_path + ".resources.zip"
- _build_config = _base_path + ".build_config"
-
- write_build_config("${target_name}__build_config") {
- build_config = _build_config
- resources_zip = _resources_zip
- type = "android_resources"
- }
-
- action("${target_name}__template") {
- sources = invoker.resources
- script = "//build/android/gyp/jinja_template.py"
- depfile = "$target_gen_dir/$target_name.d"
-
- outputs = [
- depfile,
- _resources_zip,
- ]
-
- rebased_resources = rebase_path(invoker.resources, root_build_dir)
- args = [
- "--inputs=${rebased_resources}",
- "--inputs-base-dir",
- rebase_path(invoker.res_dir, root_build_dir),
- "--outputs-zip",
- rebase_path(_resources_zip, root_build_dir),
- "--depfile",
- rebase_path(depfile, root_build_dir),
- ]
- if (defined(invoker.variables)) {
- variables = invoker.variables
- args += [ "--variables=${variables}" ]
- }
- }
-
- group(target_name) {
- deps = [
- ":${target_name}__build_config",
- ":${target_name}__template",
- ]
- }
-}
-
-# Creates a resources.zip with locale.pak files placed into appropriate
-# resource configs (e.g. en-GB.pak -> res/raw-en/en_gb.pak). Also generates
-# a locale_paks TypedArray so that resource files can be enumerated at runtime.
-#
-# If this target is included in the deps of an android resources/library/apk,
-# the resources will be included with that target.
-#
-# Variables:
-# sources: List of .pak files. Names must be of the form "en.pak" or
-# "en-US.pak".
-# deps: (optional) List of dependencies that might be needed to generate
-# the .pak files.
-#
-# Example
-# locale_pak_resources("locale_paks") {
-# sources = [ "path/en-US.pak", "path/fr.pak", ... ]
-# }
-template("locale_pak_resources") {
- set_sources_assignment_filter([])
- assert(defined(invoker.sources))
-
- _base_path = "$target_gen_dir/$target_name"
- _resources_zip = _base_path + ".resources.zip"
- _build_config = _base_path + ".build_config"
-
- write_build_config("${target_name}__build_config") {
- build_config = _build_config
- resources_zip = _resources_zip
- type = "android_resources"
- }
-
- action("${target_name}__create_resources_zip") {
- sources = invoker.sources
- script = "//build/android/gyp/locale_pak_resources.py"
- depfile = "$target_gen_dir/$target_name.d"
-
- outputs = [
- depfile,
- _resources_zip,
- ]
-
- _rebased_sources = rebase_path(invoker.sources, root_build_dir)
- args = [
- "--locale-paks=${_rebased_sources}",
- "--resources-zip",
- rebase_path(_resources_zip, root_build_dir),
- "--depfile",
- rebase_path(depfile, root_build_dir),
- ]
-
- if (defined(invoker.deps)) {
- deps = invoker.deps
- }
- }
-
- group(target_name) {
- deps = [
- ":${target_name}__build_config",
- ":${target_name}__create_resources_zip",
- ]
- }
-}
-
-# Declare an Android resources target
-#
-# This creates a resources zip file that will be used when building an Android
-# library or apk and included into a final apk.
-#
-# To include these resources in a library/apk, this target should be listed in
-# the library's deps. A library/apk will also include any resources used by its
-# own dependencies.
-#
-# Variables
-# deps: Specifies the dependencies of this target. Any Android resources
-# listed in deps will be included by libraries/apks that depend on this
-# target.
-# resource_dirs: List of directories containing resources for this target.
-# android_manifest: AndroidManifest.xml for this target. Defaults to
-# //build/android/AndroidManifest.xml.
-# custom_package: java package for generated .java files.
-# v14_skip: If true, don't run v14 resource generator on this. Defaults to
-# false. (see build/android/gyp/generate_v14_compatible_resources.py)
-#
-# shared_resources: If true make a resource package that can be loaded by a
-# different application at runtime to access the package's resources.
-#
-
-# Example
-# android_resources("foo_resources") {
-# deps = [":foo_strings_grd"]
-# resource_dirs = ["res"]
-# custom_package = "org.chromium.foo"
-# }
-template("android_resources") {
- set_sources_assignment_filter([])
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
-
- assert(defined(invoker.resource_dirs))
- assert(defined(invoker.android_manifest) || defined(invoker.custom_package))
-
- base_path = "$target_gen_dir/$target_name"
- zip_path = base_path + ".resources.zip"
- srcjar_path = base_path + ".srcjar"
- r_text_path = base_path + "_R.txt"
- build_config = base_path + ".build_config"
-
- build_config_target_name = "${target_name}__build_config"
- process_resources_target_name = "${target_name}__process_resources"
- final_target_name = target_name
-
- write_build_config(build_config_target_name) {
- visibility = [ ":$process_resources_target_name" ]
-
- type = "android_resources"
- resources_zip = zip_path
- srcjar = srcjar_path
- r_text = r_text_path
- if (defined(invoker.deps)) {
- deps = invoker.deps
- }
- if (defined(invoker.android_manifest)) {
- android_manifest = invoker.android_manifest
- }
- if (defined(invoker.custom_package)) {
- custom_package = invoker.custom_package
- }
- }
-
- android_manifest = "//build/android/AndroidManifest.xml"
- if (defined(invoker.android_manifest)) {
- android_manifest = invoker.android_manifest
- }
-
- process_resources(process_resources_target_name) {
- visibility = [ ":$final_target_name" ]
-
- resource_dirs = invoker.resource_dirs
- if (defined(invoker.custom_package)) {
- custom_package = invoker.custom_package
- }
-
- if (defined(invoker.v14_skip)) {
- v14_skip = invoker.v14_skip
- }
-
- if (defined(invoker.shared_resources)) {
- shared_resources = invoker.shared_resources
- }
-
- deps = [
- ":$build_config_target_name",
- ]
- if (defined(invoker.deps)) {
- # Invoker may have added deps that generate the input resources.
- deps += invoker.deps
- }
- }
-
- group(final_target_name) {
- if (defined(invoker.visibility)) {
- visibility = invoker.visibility
- }
- deps = [
- ":${target_name}__process_resources",
- ]
- }
-}
-
-# Declare a target that generates localized strings.xml from a .grd file.
-#
-# If this target is included in the deps of an android resources/library/apk,
-# the strings.xml will be included with that target.
-#
-# Variables
-# deps: Specifies the dependencies of this target.
-# grd_file: Path to the .grd file to generate strings.xml from.
-# outputs: Expected grit outputs (see grit rule).
-#
-# Example
-# java_strings_grd("foo_strings_grd") {
-# grd_file = "foo_strings.grd"
-# }
-template("java_strings_grd") {
- set_sources_assignment_filter([])
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
-
- base_path = "$target_gen_dir/$target_name"
- resources_zip = base_path + ".resources.zip"
- build_config = base_path + ".build_config"
-
- write_build_config("${target_name}__build_config") {
- type = "android_resources"
- if (defined(invoker.deps)) {
- deps = invoker.deps
- }
- }
-
- # Put grit files into this subdirectory of target_gen_dir.
- extra_output_path = target_name + "_grit_output"
-
- grit_target_name = "${target_name}__grit"
- grit_output_dir = "$target_gen_dir/$extra_output_path"
- grit(grit_target_name) {
- grit_flags = [
- "-E",
- "ANDROID_JAVA_TAGGED_ONLY=false",
- ]
- output_dir = grit_output_dir
- resource_ids = ""
- source = invoker.grd_file
- outputs = invoker.outputs
- }
-
- # This needs to get outputs from grit's internal target, not the final
- # source_set.
- generate_strings_outputs = get_target_outputs(":${grit_target_name}_grit")
-
- zip("${target_name}__zip") {
- base_dir = grit_output_dir
- inputs = generate_strings_outputs
- output = resources_zip
- deps = [
- ":$grit_target_name",
- ]
- }
-
- group(target_name) {
- deps = [
- ":${target_name}__build_config",
- ":${target_name}__zip",
- ]
- }
-}
-
-# Declare a target that packages strings.xml generated from a grd file.
-#
-# If this target is included in the deps of an android resources/library/apk,
-# the strings.xml will be included with that target.
-#
-# Variables
-# grit_output_dir: directory containing grit-generated files.
-# generated_files: list of android resource files to package.
-#
-# Example
-# java_strings_grd_prebuilt("foo_strings_grd") {
-# grit_output_dir = "$root_gen_dir/foo/grit"
-# generated_files = [
-# "values/strings.xml"
-# ]
-# }
-template("java_strings_grd_prebuilt") {
- set_sources_assignment_filter([])
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
-
- base_path = "$target_gen_dir/$target_name"
- resources_zip = base_path + ".resources.zip"
- build_config = base_path + ".build_config"
-
- build_config_target_name = "${target_name}__build_config"
- zip_target_name = "${target_name}__zip"
- final_target_name = target_name
-
- write_build_config(build_config_target_name) {
- visibility = [ ":$zip_target_name" ]
- type = "android_resources"
- }
-
- zip(zip_target_name) {
- visibility = [ ":$final_target_name" ]
-
- base_dir = invoker.grit_output_dir
- inputs = rebase_path(invoker.generated_files, ".", base_dir)
- output = resources_zip
- deps = [
- ":$build_config_target_name",
- ]
- if (defined(invoker.deps)) {
- deps += invoker.deps
- }
- }
-
- group(final_target_name) {
- if (defined(invoker.visibility)) {
- visibility = invoker.visibility
- }
- deps = [
- ":$zip_target_name",
- ]
- }
-}
-
-# Declare a Java executable target
-#
-# This target creates an executable from java code and libraries. The executable
-# will be in the output folder's /bin/ directory.
-#
-# Variables
-# deps: Specifies the dependencies of this target. Java targets in this list
-# will be included in the executable (and the javac classpath).
-#
-# java_files: List of .java files included in this library.
-# srcjar_deps: List of srcjar dependencies. The .java files in the srcjars
-# will be added to java_files and be included in this library.
-# srcjars: List of srcjars to be included in this library, together with the
-# ones obtained from srcjar_deps.
-#
-# bypass_platform_checks: Disables checks about cross-platform (Java/Android)
-# dependencies for this target. This will allow depending on an
-# android_library target, for example.
-#
-# chromium_code: If true, extra analysis warning/errors will be enabled.
-# enable_errorprone: If true, enables the errorprone compiler.
-#
-# data_deps, testonly
-#
-# Example
-# java_binary("foo") {
-# java_files = [ "org/chromium/foo/FooMain.java" ]
-# deps = [ ":bar_java" ]
-# main_class = "org.chromium.foo.FooMain"
-# }
-template("java_binary") {
- set_sources_assignment_filter([])
-
- # TODO(cjhopman): This should not act like a java_library for dependents (i.e.
- # dependents shouldn't get the jar in their classpath, etc.).
- java_library_impl(target_name) {
- if (defined(invoker.DEPRECATED_java_in_dir)) {
- DEPRECATED_java_in_dir = invoker.DEPRECATED_java_in_dir
- }
- if (defined(invoker.chromium_code)) {
- chromium_code = invoker.chromium_code
- }
- if (defined(invoker.data_deps)) {
- deps = invoker.data_deps
- }
- if (defined(invoker.deps)) {
- deps = invoker.deps
- }
- if (defined(invoker.enable_errorprone)) {
- enable_errorprone = invoker.enable_errorprone
- }
- if (defined(invoker.java_files)) {
- java_files = invoker.java_files
- }
- if (defined(invoker.srcjar_deps)) {
- srcjar_deps = invoker.srcjar_deps
- }
- if (defined(invoker.srcjars)) {
- srcjars = invoker.srcjars
- }
- if (defined(invoker.bypass_platform_checks)) {
- bypass_platform_checks = invoker.bypass_platform_checks
- }
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
-
- supports_android = false
- main_class = invoker.main_class
- }
-}
-
-# Declare a Junit executable target
-#
-# This target creates an executable from java code for running as a junit test
-# suite. The executable will be in the output folder's /bin/ directory.
-#
-# Variables
-# deps: Specifies the dependencies of this target. Java targets in this list
-# will be included in the executable (and the javac classpath).
-#
-# java_files: List of .java files included in this library.
-# srcjar_deps: List of srcjar dependencies. The .java files in the srcjars
-# will be added to java_files and be included in this library.
-# srcjars: List of srcjars to be included in this library, together with the
-# ones obtained from srcjar_deps.
-#
-# chromium_code: If true, extra analysis warning/errors will be enabled.
-#
-# Example
-# junit_binary("foo") {
-# java_files = [ "org/chromium/foo/FooTest.java" ]
-# deps = [ ":bar_java" ]
-# }
-template("junit_binary") {
- set_sources_assignment_filter([])
-
- java_binary(target_name) {
- bypass_platform_checks = true
- main_class = "org.chromium.testing.local.JunitTestMain"
- testonly = true
-
- if (defined(invoker.DEPRECATED_java_in_dir)) {
- DEPRECATED_java_in_dir = invoker.DEPRECATED_java_in_dir
- }
- if (defined(invoker.chromium_code)) {
- chromium_code = invoker.chromium_code
- }
- deps = [
- "//testing/android/junit:junit_test_support",
- "//third_party/junit",
- "//third_party/mockito:mockito_java",
- "//third_party/robolectric:robolectric_java",
- "//third_party/robolectric:android-all-4.3_r2-robolectric-0",
- ]
- if (defined(invoker.deps)) {
- deps += invoker.deps
- }
- if (defined(invoker.java_files)) {
- java_files = invoker.java_files
- }
- if (defined(invoker.srcjar_deps)) {
- srcjar_deps = invoker.srcjar_deps
- }
- if (defined(invoker.srcjars)) {
- srcjars = invoker.srcjars
- }
- }
-}
-
-# Declare a java library target
-#
-# Variables
-# deps: Specifies the dependencies of this target. Java targets in this list
-# will be added to the javac classpath.
-#
-# java_files: List of .java files included in this library.
-# srcjar_deps: List of srcjar dependencies. The .java files in the srcjars
-# will be added to java_files and be included in this library.
-# srcjars: List of srcjars to be included in this library, together with the
-# ones obtained from srcjar_deps.
-# DEPRECATED_java_in_dir: Directory containing java files. All .java files in
-# this directory will be included in the library. This is only supported to
-# ease the gyp->gn conversion and will be removed in the future.
-#
-# chromium_code: If true, extra analysis warning/errors will be enabled.
-# enable_errorprone: If true, enables the errorprone compiler.
-#
-# jar_excluded_patterns: List of patterns of .class files to exclude from the
-# final jar.
-#
-# proguard_preprocess: If true, proguard preprocessing will be run. This can
-# be used to remove unwanted parts of the library.
-# proguard_config: Path to the proguard config for preprocessing.
-#
-# supports_android: If true, Android targets (android_library, android_apk)
-# may depend on this target. Note: if true, this target must only use the
-# subset of Java available on Android.
-# bypass_platform_checks: Disables checks about cross-platform (Java/Android)
-# dependencies for this target. This will allow depending on an
-# android_library target, for example.
-#
-# data_deps, testonly
-#
-# Example
-# java_library("foo_java") {
-# java_files = [
-# "org/chromium/foo/Foo.java",
-# "org/chromium/foo/FooInterface.java",
-# "org/chromium/foo/FooService.java",
-# ]
-# deps = [
-# ":bar_java"
-# ]
-# srcjar_deps = [
-# ":foo_generated_enum"
-# ]
-# jar_excluded_patterns = [
-# "*/FooService.class", "*/FooService##*.class"
-# ]
-# }
-template("java_library") {
- set_sources_assignment_filter([])
- java_library_impl(target_name) {
- if (defined(invoker.DEPRECATED_java_in_dir)) {
- DEPRECATED_java_in_dir = invoker.DEPRECATED_java_in_dir
- }
- if (defined(invoker.chromium_code)) {
- chromium_code = invoker.chromium_code
- }
- if (defined(invoker.data_deps)) {
- deps = invoker.data_deps
- }
- if (defined(invoker.deps)) {
- deps = invoker.deps
- }
- if (defined(invoker.enable_errorprone)) {
- enable_errorprone = invoker.enable_errorprone
- }
- if (defined(invoker.jar_excluded_patterns)) {
- jar_excluded_patterns = invoker.jar_excluded_patterns
- }
- if (defined(invoker.java_files)) {
- java_files = invoker.java_files
- }
- if (defined(invoker.proguard_config)) {
- proguard_config = invoker.proguard_config
- }
- if (defined(invoker.proguard_preprocess)) {
- proguard_preprocess = invoker.proguard_preprocess
- }
- if (defined(invoker.srcjar_deps)) {
- srcjar_deps = invoker.srcjar_deps
- }
- if (defined(invoker.srcjars)) {
- srcjars = invoker.srcjars
- }
- if (defined(invoker.bypass_platform_checks)) {
- bypass_platform_checks = invoker.bypass_platform_checks
- }
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
- if (defined(invoker.jar_path)) {
- jar_path = invoker.jar_path
- }
-
- if (defined(invoker.supports_android) && invoker.supports_android) {
- supports_android = true
- }
- }
-}
-
-# Declare a java library target for a prebuilt jar
-#
-# Variables
-# deps: Specifies the dependencies of this target. Java targets in this list
-# will be added to the javac classpath.
-# jar_path: Path to the prebuilt jar.
-# jar_dep: Target that builds jar_path (optional).
-# proguard_preprocess: If true, proguard preprocessing will be run. This can
-# be used to remove unwanted parts of the library.
-# proguard_config: Path to the proguard config for preprocessing.
-#
-# Example
-# java_prebuilt("foo_java") {
-# jar_path = "foo.jar"
-# deps = [
-# ":foo_resources",
-# ":bar_java"
-# ]
-# }
-template("java_prebuilt") {
- set_sources_assignment_filter([])
- java_prebuilt_impl(target_name) {
- jar_path = invoker.jar_path
- if (defined(invoker.jar_dep)) {
- jar_dep = invoker.jar_dep
- }
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
- if (defined(invoker.deps)) {
- deps = invoker.deps
- }
- if (defined(invoker.data_deps)) {
- data_deps = invoker.data_deps
- }
- if (defined(invoker.proguard_config)) {
- proguard_config = invoker.proguard_config
- }
- if (defined(invoker.proguard_preprocess)) {
- proguard_preprocess = invoker.proguard_preprocess
- }
- }
-}
-
-# Declare an Android library target
-#
-# This target creates an Android library containing java code and Android
-# resources.
-#
-# Variables
-# deps: Specifies the dependencies of this target. Java targets in this list
-# will be added to the javac classpath. Android resources in dependencies
-# will be used when building this library.
-#
-# java_files: List of .java files included in this library.
-# srcjar_deps: List of srcjar dependencies. The .java files in the srcjars
-# will be added to java_files and be included in this library.
-# srcjars: List of srcjars to be included in this library, together with the
-# ones obtained from srcjar_deps.
-# DEPRECATED_java_in_dir: Directory containing java files. All .java files in
-# this directory will be included in the library. This is only supported to
-# ease the gyp->gn conversion and will be removed in the future.
-#
-# chromium_code: If true, extra analysis warning/errors will be enabled.
-# enable_errorprone: If true, enables the errorprone compiler.
-#
-# jar_excluded_patterns: List of patterns of .class files to exclude from the
-# final jar.
-#
-# proguard_preprocess: If true, proguard preprocessing will be run. This can
-# be used to remove unwanted parts of the library.
-# proguard_config: Path to the proguard config for preprocessing.
-#
-# dex_path: If set, the resulting .dex.jar file will be placed under this
-# path.
-#
-#
-# Example
-# android_library("foo_java") {
-# java_files = [
-# "android/org/chromium/foo/Foo.java",
-# "android/org/chromium/foo/FooInterface.java",
-# "android/org/chromium/foo/FooService.java",
-# ]
-# deps = [
-# ":bar_java"
-# ]
-# srcjar_deps = [
-# ":foo_generated_enum"
-# ]
-# jar_excluded_patterns = [
-# "*/FooService.class", "*/FooService##*.class"
-# ]
-# }
-template("android_library") {
- set_sources_assignment_filter([])
- assert(!defined(invoker.jar_path),
- "android_library does not support a custom jar path")
- java_library_impl(target_name) {
- if (defined(invoker.DEPRECATED_java_in_dir)) {
- DEPRECATED_java_in_dir = invoker.DEPRECATED_java_in_dir
- }
- if (defined(invoker.chromium_code)) {
- chromium_code = invoker.chromium_code
- }
- if (defined(invoker.data_deps)) {
- deps = invoker.data_deps
- }
- if (defined(invoker.deps)) {
- deps = invoker.deps
- }
- if (defined(invoker.enable_errorprone)) {
- enable_errorprone = invoker.enable_errorprone
- }
- if (defined(invoker.jar_excluded_patterns)) {
- jar_excluded_patterns = invoker.jar_excluded_patterns
- }
- if (defined(invoker.java_files)) {
- java_files = invoker.java_files
- }
- if (defined(invoker.proguard_config)) {
- proguard_config = invoker.proguard_config
- }
- if (defined(invoker.proguard_preprocess)) {
- proguard_preprocess = invoker.proguard_preprocess
- }
- if (defined(invoker.srcjar_deps)) {
- srcjar_deps = invoker.srcjar_deps
- }
- if (defined(invoker.srcjars)) {
- srcjars = invoker.srcjars
- }
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
- if (defined(invoker.visibility)) {
- visibility = invoker.visibility
- }
- if (defined(invoker.dex_path)) {
- dex_path = invoker.dex_path
- }
- if (defined(invoker.manifest_entries)) {
- manifest_entries = invoker.manifest_entries
- }
-
- supports_android = true
- requires_android = true
-
- if (!defined(jar_excluded_patterns)) {
- jar_excluded_patterns = []
- }
- jar_excluded_patterns += [
- "*/R.class",
- "*/R##*.class",
- "*/Manifest.class",
- "*/Manifest##*.class",
- ]
- }
-}
-
-# Declare a target that packages a set of Java dependencies into a standalone
-# .dex.jar.
-#
-# Variables
-# deps: specifies the dependencies of this target. Android libraries in deps
-# will be packaged into the resulting .dex.jar file.
-# dex_path: location at which the output file will be put
-template("android_standalone_library") {
- set_sources_assignment_filter([])
- deps_dex(target_name) {
- deps = invoker.deps
- dex_path = invoker.dex_path
- if (defined(invoker.excluded_jars)) {
- excluded_jars = invoker.excluded_jars
- }
- }
-}
-
-# Declare an Android library target for a prebuilt jar
-#
-# This target creates an Android library containing java code and Android
-# resources.
-#
-# Variables
-# deps: Specifies the dependencies of this target. Java targets in this list
-# will be added to the javac classpath. Android resources in dependencies
-# will be used when building this library.
-# jar_path: Path to the prebuilt jar.
-# proguard_preprocess: If true, proguard preprocessing will be run. This can
-# be used to remove unwanted parts of the library.
-# proguard_config: Path to the proguard config for preprocessing.
-#
-# Example
-# android_java_prebuilt("foo_java") {
-# jar_path = "foo.jar"
-# deps = [
-# ":foo_resources",
-# ":bar_java"
-# ]
-# }
-template("android_java_prebuilt") {
- set_sources_assignment_filter([])
- java_prebuilt_impl(target_name) {
- jar_path = invoker.jar_path
- supports_android = true
- requires_android = true
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
- if (defined(invoker.deps)) {
- deps = invoker.deps
- }
- if (defined(invoker.data_deps)) {
- data_deps = invoker.data_deps
- }
- if (defined(invoker.proguard_config)) {
- proguard_config = invoker.proguard_config
- }
- if (defined(invoker.proguard_preprocess)) {
- proguard_preprocess = invoker.proguard_preprocess
- }
- }
-}
-
-# Declare an Android apk target
-#
-# This target creates an Android APK containing java code, resources, assets,
-# and (possibly) native libraries.
-#
-# Variables
-# android_manifest: Path to AndroidManifest.xml.
-# android_manifest_dep: Target that generates AndroidManifest (if applicable)
-# data_deps: List of dependencies needed at runtime. These will be built but
-# won't change the generated .apk in any way (in fact they may be built
-# after the .apk is).
-# deps: List of dependencies. All Android java resources and libraries in the
-# "transitive closure" of these dependencies will be included in the apk.
-# Note: this "transitive closure" actually only includes such targets if
-# they are depended on through android_library or android_resources targets
-# (and so not through builtin targets like 'action', 'group', etc).
-# java_files: List of .java files to include in the apk.
-# srcjar_deps: List of srcjar dependencies. The .java files in the srcjars
-# will be added to java_files and be included in this apk.
-# apk_name: Name for final apk.
-# final_apk_path: Path to final built apk. Default is
-# $root_out_dir/apks/$apk_name.apk. Setting this will override apk_name.
-# native_libs: List paths of native libraries to include in this apk. If these
-# libraries depend on other shared_library targets, those dependencies will
-# also be included in the apk.
-# apk_under_test: For an instrumentation test apk, this is the target of the
-# tested apk.
-# include_all_resources - If true include all resource IDs in all generated
-# R.java files.
-# testonly: Marks this target as "test-only".
-#
-# DEPRECATED_java_in_dir: Directory containing java files. All .java files in
-# this directory will be included in the library. This is only supported to
-# ease the gyp->gn conversion and will be removed in the future.
-#
-# Example
-# android_apk("foo_apk") {
-# android_manifest = "AndroidManifest.xml"
-# java_files = [
-# "android/org/chromium/foo/FooApplication.java",
-# "android/org/chromium/foo/FooActivity.java",
-# ]
-# deps = [
-# ":foo_support_java"
-# ":foo_resources"
-# ]
-# srcjar_deps = [
-# ":foo_generated_enum"
-# ]
-# native_libs = [
-# native_lib_path
-# ]
-# }
-template("android_apk") {
- set_sources_assignment_filter([])
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
-
- assert(defined(invoker.final_apk_path) || defined(invoker.apk_name))
- assert(defined(invoker.android_manifest))
- gen_dir = "$target_gen_dir/$target_name"
- base_path = "$gen_dir/$target_name"
- _build_config = "$target_gen_dir/$target_name.build_config"
- resources_zip_path = "$base_path.resources.zip"
- _all_resources_zip_path = "$base_path.resources.all.zip"
- jar_path = "$base_path.jar"
- _template_name = target_name
-
- final_dex_path = "$gen_dir/classes.dex"
- final_dex_target_name = "${_template_name}__final_dex"
-
- _final_apk_path = ""
- if (defined(invoker.final_apk_path)) {
- _final_apk_path = invoker.final_apk_path
- } else if (defined(invoker.apk_name)) {
- _final_apk_path = "$root_build_dir/apks/" + invoker.apk_name + ".apk"
- }
- _dist_jar_path_list =
- process_file_template(
- [ _final_apk_path ],
- "$root_build_dir/test.lib.java/{{source_name_part}}.jar")
- _dist_jar_path = _dist_jar_path_list[0]
-
- _native_libs = []
-
- _version_code = "1"
- if (defined(invoker.version_code)) {
- _version_code = invoker.version_code
- }
-
- _version_name = "Developer Build"
- if (defined(invoker.version_name)) {
- _version_name = invoker.version_name
- }
- _keystore_path = android_default_keystore_path
- _keystore_name = android_default_keystore_name
- _keystore_password = android_default_keystore_password
-
- if (defined(invoker.keystore_path)) {
- _keystore_path = invoker.keystore_path
- _keystore_name = invoker.keystore_name
- _keystore_password = invoker.keystore_password
- }
-
- _srcjar_deps = []
- if (defined(invoker.srcjar_deps)) {
- _srcjar_deps += invoker.srcjar_deps
- }
-
- _load_library_from_apk = false
-
- # The dependency that makes the chromium linker, if any is needed.
- _chromium_linker_dep = []
-
- if (defined(invoker.native_libs)) {
- _use_chromium_linker = false
- if (defined(invoker.use_chromium_linker)) {
- _use_chromium_linker =
- invoker.use_chromium_linker && chromium_linker_supported
- _chromium_linker_dep = [ "//base/android/linker:chromium_android_linker" ]
- }
-
- if (defined(invoker.load_library_from_apk) &&
- invoker.load_library_from_apk) {
- _load_library_from_apk = true
- assert(_use_chromium_linker,
- "Loading library from the apk requires use" +
- " of the Chromium linker.")
- }
-
- _enable_relocation_packing = false
- if (defined(invoker.enable_relocation_packing) &&
- invoker.enable_relocation_packing) {
- _enable_relocation_packing = relocation_packing_supported
- assert(_use_chromium_linker,
- "Relocation packing requires use of the" + " Chromium linker.")
- }
-
- if (is_component_build) {
- _native_libs += [ "$root_out_dir/lib.stripped/libc++_shared.so" ]
- _chromium_linker_dep += [ "//build/android:cpplib_stripped" ]
- }
-
- # Allow native_libs to be in the form "foo.so" or "foo.cr.so"
- _first_ext_removed =
- process_file_template(invoker.native_libs, "{{source_name_part}}")
- _native_libs += process_file_template(
- _first_ext_removed,
- "$root_build_dir/lib.stripped/{{source_name_part}}$android_product_extension")
-
- _native_libs_dir = base_path + "/libs"
-
- if (_use_chromium_linker) {
- _native_libs += [ "$root_build_dir/lib.stripped/libchromium_android_linker$android_product_extension" ]
- }
-
- _enable_relocation_packing = false
- if (_use_chromium_linker && defined(invoker.enable_relocation_packing) &&
- invoker.enable_relocation_packing) {
- _enable_relocation_packing = true
- }
-
- _native_lib_version_rule = ""
- if (defined(invoker.native_lib_version_rule)) {
- _native_lib_version_rule = invoker.native_lib_version_rule
- }
- _native_lib_version_arg = "\"\""
- if (defined(invoker.native_lib_version_arg)) {
- _native_lib_version_arg = invoker.native_lib_version_arg
- }
- }
-
- _android_manifest_deps = []
- if (defined(invoker.android_manifest_dep)) {
- _android_manifest_deps = [ invoker.android_manifest_dep ]
- }
- _android_manifest = invoker.android_manifest
-
- _rebased_build_config = rebase_path(_build_config, root_build_dir)
- _create_abi_split =
- defined(invoker.create_abi_split) && invoker.create_abi_split
- _create_density_splits =
- defined(invoker.create_density_splits) && invoker.create_density_splits
-
- # Help GN understand that _create_abi_split is not unused (bug in GN).
- assert(_create_abi_split || true)
-
- build_config_target = "${_template_name}__build_config"
- write_build_config(build_config_target) {
- type = "android_apk"
- dex_path = final_dex_path
- resources_zip = resources_zip_path
- build_config = _build_config
- android_manifest = _android_manifest
-
- deps = _chromium_linker_dep + _android_manifest_deps
- if (defined(invoker.deps)) {
- deps += invoker.deps
- }
-
- if (defined(invoker.apk_under_test)) {
- apk_under_test = invoker.apk_under_test
- }
-
- native_libs = _native_libs
- }
-
- final_deps = []
-
- process_resources_target = "${_template_name}__process_resources"
- final_deps += [ ":$process_resources_target" ]
- process_resources(process_resources_target) {
- srcjar_path = "${target_gen_dir}/${target_name}.srcjar"
- r_text_path = "${target_gen_dir}/${target_name}_R.txt"
- android_manifest = _android_manifest
- resource_dirs = [ "//build/android/ant/empty/res" ]
- zip_path = resources_zip_path
- all_resources_zip_path = _all_resources_zip_path
- generate_constant_ids = true
-
- if (defined(invoker.include_all_resources)) {
- include_all_resources = invoker.include_all_resources
- }
-
- build_config = _build_config
- deps = _android_manifest_deps + [ ":$build_config_target" ]
- if (defined(invoker.deps)) {
- deps += invoker.deps
- }
- }
- _srcjar_deps += [ ":$process_resources_target" ]
-
- if (_native_libs != []) {
- _enable_chromium_linker_tests = false
- if (defined(invoker.enable_chromium_linker_tests)) {
- _enable_chromium_linker_tests = invoker.enable_chromium_linker_tests
- }
-
- java_cpp_template("${_template_name}__native_libraries_java") {
- package_name = "org/chromium/base/library_loader"
- sources = [
- "//base/android/java/templates/NativeLibraries.template",
- ]
- inputs = [
- _build_config,
- ]
- deps = [
- ":$build_config_target",
- ]
- if (_native_lib_version_rule != "") {
- deps += [ _native_lib_version_rule ]
- }
-
- defines = [
- "NATIVE_LIBRARIES_LIST=" +
- "@FileArg($_rebased_build_config:native:java_libraries_list)",
- "NATIVE_LIBRARIES_VERSION_NUMBER=$_native_lib_version_arg",
- ]
- if (_use_chromium_linker) {
- defines += [ "ENABLE_CHROMIUM_LINKER" ]
- }
- if (_load_library_from_apk) {
- defines += [ "ENABLE_CHROMIUM_LINKER_LIBRARY_IN_ZIP_FILE" ]
- }
- if (_enable_chromium_linker_tests) {
- defines += [ "ENABLE_CHROMIUM_LINKER_TESTS" ]
- }
- }
- _srcjar_deps += [ ":${_template_name}__native_libraries_java" ]
- }
-
- java_target = "${_template_name}__java"
- final_deps += [ ":$java_target" ]
- java_library_impl(java_target) {
- supports_android = true
- requires_android = true
- override_build_config = _build_config
- deps = _android_manifest_deps + [ ":$build_config_target" ]
-
- android_manifest = _android_manifest
- chromium_code = true
- if (defined(invoker.java_files)) {
- java_files = invoker.java_files
- } else if (defined(invoker.DEPRECATED_java_in_dir)) {
- DEPRECATED_java_in_dir = invoker.DEPRECATED_java_in_dir
- } else {
- java_files = []
- }
- srcjar_deps = _srcjar_deps
- dex_path = base_path + ".dex.jar"
-
- if (defined(invoker.deps)) {
- deps += invoker.deps
- }
- }
-
- if (_dist_jar_path != "") {
- create_dist_target = "${_template_name}__create_dist_jar"
- final_deps += [ ":$create_dist_target" ]
-
- # TODO(cjhopman): This is only ever needed to calculate the list of tests to
- # run. See build/android/pylib/instrumentation/test_jar.py. We should be
- # able to just do that calculation at build time instead.
- action(create_dist_target) {
- script = "//build/android/gyp/create_dist_jar.py"
- depfile = "$target_gen_dir/$target_name.d"
- inputs = [
- _build_config,
- ]
- outputs = [
- depfile,
- _dist_jar_path,
- ]
- args = [
- "--depfile",
- rebase_path(depfile, root_build_dir),
- "--output",
- rebase_path(_dist_jar_path, root_build_dir),
- "--inputs=@FileArg($_rebased_build_config:dist_jar:dependency_jars)",
- ]
- inputs += [ jar_path ]
- _rebased_jar_path = rebase_path([ jar_path ], root_build_dir)
- args += [ "--inputs=$_rebased_jar_path" ]
- deps = [
- ":$build_config_target", # Generates the build config file.
- ":$java_target", # Generates the jar file.
- ]
- }
- }
-
- final_deps += [ ":$final_dex_target_name" ]
- dex("${final_dex_target_name}_jar") {
- deps = [
- ":$build_config_target",
- ":$java_target",
- ]
- sources = [
- jar_path,
- ]
- inputs = [
- _build_config,
- ]
- output = "${final_dex_path}.jar"
- dex_arg_key = "${_rebased_build_config}:final_dex:dependency_dex_files"
- args = [ "--inputs=@FileArg($dex_arg_key)" ]
- }
-
- dex("$final_dex_target_name") {
- deps = [
- ":${final_dex_target_name}_jar",
- ]
- sources = [
- "${final_dex_path}.jar",
- ]
- output = final_dex_path
- }
-
- if (_native_libs != []) {
- action("${_template_name}__prepare_native") {
- script = "//build/android/gyp/pack_relocations.py"
- packed_libraries_dir = "$_native_libs_dir/$android_app_abi"
- depfile = "$target_gen_dir/$target_name.d"
- outputs = [
- depfile,
- ]
-
- inputs = _native_libs
- deps = _chromium_linker_dep
-
- inputs += [ _build_config ]
- deps += [ ":$build_config_target" ]
-
- skip_packing_list = [
- "gdbserver",
- "libchromium_android_linker$android_product_extension",
- ]
-
- enable_packing_arg = 0
- if (_enable_relocation_packing) {
- enable_packing_arg = 1
- deps += [ relocation_packer_target ]
- }
-
- args = [
- "--depfile",
- rebase_path(depfile, root_build_dir),
- "--enable-packing=$enable_packing_arg",
- "--exclude-packing-list=$skip_packing_list",
- "--android-pack-relocations",
- rebase_path(relocation_packer_exe, root_build_dir),
- "--stripped-libraries-dir",
- rebase_path(root_build_dir, root_build_dir),
- "--packed-libraries-dir",
- rebase_path(packed_libraries_dir, root_build_dir),
- "--libraries=@FileArg(${_rebased_build_config}:native:libraries)",
- "--clear-dir",
- ]
-
- if (defined(invoker.deps)) {
- deps += invoker.deps
- }
- if (defined(invoker.public_deps)) {
- public_deps = invoker.public_deps
- }
- if (defined(invoker.data_deps)) {
- data_deps = invoker.data_deps
- }
-
- if (is_debug) {
- rebased_gdbserver = rebase_path([ android_gdbserver ], root_build_dir)
- inputs += [ android_gdbserver ]
- args += [ "--libraries=$rebased_gdbserver" ]
- }
- }
- }
-
- final_deps += [ ":${_template_name}__create" ]
- create_apk("${_template_name}__create") {
- apk_path = _final_apk_path
- android_manifest = _android_manifest
- resources_zip = _all_resources_zip_path
- dex_path = final_dex_path
- load_library_from_apk = _load_library_from_apk
- create_density_splits = _create_density_splits
- if (defined(invoker.language_splits)) {
- language_splits = invoker.language_splits
- }
- if (defined(invoker.extensions_to_not_compress)) {
- extensions_to_not_compress = invoker.extensions_to_not_compress
- } else {
- # Allow icu data, v8 snapshots, and pak files to be loaded directly from
- # the .apk.
- # Note: These are actually suffix matches, not necessarily extensions.
- extensions_to_not_compress = ".dat,.bin,.pak"
- }
-
- version_code = _version_code
- version_name = _version_name
-
- keystore_name = _keystore_name
- keystore_path = _keystore_path
- keystore_password = _keystore_password
-
- # This target generates the input file _all_resources_zip_path.
- deps = _android_manifest_deps + [
- ":$process_resources_target",
- ":$final_dex_target_name",
- ]
- if (defined(invoker.deps)) {
- deps += invoker.deps
- }
-
- if (defined(invoker.asset_location)) {
- asset_location = invoker.asset_location
-
- # We don't know the exact dependencies that create the assets in
- # |asset_location|; we depend on all caller deps until a better solution
- # is figured out (http://crbug.com/433330).
- if (defined(invoker.deps)) {
- deps += invoker.deps
- }
- }
-
- if (_native_libs != [] && !_create_abi_split) {
- native_libs_dir = _native_libs_dir
- deps += [ ":${_template_name}__prepare_native" ]
- }
- }
-
- if (_native_libs != [] && _create_abi_split) {
- _manifest_rule = "${_template_name}__split_manifest_abi_${android_app_abi}"
- generate_split_manifest(_manifest_rule) {
- main_manifest = _android_manifest
- out_manifest =
- "$gen_dir/split-manifests/${android_app_abi}/AndroidManifest.xml"
- split_name = "abi_${android_app_abi}"
- deps = _android_manifest_deps
- }
-
- _apk_rule = "${_template_name}__split_apk_abi_${android_app_abi}"
- final_deps += [ ":$_apk_rule" ]
- create_apk(_apk_rule) {
- _split_paths = process_file_template(
- [ _final_apk_path ],
- "{{source_dir}}/{{source_name_part}}-abi-${android_app_abi}.apk")
- apk_path = _split_paths[0]
- base_path = "$gen_dir/$_apk_rule"
-
- manifest_outputs = get_target_outputs(":${_manifest_rule}")
- android_manifest = manifest_outputs[1]
- load_library_from_apk = _load_library_from_apk
-
- version_code = _version_code
- version_name = _version_name
-
- keystore_name = _keystore_name
- keystore_path = _keystore_path
- keystore_password = _keystore_password
-
- native_libs_dir = _native_libs_dir
- deps = [
- ":${_template_name}__prepare_native",
- ":${_manifest_rule}",
- ]
- }
- }
-
- if (defined(invoker.flutter_dist_jar)) {
- flutter_jar_target = "${_template_name}__create_flutter_jar"
- final_deps += [ ":$flutter_jar_target" ]
-
- action(flutter_jar_target) {
- script = "//build/android/gyp/create_flutter_jar.py"
- depfile = "$target_gen_dir/$target_name.d"
- inputs = [
- _dist_jar_path,
- ]
- outputs = [
- invoker.flutter_dist_jar,
- ]
- args = [
- "--depfile",
- rebase_path(depfile, root_build_dir),
- "--output",
- rebase_path(invoker.flutter_dist_jar, root_build_dir),
- "--dist_jar",
- rebase_path(_dist_jar_path, root_build_dir),
- "--android_abi",
- "$android_app_abi",
- "--asset_dir",
- rebase_path(invoker.asset_location, root_build_dir),
- ]
- foreach(native_lib, rebase_path(_native_libs, root_build_dir)) {
- args += [
- "--native_lib",
- native_lib,
- ]
- }
- deps = [
- ":$create_dist_target",
- ":${_template_name}__prepare_native"
- ]
- if (defined(invoker.deps)) {
- deps += invoker.deps
- }
- }
- }
-
- group(target_name) {
- deps = final_deps
- if (defined(invoker.data_deps)) {
- data_deps = invoker.data_deps
- }
- }
-}
-
-# Declare an Android instrumentation test apk
-#
-# This target creates an Android instrumentation test apk.
-#
-# Variables
-# android_manifest: Path to AndroidManifest.xml.
-# data_deps: List of dependencies needed at runtime. These will be built but
-# won't change the generated .apk in any way (in fact they may be built
-# after the .apk is).
-# deps: List of dependencies. All Android java resources and libraries in the
-# "transitive closure" of these dependencies will be included in the apk.
-# Note: this "transitive closure" actually only includes such targets if
-# they are depended on through android_library or android_resources targets
-# (and so not through builtin targets like 'action', 'group', etc).
-# java_files: List of .java files to include in the apk.
-# srcjar_deps: List of srcjar dependencies. The .java files in the srcjars
-# will be added to java_files and be included in this apk.
-# apk_name: Name for final apk.
-# support_apk_path: Path to a support apk. If present, the test runner script
-# will install it on the device before running the instrumentation tests.
-# Should be a path relative to the src root.
-# final_apk_path: Path to final built apk. Default is
-# $root_out_dir/apks/$apk_name.apk. Setting this will override apk_name.
-# native_libs: List paths of native libraries to include in this apk. If these
-# libraries depend on other shared_library targets, those dependencies will
-# also be included in the apk.
-# apk_under_test: The apk being tested.
-# isolate_file: Isolate file containing the list of test data dependencies.
-#
-# DEPRECATED_java_in_dir: Directory containing java files. All .java files in
-# this directory will be included in the library. This is only supported to
-# ease the gyp->gn conversion and will be removed in the future.
-#
-# Example
-# instrumentation_test_apk("foo_test_apk") {
-# android_manifest = "AndroidManifest.xml"
-# apk_name = "FooTest"
-# apk_under_test = "Foo"
-# java_files = [
-# "android/org/chromium/foo/FooTestCase.java",
-# "android/org/chromium/foo/FooExampleTest.java",
-# ]
-# deps = [
-# ":foo_test_support_java"
-# ]
-# }
-template("instrumentation_test_apk") {
- set_sources_assignment_filter([])
- testonly = true
- _template_name = target_name
-
- if (defined(invoker.apk_name)) {
- test_runner_data_dep = [ ":${_template_name}__test_runner_script" ]
- test_runner_script("${_template_name}__test_runner_script") {
- test_name = invoker.target_name
- test_type = "instrumentation"
- test_apk = invoker.apk_name
- if (defined(invoker.isolate_file)) {
- isolate_file = invoker.isolate_file
- }
- if (defined(invoker.support_apk_path)) {
- support_apk_path = invoker.support_apk_path
- }
- }
- }
-
- android_apk(target_name) {
- if (defined(invoker.android_manifest)) {
- android_manifest = invoker.android_manifest
- }
- data_deps = [
- "//testing/android/driver:driver_apk",
- "//tools/android/forwarder2",
- "//tools/android/md5sum",
- ]
- if (defined(test_runner_data_dep)) {
- data_deps += test_runner_data_dep
- }
- if (defined(invoker.data_deps)) {
- data_deps += invoker.data_deps
- }
- deps = [
- "//testing/android/broker:broker_java",
- ]
- if (defined(invoker.deps)) {
- deps += invoker.deps
- }
- if (defined(invoker.java_files)) {
- java_files = invoker.java_files
- }
- if (defined(invoker.srcjar_deps)) {
- srcjar_deps = invoker.srcjar_deps
- }
- if (defined(invoker.apk_name)) {
- apk_name = invoker.apk_name
- }
- if (defined(invoker.final_apk_path)) {
- final_apk_path = invoker.final_apk_path
- }
- if (defined(invoker.native_libs)) {
- native_libs = invoker.native_libs
- }
- if (defined(invoker.apk_under_test)) {
- apk_under_test = invoker.apk_under_test
- }
- if (defined(invoker.DEPRECATED_java_in_dir)) {
- DEPRECATED_java_in_dir = invoker.DEPRECATED_java_in_dir
- }
- }
-}
-
-# Declare an Android gtest apk
-#
-# This target creates an Android apk for running gtest-based unittests.
-#
-# Variables
-# deps: Specifies the dependencies of this target. These will be passed to
-# the underlying android_apk invocation and should include the java and
-# resource dependencies of the apk.
-# unittests_dep: This should be the label of the gtest native target. This
-# target must be defined previously in the same file.
-# unittests_binary: The basename of the library produced by the unittests_dep
-# target. If unspecified, it assumes the name of the unittests_dep target
-# (which will be correct unless that target specifies an "output_name".
-# TODO(brettw) make this automatic by allowing get_target_outputs to
-# support executables.
-# apk_name: The name of the produced apk. If unspecified, it uses the name
-# of the unittests_dep target postfixed with "_apk"
-#
-# Example
-# unittest_apk("foo_unittests_apk") {
-# deps = [ ":foo_java", ":foo_resources" ]
-# unittests_dep = ":foo_unittests"
-# }
-template("unittest_apk") {
- set_sources_assignment_filter([])
- testonly = true
-
- assert(defined(invoker.unittests_dep), "Need unittests_dep for $target_name")
-
- test_suite_name = get_label_info(invoker.unittests_dep, "name")
-
- # This trivial assert is needed in case both unittests_binary and apk_name
- # are defined, as otherwise test_suite_name would not be used.
- assert(test_suite_name != "")
-
- if (defined(invoker.unittests_binary)) {
- unittests_binary = invoker.unittests_binary
- } else {
- unittests_binary = "lib${test_suite_name}${android_product_extension}"
- }
-
- if (defined(invoker.apk_name)) {
- apk_name = invoker.apk_name
- } else {
- apk_name = test_suite_name
- }
-
- android_apk(target_name) {
- final_apk_path = "$root_build_dir/${apk_name}_apk/${apk_name}-debug.apk"
- java_files = [
- "//testing/android/native_test/java/src/org/chromium/native_test/NativeBrowserTestActivity.java",
- "//testing/android/native_test/java/src/org/chromium/native_test/NativeTestActivity.java",
- "//testing/android/native_test/java/src/org/chromium/native_test/NativeUnitTestActivity.java",
- "//testing/android/native_test/java/src/org/chromium/native_test/NativeTestInstrumentationTestRunner.java",
- ]
- android_manifest = "//testing/android/native_test/java/AndroidManifest.xml"
- native_libs = [ unittests_binary ]
- if (defined(invoker.asset_location)) {
- asset_location = invoker.asset_location
- }
- deps = [
- "//base:base_java",
- "//build/android/pylib/remote/device/dummy:remote_device_dummy_apk",
- "//testing/android/appurify_support:appurify_support_java",
- "//testing/android/reporter:reporter_java",
- ]
- if (defined(invoker.deps)) {
- deps += invoker.deps
- }
- data_deps = [ "//tools/android/md5sum" ]
- if (host_os == "linux") {
- data_deps += [ "//tools/android/forwarder2" ]
- }
- if (defined(invoker.data_deps)) {
- data_deps += invoker.data_deps
- }
- }
-}
-
-# Generate .java files from .aidl files.
-#
-# This target will store the .java files in a srcjar and should be included in
-# an android_library or android_apk's srcjar_deps.
-#
-# Variables
-# sources: Paths to .aidl files to compile.
-# import_include: Path to directory containing .java files imported by the
-# .aidl files.
-# interface_file: Preprocessed aidl file to import.
-#
-# Example
-# android_aidl("foo_aidl") {
-# import_include = "java/src"
-# sources = [
-# "java/src/com/foo/bar/FooBarService.aidl",
-# "java/src/com/foo/bar/FooBarServiceCallback.aidl",
-# ]
-# }
-template("android_aidl") {
- set_sources_assignment_filter([])
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
-
- srcjar_path = "${target_gen_dir}/${target_name}.srcjar"
- aidl_path = "${android_sdk_build_tools}/aidl"
- framework_aidl = "$android_sdk/framework.aidl"
-
- action(target_name) {
- script = "//build/android/gyp/aidl.py"
- sources = invoker.sources
-
- imports = [ framework_aidl ]
- if (defined(invoker.interface_file)) {
- assert(invoker.interface_file != "")
- imports += [ invoker.interface_file ]
- }
-
- inputs = [ aidl_path ] + imports
-
- depfile = "${target_gen_dir}/${target_name}.d"
- outputs = [
- depfile,
- srcjar_path,
- ]
- rebased_imports = rebase_path(imports, root_build_dir)
- args = [
- "--depfile",
- rebase_path(depfile, root_build_dir),
- "--aidl-path",
- rebase_path(aidl_path, root_build_dir),
- "--imports=$rebased_imports",
- "--srcjar",
- rebase_path(srcjar_path, root_build_dir),
- ]
- if (defined(invoker.import_include) && invoker.import_include != "") {
- # TODO(cjhopman): aidl supports creating a depfile. We should be able to
- # switch to constructing a depfile for the overall action from that
- # instead of having all the .java files in the include paths as inputs.
- rebased_import_includes =
- rebase_path([ invoker.import_include ], root_build_dir)
- args += [ "--includes=$rebased_import_includes" ]
-
- _java_files_build_rel =
- exec_script("//build/android/gyp/find.py",
- rebase_path([ invoker.import_include ], root_build_dir),
- "list lines")
- _java_files = rebase_path(_java_files_build_rel, ".", root_build_dir)
- inputs += _java_files
- }
- args += rebase_path(sources, root_build_dir)
- }
-}
-
-# Creates a dist directory for a native executable.
-#
-# Running a native executable on a device requires all the shared library
-# dependencies of that executable. To make it easier to install and run such an
-# executable, this will create a directory containing the native exe and all
-# it's library dependencies.
-#
-# Note: It's usually better to package things as an APK than as a native
-# executable.
-#
-# Variables
-# dist_dir: Directory for the exe and libraries. Everything in this directory
-# will be deleted before copying in the exe and libraries.
-# binary: Path to (stripped) executable.
-#
-# Example
-# create_native_executable_dist("foo_dist") {
-# dist_dir = "$root_build_dir/foo_dist"
-# binary = "$root_build_dir/exe.stripped/foo"
-# deps = [ ":the_thing_that_makes_foo" ]
-# }
-template("create_native_executable_dist") {
- set_sources_assignment_filter([])
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
-
- dist_dir = invoker.dist_dir
- binary = invoker.binary
- template_name = target_name
-
- libraries_list =
- "${target_gen_dir}/${template_name}_library_dependencies.list"
-
- find_deps_target_name = "${template_name}__find_library_dependencies"
- copy_target_name = "${template_name}__copy_libraries_and_exe"
-
- stripped_libraries_dir = "$root_build_dir/lib.stripped"
- action(find_deps_target_name) {
- visibility = [ ":$copy_target_name" ]
-
- script = "//build/android/gyp/write_ordered_libraries.py"
- depfile = "$target_gen_dir/$target_name.d"
- inputs = [
- binary,
- android_readelf,
- ]
- outputs = [
- depfile,
- libraries_list,
- ]
- rebased_binaries = rebase_path([ binary ], root_build_dir)
- args = [
- "--depfile",
- rebase_path(depfile, root_build_dir),
- "--input-libraries=$rebased_binaries",
- "--libraries-dir",
- rebase_path(stripped_libraries_dir, root_build_dir),
- "--output",
- rebase_path(libraries_list, root_build_dir),
- "--readelf",
- rebase_path(android_readelf, root_build_dir),
- ]
- if (defined(invoker.deps)) {
- deps = invoker.deps
- }
- }
-
- copy_ex(copy_target_name) {
- visibility = [ ":$template_name" ]
-
- clear_dir = true
- inputs = [
- binary,
- libraries_list,
- ]
- dest = dist_dir
- rebased_binaries_list = rebase_path([ binary ], root_build_dir)
- rebased_libraries_list = rebase_path(libraries_list, root_build_dir)
- args = [
- "--files=$rebased_binaries_list",
- "--files=@FileArg($rebased_libraries_list:lib_paths)",
- ]
-
- deps = [
- ":$find_deps_target_name",
- ]
- if (defined(invoker.deps)) {
- deps += invoker.deps
- }
- }
-
- group(template_name) {
- if (defined(invoker.visibility)) {
- visibility = invoker.visibility
- }
- deps = [
- ":$copy_target_name",
- ]
- }
-}
-
-# Compile a protocol buffer to java.
-#
-# This generates java files from protocol buffers and creates an Android library
-# containing the classes.
-#
-# Variables
-# sources: Paths to .proto files to compile.
-# proto_path: Root directory of .proto files.
-#
-# Example:
-# proto_java_library("foo_proto_java") {
-# proto_path = [ "src/foo" ]
-# sources = [ "$proto_path/foo.proto" ]
-# }
-template("proto_java_library") {
- set_sources_assignment_filter([])
- _protoc_dep = "//third_party/android_protobuf:android_protoc($host_toolchain)"
- _protoc_out_dir = get_label_info(_protoc_dep, "root_out_dir")
- _protoc_bin = "$_protoc_out_dir/android_protoc"
- _proto_path = invoker.proto_path
-
- _template_name = target_name
-
- action("${_template_name}__protoc_java") {
- srcjar_path = "$target_gen_dir/$target_name.srcjar"
- script = "//build/protoc_java.py"
- deps = [
- _protoc_dep,
- ]
- sources = invoker.sources
- depfile = "$target_gen_dir/$target_name.d"
- outputs = [
- depfile,
- srcjar_path,
- ]
- args = [
- "--depfile",
- rebase_path(depfile, root_build_dir),
- "--protoc",
- rebase_path(_protoc_bin, root_build_dir),
- "--proto-path",
- rebase_path(_proto_path, root_build_dir),
- "--srcjar",
- rebase_path(srcjar_path, root_build_dir),
- ] + rebase_path(sources, root_build_dir)
- }
-
- android_library(target_name) {
- java_files = []
- srcjar_deps = [ ":${_template_name}__protoc_java" ]
- deps = [
- "//third_party/android_protobuf:protobuf_nano_javalib",
- ]
- }
-}
-
-# TODO(GYP): implement this.
-template("uiautomator_test") {
- set_sources_assignment_filter([])
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
- assert(target_name != "")
- assert(invoker.deps != [] || true)
- group(target_name) {
- }
-}
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index 7f7e423..c86203c 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -17,16 +17,6 @@
}
import("//build/toolchain/ccache.gni")
-import("//build/config/sanitizers/sanitizers.gni")
-
-declare_args() {
- if (is_win) {
- # Whether the VS xtree header has been patched to disable warning 4702. If
- # it has, then we don't need to disable 4702 (unreachable code warning).
- # The patch is preapplied to the internal toolchain and hence all bots.
- msvs_xtree_patched = false
- }
-}
# default_include_dirs ---------------------------------------------------------
#
@@ -40,7 +30,6 @@
]
}
-# TODO(GYP): is_ubsan, is_ubsan_vptr
if (!is_win) {
using_sanitizer = is_asan || is_lsan || is_tsan || is_msan
}
@@ -73,40 +62,6 @@
"/GS", # Enable buffer security checking.
"/FS", # Preserve previous PDB behavior.
]
-
- # Building with Clang on Windows is a work in progress and very
- # experimental. See crbug.com/82385.
- # Keep this in sync with the similar block in build/common.gypi
- if (is_clang) {
- cflags += [
- # Many files use intrinsics without including this header.
- # TODO(hans): Fix those files, or move this to sub-GYPs.
- "/FIIntrin.h",
- ]
-
- if (visual_studio_version == "2013") {
- cflags += [ "-fmsc-version=1800" ]
- } else if (visual_studio_version == "2015") {
- cflags += [ "-fmsc-version=1900" ]
- }
-
- if (current_cpu == "x86") {
- cflags += [
- "/fallback",
- "-m32",
- ]
- } else {
- cflags += [ "-m64" ]
- }
- if (exec_script("//build/win/use_ansi_codes.py", [], "trim string") ==
- "True") {
- cflags += [
- # cmd.exe doesn't understand ANSI escape codes by default,
- # so only enable them if something emulating them is around.
- "-fansi-escape-codes",
- ]
- }
- }
} else {
# Common GCC compiler flags setup.
# --------------------------------
@@ -136,44 +91,20 @@
]
}
if (is_asan) {
- asan_blacklist_path =
- rebase_path("//tools/memory/asan/blacklist.txt", root_build_dir)
- cflags += [
- "-fsanitize=address",
- "-fsanitize-blacklist=$asan_blacklist_path",
- ]
- if (is_mac) {
- cflags += [ "-mllvm -asan-globals=0" ] # http://crbug.com/352073
- # TODO(GYP): deal with mac_bundles.
- }
+ cflags += [ "-fsanitize=address" ]
+ ldflags += [ "-fsanitize=address" ]
}
if (is_lsan) {
cflags += [ "-fsanitize=leak" ]
+ ldflags += [ "-fsanitize=leak" ]
}
if (is_tsan) {
- tsan_blacklist_path =
- rebase_path("//tools/memory/tsan_v2/ignores.txt", root_build_dir)
- cflags += [
- "-fsanitize=thread",
- "-fsanitize-blacklist=$tsan_blacklist_path",
- ]
+ cflags += [ "-fsanitize=thread" ]
+ ldflags += [ "-fsanitize=thread" ]
}
if (is_msan) {
- msan_blacklist_path =
- rebase_path("//tools/msan/blacklist.txt", root_build_dir)
- cflags += [
- "-fsanitize=memory",
- "-fsanitize-memory-track-origins=$msan_track_origins",
- "-fsanitize-blacklist=$msan_blacklist_path",
- ]
- }
-
- if (use_custom_libcxx) {
- cflags_cc += [ "-nostdinc++" ]
- include_dirs = [
- "//buildtools/third_party/libc++/trunk/include",
- "//buildtools/third_party/libc++abi/trunk/include",
- ]
+ cflags += [ "-fsanitize=memory" ]
+ ldflags += [ "-fsanitize=memory" ]
}
}
@@ -470,9 +401,9 @@
#
# How do you determine what should go in here vs. "compiler" above? Consider if
# a target might choose to use a different runtime library (ignore for a moment
-# if this is possible or reasonable on your system). If such a target would want
-# to change or remove your option, put it in the runtime_library config. If a
-# target wants the option regardless, put it in the compiler config.
+# if this is possible or reasonable on your system). If such a target would
+# want to change or remove your option, put it in the runtime_library config.
+# If a target wants the option regardless, put it in the compiler config.
config("runtime_library") {
cflags = []
@@ -481,30 +412,13 @@
lib_dirs = []
libs = []
- if (is_component_build) {
- # Component mode: dynamic CRT.
- defines += [ "COMPONENT_BUILD" ]
- if (is_win) {
- # Since the library is shared, it requires exceptions or will give errors
- # about things not matching, so keep exceptions on.
- if (is_debug) {
- cflags += [ "/MDd" ]
- } else {
- cflags += [ "/MD" ]
- }
- }
- } else {
- # Static CRT.
- if (is_win) {
- if (is_debug) {
- cflags += [ "/MTd" ]
- } else {
- cflags += [ "/MT" ]
- }
- }
- }
-
+ # Static CRT.
if (is_win) {
+ if (is_debug) {
+ cflags += [ "/MTd" ]
+ } else {
+ cflags += [ "/MT" ]
+ }
defines += [
"__STD_C",
"_CRT_RAND_S",
@@ -590,114 +504,26 @@
default_warning_flags = []
default_warning_flags_cc = []
if (is_win) {
- if (!is_clang || current_cpu != "x86") {
+ if (current_cpu != "x86") {
default_warning_flags += [ "/WX" ] # Treat warnings as errors.
}
default_warning_flags += [
- # Warnings permanently disabled:
-
- # TODO(GYP) The GYP build doesn't have this globally enabled but disabled
- # for a bunch of individual targets. Re-enable this globally when those
- # targets are fixed.
- "/wd4018", # Comparing signed and unsigned values.
-
- # C4127: conditional expression is constant
- # This warning can in theory catch dead code and other problems, but
- # triggers in far too many desirable cases where the conditional
- # expression is either set by macros or corresponds some legitimate
- # compile-time constant expression (due to constant template args,
- # conditionals comparing the sizes of different types, etc.). Some of
- # these can be worked around, but it's not worth it.
- "/wd4127",
-
- # C4251: 'identifier' : class 'type' needs to have dll-interface to be
- # used by clients of class 'type2'
- # This is necessary for the shared library build.
- "/wd4251",
-
- # C4351: new behavior: elements of array 'array' will be default
- # initialized
- # This is a silly "warning" that basically just alerts you that the
- # compiler is going to actually follow the language spec like it's
- # supposed to, instead of not following it like old buggy versions did.
- # There's absolutely no reason to turn this on.
- "/wd4351",
-
- # C4355: 'this': used in base member initializer list
- # It's commonly useful to pass |this| to objects in a class' initializer
- # list. While this warning can catch real bugs, most of the time the
- # constructors in question don't attempt to call methods on the passed-in
- # pointer (until later), and annotating every legit usage of this is
- # simply more hassle than the warning is worth.
- "/wd4355",
-
- # C4503: 'identifier': decorated name length exceeded, name was
- # truncated
- # This only means that some long error messages might have truncated
- # identifiers in the presence of lots of templates. It has no effect on
- # program correctness and there's no real reason to waste time trying to
- # prevent it.
- "/wd4503",
-
- # Warning C4589 says: "Constructor of abstract class ignores
- # initializer for virtual base class." Disable this warning because it
- # is flaky in VS 2015 RTM. It triggers on compiler generated
- # copy-constructors in some cases.
- "/wd4589",
-
- # C4611: interaction between 'function' and C++ object destruction is
- # non-portable
- # This warning is unavoidable when using e.g. setjmp/longjmp. MSDN
- # suggests using exceptions instead of setjmp/longjmp for C++, but
- # Chromium code compiles without exception support. We therefore have to
- # use setjmp/longjmp for e.g. JPEG decode error handling, which means we
- # have to turn off this warning (and be careful about how object
- # destruction happens in such cases).
- "/wd4611",
-
- # Warnings to evaluate and possibly fix/reenable later:
-
- "/wd4100", # Unreferenced formal function parameter.
- "/wd4121", # Alignment of a member was sensitive to packing.
- "/wd4244", # Conversion: possible loss of data.
- "/wd4481", # Nonstandard extension: override specifier.
- "/wd4505", # Unreferenced local function has been removed.
- "/wd4510", # Default constructor could not be generated.
- "/wd4512", # Assignment operator could not be generated.
- "/wd4610", # Class can never be instantiated, constructor required.
- "/wd4996", # Deprecated function warning.
+ # Permanent.
+ "/wd4091", # typedef warning from dbghelp.h
+ # Investigate.
+ "/wd4312", # int to pointer of greater size conversion.
+ "/wd4838", # Narrowing conversion required.
+ "/wd4172", # Returning address of local.
+ "/wd4005", # Redefinition of macros for PRId64 etc.
+ "/wd4311", # Pointer truncation from PVOID to DWORD.
+ "/wd4477", # Format string requires wchar_t*
]
-
- # VS xtree header file needs to be patched or 4702 (unreachable code
- # warning) is reported if _HAS_EXCEPTIONS=0. Disable the warning if xtree is
- # not patched.
- if (!msvs_xtree_patched &&
- exec_script("../../win_is_xtree_patched.py", [], "value") == 0) {
- default_warning_flags += [ "/wd4702" ] # Unreachable code.
- }
-
- # Building with Clang on Windows is a work in progress and very
- # experimental. See crbug.com/82385.
- # Keep this in sync with the similar block in build/common.gypi
- if (is_clang) {
- default_warning_flags += [
- # TODO(hans): Make this list shorter eventually, http://crbug.com/504657
- "-Qunused-arguments", # http://crbug.com/504658
- "-Wno-microsoft", # http://crbug.com/505296
- "-Wno-switch", # http://crbug.com/505308
- "-Wno-unknown-pragmas", # http://crbug.com/505314
- "-Wno-unused-function", # http://crbug.com/505316
- "-Wno-unused-value", # http://crbug.com/505318
- "-Wno-unused-local-typedef", # http://crbug.com/411648
- ]
- }
} else {
# Common GCC warning setup.
default_warning_flags += [
# Enables.
"-Wendif-labels", # Weird old-style text after an #endif.
- "-Werror", # Warnings as errors.
# Disables.
"-Wno-missing-field-initializers", # "struct foo f = {0};"
@@ -758,11 +584,14 @@
config("chromium_code") {
if (is_win) {
- cflags = [ "/W4" ] # Warning level 4.
+ # TODO(zra): Enable higher warning levels.
+ # cflags = [ "/W4" ] # Warning level 4.
+ cflags = []
} else {
cflags = [
"-Wall",
"-Wextra",
+ "-Werror",
]
defines = []
@@ -787,12 +616,6 @@
defines = []
if (is_win) {
- cflags += [
- "/W3", # Warning level 3.
- "/wd4800", # Disable warning when forcing value to bool.
- "/wd4267", # TODO(jschuh): size_t to int.
- "/wd4996", # Deprecated function warning.
- ]
defines += [
"_CRT_NONSTDC_NO_WARNINGS",
"_CRT_NONSTDC_NO_DEPRECATE",
diff --git a/build/config/fnl/BUILD.gn b/build/config/fnl/BUILD.gn
deleted file mode 100644
index 0eb35e3..0000000
--- a/build/config/fnl/BUILD.gn
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/config/linux/pkg_config.gni")
-import("//build/config/features.gni")
-import("//build/config/sysroot.gni")
-import("//build/config/ui.gni")
-
-config("sdk") {
- if (sysroot != "") {
- cflags = [ "--sysroot=" + sysroot ]
- ldflags = [ "--sysroot=" + sysroot ]
-
- # Need to get some linker flags out of the sysroot.
- ldflags += [ exec_script("../linux/sysroot_ld_path.py",
- [
- rebase_path("//build/linux/sysroot_ld_path.sh",
- root_build_dir),
- sysroot,
- ],
- "value") ]
- }
-
- defines = [ "FNL_MUSL" ]
-
- if (use_ozone) {
- defines += [ "MESA_EGL_NO_X11_HEADERS" ]
- }
-}
-
-config("fontconfig") {
- libs = [ "fontconfig" ]
-}
-
-pkg_config("freetype2") {
- packages = [ "freetype2" ]
-}
-
-if (use_evdev_gestures) {
- pkg_config("libevdev-cros") {
- packages = [ "libevdev-cros" ]
- }
-
- pkg_config("libgestures") {
- packages = [ "libgestures" ]
- }
-}
diff --git a/build/config/ios/BUILD.gn b/build/config/ios/BUILD.gn
deleted file mode 100644
index 0292315..0000000
--- a/build/config/ios/BUILD.gn
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/config/sysroot.gni")
-import("//build/config/ios/ios_sdk.gni")
-
-config("sdk") {
- common_flags = [
- "-stdlib=libc++",
- ]
-
- cflags = common_flags
- ldflags = common_flags
-}
diff --git a/build/config/ios/XcodeHarness/.gitignore b/build/config/ios/XcodeHarness/.gitignore
deleted file mode 100644
index 89c499e..0000000
--- a/build/config/ios/XcodeHarness/.gitignore
+++ /dev/null
@@ -1,18 +0,0 @@
-# Xcode
-.DS_Store
-build/
-*.pbxuser
-!default.pbxuser
-*.mode1v3
-!default.mode1v3
-*.mode2v3
-!default.mode2v3
-*.perspectivev3
-!default.perspectivev3
-*.xcworkspace
-!default.xcworkspace
-xcuserdata
-profile
-*.moved-aside
-DerivedData
-.idea/
diff --git a/build/config/ios/XcodeHarness/FakeMain.m b/build/config/ios/XcodeHarness/FakeMain.m
deleted file mode 100644
index 5ddbd34..0000000
--- a/build/config/ios/XcodeHarness/FakeMain.m
+++ /dev/null
@@ -1,10 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#import <Foundation/Foundation.h>
-
-int main(int argc, char* argv[]) {
- NSCAssert(NO, @"Placeholder for Xcode. Should never be run");
- return EXIT_FAILURE;
-}
diff --git a/build/config/ios/find_signing_identity.py b/build/config/ios/find_signing_identity.py
deleted file mode 100644
index 2fe67f9..0000000
--- a/build/config/ios/find_signing_identity.py
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/python
-# Copyright (c) 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import subprocess
-import sys
-import re
-
-def ListIdentities():
- return subprocess.check_output([
- '/usr/bin/env',
- 'xcrun',
- 'security',
- 'find-identity',
- '-v',
- '-p',
- 'codesigning',
- ]).strip()
-
-
-def FindValidIdentity():
- lines = ListIdentities().splitlines()
- # Look for something like "2) XYZ "iPhone Developer: Name (ABC)""
- exp = re.compile('.*\) ([A-F|0-9]*)(.*)')
- for line in lines:
- res = exp.match(line)
- if res is None:
- continue
- if "iPhone Developer: Google Development" in res.group(2):
- return res.group(1)
- return ""
-
-
-if __name__ == '__main__':
- print FindValidIdentity()
diff --git a/build/config/ios/ios_app.py b/build/config/ios/ios_app.py
deleted file mode 100644
index b8bf544..0000000
--- a/build/config/ios/ios_app.py
+++ /dev/null
@@ -1,137 +0,0 @@
-#!/usr/bin/python
-# Copyright (c) 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import argparse
-import os
-import errno
-import subprocess
-import sys
-
-PLUTIL = [
- '/usr/bin/env',
- 'xcrun',
- 'plutil'
-]
-
-def MakeDirectories(path):
- try:
- os.makedirs(path)
- except OSError as exc:
- if exc.errno == errno.EEXIST and os.path.isdir(path):
- return 0
- else:
- return -1
-
- return 0
-
-
-def ProcessInfoPlist(args):
- output_plist_file = os.path.abspath(os.path.join(args.output, 'Info.plist'))
-
- if MakeDirectories(os.path.dirname(output_plist_file)) == -1:
- return -1
-
- return subprocess.check_call( PLUTIL + [
- '-convert',
- 'binary1',
- '-o',
- output_plist_file,
- '--',
- args.input,
- ])
-
-
-def PerformCodeSigning(args):
- return subprocess.check_call([
- '/usr/bin/env',
- 'xcrun',
- 'codesign',
- '--entitlements',
- args.entitlements_path,
- '--sign',
- args.identity,
- '-f',
- args.application_path,
- ])
-
-def GenerateDSYM(args):
- return subprocess.check_call([
- '/usr/bin/env',
- 'xcrun',
- 'dsymutil',
- '-o',
- args.output,
- args.executable_path
- ])
-
-
-def GenerateProjectStructure(args):
- application_path = os.path.join( args.dir, args.name + ".app" )
- return MakeDirectories( application_path )
-
-
-def Main():
- parser = argparse.ArgumentParser(description='A script that aids in '
- 'the creation of an iOS application')
-
- subparsers = parser.add_subparsers()
-
- # Plist Parser
-
- plist_parser = subparsers.add_parser('plist',
- help='Process the Info.plist')
- plist_parser.set_defaults(func=ProcessInfoPlist)
-
- plist_parser.add_argument('-i', dest='input', help='The input plist path')
- plist_parser.add_argument('-o', dest='output', help='The output plist dir')
-
- # Directory Structure Parser
-
- dir_struct_parser = subparsers.add_parser('structure',
- help='Creates the directory of an iOS application')
-
- dir_struct_parser.set_defaults(func=GenerateProjectStructure)
-
- dir_struct_parser.add_argument('-d', dest='dir', help='Out directory')
- dir_struct_parser.add_argument('-n', dest='name', help='App name')
-
- # Code Signing
-
- code_signing_parser = subparsers.add_parser('codesign',
- help='Code sign the specified application')
-
- code_signing_parser.set_defaults(func=PerformCodeSigning)
-
- code_signing_parser.add_argument('-p', dest='application_path', required=True,
- help='The application path')
- code_signing_parser.add_argument('-i', dest='identity', required=True,
- help='The code signing identity to use')
- code_signing_parser.add_argument('-e', dest='entitlements_path',
- required=True,
- help='The path to the entitlements .xcent')
-
- # dSYM Generation
-
- dsym_generation_parser = subparsers.add_parser('dsym',
- help='Generate a .dSYM file for an executable')
-
- dsym_generation_parser.set_defaults(func=GenerateDSYM)
-
- dsym_generation_parser.add_argument('-e', dest='executable_path',
- required=True,
- help='The executable path')
- dsym_generation_parser.add_argument('-o', dest='output',
- required=True,
- help='The output file name')
-
- # Engage!
-
- args = parser.parse_args()
-
- return args.func(args)
-
-
-if __name__ == '__main__':
- sys.exit(Main())
diff --git a/build/config/ios/ios_sdk.gni b/build/config/ios/ios_sdk.gni
deleted file mode 100644
index 65654a5..0000000
--- a/build/config/ios/ios_sdk.gni
+++ /dev/null
@@ -1,58 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-declare_args() {
- # SDK path to use. When empty this will use the default SDK based on the
- # value of use_ios_simulator.
- ios_sdk_path = ""
-
- # Set to true when targeting a simulator build on iOS. False means that the
- # target is for running on the device. The default value is to use the
- # Simulator except when targeting GYP's Xcode builds (for compat with the
- # existing GYP build).
- use_ios_simulator = true
-
- # Version of iOS that we're targeting.
- ios_deployment_target = "6.0"
-
- # The iOS Code signing identity to use
- ios_code_signing_identity = ""
-
- # The path to the iOS device SDK.
- ios_device_sdk_path = ""
-
- # The path to the iOS simulator SDK.
- ios_simulator_sdk_path = ""
-}
-
-if (ios_device_sdk_path == "") {
- _ios_device_sdk_result =
- exec_script("ios_sdk.py", [ "iphoneos" ], "list lines")
- ios_device_sdk_path = _ios_device_sdk_result[0]
-}
-
-if (ios_simulator_sdk_path == "") {
- _ios_sim_sdk_result =
- exec_script("ios_sdk.py", [ "iphonesimulator" ], "list lines")
- ios_simulator_sdk_path = _ios_sim_sdk_result[0]
-}
-
-# Compute default target.
-if (use_ios_simulator) {
- ios_sdk_path = ios_simulator_sdk_path
-} else {
- ios_sdk_path = ios_device_sdk_path
-}
-
-if (use_ios_simulator) {
- # Always disable code signing on the simulator
- ios_code_signing_identity = ""
-} else {
- # If an identity is not provided, look for one on the host
- if (ios_code_signing_identity == "") {
- _ios_identities = exec_script("find_signing_identity.py",
- [], "list lines")
- ios_code_signing_identity = _ios_identities[0]
- }
-}
diff --git a/build/config/ios/ios_sdk.py b/build/config/ios/ios_sdk.py
deleted file mode 100644
index dfec4db..0000000
--- a/build/config/ios/ios_sdk.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import subprocess
-import sys
-
-# This script returns the path to the SDK of the given type. Pass the type of
-# SDK you want, which is typically "iphone" or "iphonesimulator".
-#
-# In the GYP build, this is done inside GYP itself based on the SDKROOT
-# variable.
-
-if len(sys.argv) != 2:
- print "Takes one arg (SDK to find)"
- sys.exit(1)
-
-print subprocess.check_output(['xcodebuild', '-version', '-sdk',
- sys.argv[1], 'Path']).strip()
diff --git a/build/config/ios/lldb_start_commands.txt b/build/config/ios/lldb_start_commands.txt
deleted file mode 100644
index 42e0b14..0000000
--- a/build/config/ios/lldb_start_commands.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-breakpoint set --name UIApplicationMain
-breakpoint set --name objc_exception_throw
-continue
-script print "........ Debugger break on main() ........"
diff --git a/build/config/ios/rules.gni b/build/config/ios/rules.gni
deleted file mode 100644
index 429c153..0000000
--- a/build/config/ios/rules.gni
+++ /dev/null
@@ -1,234 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-ios_app_script = "//build/config/ios/ios_app.py"
-
-template("code_sign_ios") {
- assert(defined(invoker.entitlements_path),
- "The path to the entitlements .xcent file")
- assert(defined(invoker.identity),
- "The code signing identity")
- assert(defined(invoker.application_path),
- "The application to code sign")
- assert(defined(invoker.deps))
-
- action(target_name) {
- sources = [
- invoker.entitlements_path,
- ]
-
- _application_path = invoker.application_path
-
- script = ios_app_script
-
- outputs = [
- "$_application_path/_CodeSignature/CodeResources"
- ]
-
- args = [
- "codesign",
- "-p",
- rebase_path(invoker.application_path, root_build_dir),
- "-i",
- invoker.identity,
- "-e",
- rebase_path(invoker.entitlements_path, root_build_dir),
- ]
-
- deps = invoker.deps
- }
-}
-
-template("xcode_harness_ios") {
- assert(defined(invoker.deps),
- "The dependencies must be specified")
- assert(defined(invoker.app_bundle),
- "The app bundle must be defined")
- assert(defined(invoker.app_name),
- "The application name must be defined")
- app_name = invoker.app_name
-
- xcode_project_gen_target_name = app_name + "_xcode"
- copy(xcode_project_gen_target_name) {
- sources = [
- "//build/config/ios/XcodeHarness/FakeMain.m",
- "//build/config/ios/XcodeHarness/Harness.xcodeproj",
- ]
- outputs = [
- "$root_build_dir/$xcode_project_gen_target_name/{{source_file_part}}",
- ]
- }
-
- bundle_copy_gen_target_name = app_name + "_bundle_copy"
- copy(bundle_copy_gen_target_name) {
- sources = [
- invoker.app_bundle
- ]
- outputs = [
- "$root_build_dir/$xcode_project_gen_target_name/Application",
- ]
-
- deps = invoker.deps
- }
-
- group(target_name) {
- deps = [
- ":$xcode_project_gen_target_name",
- ":$bundle_copy_gen_target_name",
- ]
- }
-}
-
-template("resource_copy_ios") {
- assert(defined(invoker.resources),
- "The source list of resources to copy over")
- assert(defined(invoker.bundle_directory),
- "The directory within the bundle to place the sources in")
- assert(defined(invoker.app_name),
- "The name of the application")
-
- _bundle_directory = invoker.bundle_directory
- _app_name = invoker.app_name
- _resources = invoker.resources
-
- copy(target_name) {
- set_sources_assignment_filter([])
- sources = _resources
- outputs = [ "$root_build_dir/$_app_name.app/$_bundle_directory/{{source_file_part}}" ]
-
- if (defined(invoker.deps)) {
- deps = invoker.deps
- }
- }
-}
-
-template("ios_app") {
-
- assert(defined(invoker.deps),
- "Dependencies must be specified for $target_name")
- assert(defined(invoker.info_plist),
- "The application plist file must be specified for $target_name")
- assert(defined(invoker.app_name),
- "The name of iOS application for $target_name")
- assert(defined(invoker.entitlements_path),
- "The entitlements path must be specified for $target_name")
- assert(defined(invoker.code_signing_identity),
- "The entitlements path must be specified for $target_name")
-
- # We just create a variable so we can use the same in interpolation
- app_name = invoker.app_name
-
- # Generate the project structure
-
- struct_gen_target_name = target_name + "_struct"
-
- action(struct_gen_target_name) {
-
- script = ios_app_script
-
- sources = []
- outputs = [ "$root_build_dir/$app_name.app" ]
-
- args = [
- "structure",
- "-d",
- rebase_path(root_build_dir),
- "-n",
- app_name
- ]
-
- }
-
- # Generate the executable
-
- bin_gen_target_name = target_name + "_bin"
-
- executable(bin_gen_target_name) {
- libs = [
- "AudioToolbox.framework",
- "AVFoundation.framework",
- "OpenGLES.framework",
- "QuartzCore.framework",
- "UIKit.framework",
- ]
- deps = invoker.deps
- output_name = app_name
- }
-
- # Process the Info.plist
-
- plist_gen_target_name = target_name + "_plist"
-
- action(plist_gen_target_name) {
-
- script = ios_app_script
-
- sources = [ invoker.info_plist ]
- outputs = [ "$root_build_dir/plist/$app_name/Info.plist" ]
-
- args = [
- "plist",
- "-i",
- rebase_path(invoker.info_plist, root_build_dir),
- "-o",
- rebase_path("$root_build_dir/plist/$app_name"),
- ]
- }
-
- # Copy the generated binaries and assets to their appropriate locations
-
- copy_gen_target_name = target_name + "_copy"
- copy(copy_gen_target_name) {
- sources = [
- "$root_build_dir/plist/$app_name/Info.plist",
- "$root_build_dir/$app_name",
- ]
-
- outputs = [
- "$root_build_dir/$app_name.app/{{source_file_part}}"
- ]
-
- deps = [
- ":$struct_gen_target_name",
- ":$bin_gen_target_name",
- ":$plist_gen_target_name",
- ]
- }
-
- # Generate the Xcode Harness for Profiling
-
- xcode_harness_gen_target_name = app_name + "_harness"
- xcode_harness_ios(xcode_harness_gen_target_name) {
- app_bundle = "$root_build_dir/$app_name.app"
- deps = [
- ":$bin_gen_target_name",
- ":$struct_gen_target_name",
- ":$copy_gen_target_name",
- ]
- }
-
- # Perform Code Signing
-
- code_sign_gen_target_name = target_name + "_codesign"
- code_sign_ios(code_sign_gen_target_name) {
- entitlements_path = invoker.entitlements_path
- identity = invoker.code_signing_identity
- application_path = "$root_build_dir/$app_name.app"
- deps = [ ":$copy_gen_target_name" ]
- }
-
- # Top level group
-
- group(target_name) {
- # Skip code signing if no identity is provided. This is useful for simulator
- # builds
- deps = [ ":$xcode_harness_gen_target_name" ]
- if (invoker.code_signing_identity == "") {
- deps += [ ":$copy_gen_target_name" ]
- } else {
- deps += [ ":$code_sign_gen_target_name" ]
- }
- }
-
-}
diff --git a/build/config/mac/BUILD.gn b/build/config/mac/BUILD.gn
index 132e12c..5825641 100644
--- a/build/config/mac/BUILD.gn
+++ b/build/config/mac/BUILD.gn
@@ -19,6 +19,9 @@
"-Wl,-search_paths_first",
"-L.",
+ # Forces shared libraries to search for undefined symbols.
+ "-undefined", "dynamic_lookup",
+
# Path for loading shared libraries for unbundled binaries.
"-Wl,-rpath,@loader_path/.",
diff --git a/build/config/mac/mac_sdk.gni b/build/config/mac/mac_sdk.gni
index 54b68c4..b2a89e5 100644
--- a/build/config/mac/mac_sdk.gni
+++ b/build/config/mac/mac_sdk.gni
@@ -2,8 +2,6 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import("//build/config/chrome_build.gni")
-
declare_args() {
# Minimum supported version of the Mac SDK.
mac_sdk_min = "10.8"
@@ -14,16 +12,7 @@
mac_sdk_path = ""
}
-find_sdk_args = [ "--print_sdk_path" ]
-if (is_chrome_branded && is_official_build) {
- find_sdk_args += [
- "--verify",
- mac_sdk_min,
- "--sdk_path=" + mac_sdk_path,
- ]
-} else {
- find_sdk_args += [ mac_sdk_min ]
-}
+find_sdk_args = [ "--print_sdk_path", mac_sdk_min ]
# The tool will print the SDK path on the first line, and the version on the
# second line.
diff --git a/build/config/win/BUILD.gn b/build/config/win/BUILD.gn
index c939100..ed6583e 100644
--- a/build/config/win/BUILD.gn
+++ b/build/config/win/BUILD.gn
@@ -65,6 +65,7 @@
"/FIXED:NO",
"/ignore:4199",
"/ignore:4221",
+ "/ignore:4197", # Disable multiple Dart_True export warning.
"/NXCOMPAT",
# Suggested by Microsoft Devrel to avoid
@@ -85,17 +86,9 @@
} else {
ldflags += [ "/DYNAMICBASE" ]
}
-
- # Delay loaded DLLs.
- ldflags += [
- "/DELAYLOAD:dbghelp.dll",
- "/DELAYLOAD:dwmapi.dll",
- "/DELAYLOAD:shell32.dll",
- "/DELAYLOAD:uxtheme.dll",
- ]
}
-# Subsystem --------------------------------------------------------------------
+# Subsystem -------------------------------------------------------------------
# This is appended to the subsystem to specify a minimum version.
if (current_cpu == "x64") {
@@ -114,7 +107,7 @@
ldflags = [ "/SUBSYSTEM:WINDOWS$subsystem_version_suffix" ]
}
-# Incremental linking ----------------------------------------------------------
+# Incremental linking ---------------------------------------------------------
incremental_linking_on_switch = [ "/INCREMENTAL" ]
incremental_linking_off_switch = [ "/INCREMENTAL:NO" ]
@@ -151,7 +144,7 @@
}
}
-# Character set ----------------------------------------------------------------
+# Character set ---------------------------------------------------------------
# Not including this config means "ansi" (8-bit system codepage).
config("unicode") {
@@ -161,7 +154,7 @@
]
}
-# Lean and mean ----------------------------------------------------------------
+# Lean and mean ---------------------------------------------------------------
# Some third party code might not compile with WIN32_LEAN_AND_MEAN so we have
# to have a separate config for it. Remove this config from your target to
diff --git a/build/config/win/visual_studio_version.gni b/build/config/win/visual_studio_version.gni
index 6a2828c..782d8e8 100644
--- a/build/config/win/visual_studio_version.gni
+++ b/build/config/win/visual_studio_version.gni
@@ -23,13 +23,13 @@
}
if (visual_studio_path == "") {
- toolchain_data =
+ _toolchain_data =
exec_script("../../vs_toolchain.py", [ "get_toolchain_dir" ], "scope")
- visual_studio_path = toolchain_data.vs_path
- windows_sdk_path = toolchain_data.sdk_path
- visual_studio_version = toolchain_data.vs_version
- wdk_path = toolchain_data.wdk_dir
- visual_studio_runtime_dirs = toolchain_data.runtime_dirs
+ visual_studio_path = _toolchain_data.vs_path
+ windows_sdk_path = _toolchain_data.sdk_path
+ visual_studio_version = _toolchain_data.vs_version
+ wdk_path = _toolchain_data.wdk_dir
+ visual_studio_runtime_dirs = _toolchain_data.runtime_dirs
} else {
assert(visual_studio_version != "",
"You must set the visual_studio_version if you set the path")
diff --git a/build/copy_test_data_ios.gypi b/build/copy_test_data_ios.gypi
deleted file mode 100644
index 576a0f2..0000000
--- a/build/copy_test_data_ios.gypi
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included into an action to copy test data files into
-# an iOS app bundle. To use this the following variables need to be defined:
-# test_data_files: list: paths to test data files or directories
-# test_data_prefix: string: a directory prefix that will be prepended to each
-# output path. Generally, this should be the base
-# directory of the gypi file containing the unittest
-# target (e.g. "base" or "chrome").
-#
-# To use this, create a gyp target with the following form:
-# {
-# 'target_name': 'my_unittests',
-# 'conditions': [
-# ['OS == "ios"', {
-# 'actions': [
-# {
-# 'action_name': 'copy_test_data',
-# 'variables': {
-# 'test_data_files': [
-# 'path/to/datafile.txt',
-# 'path/to/data/directory/',
-# ]
-# 'test_data_prefix' : 'prefix',
-# },
-# 'includes': ['path/to/this/gypi/file'],
-# },
-# ],
-# }],
-# }
-#
-
-{
- 'inputs': [
- # The |-o <(test_data_prefix)| is ignored; it is there to work around a
- # caching bug in gyp (https://code.google.com/p/gyp/issues/detail?id=112).
- # It caches command output when the string is the same, so if two copy
- # steps have the same relative paths, there can be bogus cache hits that
- # cause compile failures unless something varies.
- '<!@pymod_do_main(copy_test_data_ios -o <(test_data_prefix) --inputs <(test_data_files))',
- ],
- 'outputs': [
- '<!@pymod_do_main(copy_test_data_ios -o <(PRODUCT_DIR)/<(_target_name).app/<(test_data_prefix) --outputs <(test_data_files))',
- ],
- 'action': [
- 'python',
- '<(DEPTH)/build/copy_test_data_ios.py',
- '-o', '<(PRODUCT_DIR)/<(_target_name).app/<(test_data_prefix)',
- '<@(_inputs)',
- ],
-}
diff --git a/build/copy_test_data_ios.py b/build/copy_test_data_ios.py
deleted file mode 100755
index 6f0302f..0000000
--- a/build/copy_test_data_ios.py
+++ /dev/null
@@ -1,105 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Copies test data files or directories into a given output directory."""
-
-import optparse
-import os
-import shutil
-import sys
-
-class WrongNumberOfArgumentsException(Exception):
- pass
-
-def EscapePath(path):
- """Returns a path with spaces escaped."""
- return path.replace(" ", "\\ ")
-
-def ListFilesForPath(path):
- """Returns a list of all the files under a given path."""
- output = []
- # Ignore revision control metadata directories.
- if (os.path.basename(path).startswith('.git') or
- os.path.basename(path).startswith('.svn')):
- return output
-
- # Files get returned without modification.
- if not os.path.isdir(path):
- output.append(path)
- return output
-
- # Directories get recursively expanded.
- contents = os.listdir(path)
- for item in contents:
- full_path = os.path.join(path, item)
- output.extend(ListFilesForPath(full_path))
- return output
-
-def CalcInputs(inputs):
- """Computes the full list of input files for a set of command-line arguments.
- """
- # |inputs| is a list of paths, which may be directories.
- output = []
- for input in inputs:
- output.extend(ListFilesForPath(input))
- return output
-
-def CopyFiles(relative_filenames, output_basedir):
- """Copies files to the given output directory."""
- for file in relative_filenames:
- relative_dirname = os.path.dirname(file)
- output_dir = os.path.join(output_basedir, relative_dirname)
- output_filename = os.path.join(output_basedir, file)
-
- # In cases where a directory has turned into a file or vice versa, delete it
- # before copying it below.
- if os.path.exists(output_dir) and not os.path.isdir(output_dir):
- os.remove(output_dir)
- if os.path.exists(output_filename) and os.path.isdir(output_filename):
- shutil.rmtree(output_filename)
-
- if not os.path.exists(output_dir):
- os.makedirs(output_dir)
- shutil.copy(file, output_filename)
-
-def DoMain(argv):
- parser = optparse.OptionParser()
- usage = 'Usage: %prog -o <output_dir> [--inputs] [--outputs] <input_files>'
- parser.set_usage(usage)
- parser.add_option('-o', dest='output_dir')
- parser.add_option('--inputs', action='store_true', dest='list_inputs')
- parser.add_option('--outputs', action='store_true', dest='list_outputs')
- options, arglist = parser.parse_args(argv)
-
- if len(arglist) == 0:
- raise WrongNumberOfArgumentsException('<input_files> required.')
-
- files_to_copy = CalcInputs(arglist)
- escaped_files = [EscapePath(x) for x in CalcInputs(arglist)]
- if options.list_inputs:
- return '\n'.join(escaped_files)
-
- if not options.output_dir:
- raise WrongNumberOfArgumentsException('-o required.')
-
- if options.list_outputs:
- outputs = [os.path.join(options.output_dir, x) for x in escaped_files]
- return '\n'.join(outputs)
-
- CopyFiles(files_to_copy, options.output_dir)
- return
-
-def main(argv):
- try:
- result = DoMain(argv[1:])
- except WrongNumberOfArgumentsException, e:
- print >>sys.stderr, e
- return 1
- if result:
- print result
- return 0
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv))
diff --git a/build/cp.py b/build/cp.py
deleted file mode 100755
index 0f32536..0000000
--- a/build/cp.py
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Copy a file.
-
-This module works much like the cp posix command - it takes 2 arguments:
-(src, dst) and copies the file with path |src| to |dst|.
-"""
-
-import os
-import shutil
-import sys
-
-
-def Main(src, dst):
- # Use copy instead of copyfile to ensure the executable bit is copied.
- return shutil.copy(src, os.path.normpath(dst))
-
-
-if __name__ == '__main__':
- sys.exit(Main(sys.argv[1], sys.argv[2]))
diff --git a/build/detect_host_arch.py b/build/detect_host_arch.py
deleted file mode 100755
index 19579eb..0000000
--- a/build/detect_host_arch.py
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Outputs host CPU architecture in format recognized by gyp."""
-
-import platform
-import re
-import sys
-
-
-def HostArch():
- """Returns the host architecture with a predictable string."""
- host_arch = platform.machine()
-
- # Convert machine type to format recognized by gyp.
- if re.match(r'i.86', host_arch) or host_arch == 'i86pc':
- host_arch = 'ia32'
- elif host_arch in ['x86_64', 'amd64']:
- host_arch = 'x64'
- elif host_arch.startswith('arm'):
- host_arch = 'arm'
-
- # platform.machine is based on running kernel. It's possible to use 64-bit
- # kernel with 32-bit userland, e.g. to give linker slightly more memory.
- # Distinguish between different userland bitness by querying
- # the python binary.
- if host_arch == 'x64' and platform.architecture()[0] == '32bit':
- host_arch = 'ia32'
-
- return host_arch
-
-def DoMain(_):
- """Hook to be called from gyp without starting a separate python
- interpreter."""
- return HostArch()
-
-if __name__ == '__main__':
- print DoMain([])
diff --git a/build/dir_exists.py b/build/dir_exists.py
deleted file mode 100755
index 70d367e..0000000
--- a/build/dir_exists.py
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2011 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-"""Writes True if the argument is a directory."""
-
-import os.path
-import sys
-
-def main():
- sys.stdout.write(_is_dir(sys.argv[1]))
- return 0
-
-def _is_dir(dir_name):
- return str(os.path.isdir(dir_name))
-
-def DoMain(args):
- """Hook to be called from gyp without starting a separate python
- interpreter."""
- return _is_dir(args[0])
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/build/download_gold_plugin.py b/build/download_gold_plugin.py
deleted file mode 100755
index cd7ca41..0000000
--- a/build/download_gold_plugin.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Script to download LLVM gold plugin from google storage."""
-
-import json
-import os
-import shutil
-import subprocess
-import sys
-import zipfile
-
-SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
-CHROME_SRC = os.path.abspath(os.path.join(SCRIPT_DIR, os.pardir))
-sys.path.insert(0, os.path.join(CHROME_SRC, 'tools'))
-
-import find_depot_tools
-
-DEPOT_PATH = find_depot_tools.add_depot_tools_to_path()
-GSUTIL_PATH = os.path.join(DEPOT_PATH, 'gsutil.py')
-
-LLVM_BUILD_PATH = os.path.join(CHROME_SRC, 'third_party', 'llvm-build',
- 'Release+Asserts')
-CLANG_UPDATE_PY = os.path.join(CHROME_SRC, 'tools', 'clang', 'scripts',
- 'update.py')
-CLANG_REVISION = os.popen(CLANG_UPDATE_PY + ' --print-revision').read().rstrip()
-
-CLANG_BUCKET = 'gs://chromium-browser-clang/Linux_x64'
-
-def main():
- targz_name = 'llvmgold-%s.tgz' % CLANG_REVISION
- remote_path = '%s/%s' % (CLANG_BUCKET, targz_name)
-
- os.chdir(LLVM_BUILD_PATH)
-
- subprocess.check_call(['python', GSUTIL_PATH,
- 'cp', remote_path, targz_name])
- subprocess.check_call(['tar', 'xzf', targz_name])
- os.remove(targz_name)
- return 0
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/build/download_nacl_toolchains.py b/build/download_nacl_toolchains.py
deleted file mode 100755
index b99b940..0000000
--- a/build/download_nacl_toolchains.py
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Shim to run nacl toolchain download script only if there is a nacl dir."""
-
-import os
-import shutil
-import sys
-
-
-def Main(args):
- # Exit early if disable_nacl=1.
- if 'disable_nacl=1' in os.environ.get('GYP_DEFINES', ''):
- return 0
- script_dir = os.path.dirname(os.path.abspath(__file__))
- src_dir = os.path.dirname(script_dir)
- nacl_dir = os.path.join(src_dir, 'native_client')
- nacl_build_dir = os.path.join(nacl_dir, 'build')
- package_version_dir = os.path.join(nacl_build_dir, 'package_version')
- package_version = os.path.join(package_version_dir, 'package_version.py')
- if not os.path.exists(package_version):
- print "Can't find '%s'" % package_version
- print 'Presumably you are intentionally building without NativeClient.'
- print 'Skipping NativeClient toolchain download.'
- sys.exit(0)
- sys.path.insert(0, package_version_dir)
- import package_version
-
- # BUG:
- # We remove this --optional-pnacl argument, and instead replace it with
- # --no-pnacl for most cases. However, if the bot name is an sdk
- # bot then we will go ahead and download it. This prevents increasing the
- # gclient sync time for developers, or standard Chrome bots.
- if '--optional-pnacl' in args:
- args.remove('--optional-pnacl')
- use_pnacl = False
- buildbot_name = os.environ.get('BUILDBOT_BUILDERNAME', '')
- if 'pnacl' in buildbot_name and 'sdk' in buildbot_name:
- use_pnacl = True
- if use_pnacl:
- print '\n*** DOWNLOADING PNACL TOOLCHAIN ***\n'
- else:
- args = ['--exclude', 'pnacl_newlib'] + args
-
- # Only download the ARM gcc toolchain if we are building for ARM
- # TODO(olonho): we need to invent more reliable way to get build
- # configuration info, to know if we're building for ARM.
- if 'target_arch=arm' not in os.environ.get('GYP_DEFINES', ''):
- args = ['--exclude', 'nacl_arm_newlib'] + args
-
- package_version.main(args)
-
- return 0
-
-
-if __name__ == '__main__':
- sys.exit(Main(sys.argv[1:]))
diff --git a/build/download_sdk_extras.py b/build/download_sdk_extras.py
deleted file mode 100755
index d7c5d6c..0000000
--- a/build/download_sdk_extras.py
+++ /dev/null
@@ -1,71 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Script to download sdk/extras packages on the bots from google storage.
-
-The script expects arguments that specify zips file in the google storage
-bucket named: <dir in SDK extras>_<package name>_<version>.zip. The file will
-be extracted in the android_tools/sdk/extras directory on the test bots. This
-script will not do anything for developers.
-
-TODO(navabi): Move this script (crbug.com/459819).
-"""
-
-import json
-import os
-import shutil
-import subprocess
-import sys
-import zipfile
-
-SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
-CHROME_SRC = os.path.abspath(os.path.join(SCRIPT_DIR, os.pardir))
-sys.path.insert(0, os.path.join(SCRIPT_DIR, 'android'))
-sys.path.insert(1, os.path.join(CHROME_SRC, 'tools'))
-
-from pylib import constants
-import find_depot_tools
-
-DEPOT_PATH = find_depot_tools.add_depot_tools_to_path()
-GSUTIL_PATH = os.path.join(DEPOT_PATH, 'gsutil.py')
-SDK_EXTRAS_BUCKET = 'gs://chrome-sdk-extras'
-SDK_EXTRAS_PATH = os.path.join(constants.ANDROID_SDK_ROOT, 'extras')
-SDK_EXTRAS_JSON_FILE = os.path.join(os.path.dirname(__file__),
- 'android_sdk_extras.json')
-
-
-def clean_and_extract(dir_name, package_name, zip_file):
- local_dir = '%s/%s/%s' % (SDK_EXTRAS_PATH, dir_name, package_name)
- if os.path.exists(local_dir):
- shutil.rmtree(local_dir)
- local_zip = '%s/%s' % (SDK_EXTRAS_PATH, zip_file)
- with zipfile.ZipFile(local_zip) as z:
- z.extractall(path=SDK_EXTRAS_PATH)
-
-
-def main():
- if not os.environ.get('CHROME_HEADLESS'):
- # This is not a buildbot checkout.
- return 0
- # Update the android_sdk_extras.json file to update downloaded packages.
- with open(SDK_EXTRAS_JSON_FILE) as json_file:
- packages = json.load(json_file)
- for package in packages:
- local_zip = '%s/%s' % (SDK_EXTRAS_PATH, package['zip'])
- if not os.path.exists(local_zip):
- package_zip = '%s/%s' % (SDK_EXTRAS_BUCKET, package['zip'])
- try:
- subprocess.check_call(['python', GSUTIL_PATH, '--force-version', '4.7',
- 'cp', package_zip, local_zip])
- except subprocess.CalledProcessError:
- print ('WARNING: Failed to download SDK packages. If this bot compiles '
- 'for Android, it may have errors.')
- return 0
- # Always clean dir and extract zip to ensure correct contents.
- clean_and_extract(package['dir_name'], package['package'], package['zip'])
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/build/env_dump.py b/build/env_dump.py
deleted file mode 100755
index 21edfe6..0000000
--- a/build/env_dump.py
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/usr/bin/python
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This script can either source a file and dump the enironment changes done by
-# it, or just simply dump the current environment as JSON into a file.
-
-import json
-import optparse
-import os
-import pipes
-import subprocess
-import sys
-
-
-def main():
- parser = optparse.OptionParser()
- parser.add_option('-f', '--output-json',
- help='File to dump the environment as JSON into.')
- parser.add_option(
- '-d', '--dump-mode', action='store_true',
- help='Dump the environment to sys.stdout and exit immediately.')
-
- parser.disable_interspersed_args()
- options, args = parser.parse_args()
- if options.dump_mode:
- if args or options.output_json:
- parser.error('Cannot specify args or --output-json with --dump-mode.')
- json.dump(dict(os.environ), sys.stdout)
- else:
- if not options.output_json:
- parser.error('Requires --output-json option.')
-
- envsetup_cmd = ' '.join(map(pipes.quote, args))
- full_cmd = [
- 'bash', '-c',
- '. %s > /dev/null; %s -d' % (envsetup_cmd, os.path.abspath(__file__))
- ]
- try:
- output = subprocess.check_output(full_cmd)
- except Exception as e:
- sys.exit('Error running %s and dumping environment.' % envsetup_cmd)
-
- env_diff = {}
- new_env = json.loads(output)
- for k, val in new_env.items():
- if k == '_' or (k in os.environ and os.environ[k] == val):
- continue
- env_diff[k] = val
- with open(options.output_json, 'w') as f:
- json.dump(env_diff, f)
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/build/extract_from_cab.py b/build/extract_from_cab.py
deleted file mode 100755
index 080370c..0000000
--- a/build/extract_from_cab.py
+++ /dev/null
@@ -1,63 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Extracts a single file from a CAB archive."""
-
-import os
-import shutil
-import subprocess
-import sys
-import tempfile
-
-def run_quiet(*args):
- """Run 'expand' suppressing noisy output. Returns returncode from process."""
- popen = subprocess.Popen(args, stdout=subprocess.PIPE)
- out, _ = popen.communicate()
- if popen.returncode:
- # expand emits errors to stdout, so if we fail, then print that out.
- print out
- return popen.returncode
-
-def main():
- if len(sys.argv) != 4:
- print 'Usage: extract_from_cab.py cab_path archived_file output_dir'
- return 1
-
- [cab_path, archived_file, output_dir] = sys.argv[1:]
-
- # Expand.exe does its work in a fixed-named temporary directory created within
- # the given output directory. This is a problem for concurrent extractions, so
- # create a unique temp dir within the desired output directory to work around
- # this limitation.
- temp_dir = tempfile.mkdtemp(dir=output_dir)
-
- try:
- # Invoke the Windows expand utility to extract the file.
- level = run_quiet('expand', cab_path, '-F:' + archived_file, temp_dir)
- if level == 0:
- # Move the output file into place, preserving expand.exe's behavior of
- # paving over any preexisting file.
- output_file = os.path.join(output_dir, archived_file)
- try:
- os.remove(output_file)
- except OSError:
- pass
- os.rename(os.path.join(temp_dir, archived_file), output_file)
- finally:
- shutil.rmtree(temp_dir, True)
-
- if level != 0:
- return level
-
- # The expand utility preserves the modification date and time of the archived
- # file. Touch the extracted file. This helps build systems that compare the
- # modification times of input and output files to determine whether to do an
- # action.
- os.utime(os.path.join(output_dir, archived_file), None)
- return 0
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/build/filename_rules.gypi b/build/filename_rules.gypi
deleted file mode 100644
index f67287f..0000000
--- a/build/filename_rules.gypi
+++ /dev/null
@@ -1,106 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This gypi file defines the patterns used for determining whether a
-# file is excluded from the build on a given platform. It is
-# included by common.gypi for chromium_code.
-
-{
- 'target_conditions': [
- ['OS!="win" or >(nacl_untrusted_build)==1', {
- 'sources/': [ ['exclude', '_win(_browsertest|_unittest)?\\.(h|cc)$'],
- ['exclude', '(^|/)win/'],
- ['exclude', '(^|/)win_[^/]*\\.(h|cc)$'] ],
- }],
- ['OS!="mac" or >(nacl_untrusted_build)==1', {
- 'sources/': [ ['exclude', '_(cocoa|mac)(_unittest)?\\.(h|cc|mm?)$'],
- ['exclude', '(^|/)(cocoa|mac)/'] ],
- }],
- ['OS!="ios" or >(nacl_untrusted_build)==1', {
- 'sources/': [ ['exclude', '_ios(_unittest)?\\.(h|cc|mm?)$'],
- ['exclude', '(^|/)ios/'] ],
- }],
- ['(OS!="mac" and OS!="ios") or >(nacl_untrusted_build)==1', {
- 'sources/': [ ['exclude', '\\.mm?$' ] ],
- }],
- # Do not exclude the linux files on *BSD since most of them can be
- # shared at this point.
- # In case a file is not needed, it is going to be excluded later on.
- # TODO(evan): the above is not correct; we shouldn't build _linux
- # files on non-linux.
- ['OS!="linux" and OS!="openbsd" and OS!="freebsd" or >(nacl_untrusted_build)==1', {
- 'sources/': [
- ['exclude', '_linux(_unittest)?\\.(h|cc)$'],
- ['exclude', '(^|/)linux/'],
- ],
- }],
- ['OS!="android" or _toolset=="host" or >(nacl_untrusted_build)==1', {
- 'sources/': [
- ['exclude', '_android(_unittest)?\\.(h|cc)$'],
- ['exclude', '(^|/)android/'],
- ],
- }],
- ['OS=="win" and >(nacl_untrusted_build)==0', {
- 'sources/': [
- ['exclude', '_posix(_unittest)?\\.(h|cc)$'],
- ['exclude', '(^|/)posix/'],
- ],
- }],
- ['<(chromeos)!=1 or >(nacl_untrusted_build)==1', {
- 'sources/': [
- ['exclude', '_chromeos(_unittest)?\\.(h|cc)$'],
- ['exclude', '(^|/)chromeos/'],
- ],
- }],
- ['>(nacl_untrusted_build)==0', {
- 'sources/': [
- ['exclude', '_nacl(_unittest)?\\.(h|cc)$'],
- ],
- }],
- ['OS!="linux" and OS!="openbsd" and OS!="freebsd" or >(nacl_untrusted_build)==1', {
- 'sources/': [
- ['exclude', '_xdg(_unittest)?\\.(h|cc)$'],
- ],
- }],
- ['<(use_x11)!=1 or >(nacl_untrusted_build)==1', {
- 'sources/': [
- ['exclude', '_(x|x11)(_interactive_uitest|_unittest)?\\.(h|cc)$'],
- ['exclude', '(^|/)x11_[^/]*\\.(h|cc)$'],
- ['exclude', '(^|/)x11/'],
- ['exclude', '(^|/)x/'],
- ],
- }],
- ['<(toolkit_views)==0 or >(nacl_untrusted_build)==1', {
- 'sources/': [ ['exclude', '_views(_browsertest|_unittest)?\\.(h|cc)$'] ]
- }],
- ['<(use_aura)==0 or >(nacl_untrusted_build)==1', {
- 'sources/': [ ['exclude', '_aura(_browsertest|_unittest)?\\.(h|cc)$'],
- ['exclude', '(^|/)aura/'],
- ]
- }],
- ['<(use_aura)==0 or <(use_x11)==0 or >(nacl_untrusted_build)==1', {
- 'sources/': [ ['exclude', '_aurax11(_browsertest|_unittest)?\\.(h|cc)$'] ]
- }],
- ['<(use_aura)==0 or OS!="win" or >(nacl_untrusted_build)==1', {
- 'sources/': [ ['exclude', '_aurawin\\.(h|cc)$'] ]
- }],
- ['<(use_aura)==0 or OS!="linux" or >(nacl_untrusted_build)==1', {
- 'sources/': [ ['exclude', '_auralinux\\.(h|cc)$'] ]
- }],
- ['<(use_ash)==0 or >(nacl_untrusted_build)==1', {
- 'sources/': [ ['exclude', '_ash(_browsertest|_unittest)?\\.(h|cc)$'],
- ['exclude', '(^|/)ash/'],
- ]
- }],
- ['<(use_ash)==0 or OS!="win" or >(nacl_untrusted_build)==1', {
- 'sources/': [ ['exclude', '_ashwin\\.(h|cc)$'] ]
- }],
- ['<(use_ozone)==0 or >(nacl_untrusted_build)==1', {
- 'sources/': [ ['exclude', '_ozone(_browsertest|_unittest)?\\.(h|cc)$'] ]
- }],
- ['<(use_pango)==0', {
- 'sources/': [ ['exclude', '(^|_)pango(_util|_browsertest|_unittest)?\\.(h|cc)$'], ],
- }],
- ]
-}
diff --git a/build/find_isolated_tests.py b/build/find_isolated_tests.py
deleted file mode 100755
index c5b3ab7..0000000
--- a/build/find_isolated_tests.py
+++ /dev/null
@@ -1,78 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Scans build output directory for .isolated files, calculates their SHA1
-hashes, stores final list in JSON document and then removes *.isolated files
-found (to ensure no stale *.isolated stay around on the next build).
-
-Used to figure out what tests were build in isolated mode to trigger these
-tests to run on swarming.
-
-For more info see:
-https://sites.google.com/a/chromium.org/dev/developers/testing/isolated-testing
-"""
-
-import glob
-import hashlib
-import json
-import optparse
-import os
-import re
-import sys
-
-
-def hash_file(filepath):
- """Calculates the hash of a file without reading it all in memory at once."""
- digest = hashlib.sha1()
- with open(filepath, 'rb') as f:
- while True:
- chunk = f.read(1024*1024)
- if not chunk:
- break
- digest.update(chunk)
- return digest.hexdigest()
-
-
-def main():
- parser = optparse.OptionParser(
- usage='%prog --build-dir <path> --output-json <path>',
- description=sys.modules[__name__].__doc__)
- parser.add_option(
- '--build-dir',
- help='Path to a directory to search for *.isolated files.')
- parser.add_option(
- '--output-json',
- help='File to dump JSON results into.')
-
- options, _ = parser.parse_args()
- if not options.build_dir:
- parser.error('--build-dir option is required')
- if not options.output_json:
- parser.error('--output-json option is required')
-
- result = {}
-
- # Get the file hash values and output the pair.
- pattern = os.path.join(options.build_dir, '*.isolated')
- for filepath in sorted(glob.glob(pattern)):
- test_name = os.path.splitext(os.path.basename(filepath))[0]
- if re.match(r'^.+?\.\d$', test_name):
- # It's a split .isolated file, e.g. foo.0.isolated. Ignore these.
- continue
-
- # TODO(csharp): Remove deletion once the isolate tracked dependencies are
- # inputs for the isolated files.
- sha1_hash = hash_file(filepath)
- os.remove(filepath)
- result[test_name] = sha1_hash
-
- with open(options.output_json, 'wb') as f:
- json.dump(result, f)
-
- return 0
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/build/gdb-add-index b/build/gdb-add-index
deleted file mode 100755
index 992ac16..0000000
--- a/build/gdb-add-index
+++ /dev/null
@@ -1,162 +0,0 @@
-#!/bin/bash
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-#
-# Saves the gdb index for a given binary and its shared library dependencies.
-#
-# This will run gdb index in parallel on a number of binaries using SIGUSR1
-# as the communication mechanism to simulate a semaphore. Because of the
-# nature of this technique, using "set -e" is very difficult. The SIGUSR1
-# terminates a "wait" with an error which we need to interpret.
-#
-# When modifying this code, most of the real logic is in the index_one_file
-# function. The rest is cleanup + sempahore plumbing.
-
-# Cleanup temp directory and ensure all child jobs are dead-dead.
-function on_exit {
- trap "" EXIT USR1 # Avoid reentrancy.
-
- local jobs=$(jobs -p)
- if [ -n "$jobs" ]; then
- echo -n "Killing outstanding index jobs..."
- kill -KILL $(jobs -p)
- wait
- echo "done"
- fi
-
- if [ -f "$DIRECTORY" ]; then
- echo -n "Removing temp directory $DIRECTORY..."
- rm -rf $DIRECTORY
- echo done
- fi
-}
-
-# Add index to one binary.
-function index_one_file {
- local file=$1
- local basename=$(basename "$file")
- local should_index="${SHOULD_INDEX}"
-
- local readelf_out=$(${TOOLCHAIN_PREFIX}readelf -S "$file")
- if [[ $readelf_out =~ "gdb_index" ]]; then
- if [ "${REMOVE_INDEX}" = 1 ]; then
- ${TOOLCHAIN_PREFIX}objcopy --remove-section .gdb_index "$file"
- echo "Removed index from $basename."
- else
- echo "Skipped $basename -- already contains index."
- should_index=0
- fi
- fi
-
- if [ "${should_index}" = 1 ]; then
- local start=$(date +"%s%N")
- echo "Adding index to $basename..."
-
- ${TOOLCHAIN_PREFIX}gdb -batch "$file" -ex "save gdb-index $DIRECTORY" \
- -ex "quit"
- local index_file="$DIRECTORY/$basename.gdb-index"
- if [ -f "$index_file" ]; then
- ${TOOLCHAIN_PREFIX}objcopy --add-section .gdb_index="$index_file" \
- --set-section-flags .gdb_index=readonly "$file" "$file"
- local finish=$(date +"%s%N")
- local elapsed=$(((finish - start)/1000000))
- echo " ...$basename indexed. [${elapsed}ms]"
- else
- echo " ...$basename unindexable."
- fi
- fi
-}
-
-# Functions that when combined, concurrently index all files in FILES_TO_INDEX
-# array. The global FILES_TO_INDEX is declared in the main body of the script.
-function async_index {
- # Start a background subshell to run the index command.
- {
- index_one_file $1
- kill -SIGUSR1 $$ # $$ resolves to the parent script.
- exit 129 # See comment above wait loop at bottom.
- } &
-}
-
-CUR_FILE_NUM=0
-function index_next {
- if (( CUR_FILE_NUM >= ${#FILES_TO_INDEX[@]} )); then
- return
- fi
-
- async_index "${FILES_TO_INDEX[CUR_FILE_NUM]}"
- ((CUR_FILE_NUM += 1)) || true
-}
-
-
-########
-### Main body of the script.
-
-REMOVE_INDEX=0
-SHOULD_INDEX=1
-while getopts ":f:r" opt; do
- case $opt in
- f)
- REMOVE_INDEX=1
- shift
- ;;
- r)
- REMOVE_INDEX=1
- SHOULD_INDEX=0
- shift
- ;;
- *)
- echo "Invalid option: -$OPTARG" >&2
- ;;
- esac
-done
-
-if [[ ! $# == 1 ]]; then
- echo "Usage: $0 [-f] [-r] path-to-binary"
- echo " -f forces replacement of an existing index."
- echo " -r removes the index section."
- exit 1
-fi
-
-FILENAME="$1"
-if [[ ! -f "$FILENAME" ]]; then
- echo "Path $FILENAME does not exist."
- exit 1
-fi
-
-# Ensure we cleanup on on exit.
-trap on_exit EXIT
-
-# We're good to go! Create temp directory for index files.
-DIRECTORY=$(mktemp -d)
-echo "Made temp directory $DIRECTORY."
-
-# Create array with the filename and all shared libraries that
-# have the same dirname. The dirname is a signal that these
-# shared libraries were part of the same build as the binary.
-declare -a FILES_TO_INDEX=($FILENAME
- $(ldd "$FILENAME" 2>/dev/null \
- | grep $(dirname "$FILENAME") \
- | sed "s/.*[ \t]\(.*\) (.*/\1/")
-)
-
-# Start concurrent indexing.
-trap index_next USR1
-
-# 4 is an arbitrary default. When changing, remember we are likely IO bound
-# so basing this off the number of cores is not sensible.
-INDEX_TASKS=${INDEX_TASKS:-4}
-for ((i=0;i<${INDEX_TASKS};i++)); do
- index_next
-done
-
-# Do a wait loop. Bash waits that terminate due a trap have an exit
-# code > 128. We also ensure that our subshell's "normal" exit occurs with
-# an exit code > 128. This allows us to do consider a > 128 exit code as
-# an indication that the loop should continue. Unfortunately, it also means
-# we cannot use set -e since technically the "wait" is failing.
-wait
-while (( $? > 128 )); do
- wait
-done
diff --git a/build/get_landmines.py b/build/get_landmines.py
deleted file mode 100755
index 92f81fe..0000000
--- a/build/get_landmines.py
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""
-This file emits the list of reasons why a particular build needs to be clobbered
-(or a list of 'landmines').
-"""
-
-import sys
-
-import landmine_utils
-
-
-builder = landmine_utils.builder
-distributor = landmine_utils.distributor
-gyp_defines = landmine_utils.gyp_defines
-gyp_msvs_version = landmine_utils.gyp_msvs_version
-platform = landmine_utils.platform
-
-
-def print_landmines():
- """
- ALL LANDMINES ARE EMITTED FROM HERE.
- """
- # DO NOT add landmines as part of a regular CL. Landmines are a last-effort
- # bandaid fix if a CL that got landed has a build dependency bug and all bots
- # need to be cleaned up. If you're writing a new CL that causes build
- # dependency problems, fix the dependency problems instead of adding a
- # landmine.
-
- print 'Lets start a new landmines file.'
-
-
-def main():
- print_landmines()
- return 0
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/build/get_sdk_extras_packages.py b/build/get_sdk_extras_packages.py
deleted file mode 100755
index a90b8a8..0000000
--- a/build/get_sdk_extras_packages.py
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import json
-import os
-import sys
-
-SDK_EXTRAS_JSON_FILE = os.path.join(os.path.dirname(__file__),
- 'android_sdk_extras.json')
-
-def main():
- with open(SDK_EXTRAS_JSON_FILE) as json_file:
- packages = json.load(json_file)
-
- out = []
- for package in packages:
- out.append(package['package_id'])
-
- print ','.join(out)
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/build/get_syzygy_binaries.py b/build/get_syzygy_binaries.py
deleted file mode 100755
index 1cab3fc..0000000
--- a/build/get_syzygy_binaries.py
+++ /dev/null
@@ -1,487 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""A utility script for downloading versioned Syzygy binaries."""
-
-import hashlib
-import errno
-import json
-import logging
-import optparse
-import os
-import re
-import shutil
-import stat
-import sys
-import subprocess
-import tempfile
-import time
-import zipfile
-
-
-_LOGGER = logging.getLogger(os.path.basename(__file__))
-
-# The relative path where official builds are archived in their GS bucket.
-_SYZYGY_ARCHIVE_PATH = ('/builds/official/%(revision)s')
-
-# A JSON file containing the state of the download directory. If this file and
-# directory state do not agree, then the binaries will be downloaded and
-# installed again.
-_STATE = '.state'
-
-# This matches an integer (an SVN revision number) or a SHA1 value (a GIT hash).
-# The archive exclusively uses lowercase GIT hashes.
-_REVISION_RE = re.compile('^(?:\d+|[a-f0-9]{40})$')
-
-# This matches an MD5 hash.
-_MD5_RE = re.compile('^[a-f0-9]{32}$')
-
-# List of reources to be downloaded and installed. These are tuples with the
-# following format:
-# (basename, logging name, relative installation path, extraction filter)
-_RESOURCES = [
- ('benchmark.zip', 'benchmark', '', None),
- ('binaries.zip', 'binaries', 'exe', None),
- ('symbols.zip', 'symbols', 'exe',
- lambda x: x.filename.endswith('.dll.pdb'))]
-
-
-def _LoadState(output_dir):
- """Loads the contents of the state file for a given |output_dir|, returning
- None if it doesn't exist.
- """
- path = os.path.join(output_dir, _STATE)
- if not os.path.exists(path):
- _LOGGER.debug('No state file found.')
- return None
- with open(path, 'rb') as f:
- _LOGGER.debug('Reading state file: %s', path)
- try:
- return json.load(f)
- except ValueError:
- _LOGGER.debug('Invalid state file.')
- return None
-
-
-def _SaveState(output_dir, state, dry_run=False):
- """Saves the |state| dictionary to the given |output_dir| as a JSON file."""
- path = os.path.join(output_dir, _STATE)
- _LOGGER.debug('Writing state file: %s', path)
- if dry_run:
- return
- with open(path, 'wb') as f:
- f.write(json.dumps(state, sort_keys=True, indent=2))
-
-
-def _Md5(path):
- """Returns the MD5 hash of the file at |path|, which must exist."""
- return hashlib.md5(open(path, 'rb').read()).hexdigest()
-
-
-def _StateIsValid(state):
- """Returns true if the given state structure is valid."""
- if not isinstance(state, dict):
- _LOGGER.debug('State must be a dict.')
- return False
- r = state.get('revision', None)
- if not isinstance(r, basestring) or not _REVISION_RE.match(r):
- _LOGGER.debug('State contains an invalid revision.')
- return False
- c = state.get('contents', None)
- if not isinstance(c, dict):
- _LOGGER.debug('State must contain a contents dict.')
- return False
- for (relpath, md5) in c.iteritems():
- if not isinstance(relpath, basestring) or len(relpath) == 0:
- _LOGGER.debug('State contents dict contains an invalid path.')
- return False
- if not isinstance(md5, basestring) or not _MD5_RE.match(md5):
- _LOGGER.debug('State contents dict contains an invalid MD5 digest.')
- return False
- return True
-
-
-def _BuildActualState(stored, revision, output_dir):
- """Builds the actual state using the provided |stored| state as a template.
- Only examines files listed in the stored state, causing the script to ignore
- files that have been added to the directories locally. |stored| must be a
- valid state dictionary.
- """
- contents = {}
- state = { 'revision': revision, 'contents': contents }
- for relpath, md5 in stored['contents'].iteritems():
- abspath = os.path.abspath(os.path.join(output_dir, relpath))
- if os.path.isfile(abspath):
- m = _Md5(abspath)
- contents[relpath] = m
-
- return state
-
-
-def _StatesAreConsistent(stored, actual):
- """Validates whether two state dictionaries are consistent. Both must be valid
- state dictionaries. Additional entries in |actual| are ignored.
- """
- if stored['revision'] != actual['revision']:
- _LOGGER.debug('Mismatched revision number.')
- return False
- cont_stored = stored['contents']
- cont_actual = actual['contents']
- for relpath, md5 in cont_stored.iteritems():
- if relpath not in cont_actual:
- _LOGGER.debug('Missing content: %s', relpath)
- return False
- if md5 != cont_actual[relpath]:
- _LOGGER.debug('Modified content: %s', relpath)
- return False
- return True
-
-
-def _GetCurrentState(revision, output_dir):
- """Loads the current state and checks to see if it is consistent. Returns
- a tuple (state, bool). The returned state will always be valid, even if an
- invalid state is present on disk.
- """
- stored = _LoadState(output_dir)
- if not _StateIsValid(stored):
- _LOGGER.debug('State is invalid.')
- # Return a valid but empty state.
- return ({'revision': '0', 'contents': {}}, False)
- actual = _BuildActualState(stored, revision, output_dir)
- # If the script has been modified consider the state invalid.
- path = os.path.join(output_dir, _STATE)
- if os.path.getmtime(__file__) > os.path.getmtime(path):
- return (stored, False)
- # Otherwise, explicitly validate the state.
- if not _StatesAreConsistent(stored, actual):
- return (stored, False)
- return (stored, True)
-
-
-def _DirIsEmpty(path):
- """Returns true if the given directory is empty, false otherwise."""
- for root, dirs, files in os.walk(path):
- return not dirs and not files
-
-
-def _RmTreeHandleReadOnly(func, path, exc):
- """An error handling function for use with shutil.rmtree. This will
- detect failures to remove read-only files, and will change their properties
- prior to removing them. This is necessary on Windows as os.remove will return
- an access error for read-only files, and git repos contain read-only
- pack/index files.
- """
- excvalue = exc[1]
- if func in (os.rmdir, os.remove) and excvalue.errno == errno.EACCES:
- _LOGGER.debug('Removing read-only path: %s', path)
- os.chmod(path, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
- func(path)
- else:
- raise
-
-
-def _RmTree(path):
- """A wrapper of shutil.rmtree that handles read-only files."""
- shutil.rmtree(path, ignore_errors=False, onerror=_RmTreeHandleReadOnly)
-
-
-def _CleanState(output_dir, state, dry_run=False):
- """Cleans up files/directories in |output_dir| that are referenced by
- the given |state|. Raises an error if there are local changes. Returns a
- dictionary of files that were deleted.
- """
- _LOGGER.debug('Deleting files from previous installation.')
- deleted = {}
-
- # Generate a list of files to delete, relative to |output_dir|.
- contents = state['contents']
- files = sorted(contents.keys())
-
- # Try to delete the files. Keep track of directories to delete as well.
- dirs = {}
- for relpath in files:
- fullpath = os.path.join(output_dir, relpath)
- fulldir = os.path.dirname(fullpath)
- dirs[fulldir] = True
- if os.path.exists(fullpath):
- # If somehow the file has become a directory complain about it.
- if os.path.isdir(fullpath):
- raise Exception('Directory exists where file expected: %s' % fullpath)
-
- # Double check that the file doesn't have local changes. If it does
- # then refuse to delete it.
- if relpath in contents:
- stored_md5 = contents[relpath]
- actual_md5 = _Md5(fullpath)
- if actual_md5 != stored_md5:
- raise Exception('File has local changes: %s' % fullpath)
-
- # The file is unchanged so it can safely be deleted.
- _LOGGER.debug('Deleting file "%s".', fullpath)
- deleted[relpath] = True
- if not dry_run:
- os.unlink(fullpath)
-
- # Sort directories from longest name to shortest. This lets us remove empty
- # directories from the most nested paths first.
- dirs = sorted(dirs.keys(), key=lambda x: len(x), reverse=True)
- for p in dirs:
- if os.path.exists(p) and _DirIsEmpty(p):
- _LOGGER.debug('Deleting empty directory "%s".', p)
- if not dry_run:
- _RmTree(p)
-
- return deleted
-
-
-def _FindGsUtil():
- """Looks for depot_tools and returns the absolute path to gsutil.py."""
- for path in os.environ['PATH'].split(os.pathsep):
- path = os.path.abspath(path)
- git_cl = os.path.join(path, 'git_cl.py')
- gs_util = os.path.join(path, 'gsutil.py')
- if os.path.exists(git_cl) and os.path.exists(gs_util):
- return gs_util
- return None
-
-
-def _GsUtil(*cmd):
- """Runs the given command in gsutil with exponential backoff and retries."""
- gs_util = _FindGsUtil()
- cmd = [sys.executable, gs_util] + list(cmd)
-
- retries = 3
- timeout = 4 # Seconds.
- while True:
- _LOGGER.debug('Running %s', cmd)
- prog = subprocess.Popen(cmd, shell=False)
- prog.communicate()
-
- # Stop retrying on success.
- if prog.returncode == 0:
- return
-
- # Raise a permanent failure if retries have been exhausted.
- if retries == 0:
- raise RuntimeError('Command "%s" returned %d.' % (cmd, prog.returncode))
-
- _LOGGER.debug('Sleeping %d seconds and trying again.', timeout)
- time.sleep(timeout)
- retries -= 1
- timeout *= 2
-
-
-def _Download(resource):
- """Downloads the given GS resource to a temporary file, returning its path."""
- tmp = tempfile.mkstemp(suffix='syzygy_archive')
- os.close(tmp[0])
- url = 'gs://syzygy-archive' + resource
- _GsUtil('cp', url, tmp[1])
- return tmp[1]
-
-
-def _InstallBinaries(options, deleted={}):
- """Installs Syzygy binaries. This assumes that the output directory has
- already been cleaned, as it will refuse to overwrite existing files."""
- contents = {}
- state = { 'revision': options.revision, 'contents': contents }
- archive_path = _SYZYGY_ARCHIVE_PATH % { 'revision': options.revision }
- if options.resources:
- resources = [(resource, resource, '', None)
- for resource in options.resources]
- else:
- resources = _RESOURCES
- for (base, name, subdir, filt) in resources:
- # Create the output directory if it doesn't exist.
- fulldir = os.path.join(options.output_dir, subdir)
- if os.path.isfile(fulldir):
- raise Exception('File exists where a directory needs to be created: %s' %
- fulldir)
- if not os.path.exists(fulldir):
- _LOGGER.debug('Creating directory: %s', fulldir)
- if not options.dry_run:
- os.makedirs(fulldir)
-
- # Download and read the archive.
- resource = archive_path + '/' + base
- _LOGGER.debug('Retrieving %s archive at "%s".', name, resource)
- path = _Download(resource)
-
- _LOGGER.debug('Unzipping %s archive.', name)
- with open(path, 'rb') as data:
- archive = zipfile.ZipFile(data)
- for entry in archive.infolist():
- if not filt or filt(entry):
- fullpath = os.path.normpath(os.path.join(fulldir, entry.filename))
- relpath = os.path.relpath(fullpath, options.output_dir)
- if os.path.exists(fullpath):
- # If in a dry-run take into account the fact that the file *would*
- # have been deleted.
- if options.dry_run and relpath in deleted:
- pass
- else:
- raise Exception('Path already exists: %s' % fullpath)
-
- # Extract the file and update the state dictionary.
- _LOGGER.debug('Extracting "%s".', fullpath)
- if not options.dry_run:
- archive.extract(entry.filename, fulldir)
- md5 = _Md5(fullpath)
- contents[relpath] = md5
- if sys.platform == 'cygwin':
- os.chmod(fullpath, os.stat(fullpath).st_mode | stat.S_IXUSR)
-
- _LOGGER.debug('Removing temporary file "%s".', path)
- os.remove(path)
-
- return state
-
-
-def _ParseCommandLine():
- """Parses the command-line and returns an options structure."""
- option_parser = optparse.OptionParser()
- option_parser.add_option('--dry-run', action='store_true', default=False,
- help='If true then will simply list actions that would be performed.')
- option_parser.add_option('--force', action='store_true', default=False,
- help='Force an installation even if the binaries are up to date.')
- option_parser.add_option('--no-cleanup', action='store_true', default=False,
- help='Allow installation on non-Windows platforms, and skip the forced '
- 'cleanup step.')
- option_parser.add_option('--output-dir', type='string',
- help='The path where the binaries will be replaced. Existing binaries '
- 'will only be overwritten if not up to date.')
- option_parser.add_option('--overwrite', action='store_true', default=False,
- help='If specified then the installation will happily delete and rewrite '
- 'the entire output directory, blasting any local changes.')
- option_parser.add_option('--revision', type='string',
- help='The SVN revision or GIT hash associated with the required version.')
- option_parser.add_option('--revision-file', type='string',
- help='A text file containing an SVN revision or GIT hash.')
- option_parser.add_option('--resource', type='string', action='append',
- dest='resources', help='A resource to be downloaded.')
- option_parser.add_option('--verbose', dest='log_level', action='store_const',
- default=logging.INFO, const=logging.DEBUG,
- help='Enables verbose logging.')
- option_parser.add_option('--quiet', dest='log_level', action='store_const',
- default=logging.INFO, const=logging.ERROR,
- help='Disables all output except for errors.')
- options, args = option_parser.parse_args()
- if args:
- option_parser.error('Unexpected arguments: %s' % args)
- if not options.output_dir:
- option_parser.error('Must specify --output-dir.')
- if not options.revision and not options.revision_file:
- option_parser.error('Must specify one of --revision or --revision-file.')
- if options.revision and options.revision_file:
- option_parser.error('Must not specify both --revision and --revision-file.')
-
- # Configure logging.
- logging.basicConfig(level=options.log_level)
-
- # If a revision file has been specified then read it.
- if options.revision_file:
- options.revision = open(options.revision_file, 'rb').read().strip()
- _LOGGER.debug('Parsed revision "%s" from file "%s".',
- options.revision, options.revision_file)
-
- # Ensure that the specified SVN revision or GIT hash is valid.
- if not _REVISION_RE.match(options.revision):
- option_parser.error('Must specify a valid SVN or GIT revision.')
-
- # This just makes output prettier to read.
- options.output_dir = os.path.normpath(options.output_dir)
-
- return options
-
-
-def _RemoveOrphanedFiles(options):
- """This is run on non-Windows systems to remove orphaned files that may have
- been downloaded by a previous version of this script.
- """
- # Reconfigure logging to output info messages. This will allow inspection of
- # cleanup status on non-Windows buildbots.
- _LOGGER.setLevel(logging.INFO)
-
- output_dir = os.path.abspath(options.output_dir)
-
- # We only want to clean up the folder in 'src/third_party/syzygy', and we
- # expect to be called with that as an output directory. This is an attempt to
- # not start deleting random things if the script is run from an alternate
- # location, or not called from the gclient hooks.
- expected_syzygy_dir = os.path.abspath(os.path.join(
- os.path.dirname(__file__), '..', 'third_party', 'syzygy'))
- expected_output_dir = os.path.join(expected_syzygy_dir, 'binaries')
- if expected_output_dir != output_dir:
- _LOGGER.info('Unexpected output directory, skipping cleanup.')
- return
-
- if not os.path.isdir(expected_syzygy_dir):
- _LOGGER.info('Output directory does not exist, skipping cleanup.')
- return
-
- def OnError(function, path, excinfo):
- """Logs error encountered by shutil.rmtree."""
- _LOGGER.error('Error when running %s(%s)', function, path, exc_info=excinfo)
-
- _LOGGER.info('Removing orphaned files from %s', expected_syzygy_dir)
- if not options.dry_run:
- shutil.rmtree(expected_syzygy_dir, True, OnError)
-
-
-def main():
- options = _ParseCommandLine()
-
- if options.dry_run:
- _LOGGER.debug('Performing a dry-run.')
-
- # We only care about Windows platforms, as the Syzygy binaries aren't used
- # elsewhere. However, there was a short period of time where this script
- # wasn't gated on OS types, and those OSes downloaded and installed binaries.
- # This will cleanup orphaned files on those operating systems.
- if sys.platform not in ('win32', 'cygwin'):
- if options.no_cleanup:
- _LOGGER.debug('Skipping usual cleanup for non-Windows platforms.')
- else:
- return _RemoveOrphanedFiles(options)
-
- # Load the current installation state, and validate it against the
- # requested installation.
- state, is_consistent = _GetCurrentState(options.revision, options.output_dir)
-
- # Decide whether or not an install is necessary.
- if options.force:
- _LOGGER.debug('Forcing reinstall of binaries.')
- elif is_consistent:
- # Avoid doing any work if the contents of the directory are consistent.
- _LOGGER.debug('State unchanged, no reinstall necessary.')
- return
-
- # Under normal logging this is the only only message that will be reported.
- _LOGGER.info('Installing revision %s Syzygy binaries.',
- options.revision[0:12])
-
- # Clean up the old state to begin with.
- deleted = []
- if options.overwrite:
- if os.path.exists(options.output_dir):
- # If overwrite was specified then take a heavy-handed approach.
- _LOGGER.debug('Deleting entire installation directory.')
- if not options.dry_run:
- _RmTree(options.output_dir)
- else:
- # Otherwise only delete things that the previous installation put in place,
- # and take care to preserve any local changes.
- deleted = _CleanState(options.output_dir, state, options.dry_run)
-
- # Install the new binaries. In a dry-run this will actually download the
- # archives, but it won't write anything to disk.
- state = _InstallBinaries(options, deleted)
-
- # Build and save the state for the directory.
- _SaveState(options.output_dir, state, options.dry_run)
-
-
-if __name__ == '__main__':
- main()
diff --git a/build/git-hooks/OWNERS b/build/git-hooks/OWNERS
deleted file mode 100644
index 3e327dc..0000000
--- a/build/git-hooks/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-set noparent
-szager@chromium.org
-cmp@chromium.org
diff --git a/build/git-hooks/pre-commit b/build/git-hooks/pre-commit
deleted file mode 100755
index 41b5963..0000000
--- a/build/git-hooks/pre-commit
+++ /dev/null
@@ -1,60 +0,0 @@
-#!/bin/sh
-
-submodule_diff() {
- if test -n "$2"; then
- git diff-tree -r --ignore-submodules=dirty "$1" "$2" | grep -e '^:160000' -e '^:...... 160000' | xargs
- else
- git diff-index --cached --ignore-submodules=dirty "$1" | grep -e '^:160000' -e '^:...... 160000' | xargs
- fi
-}
-
-if git rev-parse --verify --quiet --no-revs MERGE_HEAD; then
- merge_base=$(git merge-base HEAD MERGE_HEAD)
- if test -z "$(submodule_diff $merge_base HEAD)"; then
- # Most up-to-date submodules are in MERGE_HEAD.
- head_ref=MERGE_HEAD
- else
- # Most up-to-date submodules are in HEAD.
- head_ref=HEAD
- fi
-else
- # No merge in progress. Submodules must match HEAD.
- head_ref=HEAD
-fi
-
-submods=$(submodule_diff $head_ref)
-if test "$submods"; then
- echo "You are trying to commit changes to the following submodules:" 1>&2
- echo 1>&2
- echo $submods | cut -d ' ' -f 6 | sed 's/^/ /g' 1>&2
- cat <<EOF 1>&2
-
-Submodule commits are not allowed. Please run:
-
- git status --ignore-submodules=dirty
-
-and/or:
-
- git diff-index --cached --ignore-submodules=dirty HEAD
-
-... to see what's in your index.
-
-If you're really and truly trying to roll the version of a submodule, you should
-commit the new version to DEPS, instead.
-EOF
- exit 1
-fi
-
-gitmodules_diff() {
- git diff-index --cached "$1" .gitmodules
-}
-
-if [ "$(git ls-files .gitmodules)" ] && [ "$(gitmodules_diff $head_ref)" ]; then
- cat <<EOF 1>&2
-You are trying to commit a change to .gitmodules. That is not allowed.
-To make changes to submodule names/paths, edit DEPS.
-EOF
- exit 1
-fi
-
-exit 0
diff --git a/build/gn_migration.gypi b/build/gn_migration.gypi
deleted file mode 100644
index 2527b2e..0000000
--- a/build/gn_migration.gypi
+++ /dev/null
@@ -1,726 +0,0 @@
-# Copyright (c) 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file defines five targets that we are using to track the progress of the
-# GYP->GN migration:
-#
-# 'both_gn_and_gyp' lists what GN is currently capable of building and should
-# match the 'both_gn_and_gyp' target in //BUILD.gn.
-#
-# 'gyp_all' Should include everything built when building "all"; i.e., if you
-# type 'ninja gyp_all' and then 'ninja all', the second build should do
-# nothing. 'gyp_all' should just depend on the other four targets.
-#
-# 'gyp_only' lists any targets that are not meant to be ported over to the GN
-# build.
-#
-# 'gyp_remaining' lists all of the targets that still need to be converted,
-# i.e., all of the other (non-empty) targets that a GYP build will build.
-#
-# TODO(GYP): crbug.com/481694. Add a build step to the bot that enforces the
-# above contracts.
-
-{
- 'targets': [
- {
- 'target_name': 'gyp_all',
- 'type': 'none',
- 'dependencies': [
- 'both_gn_and_gyp',
- 'gyp_only',
- 'gyp_remaining',
- ]
- },
- {
- # This target should mirror the structure of //:both_gn_and_gyp
- # in src/BUILD.gn as closely as possible, for ease of comparison.
- 'target_name': 'both_gn_and_gyp',
- 'type': 'none',
- 'dependencies': [
- '../base/base.gyp:base_i18n_perftests',
- '../base/base.gyp:base_perftests',
- '../base/base.gyp:base_unittests',
- '../base/base.gyp:build_utf8_validator_tables#host',
- '../base/base.gyp:check_example',
- '../cc/cc_tests.gyp:cc_perftests',
- '../cc/cc_tests.gyp:cc_unittests',
- '../cc/blink/cc_blink_tests.gyp:cc_blink_unittests',
- '../chrome/chrome.gyp:chrome',
- '../chrome/chrome.gyp:browser_tests',
- '../chrome/chrome.gyp:chrome_app_unittests',
- '../chrome/chrome.gyp:chromedriver',
- '../chrome/chrome.gyp:chromedriver_tests',
- '../chrome/chrome.gyp:chromedriver_unittests',
- '../chrome/chrome.gyp:interactive_ui_tests',
- '../chrome/chrome.gyp:load_library_perf_tests',
- '../chrome/chrome.gyp:performance_browser_tests',
- '../chrome/chrome.gyp:sync_integration_tests',
- '../chrome/chrome.gyp:sync_performance_tests',
- '../chrome/chrome.gyp:unit_tests',
- '../chrome/tools/profile_reset/jtl_compiler.gyp:jtl_compiler',
- '../cloud_print/cloud_print.gyp:cloud_print_unittests',
- '../components/components.gyp:network_hints_browser',
- '../components/components.gyp:policy_templates',
- '../components/components_tests.gyp:components_browsertests',
- '../components/components_tests.gyp:components_perftests',
- '../components/components_tests.gyp:components_unittests',
- '../content/content.gyp:content_app_browser',
- '../content/content.gyp:content_app_child',
- '../content/content_shell_and_tests.gyp:content_browsertests',
- '../content/content_shell_and_tests.gyp:content_gl_benchmark',
- '../content/content_shell_and_tests.gyp:content_gl_tests',
- '../content/content_shell_and_tests.gyp:content_perftests',
- '../content/content_shell_and_tests.gyp:content_shell',
- '../content/content_shell_and_tests.gyp:content_unittests',
- '../courgette/courgette.gyp:courgette',
- '../courgette/courgette.gyp:courgette_fuzz',
- '../courgette/courgette.gyp:courgette_minimal_tool',
- '../courgette/courgette.gyp:courgette_unittests',
- '../crypto/crypto.gyp:crypto_unittests',
- '../extensions/extensions_tests.gyp:extensions_browsertests',
- '../extensions/extensions_tests.gyp:extensions_unittests',
- '../device/device_tests.gyp:device_unittests',
- '../gin/gin.gyp:gin_v8_snapshot_fingerprint',
- '../gin/gin.gyp:gin_shell',
- '../gin/gin.gyp:gin_unittests',
- '../google_apis/gcm/gcm.gyp:gcm_unit_tests',
- '../google_apis/gcm/gcm.gyp:mcs_probe',
- '../google_apis/google_apis.gyp:google_apis_unittests',
- '../gpu/gpu.gyp:angle_unittests',
- '../gpu/gpu.gyp:gl_tests',
- '../gpu/gpu.gyp:gpu_perftests',
- '../gpu/gpu.gyp:gpu_unittests',
- '../gpu/gles2_conform_support/gles2_conform_support.gyp:gles2_conform_support', # TODO(GYP) crbug.com/471920
- '../gpu/gles2_conform_support/gles2_conform_test.gyp:gles2_conform_test', # TODO(GYP) crbug.com/471920
- '../gpu/khronos_glcts_support/khronos_glcts_test.gyp:khronos_glcts_test', # TODO(GYP) crbug.com/471903 to make this complete.
- '../ipc/ipc.gyp:ipc_perftests',
- '../ipc/ipc.gyp:ipc_tests',
- '../ipc/mojo/ipc_mojo.gyp:ipc_mojo_unittests',
- '../jingle/jingle.gyp:jingle_unittests',
- '../media/media.gyp:ffmpeg_regression_tests', # TODO(GYP) this should be conditional on media_use_ffmpeg
- '../media/media.gyp:media_perftests',
- '../media/media.gyp:media_unittests',
- '../media/midi/midi.gyp:midi_unittests',
- '../media/cast/cast.gyp:cast_benchmarks',
- '../media/cast/cast.gyp:cast_unittests',
- '../media/cast/cast.gyp:generate_barcode_video',
- '../media/cast/cast.gyp:generate_timecode_audio',
- '../mojo/mojo.gyp:mojo',
- '../mojo/mojo_base.gyp:mojo_application_base',
- '../mojo/mojo_base.gyp:mojo_common_unittests',
- '../net/net.gyp:crash_cache',
- '../net/net.gyp:crl_set_dump',
- '../net/net.gyp:dns_fuzz_stub',
- '../net/net.gyp:dump_cache',
- '../net/net.gyp:gdig',
- '../net/net.gyp:get_server_time',
- '../net/net.gyp:hpack_example_generator',
- '../net/net.gyp:hpack_fuzz_mutator',
- '../net/net.gyp:hpack_fuzz_wrapper',
- '../net/net.gyp:net_perftests',
- '../net/net.gyp:net_unittests',
- '../net/net.gyp:net_watcher', # TODO(GYP): This should be conditional on use_v8_in_net
- '../net/net.gyp:run_testserver',
- '../net/net.gyp:stress_cache',
- '../net/net.gyp:tld_cleanup',
- '../ppapi/ppapi_internal.gyp:ppapi_example_audio',
- '../ppapi/ppapi_internal.gyp:ppapi_example_audio_input',
- '../ppapi/ppapi_internal.gyp:ppapi_example_c_stub',
- '../ppapi/ppapi_internal.gyp:ppapi_example_cc_stub',
- '../ppapi/ppapi_internal.gyp:ppapi_example_compositor',
- '../ppapi/ppapi_internal.gyp:ppapi_example_crxfs',
- '../ppapi/ppapi_internal.gyp:ppapi_example_enumerate_devices',
- '../ppapi/ppapi_internal.gyp:ppapi_example_file_chooser',
- '../ppapi/ppapi_internal.gyp:ppapi_example_flash_topmost',
- '../ppapi/ppapi_internal.gyp:ppapi_example_gamepad',
- '../ppapi/ppapi_internal.gyp:ppapi_example_gles2',
- '../ppapi/ppapi_internal.gyp:ppapi_example_gles2_spinning_cube',
- '../ppapi/ppapi_internal.gyp:ppapi_example_graphics_2d',
- '../ppapi/ppapi_internal.gyp:ppapi_example_ime',
- '../ppapi/ppapi_internal.gyp:ppapi_example_input',
- '../ppapi/ppapi_internal.gyp:ppapi_example_media_stream_audio',
- '../ppapi/ppapi_internal.gyp:ppapi_example_media_stream_video',
- '../ppapi/ppapi_internal.gyp:ppapi_example_mouse_cursor',
- '../ppapi/ppapi_internal.gyp:ppapi_example_mouse_lock',
- '../ppapi/ppapi_internal.gyp:ppapi_example_paint_manager',
- '../ppapi/ppapi_internal.gyp:ppapi_example_post_message',
- '../ppapi/ppapi_internal.gyp:ppapi_example_printing',
- '../ppapi/ppapi_internal.gyp:ppapi_example_scaling',
- '../ppapi/ppapi_internal.gyp:ppapi_example_scroll',
- '../ppapi/ppapi_internal.gyp:ppapi_example_simple_font',
- '../ppapi/ppapi_internal.gyp:ppapi_example_threading',
- '../ppapi/ppapi_internal.gyp:ppapi_example_url_loader',
- '../ppapi/ppapi_internal.gyp:ppapi_example_url_loader_file',
- '../ppapi/ppapi_internal.gyp:ppapi_example_vc',
- '../ppapi/ppapi_internal.gyp:ppapi_example_video_decode',
- '../ppapi/ppapi_internal.gyp:ppapi_example_video_decode_dev',
- '../ppapi/ppapi_internal.gyp:ppapi_example_video_effects',
- '../ppapi/ppapi_internal.gyp:ppapi_example_video_encode',
- '../ppapi/ppapi_internal.gyp:ppapi_tests',
- '../ppapi/ppapi_internal.gyp:ppapi_perftests',
- '../ppapi/ppapi_internal.gyp:ppapi_unittests',
- '../ppapi/tools/ppapi_tools.gyp:pepper_hash_for_uma',
- '../printing/printing.gyp:printing_unittests',
- '../skia/skia_tests.gyp:skia_unittests',
- '../skia/skia.gyp:filter_fuzz_stub',
- '../skia/skia.gyp:image_operations_bench',
- '../sql/sql.gyp:sql_unittests',
- '../sync/sync.gyp:run_sync_testserver',
- '../sync/sync.gyp:sync_unit_tests',
- '../sync/tools/sync_tools.gyp:sync_client',
- '../sync/tools/sync_tools.gyp:sync_listen_notifications',
- '../testing/gmock.gyp:gmock_main',
- '../third_party/WebKit/Source/platform/blink_platform_tests.gyp:blink_heap_unittests',
- '../third_party/WebKit/Source/platform/blink_platform_tests.gyp:blink_platform_unittests',
- '../third_party/WebKit/Source/web/web_tests.gyp:webkit_unit_tests',
- '../third_party/WebKit/Source/wtf/wtf_tests.gyp:wtf_unittests',
- '../third_party/cacheinvalidation/cacheinvalidation.gyp:cacheinvalidation_unittests',
- '../third_party/codesighs/codesighs.gyp:codesighs',
- '../third_party/codesighs/codesighs.gyp:maptsvdifftool',
- '../third_party/leveldatabase/leveldatabase.gyp:env_chromium_unittests',
- '../third_party/libphonenumber/libphonenumber.gyp:libphonenumber_unittests',
- '../third_party/libaddressinput/libaddressinput.gyp:libaddressinput_unittests',
- '../third_party/mojo/mojo_edk_tests.gyp:mojo_system_unittests',
- '../third_party/mojo/mojo_edk_tests.gyp:mojo_public_bindings_unittests',
- '../third_party/mojo/mojo_edk_tests.gyp:mojo_public_environment_unittests',
- '../third_party/mojo/mojo_edk_tests.gyp:mojo_public_system_perftests',
- '../third_party/mojo/mojo_edk_tests.gyp:mojo_public_system_unittests',
- '../third_party/mojo/mojo_edk_tests.gyp:mojo_public_utility_unittests',
- '../third_party/pdfium/samples/samples.gyp:pdfium_diff',
- '../third_party/pdfium/samples/samples.gyp:pdfium_test',
- '../third_party/smhasher/smhasher.gyp:pmurhash',
- '../tools/gn/gn.gyp:gn',
- '../tools/gn/gn.gyp:generate_test_gn_data',
- '../tools/gn/gn.gyp:gn_unittests',
- '../tools/imagediff/image_diff.gyp:image_diff',
- '../tools/perf/clear_system_cache/clear_system_cache.gyp:clear_system_cache',
- '../tools/telemetry/telemetry.gyp:bitmaptools#host',
- '../ui/accessibility/accessibility.gyp:accessibility_unittests',
- '../ui/app_list/app_list.gyp:app_list_unittests',
- '../ui/base/ui_base_tests.gyp:ui_base_unittests',
- '../ui/compositor/compositor.gyp:compositor_unittests',
- '../ui/display/display.gyp:display_unittests',
- '../ui/events/events.gyp:events_unittests',
- '../ui/gfx/gfx_tests.gyp:gfx_unittests',
- '../ui/gl/gl_tests.gyp:gl_unittests',
- '../ui/message_center/message_center.gyp:message_center_unittests',
- '../ui/snapshot/snapshot.gyp:snapshot_unittests',
- '../ui/touch_selection/ui_touch_selection.gyp:ui_touch_selection_unittests',
- '../ui/views/examples/examples.gyp:views_examples_with_content_exe',
- '../url/url.gyp:url_unittests',
- '../v8/tools/gyp/v8.gyp:v8_snapshot',
- '../v8/tools/gyp/v8.gyp:postmortem-metadata',
- ],
- 'conditions': [
- ['clang==1', {
- 'dependencies': [
- '../build/sanitizers/sanitizers.gyp:llvm-symbolizer',
- ],
- }],
- ['disable_nacl==0 and disable_nacl_untrusted==0', {
- 'dependencies': [
- '../components/nacl.gyp:nacl_loader_unittests',
- ]
- }],
- ['enable_extensions==1 and OS!="mac"', {
- 'dependencies': [
- '../extensions/shell/app_shell.gyp:app_shell',
- '../extensions/shell/app_shell.gyp:app_shell_unittests',
- ],
- }],
- ['enable_mdns==1', {
- 'dependencies': [
- '../chrome/chrome.gyp:service_discovery_sniffer',
- ]
- }],
- ['remoting==1', {
- 'dependencies': [
- '../remoting/remoting_all.gyp:remoting_all',
- ],
- }],
- ['remoting==1 and chromeos==0 and use_x11==1', {
- 'dependencies': [
- '../remoting/remoting.gyp:remoting_me2me_host',
- '../remoting/remoting.gyp:remoting_me2me_native_messaging_host',
- ],
- }],
- ['toolkit_views==1', {
- 'dependencies': [
- '../ui/app_list/app_list.gyp:app_list_demo',
- '../ui/views/views.gyp:views_unittests',
- ],
- }],
- ['use_ash==1', {
- 'dependencies': [
- '../ash/ash.gyp:ash_shell',
- '../ash/ash.gyp:ash_shell_unittests',
- '../ash/ash.gyp:ash_unittests',
- ],
- }],
- ['use_ash==1 or chromeos== 1', {
- 'dependencies': [
- '../components/components.gyp:session_manager_component',
- ]
- }],
- ['use_aura==1', {
- 'dependencies': [
- '../ui/aura/aura.gyp:aura_bench',
- '../ui/aura/aura.gyp:aura_demo',
- '../ui/aura/aura.gyp:aura_unittests',
- '../ui/keyboard/keyboard.gyp:keyboard_unittests',
- '../ui/wm/wm.gyp:wm_unittests',
- ],
- }],
- ['use_ozone==1', {
- 'dependencies': [
- '../ui/ozone/ozone.gyp:ozone',
- ],
- }],
- ['use_x11==1', {
- 'dependencies': [
- '../tools/xdisplaycheck/xdisplaycheck.gyp:xdisplaycheck',
- ],
- 'conditions': [
- ['target_arch!="arm"', {
- 'dependencies': [
- '../gpu/tools/tools.gyp:compositor_model_bench',
- ],
- }],
- ],
- }],
- ['OS=="android"', {
- 'dependencies': [
- '../base/base.gyp:chromium_android_linker',
- '../breakpad/breakpad.gyp:dump_syms',
- '../build/android/rezip.gyp:rezip_apk_jar',
- '../chrome/chrome.gyp:chrome_public_apk',
- '../chrome/chrome.gyp:chrome_public_test_apk',
- '../chrome/chrome.gyp:chrome_shell_apk',
- '../chrome/chrome.gyp:chromedriver_webview_shell_apk',
- #"//clank" TODO(GYP) - conditional somehow?
- '../tools/imagediff/image_diff.gyp:image_diff#host',
- '../tools/telemetry/telemetry.gyp:bitmaptools#host',
-
- # TODO(GYP): Remove these when the components_unittests work.
- #"//components/history/core/test:test",
- #"//components/policy:policy_component_test_support",
- #"//components/policy:test_support",
- #"//components/rappor:test_support",
- #"//components/signin/core/browser:test_support",
- #"//components/sync_driver:test_support",
- #"//components/user_manager",
- #"//components/wallpaper",
-
- '../content/content_shell_and_tests.gyp:content_shell_apk',
-
- '../third_party/WebKit/Source/platform/blink_platform_tests.gyp:blink_heap_unittests_apk',
- '../third_party/WebKit/Source/platform/blink_platform_tests.gyp:blink_platform_unittests_apk',
- '../third_party/WebKit/Source/web/web_tests.gyp:webkit_unit_tests_apk',
- '../third_party/WebKit/Source/wtf/wtf_tests.gyp:wtf_unittests_apk',
- # TODO(GYP): Are these needed, or will they be pulled in automatically?
- #"//third_party/android_tools:android_gcm_java",
- #"//third_party/android_tools:uiautomator_java",
- #"//third_party/android_tools:android_support_v13_java",
- #"//third_party/android_tools:android_support_v7_appcompat_java",
- #"//third_party/android_tools:android_support_v7_mediarouter_java",
- #"//third_party/mesa",
- #"//third_party/mockito:mockito_java",
- #"//third_party/openmax_dl/dl",
- #"//third_party/speex",
- #"//ui/android:ui_java",
-
- # TODO(GYP): Are these needed?
- #"//chrome/test:test_support_unit",
- #"//third_party/smhasher:murmurhash3",
- #"//ui/message_center:test_support",
- ],
- 'dependencies!': [
- '../breakpad/breakpad.gyp:symupload',
- '../chrome/chrome.gyp:browser_tests',
- '../chrome/chrome.gyp:chromedriver',
- '../chrome/chrome.gyp:chromedriver_unitests',
- '../chrome/chrome.gyp:interactive_ui_tests',
- '../chrome/chrome.gyp:performance_browser_tests',
- '../chrome/chrome.gyp:sync_integration_tests',
- '../chrome/chrome.gyp:unit_tests',
- '../extensions/extensions_tests.gyp:extensions_browsertests',
- '../extensions/extensions_tests.gyp:extensions_unittests',
- '../google_apis/gcm/gcm.gyp:gcm_unit_tests',
- '../ipc/ipc.gyp:ipc_tests',
- '../jingle/jingle.gyp:jingle_unittests',
- '../net/net.gyp:net_unittests',
- #"//ppapi/examples",
- '../third_party/pdfium/samples/samples.gyp:pdfium_test',
- '../tools/gn/gn.gyp:gn',
- '../tools/gn/gn.gyp:gn_unittests',
- '../tools/imagediff/image_diff.gyp:image_diff',
- '../tools/gn/gn.gyp:gn',
- '../tools/gn/gn.gyp:gn_unittests',
- '../ui/app_list/app_list.gyp:app_list_unittests',
- '../url/url.gyp:url_unittests',
- ],
- }],
- ['OS=="android" or OS=="linux"', {
- 'dependencies': [
- '../net/net.gyp:disk_cache_memory_test',
- ],
- }],
- ['chromeos==1', {
- 'dependencies': [
- '../chromeos/chromeos.gyp:chromeos_unittests',
- '../ui/chromeos/ui_chromeos.gyp:ui_chromeos_unittests',
- ]
- }],
- ['chromeos==1 or OS=="win" or OS=="mac"', {
- 'dependencies': [
- '../rlz/rlz.gyp:rlz_id',
- '../rlz/rlz.gyp:rlz_lib',
- '../rlz/rlz.gyp:rlz_unittests',
- ],
- }],
- ['OS=="android" or OS=="linux" or os_bsd==1', {
- 'dependencies': [
- '../breakpad/breakpad.gyp:core-2-minidump',
- '../breakpad/breakpad.gyp:microdump_stackwalk',
- '../breakpad/breakpad.gyp:minidump_dump',
- '../breakpad/breakpad.gyp:minidump_stackwalk',
- '../breakpad/breakpad.gyp:symupload',
- '../third_party/codesighs/codesighs.gyp:nm2tsv',
- ],
- }],
- ['OS=="linux"', {
- 'dependencies': [
- '../breakpad/breakpad.gyp:breakpad_unittests',
- '../breakpad/breakpad.gyp:dump_syms#host',
- '../breakpad/breakpad.gyp:generate_test_dump',
- '../breakpad/breakpad.gyp:minidump-2-core',
- '../dbus/dbus.gyp:dbus_test_server',
- '../dbus/dbus.gyp:dbus_unittests',
- '../media/cast/cast.gyp:tap_proxy',
- '../net/net.gyp:disk_cache_memory_test',
- '../net/net.gyp:flip_in_mem_edsm_server',
- '../net/net.gyp:flip_in_mem_edsm_server_unittests',
- '../net/net.gyp:epoll_quic_client',
- '../net/net.gyp:epoll_quic_server',
- '../net/net.gyp:hpack_example_generator',
- '../net/net.gyp:hpack_fuzz_mutator',
- '../net/net.gyp:hpack_fuzz_wrapper',
- '../net/net.gyp:net_perftests',
- '../net/net.gyp:quic_client',
- '../net/net.gyp:quic_server',
- '../sandbox/sandbox.gyp:chrome_sandbox',
- '../sandbox/sandbox.gyp:sandbox_linux_unittests',
- '../sandbox/sandbox.gyp:sandbox_linux_jni_unittests',
- '../third_party/sqlite/sqlite.gyp:sqlite_shell',
- ],
- }],
- ['OS=="mac"', {
- 'dependencies': [
- '../breakpad/breakpad.gyp:crash_inspector',
- '../breakpad/breakpad.gyp:dump_syms',
- '../breakpad/breakpad.gyp:symupload',
- '../third_party/apple_sample_code/apple_sample_code.gyp:apple_sample_code',
- '../third_party/molokocacao/molokocacao.gyp:molokocacao',
-
- # TODO(GYP): remove these when the corresponding root targets work.
- #"//cc/blink",
- #"//components/ui/zoom:ui_zoom",
- #"//content",
- #"//content/test:test_support",
- #"//device/battery",
- #"//device/bluetooth",
- #"//device/nfc",
- #"//device/usb",
- #"//device/vibration",
- #"//media/blink",
- #"//pdf",
- #"//storage/browser",
- #"//third_party/brotli",
- #"//third_party/flac",
- #"//third_party/hunspell",
- #//third_party/iccjpeg",
- #"//third_party/libphonenumber",
- #"//third_party/ots",
- #"//third_party/qcms",
- #"//third_party/smhasher:murmurhash3",
- #"//third_party/speex",
- #"//third_party/webrtc/system_wrappers",
- #"//ui/native_theme",
- #"//ui/snapshot",
- #"//ui/surface",
- ],
- 'dependencies!': [
- #"//chrome", # TODO(GYP)
- #"//chrome/test:browser_tests", # TODO(GYP)
- #"//chrome/test:interactive_ui_tests", # TODO(GYP)
- #"//chrome/test:sync_integration_tests", # TODO(GYP)
- #"//chrome/test:unit_tests", # TODO(GYP)
- #"//components:components_unittests", # TODO(GYP)
- #"//content/test:content_browsertests", # TODO(GYP)
- #"//content/test:content_perftests", # TODO(GYP)
- #"//content/test:content_unittests", # TODO(GYP)
- #"//extensions:extensions_browsertests", # TODO(GYP)
- #"//extensions:extensions_unittests", # TODO(GYP)
- #"//net:net_unittests", # TODO(GYP)
- #"//third_party/usrsctp", # TODO(GYP)
- #"//ui/app_list:app_list_unittests", # TODO(GYP)
- #"//ui/gfx:gfx_unittests", # TODO(GYP)
- ],
- }],
- ['OS=="win"', {
- 'dependencies': [
- '../base/base.gyp:pe_image_test',
- '../chrome/chrome.gyp:crash_service',
- '../chrome/chrome.gyp:setup_unittests',
- '../chrome_elf/chrome_elf.gyp:chrome_elf_unittests',
- '../chrome_elf/chrome_elf.gyp:dll_hash_main',
- '../components/components.gyp:wifi_test',
- '../net/net.gyp:quic_client',
- '../net/net.gyp:quic_server',
- '../sandbox/sandbox.gyp:pocdll',
- '../sandbox/sandbox.gyp:sandbox_poc',
- '../sandbox/sandbox.gyp:sbox_integration_tests',
- '../sandbox/sandbox.gyp:sbox_unittests',
- '../sandbox/sandbox.gyp:sbox_validation_tests',
- '../testing/gtest.gyp:gtest_main',
- '../third_party/codesighs/codesighs.gyp:msdump2symdb',
- '../third_party/codesighs/codesighs.gyp:msmap2tsv',
- '../third_party/pdfium/samples/samples.gyp:pdfium_diff',
- '../win8/win8.gyp:metro_viewer',
- ],
- }],
- ],
- },
- {
- 'target_name': 'gyp_only',
- 'type': 'none',
- 'conditions': [
- ['OS=="linux" or OS=="win"', {
- 'conditions': [
- ['disable_nacl==0 and disable_nacl_untrusted==0', {
- 'dependencies': [
- '../mojo/mojo_nacl.gyp:monacl_shell', # This should not be built in chromium.
- ]
- }],
- ]
- }],
- ],
- },
- {
- 'target_name': 'gyp_remaining',
- 'type': 'none',
- 'conditions': [
- ['remoting==1', {
- 'dependencies': [
- '../remoting/app_remoting_webapp.gyp:ar_sample_app', # crbug.com/471916
- ],
- }],
- ['test_isolation_mode!="noop"', {
- 'dependencies': [
- '../base/base.gyp:base_unittests_run',
- '../cc/cc_tests.gyp:cc_unittests_run',
- '../chrome/chrome.gyp:browser_tests_run',
- '../chrome/chrome.gyp:chrome_run',
- '../chrome/chrome.gyp:interactive_ui_tests_run',
- '../chrome/chrome.gyp:sync_integration_tests_run',
- '../chrome/chrome.gyp:unit_tests_run',
- '../components/components_tests.gyp:components_browsertests_run',
- '../components/components_tests.gyp:components_unittests_run',
- '../content/content_shell_and_tests.gyp:content_browsertests_run',
- '../content/content_shell_and_tests.gyp:content_unittests_run',
- '../courgette/courgette.gyp:courgette_unittests_run',
- '../crypto/crypto.gyp:crypto_unittests_run',
- '../google_apis/gcm/gcm.gyp:gcm_unit_tests_run',
- '../gpu/gpu.gyp:gpu_unittests_run',
- '../ipc/ipc.gyp:ipc_tests_run',
- '../media/cast/cast.gyp:cast_unittests_run',
- '../media/media.gyp:media_unittests_run',
- '../media/midi/midi.gyp:midi_unittests_run',
- '../net/net.gyp:net_unittests_run',
- '../printing/printing.gyp:printing_unittests_run',
- '../remoting/remoting.gyp:remoting_unittests_run',
- '../skia/skia_tests.gyp:skia_unittests_run',
- '../sql/sql.gyp:sql_unittests_run',
- '../sync/sync.gyp:sync_unit_tests_run',
- '../third_party/cacheinvalidation/cacheinvalidation.gyp:cacheinvalidation_unittests_run',
- '../third_party/mojo/mojo_edk_tests.gyp:mojo_public_bindings_unittests_run',
- '../tools/gn/gn.gyp:gn_unittests_run',
- '../ui/accessibility/accessibility.gyp:accessibility_unittests_run',
- '../ui/app_list/app_list.gyp:app_list_unittests_run',
- '../ui/compositor/compositor.gyp:compositor_unittests_run',
- '../ui/events/events.gyp:events_unittests_run',
- '../ui/gl/gl_tests.gyp:gl_unittests_run',
- '../ui/message_center/message_center.gyp:message_center_unittests_run',
- '../ui/touch_selection/ui_touch_selection.gyp:ui_touch_selection_unittests_run',
- '../url/url.gyp:url_unittests_run',
- ],
- 'conditions': [
- ['OS=="linux"', {
- 'dependencies': [
- '../sandbox/sandbox.gyp:sandbox_linux_unittests_run',
- '../ui/display/display.gyp:display_unittests_run',
- ],
- }],
- ['OS=="mac"', {
- 'dependencies': [
- '../sandbox/sandbox.gyp:sandbox_mac_unittests_run',
- ],
- }],
- ['OS=="win"', {
- 'dependencies': [
- '../chrome/chrome.gyp:installer_util_unittests_run',
- '../chrome/chrome.gyp:setup_unittests_run',
- '../sandbox/sandbox.gyp:sbox_integration_tests',
- '../sandbox/sandbox.gyp:sbox_unittests',
- '../sandbox/sandbox.gyp:sbox_validation_tests',
- ],
- }],
- ['use_ash==1', {
- 'dependencies': [
- '../ash/ash.gyp:ash_unittests_run',
- ],
- }],
- ['use_aura==1', {
- 'dependencies': [
- '../ui/aura/aura.gyp:aura_unittests_run',
- '../ui/wm/wm.gyp:wm_unittests_run',
- ],
- }],
- ['enable_webrtc==1 or OS!="android"', {
- 'dependencies': [
- '../jingle/jingle.gyp:jingle_unittests_run',
- ],
- }],
- ['disable_nacl==0 and disable_nacl_untrusted==0', {
- 'dependencies': [
- '../components/nacl.gyp:nacl_loader_unittests_run',
- ]
- }],
- ],
- }],
- ['use_openssl==1', {
- 'dependencies': [
- # TODO(GYP): All of these targets still need to be converted.
- '../third_party/boringssl/boringssl_tests.gyp:boringssl_ecdsa_test',
- '../third_party/boringssl/boringssl_tests.gyp:boringssl_bn_test',
- '../third_party/boringssl/boringssl_tests.gyp:boringssl_pqueue_test',
- '../third_party/boringssl/boringssl_tests.gyp:boringssl_digest_test',
- '../third_party/boringssl/boringssl_tests.gyp:boringssl_cipher_test',
- '../third_party/boringssl/boringssl_tests.gyp:boringssl_hkdf_test',
- '../third_party/boringssl/boringssl_tests.gyp:boringssl_constant_time_test',
- '../third_party/boringssl/boringssl_tests.gyp:boringssl_thread_test',
- '../third_party/boringssl/boringssl_tests.gyp:boringssl_base64_test',
- '../third_party/boringssl/boringssl_tests.gyp:boringssl_gcm_test',
- '../third_party/boringssl/boringssl_tests.gyp:boringssl_bytestring_test',
- '../third_party/boringssl/boringssl_tests.gyp:boringssl_evp_test',
- '../third_party/boringssl/boringssl_tests.gyp:boringssl_dsa_test',
- '../third_party/boringssl/boringssl_tests.gyp:boringssl_rsa_test',
- '../third_party/boringssl/boringssl_tests.gyp:boringssl_hmac_test',
- '../third_party/boringssl/boringssl_tests.gyp:boringssl_aead_test',
- '../third_party/boringssl/boringssl_tests.gyp:boringssl_ssl_test',
- '../third_party/boringssl/boringssl_tests.gyp:boringssl_err_test',
- '../third_party/boringssl/boringssl_tests.gyp:boringssl_lhash_test',
- '../third_party/boringssl/boringssl_tests.gyp:boringssl_pbkdf_test',
- '../third_party/boringssl/boringssl_tests.gyp:boringssl_dh_test',
- '../third_party/boringssl/boringssl_tests.gyp:boringssl_pkcs12_test',
- '../third_party/boringssl/boringssl_tests.gyp:boringssl_example_mul',
- '../third_party/boringssl/boringssl_tests.gyp:boringssl_ec_test',
- '../third_party/boringssl/boringssl_tests.gyp:boringssl_bio_test',
- '../third_party/boringssl/boringssl_tests.gyp:boringssl_pkcs7_test',
- '../third_party/boringssl/boringssl_tests.gyp:boringssl_unittests',
- ],
- }],
- ['chromeos==1', {
- 'dependencies': [
- '../content/content_shell_and_tests.gyp:jpeg_decode_accelerator_unittest',
- '../content/content_shell_and_tests.gyp:video_encode_accelerator_unittest',
- ],
- }],
- ['chromeos==1 and target_arch != "arm"', {
- 'dependencies': [
- '../content/content_shell_and_tests.gyp:vaapi_jpeg_decoder_unittest',
- ],
- }],
- ['chromeos==1 or OS=="win" or OS=="android"', {
- 'dependencies': [
- '../content/content_shell_and_tests.gyp:video_decode_accelerator_unittest',
- ],
- }],
- ['OS=="linux" or OS=="win"', {
- 'dependencies': [
- # TODO(GYP): Figure out which of these run on android/mac/win/ios/etc.
- '../net/net.gyp:net_docs',
- '../remoting/remoting.gyp:ar_sample_test_driver',
-
- # TODO(GYP): in progress - see tfarina.
- '../third_party/webrtc/tools/tools.gyp:frame_analyzer',
- '../third_party/webrtc/tools/tools.gyp:rgba_to_i420_converter',
- ],
- }],
- ['OS=="win"', {
- 'dependencies': [
- # TODO(GYP): All of these targets still need to be converted.
- '../base/base.gyp:debug_message',
- '../chrome/chrome.gyp:app_shim',
- '../chrome/chrome.gyp:gcapi_dll',
- '../chrome/chrome.gyp:gcapi_test',
- '../chrome/chrome.gyp:installer_util_unittests',
- '../chrome/chrome.gyp:pack_policy_templates',
- '../chrome/chrome.gyp:sb_sigutil',
- '../chrome/chrome.gyp:setup',
- '../chrome/installer/mini_installer.gyp:mini_installer',
- '../chrome/tools/crash_service/caps/caps.gyp:caps',
- '../cloud_print/gcp20/prototype/gcp20_device.gyp:gcp20_device',
- '../cloud_print/gcp20/prototype/gcp20_device.gyp:gcp20_device_unittests',
- '../cloud_print/service/win/service.gyp:cloud_print_service',
- '../cloud_print/service/win/service.gyp:cloud_print_service_config',
- '../cloud_print/service/win/service.gyp:cloud_print_service_setup',
- '../cloud_print/virtual_driver/win/install/virtual_driver_install.gyp:virtual_driver_setup',
- '../cloud_print/virtual_driver/win/virtual_driver.gyp:gcp_portmon',
- '../components/test_runner/test_runner.gyp:layout_test_helper',
- '../content/content_shell_and_tests.gyp:content_shell_crash_service',
- '../gpu/gpu.gyp:angle_end2end_tests',
- '../gpu/gpu.gyp:angle_perftests',
- '../net/net.gyp:net_docs',
- '../ppapi/ppapi_internal.gyp:ppapi_perftests',
- '../remoting/remoting.gyp:ar_sample_test_driver',
- '../remoting/remoting.gyp:remoting_breakpad_tester',
- '../remoting/remoting.gyp:remoting_console',
- '../remoting/remoting.gyp:remoting_desktop',
- '../rlz/rlz.gyp:rlz',
- '../tools/win/static_initializers/static_initializers.gyp:static_initializers',
- ],
- }],
- ['OS=="win" and win_use_allocator_shim==1', {
- 'dependencies': [
- '../base/allocator/allocator.gyp:allocator_unittests',
- ]
- }],
- ['OS=="win" and target_arch=="ia32"', {
- 'dependencies': [
- # TODO(GYP): All of these targets need to be ported over.
- '../base/base.gyp:base_win64',
- '../base/base.gyp:base_i18n_nacl_win64',
- '../chrome/chrome.gyp:crash_service_win64',
- '../chrome/chrome.gyp:launcher_support64',
- '../components/components.gyp:breakpad_win64',
- '../courgette/courgette.gyp:courgette64',
- '../crypto/crypto.gyp:crypto_nacl_win64',
- '../ipc/ipc.gyp:ipc_win64',
- '../sandbox/sandbox.gyp:sandbox_win64',
- '../cloud_print/virtual_driver/win/virtual_driver64.gyp:gcp_portmon64',
- '../cloud_print/virtual_driver/win/virtual_driver64.gyp:virtual_driver_lib64',
- ],
- }],
- ['OS=="win" and target_arch=="ia32" and configuration_policy==1', {
- 'dependencies': [
- # TODO(GYP): All of these targets need to be ported over.
- '../components/components.gyp:policy_win64',
- ]
- }],
- ],
- },
- ]
-}
-
diff --git a/build/grit_action.gypi b/build/grit_action.gypi
deleted file mode 100644
index b24f0f8..0000000
--- a/build/grit_action.gypi
+++ /dev/null
@@ -1,71 +0,0 @@
-# Copyright (c) 2011 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included into an action to invoke grit in a
-# consistent manner. To use this the following variables need to be
-# defined:
-# grit_grd_file: string: grd file path
-# grit_out_dir: string: the output directory path
-
-# It would be really nice to do this with a rule instead of actions, but it
-# would need to determine inputs and outputs via grit_info on a per-file
-# basis. GYP rules don't currently support that. They could be extended to
-# do this, but then every generator would need to be updated to handle this.
-
-{
- 'variables': {
- 'grit_cmd': ['python', '<(DEPTH)/tools/grit/grit.py'],
- 'grit_resource_ids%': '<(DEPTH)/tools/gritsettings/resource_ids',
- # This makes it possible to add more defines in specific targets,
- # instead of build/common.gypi .
- 'grit_additional_defines%': [],
- 'grit_rc_header_format%': [],
- 'grit_whitelist%': '',
-
- 'conditions': [
- # These scripts can skip writing generated files if they are identical
- # to the already existing files, which avoids further build steps, like
- # recompilation. However, a dependency (earlier build step) having a
- # newer timestamp than an output (later build step) confuses some build
- # systems, so only use this on ninja, which explicitly supports this use
- # case (gyp turns all actions into ninja restat rules).
- ['"<(GENERATOR)"=="ninja"', {
- 'write_only_new': '1',
- }, {
- 'write_only_new': '0',
- }],
- ],
- },
- 'conditions': [
- ['"<(grit_whitelist)"==""', {
- 'variables': {
- 'grit_whitelist_flag': [],
- }
- }, {
- 'variables': {
- 'grit_whitelist_flag': ['-w', '<(grit_whitelist)'],
- }
- }]
- ],
- 'inputs': [
- '<!@pymod_do_main(grit_info <@(grit_defines) <@(grit_additional_defines) '
- '<@(grit_whitelist_flag) --inputs <(grit_grd_file) '
- '-f "<(grit_resource_ids)")',
- ],
- 'outputs': [
- '<!@pymod_do_main(grit_info <@(grit_defines) <@(grit_additional_defines) '
- '<@(grit_whitelist_flag) --outputs \'<(grit_out_dir)\' '
- '<(grit_grd_file) -f "<(grit_resource_ids)")',
- ],
- 'action': ['<@(grit_cmd)',
- '-i', '<(grit_grd_file)', 'build',
- '-f', '<(grit_resource_ids)',
- '-o', '<(grit_out_dir)',
- '--write-only-new=<(write_only_new)',
- '<@(grit_defines)',
- '<@(grit_whitelist_flag)',
- '<@(grit_additional_defines)',
- '<@(grit_rc_header_format)'],
- 'message': 'Generating resources from <(grit_grd_file)',
-}
diff --git a/build/grit_target.gypi b/build/grit_target.gypi
deleted file mode 100644
index 179f986..0000000
--- a/build/grit_target.gypi
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright (c) 2011 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included into a target that will have one or more
-# uses of grit_action.gypi. To use this the following variables need to be
-# defined:
-# grit_out_dir: string: the output directory path
-
-# DO NOT USE THIS FILE. Instead, use qualified includes.
-# TODO: Convert everything to qualified includes, and delete this file,
-# http://crbug.com/401588
-{
- 'conditions': [
- # If the target is a direct binary, it needs to be able to find the header,
- # otherwise it probably a supporting target just for grit so the include
- # dir needs to be set on anything that depends on this action.
- ['_type=="executable" or _type=="shared_library" or \
- _type=="loadable_module" or _type=="static_library"', {
- 'include_dirs': [
- '<(grit_out_dir)',
- ],
- }, {
- 'direct_dependent_settings': {
- 'include_dirs': [
- '<(grit_out_dir)',
- ],
- },
- }],
- ],
-}
diff --git a/build/gyp_environment.py b/build/gyp_environment.py
deleted file mode 100644
index fb50645..0000000
--- a/build/gyp_environment.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""
-Sets up various automatic gyp environment variables. These are used by
-gyp_chromium and landmines.py which run at different stages of runhooks. To
-make sure settings are consistent between them, all setup should happen here.
-"""
-
-import gyp_helper
-import os
-import sys
-import vs_toolchain
-
-def SetEnvironment():
- """Sets defaults for GYP_* variables."""
- gyp_helper.apply_chromium_gyp_env()
-
- # Default to ninja on linux and windows, but only if no generator has
- # explicitly been set.
- # Also default to ninja on mac, but only when not building chrome/ios.
- # . -f / --format has precedence over the env var, no need to check for it
- # . set the env var only if it hasn't been set yet
- # . chromium.gyp_env has been applied to os.environ at this point already
- if sys.platform.startswith(('linux', 'win', 'freebsd')) and \
- not os.environ.get('GYP_GENERATORS'):
- os.environ['GYP_GENERATORS'] = 'ninja'
- elif sys.platform == 'darwin' and not os.environ.get('GYP_GENERATORS') and \
- not 'OS=ios' in os.environ.get('GYP_DEFINES', []):
- os.environ['GYP_GENERATORS'] = 'ninja'
-
- vs_toolchain.SetEnvironmentAndGetRuntimeDllDirs()
diff --git a/build/gyp_helper.py b/build/gyp_helper.py
deleted file mode 100644
index c840f2d..0000000
--- a/build/gyp_helper.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file helps gyp_chromium and landmines correctly set up the gyp
-# environment from chromium.gyp_env on disk
-
-import os
-
-SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__))
-CHROME_SRC = os.path.dirname(SCRIPT_DIR)
-
-
-def apply_gyp_environment_from_file(file_path):
- """Reads in a *.gyp_env file and applies the valid keys to os.environ."""
- if not os.path.exists(file_path):
- return
- with open(file_path, 'rU') as f:
- file_contents = f.read()
- try:
- file_data = eval(file_contents, {'__builtins__': None}, None)
- except SyntaxError, e:
- e.filename = os.path.abspath(file_path)
- raise
- supported_vars = (
- 'CC',
- 'CC_wrapper',
- 'CC.host_wrapper',
- 'CHROMIUM_GYP_FILE',
- 'CHROMIUM_GYP_SYNTAX_CHECK',
- 'CXX',
- 'CXX_wrapper',
- 'CXX.host_wrapper',
- 'GYP_DEFINES',
- 'GYP_GENERATOR_FLAGS',
- 'GYP_CROSSCOMPILE',
- 'GYP_GENERATOR_OUTPUT',
- 'GYP_GENERATORS',
- 'GYP_INCLUDE_FIRST',
- 'GYP_INCLUDE_LAST',
- 'GYP_MSVS_VERSION',
- )
- for var in supported_vars:
- file_val = file_data.get(var)
- if file_val:
- if var in os.environ:
- behavior = 'replaces'
- if var == 'GYP_DEFINES':
- result = file_val + ' ' + os.environ[var]
- behavior = 'merges with, and individual components override,'
- else:
- result = os.environ[var]
- print 'INFO: Environment value for "%s" %s value in %s' % (
- var, behavior, os.path.abspath(file_path)
- )
- string_padding = max(len(var), len(file_path), len('result'))
- print ' %s: %s' % (var.rjust(string_padding), os.environ[var])
- print ' %s: %s' % (file_path.rjust(string_padding), file_val)
- os.environ[var] = result
- else:
- os.environ[var] = file_val
-
-
-def apply_chromium_gyp_env():
- if 'SKIP_CHROMIUM_GYP_ENV' not in os.environ:
- # Update the environment based on chromium.gyp_env
- path = os.path.join(os.path.dirname(CHROME_SRC), 'chromium.gyp_env')
- apply_gyp_environment_from_file(path)
diff --git a/build/host_jar.gypi b/build/host_jar.gypi
deleted file mode 100644
index a47f6bb..0000000
--- a/build/host_jar.gypi
+++ /dev/null
@@ -1,146 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included into a target to provide a rule to build
-# a JAR file for use on a host in a consistent manner. If a main class is
-# specified, this file will also generate an executable to run the jar in the
-# output folder's /bin/ directory.
-#
-# To use this, create a gyp target with the following form:
-# {
-# 'target_name': 'my_jar',
-# 'type': 'none',
-# 'variables': {
-# 'src_paths': [
-# 'path/to/directory',
-# 'path/to/other/directory',
-# 'path/to/individual_file.java',
-# ...
-# ],
-# },
-# 'includes': [ 'path/to/this/gypi/file' ],
-# }
-#
-# Required variables:
-# src_paths - A list of all paths containing java files that should be
-# included in the jar. Paths can be either directories or files.
-# Optional/automatic variables:
-# excluded_src_paths - A list of all paths that should be excluded from
-# the jar.
-# generated_src_dirs - Directories containing additional .java files
-# generated at build time.
-# input_jars_paths - A list of paths to the jars that should be included
-# in the classpath.
-# main_class - The class containing the main() function that should be called
-# when running the jar file.
-# jar_excluded_classes - A list of .class files that should be excluded
-# from the jar.
-
-{
- 'dependencies': [
- '<(DEPTH)/build/android/setup.gyp:build_output_dirs',
- ],
- 'variables': {
- 'classes_dir': '<(intermediate_dir)/classes',
- 'excluded_src_paths': [],
- 'generated_src_dirs': [],
- 'input_jars_paths': [],
- 'intermediate_dir': '<(SHARED_INTERMEDIATE_DIR)/<(_target_name)',
- 'jar_dir': '<(PRODUCT_DIR)/lib.java',
- 'jar_excluded_classes': [],
- 'jar_name': '<(_target_name).jar',
- 'jar_path': '<(jar_dir)/<(jar_name)',
- 'main_class%': '',
- 'stamp': '<(intermediate_dir)/jar.stamp',
- 'enable_errorprone%': '0',
- 'errorprone_exe_path': '<(PRODUCT_DIR)/bin.java/chromium_errorprone',
- },
- 'all_dependent_settings': {
- 'variables': {
- 'input_jars_paths': ['<(jar_path)']
- },
- },
- 'actions': [
- {
- 'action_name': 'javac_<(_target_name)',
- 'message': 'Compiling <(_target_name) java sources',
- 'variables': {
- 'extra_args': [],
- 'extra_inputs': [],
- 'java_sources': [ '<!@(find <@(src_paths) -name "*.java")' ],
- 'conditions': [
- ['"<(excluded_src_paths)" != ""', {
- 'java_sources!': ['<!@(find <@(excluded_src_paths) -name "*.java")']
- }],
- ['"<(jar_excluded_classes)" != ""', {
- 'extra_args': ['--jar-excluded-classes=<(jar_excluded_classes)']
- }],
- ['main_class != ""', {
- 'extra_args': ['--main-class=>(main_class)']
- }],
- ['enable_errorprone == 1', {
- 'extra_inputs': [
- '<(errorprone_exe_path)',
- ],
- 'extra_args': [ '--use-errorprone-path=<(errorprone_exe_path)' ],
- }],
- ],
- },
- 'inputs': [
- '<(DEPTH)/build/android/gyp/util/build_utils.py',
- '<(DEPTH)/build/android/gyp/javac.py',
- '^@(java_sources)',
- '>@(input_jars_paths)',
- '<@(extra_inputs)',
- ],
- 'outputs': [
- '<(jar_path)',
- '<(stamp)',
- ],
- 'action': [
- 'python', '<(DEPTH)/build/android/gyp/javac.py',
- '--classpath=>(input_jars_paths)',
- '--src-gendirs=>(generated_src_dirs)',
- '--chromium-code=<(chromium_code)',
- '--stamp=<(stamp)',
- '--jar-path=<(jar_path)',
- '<@(extra_args)',
- '^@(java_sources)',
- ],
- },
- ],
- 'conditions': [
- ['main_class != ""', {
- 'actions': [
- {
- 'action_name': 'create_java_binary_script_<(_target_name)',
- 'message': 'Creating java binary script <(_target_name)',
- 'variables': {
- 'output': '<(PRODUCT_DIR)/bin/<(_target_name)',
- },
- 'inputs': [
- '<(DEPTH)/build/android/gyp/create_java_binary_script.py',
- '<(jar_path)',
- ],
- 'outputs': [
- '<(output)',
- ],
- 'action': [
- 'python', '<(DEPTH)/build/android/gyp/create_java_binary_script.py',
- '--classpath=>(input_jars_paths)',
- '--jar-path=<(jar_path)',
- '--output=<(output)',
- '--main-class=>(main_class)',
- ]
- }
- ]
- }],
- ['enable_errorprone == 1', {
- 'dependencies': [
- '<(DEPTH)/third_party/errorprone/errorprone.gyp:chromium_errorprone',
- ],
- }],
- ]
-}
-
diff --git a/build/host_prebuilt_jar.gypi b/build/host_prebuilt_jar.gypi
deleted file mode 100644
index feed5ca..0000000
--- a/build/host_prebuilt_jar.gypi
+++ /dev/null
@@ -1,50 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included into a target to provide a rule to
-# copy a prebuilt JAR for use on a host to the output directory.
-#
-# To use this, create a gyp target with the following form:
-# {
-# 'target_name': 'my_prebuilt_jar',
-# 'type': 'none',
-# 'variables': {
-# 'jar_path': 'path/to/prebuilt.jar',
-# },
-# 'includes': [ 'path/to/this/gypi/file' ],
-# }
-#
-# Required variables:
-# jar_path - The path to the prebuilt jar.
-
-{
- 'dependencies': [
- ],
- 'variables': {
- 'dest_path': '<(PRODUCT_DIR)/lib.java/<(_target_name).jar',
- 'src_path': '<(jar_path)',
- },
- 'all_dependent_settings': {
- 'variables': {
- 'input_jars_paths': [
- '<(dest_path)',
- ]
- },
- },
- 'actions': [
- {
- 'action_name': 'copy_prebuilt_jar',
- 'message': 'Copy <(src_path) to <(dest_path)',
- 'inputs': [
- '<(src_path)',
- ],
- 'outputs': [
- '<(dest_path)',
- ],
- 'action': [
- 'python', '<(DEPTH)/build/cp.py', '<(src_path)', '<(dest_path)',
- ],
- }
- ]
-}
diff --git a/build/install-android-sdks.sh b/build/install-android-sdks.sh
deleted file mode 100755
index 1119b7d..0000000
--- a/build/install-android-sdks.sh
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/bash -e
-
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# Script to install SDKs needed to build chromium on android.
-# See http://code.google.com/p/chromium/wiki/AndroidBuildInstructions
-
-echo 'checking for sdk packages install'
-# Use absolute path to call 'android' so script can be run from any directory.
-cwd=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
-# Get the SDK extras packages to install from the DEPS file 'sdkextras' hook.
-packages="$(python ${cwd}/get_sdk_extras_packages.py)"
-if [[ -n "${packages}" ]]; then
- ${cwd}/../third_party/android_tools/sdk/tools/android update sdk --no-ui \
- --filter ${packages}
-fi
-
-echo "install-android-sdks.sh complete."
diff --git a/build/install-build-deps-android.sh b/build/install-build-deps-android.sh
deleted file mode 100755
index cf87381..0000000
--- a/build/install-build-deps-android.sh
+++ /dev/null
@@ -1,100 +0,0 @@
-#!/bin/bash -e
-
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# Script to install everything needed to build chromium on android, including
-# items requiring sudo privileges.
-# See http://code.google.com/p/chromium/wiki/AndroidBuildInstructions
-
-# This script installs the sun-java6 packages (bin, jre and jdk). Sun requires
-# a license agreement, so upon installation it will prompt the user. To get
-# past the curses-based dialog press TAB <ret> TAB <ret> to agree.
-
-args="$@"
-if test "$1" = "--skip-sdk-packages"; then
- skip_inst_sdk_packages=1
- args="${@:2}"
-else
- skip_inst_sdk_packages=0
-fi
-
-if ! uname -m | egrep -q "i686|x86_64"; then
- echo "Only x86 architectures are currently supported" >&2
- exit
-fi
-
-# Install first the default Linux build deps.
-"$(dirname "${BASH_SOURCE[0]}")/install-build-deps.sh" \
- --no-syms --lib32 --no-arm --no-chromeos-fonts --no-nacl --no-prompt "${args}"
-
-lsb_release=$(lsb_release --codename --short)
-
-# The temporary directory used to store output of update-java-alternatives
-TEMPDIR=$(mktemp -d)
-cleanup() {
- local status=${?}
- trap - EXIT
- rm -rf "${TEMPDIR}"
- exit ${status}
-}
-trap cleanup EXIT
-
-# Fix deps
-sudo apt-get -f install
-
-# Install deps
-# This step differs depending on what Ubuntu release we are running
-# on since the package names are different, and Sun's Java must
-# be installed manually on late-model versions.
-
-# common
-sudo apt-get -y install lighttpd python-pexpect xvfb x11-utils
-
-# Some binaries in the Android SDK require 32-bit libraries on the host.
-# See https://developer.android.com/sdk/installing/index.html?pkg=tools
-if [[ $lsb_release == "precise" ]]; then
- sudo apt-get -y install ia32-libs
-else
- sudo apt-get -y install libncurses5:i386 libstdc++6:i386 zlib1g:i386
-fi
-
-sudo apt-get -y install ant
-
-# Install openjdk and openjre 7 stuff
-sudo apt-get -y install openjdk-7-jre openjdk-7-jdk
-
-# Switch version of Java to openjdk 7.
-# Some Java plugins (e.g. for firefox, mozilla) are not required to build, and
-# thus are treated only as warnings. Any errors in updating java alternatives
-# which are not '*-javaplugin.so' will cause errors and stop the script from
-# completing successfully.
-if ! sudo update-java-alternatives -s java-1.7.0-openjdk-amd64 \
- >& "${TEMPDIR}"/update-java-alternatives.out
-then
- # Check that there are the expected javaplugin.so errors for the update
- if grep 'javaplugin.so' "${TEMPDIR}"/update-java-alternatives.out >& \
- /dev/null
- then
- # Print as warnings all the javaplugin.so errors
- echo 'WARNING: java-6-sun has no alternatives for the following plugins:'
- grep 'javaplugin.so' "${TEMPDIR}"/update-java-alternatives.out
- fi
- # Check if there are any errors that are not javaplugin.so
- if grep -v 'javaplugin.so' "${TEMPDIR}"/update-java-alternatives.out \
- >& /dev/null
- then
- # If there are non-javaplugin.so errors, treat as errors and exit
- echo 'ERRORS: Failed to update alternatives for java-6-sun:'
- grep -v 'javaplugin.so' "${TEMPDIR}"/update-java-alternatives.out
- exit 1
- fi
-fi
-
-# Install SDK packages for android
-if test "$skip_inst_sdk_packages" != 1; then
- "$(dirname "${BASH_SOURCE[0]}")/install-android-sdks.sh"
-fi
-
-echo "install-build-deps-android.sh complete."
diff --git a/build/install-build-deps.py b/build/install-build-deps.py
deleted file mode 100755
index 7cc3760..0000000
--- a/build/install-build-deps.py
+++ /dev/null
@@ -1,430 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import argparse
-import operator
-import os
-import platform
-import re
-import subprocess
-import sys
-
-
-SUPPORTED_UBUNTU_VERSIONS = (
- {'number': '12.04', 'codename': 'precise'},
- {'number': '14.04', 'codename': 'trusty'},
- {'number': '14.10', 'codename': 'utopic'},
- {'number': '15.04', 'codename': 'vivid'},
-)
-
-
-# Packages needed for chromeos only.
-_packages_chromeos_dev = (
- 'libbluetooth-dev',
- 'libxkbcommon-dev',
- 'realpath',
-)
-
-
-# Packages needed for development.
-_packages_dev = (
- 'apache2.2-bin',
- 'bison',
- 'cdbs',
- 'curl',
- 'devscripts',
- 'dpkg-dev',
- 'elfutils',
- 'fakeroot',
- 'flex',
- 'fonts-thai-tlwg',
- 'g++',
- 'git-core',
- 'git-svn',
- 'gperf',
- 'language-pack-da',
- 'language-pack-fr',
- 'language-pack-he',
- 'language-pack-zh-hant',
- 'libapache2-mod-php5',
- 'libasound2-dev',
- 'libav-tools',
- 'libbrlapi-dev',
- 'libbz2-dev',
- 'libcairo2-dev',
- 'libcap-dev',
- 'libcups2-dev',
- 'libcurl4-gnutls-dev',
- 'libdrm-dev',
- 'libelf-dev',
- 'libexif-dev',
- 'libgconf2-dev',
- 'libglib2.0-dev',
- 'libglu1-mesa-dev',
- 'libgnome-keyring-dev',
- 'libgtk2.0-dev',
- 'libkrb5-dev',
- 'libnspr4-dev',
- 'libnss3-dev',
- 'libpam0g-dev',
- 'libpci-dev',
- 'libpulse-dev',
- 'libsctp-dev',
- 'libspeechd-dev',
- 'libsqlite3-dev',
- 'libssl-dev',
- 'libudev-dev',
- 'libwww-perl',
- 'libxslt1-dev',
- 'libxss-dev',
- 'libxt-dev',
- 'libxtst-dev',
- 'openbox',
- 'patch',
- 'perl',
- 'php5-cgi',
- 'pkg-config',
- 'python',
- 'python-cherrypy3',
- 'python-crypto',
- 'python-dev',
- 'python-numpy',
- 'python-opencv',
- 'python-openssl',
- 'python-psutil',
- 'python-yaml',
- 'rpm',
- 'ruby',
- 'subversion',
- 'ttf-dejavu-core',
- 'ttf-indic-fonts',
- 'ttf-kochi-gothic',
- 'ttf-kochi-mincho',
- 'wdiff',
- 'xfonts-mathml',
- 'zip',
-)
-
-
-# Run-time libraries required by chromeos only.
-_packages_chromeos_lib = (
- 'libbz2-1.0',
- 'libpulse0',
-)
-
-
-# Full list of required run-time libraries.
-_packages_lib = (
- 'libasound2',
- 'libatk1.0-0',
- 'libc6',
- 'libcairo2',
- 'libcap2',
- 'libcups2',
- 'libexif12',
- 'libexpat1',
- 'libfontconfig1',
- 'libfreetype6',
- 'libglib2.0-0',
- 'libgnome-keyring0',
- 'libgtk2.0-0',
- 'libpam0g',
- 'libpango1.0-0',
- 'libpci3',
- 'libpcre3',
- 'libpixman-1-0',
- 'libpng12-0',
- 'libspeechd2',
- 'libsqlite3-0',
- 'libstdc++6',
- 'libx11-6',
- 'libxau6',
- 'libxcb1',
- 'libxcomposite1',
- 'libxcursor1',
- 'libxdamage1',
- 'libxdmcp6',
- 'libxext6',
- 'libxfixes3',
- 'libxi6',
- 'libxinerama1',
- 'libxrandr2',
- 'libxrender1',
- 'libxtst6',
- 'zlib1g',
-)
-
-
-# Debugging symbols for all of the run-time libraries.
-_packages_dbg = (
- 'libatk1.0-dbg',
- 'libc6-dbg',
- 'libcairo2-dbg',
- 'libfontconfig1-dbg',
- 'libglib2.0-0-dbg',
- 'libgtk2.0-0-dbg',
- 'libpango1.0-0-dbg',
- 'libpcre3-dbg',
- 'libpixman-1-0-dbg',
- 'libsqlite3-0-dbg',
- 'libx11-6-dbg',
- 'libxau6-dbg',
- 'libxcb1-dbg',
- 'libxcomposite1-dbg',
- 'libxcursor1-dbg',
- 'libxdamage1-dbg',
- 'libxdmcp6-dbg',
- 'libxext6-dbg',
- 'libxfixes3-dbg',
- 'libxi6-dbg',
- 'libxinerama1-dbg',
- 'libxrandr2-dbg',
- 'libxrender1-dbg',
- 'libxtst6-dbg',
- 'zlib1g-dbg',
-)
-
-
-# 32-bit libraries needed e.g. to compile V8 snapshot for Android or armhf.
-_packages_lib32 = (
- 'linux-libc-dev:i386',
-)
-
-
-# arm cross toolchain packages needed to build chrome on armhf.
-_packages_arm = (
- 'g++-arm-linux-gnueabihf',
- 'libc6-dev-armhf-cross',
- 'linux-libc-dev-armhf-cross',
-)
-
-
-# Packages to build NaCl, its toolchains, and its ports.
-_packages_naclports = (
- 'ant',
- 'autoconf',
- 'bison',
- 'cmake',
- 'gawk',
- 'intltool',
- 'xsltproc',
- 'xutils-dev',
-)
-_packages_nacl = (
- 'g++-mingw-w64-i686',
- 'lib32ncurses5-dev',
- 'lib32z1-dev',
- 'libasound2:i386',
- 'libcap2:i386',
- 'libelf-dev:i386',
- 'libexif12:i386',
- 'libfontconfig1:i386',
- 'libgconf-2-4:i386',
- 'libglib2.0-0:i386',
- 'libgpm2:i386',
- 'libgtk2.0-0:i386',
- 'libncurses5:i386',
- 'libnss3:i386',
- 'libpango1.0-0:i386',
- 'libssl1.0.0:i386',
- 'libtinfo-dev',
- 'libtinfo-dev:i386',
- 'libtool',
- 'libxcomposite1:i386',
- 'libxcursor1:i386',
- 'libxdamage1:i386',
- 'libxi6:i386',
- 'libxrandr2:i386',
- 'libxss1:i386',
- 'libxtst6:i386',
- 'texinfo',
- 'xvfb',
-)
-
-
-def is_userland_64_bit():
- return platform.architecture()[0] == '64bit'
-
-
-def package_exists(pkg):
- return pkg in subprocess.check_output(['apt-cache', 'pkgnames']).splitlines()
-
-
-def lsb_release_short_codename():
- return subprocess.check_output(
- ['lsb_release', '--codename', '--short']).strip()
-
-
-def write_error(message):
- sys.stderr.write('ERROR: %s\n' % message)
- sys.stderr.flush()
-
-
-def nonfatal_get_output(*popenargs, **kwargs):
- process = subprocess.Popen(
- stdout=subprocess.PIPE, stderr=subprocess.PIPE, *popenargs, **kwargs)
- stdout, stderr = process.communicate()
- retcode = process.poll()
- return retcode, stdout, stderr
-
-
-def compute_dynamic_package_lists():
- global _packages_arm
- global _packages_dbg
- global _packages_dev
- global _packages_lib
- global _packages_lib32
- global _packages_nacl
-
- if is_userland_64_bit():
- # 64-bit systems need a minimum set of 32-bit compat packages
- # for the pre-built NaCl binaries.
- _packages_dev += (
- 'lib32gcc1',
- 'lib32stdc++6',
- 'libc6-i386',
- )
-
- # When cross building for arm/Android on 64-bit systems the host binaries
- # that are part of v8 need to be compiled with -m32 which means
- # that basic multilib support is needed.
- # gcc-multilib conflicts with the arm cross compiler (at least in trusty)
- # but g++-X.Y-multilib gives us the 32-bit support that we need. Find out
- # the appropriate value of X and Y by seeing what version the current
- # distribution's g++-multilib package depends on.
- output = subprocess.check_output(['apt-cache', 'depends', 'g++-multilib'])
- multilib_package = re.search(r'g\+\+-[0-9.]+-multilib', output).group()
- _packages_lib32 += (multilib_package,)
-
- lsb_codename = lsb_release_short_codename()
-
- # Find the proper version of libstdc++6-4.x-dbg.
- if lsb_codename == 'precise':
- _packages_dbg += ('libstdc++6-4.6-dbg',)
- elif lsb_codename == 'trusty':
- _packages_dbg += ('libstdc++6-4.8-dbg',)
- else:
- _packages_dbg += ('libstdc++6-4.9-dbg',)
-
- # Work around for dependency issue Ubuntu/Trusty: http://crbug.com/435056 .
- if lsb_codename == 'trusty':
- _packages_arm += (
- 'g++-4.8-multilib-arm-linux-gnueabihf',
- 'gcc-4.8-multilib-arm-linux-gnueabihf',
- )
-
- # Find the proper version of libgbm-dev. We can't just install libgbm-dev as
- # it depends on mesa, and only one version of mesa can exists on the system.
- # Hence we must match the same version or this entire script will fail.
- mesa_variant = ''
- for variant in ('-lts-trusty', '-lts-utopic'):
- rc, stdout, stderr = nonfatal_get_output(
- ['dpkg-query', '-Wf\'{Status}\'', 'libgl1-mesa-glx' + variant])
- if 'ok installed' in output:
- mesa_variant = variant
- _packages_dev += (
- 'libgbm-dev' + mesa_variant,
- 'libgl1-mesa-dev' + mesa_variant,
- 'libgles2-mesa-dev' + mesa_variant,
- 'mesa-common-dev' + mesa_variant,
- )
-
- if package_exists('ttf-mscorefonts-installer'):
- _packages_dev += ('ttf-mscorefonts-installer',)
- else:
- _packages_dev += ('msttcorefonts',)
-
- if package_exists('libnspr4-dbg'):
- _packages_dbg += ('libnspr4-dbg', 'libnss3-dbg')
- _packages_lib += ('libnspr4', 'libnss3')
- else:
- _packages_dbg += ('libnspr4-0d-dbg', 'libnss3-1d-dbg')
- _packages_lib += ('libnspr4-0d', 'libnss3-1d')
-
- if package_exists('libjpeg-dev'):
- _packages_dev += ('libjpeg-dev',)
- else:
- _packages_dev += ('libjpeg62-dev',)
-
- if package_exists('libudev1'):
- _packages_dev += ('libudev1',)
- _packages_nacl += ('libudev1:i386',)
- else:
- _packages_dev += ('libudev0',)
- _packages_nacl += ('libudev0:i386',)
-
- if package_exists('libbrlapi0.6'):
- _packages_dev += ('libbrlapi0.6',)
- else:
- _packages_dev += ('libbrlapi0.5',)
-
- # Some packages are only needed if the distribution actually supports
- # installing them.
- if package_exists('appmenu-gtk'):
- _packages_lib += ('appmenu-gtk',)
-
- _packages_dev += _packages_chromeos_dev
- _packages_lib += _packages_chromeos_lib
- _packages_nacl += _packages_naclports
-
-
-def quick_check(packages):
- rc, stdout, stderr = nonfatal_get_output([
- 'dpkg-query', '-W', '-f', '${PackageSpec}:${Status}\n'] + list(packages))
- if rc == 0 and not stderr:
- return 0
- print stderr
- return 1
-
-
-def main(argv):
- parser = argparse.ArgumentParser()
- parser.add_argument('--quick-check', action='store_true',
- help='quickly try to determine if dependencies are '
- 'installed (this avoids interactive prompts and '
- 'sudo commands so might not be 100% accurate)')
- parser.add_argument('--unsupported', action='store_true',
- help='attempt installation even on unsupported systems')
- args = parser.parse_args(argv)
-
- lsb_codename = lsb_release_short_codename()
- if not args.unsupported and not args.quick_check:
- if lsb_codename not in map(
- operator.itemgetter('codename'), SUPPORTED_UBUNTU_VERSIONS):
- supported_ubuntus = ['%(number)s (%(codename)s)' % v
- for v in SUPPORTED_UBUNTU_VERSIONS]
- write_error('Only Ubuntu %s are currently supported.' %
- ', '.join(supported_ubuntus))
- return 1
-
- if platform.machine() not in ('i686', 'x86_64'):
- write_error('Only x86 architectures are currently supported.')
- return 1
-
- if os.geteuid() != 0 and not args.quick_check:
- print 'Running as non-root user.'
- print 'You might have to enter your password one or more times'
- print 'for \'sudo\'.'
- print
-
- compute_dynamic_package_lists()
-
- packages = (_packages_dev + _packages_lib + _packages_dbg + _packages_lib32 +
- _packages_arm + _packages_nacl)
- def packages_key(pkg):
- s = pkg.rsplit(':', 1)
- if len(s) == 1:
- return (s, '')
- return s
- packages = sorted(set(packages), key=packages_key)
-
- if args.quick_check:
- return quick_check(packages)
-
- return 0
-
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv[1:]))
diff --git a/build/install-build-deps.sh b/build/install-build-deps.sh
deleted file mode 100755
index 57f7216..0000000
--- a/build/install-build-deps.sh
+++ /dev/null
@@ -1,477 +0,0 @@
-#!/bin/bash -e
-
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# Script to install everything needed to build chromium (well, ideally, anyway)
-# See http://code.google.com/p/chromium/wiki/LinuxBuildInstructions
-# and http://code.google.com/p/chromium/wiki/LinuxBuild64Bit
-
-usage() {
- echo "Usage: $0 [--options]"
- echo "Options:"
- echo "--[no-]syms: enable or disable installation of debugging symbols"
- echo "--lib32: enable installation of 32-bit libraries, e.g. for V8 snapshot"
- echo "--[no-]arm: enable or disable installation of arm cross toolchain"
- echo "--[no-]chromeos-fonts: enable or disable installation of Chrome OS"\
- "fonts"
- echo "--[no-]nacl: enable or disable installation of prerequisites for"\
- "building standalone NaCl and all its toolchains"
- echo "--no-prompt: silently select standard options/defaults"
- echo "--quick-check: quickly try to determine if dependencies are installed"
- echo " (this avoids interactive prompts and sudo commands,"
- echo " so might not be 100% accurate)"
- echo "--unsupported: attempt installation even on unsupported systems"
- echo "Script will prompt interactively if options not given."
- exit 1
-}
-
-# Checks whether a particular package is available in the repos.
-# USAGE: $ package_exists <package name>
-package_exists() {
- apt-cache pkgnames | grep -x "$1" > /dev/null 2>&1
-}
-
-# These default to on because (some) bots need them and it keeps things
-# simple for the bot setup if all bots just run the script in its default
-# mode. Developers who don't want stuff they don't need installed on their
-# own workstations can pass --no-arm --no-nacl when running the script.
-do_inst_arm=1
-do_inst_nacl=1
-
-while test "$1" != ""
-do
- case "$1" in
- --syms) do_inst_syms=1;;
- --no-syms) do_inst_syms=0;;
- --lib32) do_inst_lib32=1;;
- --arm) do_inst_arm=1;;
- --no-arm) do_inst_arm=0;;
- --chromeos-fonts) do_inst_chromeos_fonts=1;;
- --no-chromeos-fonts) do_inst_chromeos_fonts=0;;
- --nacl) do_inst_nacl=1;;
- --no-nacl) do_inst_nacl=0;;
- --no-prompt) do_default=1
- do_quietly="-qq --assume-yes"
- ;;
- --quick-check) do_quick_check=1;;
- --unsupported) do_unsupported=1;;
- *) usage;;
- esac
- shift
-done
-
-if test "$do_inst_arm" = "1"; then
- do_inst_lib32=1
-fi
-
-# Check for lsb_release command in $PATH
-if ! which lsb_release > /dev/null; then
- echo "ERROR: lsb_release not found in \$PATH" >&2
- exit 1;
-fi
-
-distro=$(lsb_release --id --short)
-codename=$(lsb_release --codename --short)
-ubuntu_codenames="(precise|trusty|utopic|vivid)"
-debian_codenames="(stretch)"
-if [ 0 -eq "${do_unsupported-0}" ] && [ 0 -eq "${do_quick_check-0}" ] ; then
- if [[ ! $codename =~ $ubuntu_codenames && ! $codename =~ $debian_codenames ]]; then
- echo "ERROR: Only Ubuntu 12.04 (precise), 14.04 (trusty), " \
- "14.10 (utopic) and 15.04 (vivid), and Debian Testing (stretch) are currently supported" >&2
- exit 1
- fi
-
- if ! uname -m | egrep -q "i686|x86_64"; then
- echo "Only x86 architectures are currently supported" >&2
- exit
- fi
-fi
-
-if [ "x$(id -u)" != x0 ] && [ 0 -eq "${do_quick_check-0}" ]; then
- echo "Running as non-root user."
- echo "You might have to enter your password one or more times for 'sudo'."
- echo
-fi
-
-# Packages needed for chromeos only
-chromeos_dev_list="libbluetooth-dev libxkbcommon-dev realpath"
-
-# Packages needed for development
-if [[ $distro = Debian ]] ; then
- # Debian-specific package names
- dev_list="apache2-bin fonts-indic fonts-lyx"
-else
- # Ubuntu-specific package names
- dev_list="apache2.2-bin ttf-indic-fonts xfonts-mathml language-pack-da
- language-pack-fr language-pack-he language-pack-zh-hant"
-fi
-dev_list="$dev_list bison cdbs curl dpkg-dev elfutils devscripts fakeroot
- flex fonts-thai-tlwg g++ git-core git-svn gperf libapache2-mod-php5
- libasound2-dev libbrlapi-dev libav-tools
- libbz2-dev libcairo2-dev libcap-dev libcups2-dev libcurl4-gnutls-dev
- libdrm-dev libelf-dev libexif-dev libgconf2-dev libglib2.0-dev
- libglu1-mesa-dev libgnome-keyring-dev libgtk2.0-dev libkrb5-dev
- libnspr4-dev libnss3-dev libpam0g-dev libpci-dev libpulse-dev
- libsctp-dev libspeechd-dev libsqlite3-dev libssl-dev libudev-dev
- libwww-perl libxslt1-dev libxss-dev libxt-dev libxtst-dev openbox
- patch perl php5-cgi pkg-config python python-cherrypy3 python-crypto
- python-dev python-numpy python-opencv python-openssl python-psutil
- python-yaml rpm ruby subversion ttf-dejavu-core
- ttf-kochi-gothic ttf-kochi-mincho wdiff zip
- $chromeos_dev_list"
-
-# 64-bit systems need a minimum set of 32-bit compat packages for the pre-built
-# NaCl binaries.
-if file /sbin/init | grep -q 'ELF 64-bit'; then
- dev_list="${dev_list} libc6-i386 lib32gcc1 lib32stdc++6"
-fi
-
-# Run-time libraries required by chromeos only
-chromeos_lib_list="libpulse0 libbz2-1.0"
-
-# Full list of required run-time libraries
-lib_list="libatk1.0-0 libc6 libasound2 libcairo2 libcap2 libcups2 libexpat1
- libexif12 libfontconfig1 libfreetype6 libglib2.0-0 libgnome-keyring0
- libgtk2.0-0 libpam0g libpango1.0-0 libpci3 libpcre3 libpixman-1-0
- libpng12-0 libspeechd2 libstdc++6 libsqlite3-0 libx11-6
- libxau6 libxcb1 libxcomposite1 libxcursor1 libxdamage1 libxdmcp6
- libxext6 libxfixes3 libxi6 libxinerama1 libxrandr2 libxrender1
- libxtst6 zlib1g $chromeos_lib_list"
-
-# Debugging symbols for all of the run-time libraries
-dbg_list="libatk1.0-dbg libc6-dbg libcairo2-dbg libfontconfig1-dbg
- libglib2.0-0-dbg libgtk2.0-0-dbg libpango1.0-0-dbg libpcre3-dbg
- libpixman-1-0-dbg libsqlite3-0-dbg libx11-6-dbg libxau6-dbg
- libxcb1-dbg libxcomposite1-dbg libxcursor1-dbg libxdamage1-dbg
- libxdmcp6-dbg libxext6-dbg libxfixes3-dbg libxi6-dbg libxinerama1-dbg
- libxrandr2-dbg libxrender1-dbg libxtst6-dbg zlib1g-dbg"
-
-# Find the proper version of libstdc++6-4.x-dbg.
-if [ "x$codename" = "xprecise" ]; then
- dbg_list="${dbg_list} libstdc++6-4.6-dbg"
-elif [ "x$codename" = "xtrusty" ]; then
- dbg_list="${dbg_list} libstdc++6-4.8-dbg"
-else
- dbg_list="${dbg_list} libstdc++6-4.9-dbg"
-fi
-
-# 32-bit libraries needed e.g. to compile V8 snapshot for Android or armhf
-lib32_list="linux-libc-dev:i386"
-
-# arm cross toolchain packages needed to build chrome on armhf
-arm_list="libc6-dev-armhf-cross
- linux-libc-dev-armhf-cross"
-
-# Work around for dependency issue Debian/Stretch
-if [ "x$codename" = "xstretch" ]; then
- arm_list+=" g++-5-arm-linux-gnueabihf"
-else
- arm_list+=" g++-arm-linux-gnueabihf"
-fi
-
-# Work around for dependency issue Ubuntu/Trusty: http://crbug.com/435056
-if [ "x$codename" = "xtrusty" ]; then
- arm_list+=" g++-4.8-multilib-arm-linux-gnueabihf
- gcc-4.8-multilib-arm-linux-gnueabihf"
-fi
-
-# Packages to build NaCl, its toolchains, and its ports.
-naclports_list="ant autoconf bison cmake gawk intltool xutils-dev xsltproc"
-nacl_list="g++-mingw-w64-i686 lib32z1-dev
- libasound2:i386 libcap2:i386 libelf-dev:i386 libexif12:i386
- libfontconfig1:i386 libgconf-2-4:i386 libglib2.0-0:i386 libgpm2:i386
- libgtk2.0-0:i386 libncurses5:i386 lib32ncurses5-dev
- libnss3:i386 libpango1.0-0:i386
- libssl1.0.0:i386 libtinfo-dev libtinfo-dev:i386 libtool
- libxcomposite1:i386 libxcursor1:i386 libxdamage1:i386 libxi6:i386
- libxrandr2:i386 libxss1:i386 libxtst6:i386 texinfo xvfb
- ${naclports_list}"
-
-# Find the proper version of libgbm-dev. We can't just install libgbm-dev as
-# it depends on mesa, and only one version of mesa can exists on the system.
-# Hence we must match the same version or this entire script will fail.
-mesa_variant=""
-for variant in "-lts-trusty" "-lts-utopic"; do
- if $(dpkg-query -Wf'${Status}' libgl1-mesa-glx${variant} 2>/dev/null | \
- grep -q " ok installed"); then
- mesa_variant="${variant}"
- fi
-done
-dev_list="${dev_list} libgbm-dev${mesa_variant}
- libgles2-mesa-dev${mesa_variant} libgl1-mesa-dev${mesa_variant}
- mesa-common-dev${mesa_variant}"
-nacl_list="${nacl_list} libgl1-mesa-glx${mesa_variant}:i386"
-
-# Some package names have changed over time
-if package_exists ttf-mscorefonts-installer; then
- dev_list="${dev_list} ttf-mscorefonts-installer"
-else
- dev_list="${dev_list} msttcorefonts"
-fi
-if package_exists libnspr4-dbg; then
- dbg_list="${dbg_list} libnspr4-dbg libnss3-dbg"
- lib_list="${lib_list} libnspr4 libnss3"
-else
- dbg_list="${dbg_list} libnspr4-0d-dbg libnss3-1d-dbg"
- lib_list="${lib_list} libnspr4-0d libnss3-1d"
-fi
-if package_exists libjpeg-dev; then
- dev_list="${dev_list} libjpeg-dev"
-else
- dev_list="${dev_list} libjpeg62-dev"
-fi
-if package_exists libudev1; then
- dev_list="${dev_list} libudev1"
- nacl_list="${nacl_list} libudev1:i386"
-else
- dev_list="${dev_list} libudev0"
- nacl_list="${nacl_list} libudev0:i386"
-fi
-if package_exists libbrlapi0.6; then
- dev_list="${dev_list} libbrlapi0.6"
-else
- dev_list="${dev_list} libbrlapi0.5"
-fi
-
-
-# Some packages are only needed if the distribution actually supports
-# installing them.
-if package_exists appmenu-gtk; then
- lib_list="$lib_list appmenu-gtk"
-fi
-
-# When cross building for arm/Android on 64-bit systems the host binaries
-# that are part of v8 need to be compiled with -m32 which means
-# that basic multilib support is needed.
-if file /sbin/init | grep -q 'ELF 64-bit'; then
- # gcc-multilib conflicts with the arm cross compiler (at least in trusty) but
- # g++-X.Y-multilib gives us the 32-bit support that we need. Find out the
- # appropriate value of X and Y by seeing what version the current
- # distribution's g++-multilib package depends on.
- multilib_package=$(apt-cache depends g++-multilib --important | \
- grep -E --color=never --only-matching '\bg\+\+-[0-9.]+-multilib\b')
- lib32_list="$lib32_list $multilib_package"
-fi
-
-# Waits for the user to press 'Y' or 'N'. Either uppercase of lowercase is
-# accepted. Returns 0 for 'Y' and 1 for 'N'. If an optional parameter has
-# been provided to yes_no(), the function also accepts RETURN as a user input.
-# The parameter specifies the exit code that should be returned in that case.
-# The function will echo the user's selection followed by a newline character.
-# Users can abort the function by pressing CTRL-C. This will call "exit 1".
-yes_no() {
- if [ 0 -ne "${do_default-0}" ] ; then
- [ $1 -eq 0 ] && echo "Y" || echo "N"
- return $1
- fi
- local c
- while :; do
- c="$(trap 'stty echo -iuclc icanon 2>/dev/null' EXIT INT TERM QUIT
- stty -echo iuclc -icanon 2>/dev/null
- dd count=1 bs=1 2>/dev/null | od -An -tx1)"
- case "$c" in
- " 0a") if [ -n "$1" ]; then
- [ $1 -eq 0 ] && echo "Y" || echo "N"
- return $1
- fi
- ;;
- " 79") echo "Y"
- return 0
- ;;
- " 6e") echo "N"
- return 1
- ;;
- "") echo "Aborted" >&2
- exit 1
- ;;
- *) # The user pressed an unrecognized key. As we are not echoing
- # any incorrect user input, alert the user by ringing the bell.
- (tput bel) 2>/dev/null
- ;;
- esac
- done
-}
-
-if test "$do_inst_syms" = "" && test 0 -eq ${do_quick_check-0}
-then
- echo "This script installs all tools and libraries needed to build Chromium."
- echo ""
- echo "For most of the libraries, it can also install debugging symbols, which"
- echo "will allow you to debug code in the system libraries. Most developers"
- echo "won't need these symbols."
- echo -n "Do you want me to install them for you (y/N) "
- if yes_no 1; then
- do_inst_syms=1
- fi
-fi
-if test "$do_inst_syms" = "1"; then
- echo "Including debugging symbols."
-else
- echo "Skipping debugging symbols."
- dbg_list=
-fi
-
-if test "$do_inst_lib32" = "1" ; then
- echo "Including 32-bit libraries for ARM/Android."
-else
- echo "Skipping 32-bit libraries for ARM/Android."
- lib32_list=
-fi
-
-if test "$do_inst_arm" = "1" ; then
- echo "Including ARM cross toolchain."
-else
- echo "Skipping ARM cross toolchain."
- arm_list=
-fi
-
-if test "$do_inst_nacl" = "1"; then
- echo "Including NaCl, NaCl toolchain, NaCl ports dependencies."
-else
- echo "Skipping NaCl, NaCl toolchain, NaCl ports dependencies."
- nacl_list=
-fi
-
-# The `sort -r -s -t: -k2` sorts all the :i386 packages to the front, to avoid
-# confusing dpkg-query (crbug.com/446172).
-packages="$(
- echo "${dev_list} ${lib_list} ${dbg_list} ${lib32_list} ${arm_list}"\
- "${nacl_list}" | tr " " "\n" | sort -u | sort -r -s -t: -k2 | tr "\n" " "
-)"
-
-if [ 1 -eq "${do_quick_check-0}" ] ; then
- failed_check="$(dpkg-query -W -f '${PackageSpec}:${Status}\n' \
- ${packages} 2>&1 | grep -v "ok installed" || :)"
- if [ -n "${failed_check}" ]; then
- echo
- nomatch="$(echo "${failed_check}" | \
- sed -e "s/^No packages found matching \(.*\).$/\1/;t;d")"
- missing="$(echo "${failed_check}" | \
- sed -e "/^No packages found matching/d;s/^\(.*\):.*$/\1/")"
- if [ "$nomatch" ]; then
- # Distinguish between packages that actually aren't available to the
- # system (i.e. not in any repo) and packages that just aren't known to
- # dpkg (i.e. managed by apt).
- unknown=""
- for p in ${nomatch}; do
- if apt-cache show ${p} > /dev/null 2>&1; then
- missing="${p}\n${missing}"
- else
- unknown="${p}\n${unknown}"
- fi
- done
- if [ -n "${unknown}" ]; then
- echo "WARNING: The following packages are unknown to your system"
- echo "(maybe missing a repo or need to 'sudo apt-get update'):"
- echo -e "${unknown}" | sed -e "s/^/ /"
- fi
- fi
- if [ -n "${missing}" ]; then
- echo "WARNING: The following packages are not installed:"
- echo -e "${missing}" | sed -e "s/^/ /"
- fi
- exit 1
- fi
- exit 0
-fi
-
-if test "$do_inst_lib32" = "1" || test "$do_inst_nacl" = "1"; then
- if [[ ! $codename =~ (precise) ]]; then
- sudo dpkg --add-architecture i386
- fi
-fi
-sudo apt-get update
-
-# We initially run "apt-get" with the --reinstall option and parse its output.
-# This way, we can find all the packages that need to be newly installed
-# without accidentally promoting any packages from "auto" to "manual".
-# We then re-run "apt-get" with just the list of missing packages.
-echo "Finding missing packages..."
-# Intentionally leaving $packages unquoted so it's more readable.
-echo "Packages required: " $packages
-echo
-new_list_cmd="sudo apt-get install --reinstall $(echo $packages)"
-if new_list="$(yes n | LANGUAGE=en LANG=C $new_list_cmd)"; then
- # We probably never hit this following line.
- echo "No missing packages, and the packages are up-to-date."
-elif [ $? -eq 1 ]; then
- # We expect apt-get to have exit status of 1.
- # This indicates that we cancelled the install with "yes n|".
- new_list=$(echo "$new_list" |
- sed -e '1,/The following NEW packages will be installed:/d;s/^ //;t;d')
- new_list=$(echo "$new_list" | sed 's/ *$//')
- if [ -z "$new_list" ] ; then
- echo "No missing packages, and the packages are up-to-date."
- else
- echo "Installing missing packages: $new_list."
- sudo apt-get install ${do_quietly-} ${new_list}
- fi
- echo
-else
- # An apt-get exit status of 100 indicates that a real error has occurred.
-
- # I am intentionally leaving out the '"'s around new_list_cmd,
- # as this makes it easier to cut and paste the output
- echo "The following command failed: " ${new_list_cmd}
- echo
- echo "It produces the following output:"
- yes n | $new_list_cmd || true
- echo
- echo "You will have to install the above packages yourself."
- echo
- exit 100
-fi
-
-# Install the Chrome OS default fonts. This must go after running
-# apt-get, since install-chromeos-fonts depends on curl.
-if test "$do_inst_chromeos_fonts" != "0"; then
- echo
- echo "Installing Chrome OS fonts."
- dir=`echo $0 | sed -r -e 's/\/[^/]+$//'`
- if ! sudo $dir/linux/install-chromeos-fonts.py; then
- echo "ERROR: The installation of the Chrome OS default fonts failed."
- if [ `stat -f -c %T $dir` == "nfs" ]; then
- echo "The reason is that your repo is installed on a remote file system."
- else
- echo "This is expected if your repo is installed on a remote file system."
- fi
- echo "It is recommended to install your repo on a local file system."
- echo "You can skip the installation of the Chrome OS default founts with"
- echo "the command line option: --no-chromeos-fonts."
- exit 1
- fi
-else
- echo "Skipping installation of Chrome OS fonts."
-fi
-
-# $1 - target name
-# $2 - link name
-create_library_symlink() {
- target=$1
- linkname=$2
- if [ -L $linkname ]; then
- if [ "$(basename $(readlink $linkname))" != "$(basename $target)" ]; then
- sudo rm $linkname
- fi
- fi
- if [ ! -r $linkname ]; then
- echo "Creating link: $linkname"
- sudo ln -fs $target $linkname
- fi
-}
-
-if test "$do_inst_nacl" = "1"; then
- echo "Installing symbolic links for NaCl."
- # naclports needs to cross build python for i386, but libssl1.0.0:i386
- # only contains libcrypto.so.1.0.0 and not the symlink needed for
- # linking (libcrypto.so).
- create_library_symlink /lib/i386-linux-gnu/libcrypto.so.1.0.0 \
- /usr/lib/i386-linux-gnu/libcrypto.so
-
- create_library_symlink /lib/i386-linux-gnu/libssl.so.1.0.0 \
- /usr/lib/i386-linux-gnu/libssl.so
-else
- echo "Skipping symbolic links for NaCl."
-fi
diff --git a/build/install-chroot.sh b/build/install-chroot.sh
deleted file mode 100755
index 99451ed..0000000
--- a/build/install-chroot.sh
+++ /dev/null
@@ -1,888 +0,0 @@
-#!/bin/bash -e
-
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This script installs Debian-derived distributions in a chroot environment.
-# It can for example be used to have an accurate 32bit build and test
-# environment when otherwise working on a 64bit machine.
-# N. B. it is unlikely that this script will ever work on anything other than a
-# Debian-derived system.
-
-# Older Debian based systems had both "admin" and "adm" groups, with "admin"
-# apparently being used in more places. Newer distributions have standardized
-# on just the "adm" group. Check /etc/group for the preferred name of the
-# administrator group.
-admin=$(grep '^admin:' /etc/group >&/dev/null && echo admin || echo adm)
-
-usage() {
- echo "usage: ${0##*/} [-m mirror] [-g group,...] [-s] [-c]"
- echo "-b dir additional directories that should be bind mounted,"
- echo ' or "NONE".'
- echo " Default: if local filesystems present, ask user for help"
- echo "-g group,... groups that can use the chroot unauthenticated"
- echo " Default: '${admin}' and current user's group ('$(id -gn)')"
- echo "-l List all installed chroot environments"
- echo "-m mirror an alternate repository mirror for package downloads"
- echo "-s configure default deb-srcs"
- echo "-c always copy 64bit helper binaries to 32bit chroot"
- echo "-h this help message"
-}
-
-process_opts() {
- local OPTNAME OPTIND OPTERR OPTARG
- while getopts ":b:g:lm:sch" OPTNAME; do
- case "$OPTNAME" in
- b)
- if [ "${OPTARG}" = "NONE" -a -z "${bind_mounts}" ]; then
- bind_mounts="${OPTARG}"
- else
- if [ "${bind_mounts}" = "NONE" -o "${OPTARG}" = "${OPTARG#/}" -o \
- ! -d "${OPTARG}" ]; then
- echo "Invalid -b option(s)"
- usage
- exit 1
- fi
- bind_mounts="${bind_mounts}
-${OPTARG} ${OPTARG} none rw,bind 0 0"
- fi
- ;;
- g)
- [ -n "${OPTARG}" ] &&
- chroot_groups="${chroot_groups}${chroot_groups:+,}${OPTARG}"
- ;;
- l)
- list_all_chroots
- exit
- ;;
- m)
- if [ -n "${mirror}" ]; then
- echo "You can only specify exactly one mirror location"
- usage
- exit 1
- fi
- mirror="$OPTARG"
- ;;
- s)
- add_srcs="y"
- ;;
- c)
- copy_64="y"
- ;;
- h)
- usage
- exit 0
- ;;
- \:)
- echo "'-$OPTARG' needs an argument."
- usage
- exit 1
- ;;
- *)
- echo "invalid command-line option: $OPTARG"
- usage
- exit 1
- ;;
- esac
- done
-
- if [ $# -ge ${OPTIND} ]; then
- eval echo "Unexpected command line argument: \${${OPTIND}}"
- usage
- exit 1
- fi
-}
-
-list_all_chroots() {
- for i in /var/lib/chroot/*; do
- i="${i##*/}"
- [ "${i}" = "*" ] && continue
- [ -x "/usr/local/bin/${i%bit}" ] || continue
- grep -qs "^\[${i%bit}\]\$" /etc/schroot/schroot.conf || continue
- [ -r "/etc/schroot/script-${i}" -a \
- -r "/etc/schroot/mount-${i}" ] || continue
- echo "${i%bit}"
- done
-}
-
-getkey() {
- (
- trap 'stty echo -iuclc icanon 2>/dev/null' EXIT INT TERM QUIT HUP
- stty -echo iuclc -icanon 2>/dev/null
- dd count=1 bs=1 2>/dev/null
- )
-}
-
-chr() {
- printf "\\$(printf '%03o' "$1")"
-}
-
-ord() {
- printf '%d' $(printf '%c' "$1" | od -tu1 -An)
-}
-
-is_network_drive() {
- stat -c %T -f "$1/" 2>/dev/null |
- egrep -qs '^nfs|cifs|smbfs'
-}
-
-# Check that we are running as a regular user
-[ "$(id -nu)" = root ] && {
- echo "Run this script as a regular user and provide your \"sudo\"" \
- "password if requested" >&2
- exit 1
-}
-
-process_opts "$@"
-
-echo "This script will help you through the process of installing a"
-echo "Debian or Ubuntu distribution in a chroot environment. You will"
-echo "have to provide your \"sudo\" password when requested."
-echo
-
-# Error handler
-trap 'exit 1' INT TERM QUIT HUP
-trap 'sudo apt-get clean; tput bel; echo; echo Failed' EXIT
-
-# Install any missing applications that this script relies on. If these packages
-# are already installed, don't force another "apt-get install". That would
-# prevent them from being auto-removed, if they ever become eligible for that.
-# And as this script only needs the packages once, there is no good reason to
-# introduce a hard dependency on things such as dchroot and debootstrap.
-dep=
-for i in dchroot debootstrap libwww-perl; do
- [ -d /usr/share/doc/"$i" ] || dep="$dep $i"
-done
-[ -n "$dep" ] && sudo apt-get -y install $dep
-sudo apt-get -y install schroot
-
-# Create directory for chroot
-sudo mkdir -p /var/lib/chroot
-
-# Find chroot environments that can be installed with debootstrap
-targets="$(cd /usr/share/debootstrap/scripts
- ls | grep '^[a-z]*$')"
-
-# Ask user to pick one of the available targets
-echo "The following targets are available to be installed in a chroot:"
-j=1; for i in $targets; do
- printf '%4d: %s\n' "$j" "$i"
- j=$(($j+1))
-done
-while :; do
- printf "Which target would you like to install: "
- read n
- [ "$n" -gt 0 -a "$n" -lt "$j" ] >&/dev/null && break
-done
-j=1; for i in $targets; do
- [ "$j" -eq "$n" ] && { distname="$i"; break; }
- j=$(($j+1))
-done
-echo
-
-# On x86-64, ask whether the user wants to install x86-32 or x86-64
-archflag=
-arch=
-if [ "$(uname -m)" = x86_64 ]; then
- while :; do
- echo "You are running a 64bit kernel. This allows you to install either a"
- printf "32bit or a 64bit chroot environment. %s" \
- "Which one do you want (32, 64) "
- read arch
- [ "${arch}" == 32 -o "${arch}" == 64 ] && break
- done
- [ "${arch}" == 32 ] && archflag="--arch i386" || archflag="--arch amd64"
- arch="${arch}bit"
- echo
-fi
-target="${distname}${arch}"
-
-# Don't accidentally overwrite an existing installation
-[ -d /var/lib/chroot/"${target}" ] && {
- while :; do
- echo "This chroot already exists on your machine."
- if schroot -l --all-sessions 2>&1 |
- sed 's/^session://' |
- grep -qs "^${target%bit}-"; then
- echo "And it appears to be in active use. Terminate all programs that"
- echo "are currently using the chroot environment and then re-run this"
- echo "script."
- echo "If you still get an error message, you might have stale mounts"
- echo "that you forgot to delete. You can always clean up mounts by"
- echo "executing \"${target%bit} -c\"."
- exit 1
- fi
- echo "I can abort installation, I can overwrite the existing chroot,"
- echo "or I can delete the old one and then exit. What would you like to"
- printf "do (a/o/d)? "
- read choice
- case "${choice}" in
- a|A) exit 1;;
- o|O) sudo rm -rf "/var/lib/chroot/${target}"; break;;
- d|D) sudo rm -rf "/var/lib/chroot/${target}" \
- "/usr/local/bin/${target%bit}" \
- "/etc/schroot/mount-${target}" \
- "/etc/schroot/script-${target}" \
- "/etc/schroot/${target}"
- sudo sed -ni '/^[[]'"${target%bit}"']$/,${
- :1;n;/^[[]/b2;b1;:2;p;n;b2};p' \
- "/etc/schroot/schroot.conf"
- trap '' INT TERM QUIT HUP
- trap '' EXIT
- echo "Deleted!"
- exit 0;;
- esac
- done
- echo
-}
-sudo mkdir -p /var/lib/chroot/"${target}"
-
-# Offer to include additional standard repositories for Ubuntu-based chroots.
-alt_repos=
-grep -qs ubuntu.com /usr/share/debootstrap/scripts/"${distname}" && {
- while :; do
- echo "Would you like to add ${distname}-updates and ${distname}-security "
- printf "to the chroot's sources.list (y/n)? "
- read alt_repos
- case "${alt_repos}" in
- y|Y)
- alt_repos="y"
- break
- ;;
- n|N)
- break
- ;;
- esac
- done
- echo
-}
-
-# Check for non-standard file system mount points and ask the user whether
-# they should be imported into the chroot environment
-# We limit to the first 26 mount points that much some basic heuristics,
-# because a) that allows us to enumerate choices with a single character,
-# and b) if we find more than 26 mount points, then these are probably
-# false-positives and something is very unusual about the system's
-# configuration. No need to spam the user with even more information that
-# is likely completely irrelevant.
-if [ -z "${bind_mounts}" ]; then
- mounts="$(awk '$2 != "/" && $2 !~ "^/boot" && $2 !~ "^/home" &&
- $2 !~ "^/media" && $2 !~ "^/run" &&
- ($3 ~ "ext[2-4]" || $3 == "reiserfs" || $3 == "btrfs" ||
- $3 == "xfs" || $3 == "jfs" || $3 == "u?msdos" ||
- $3 == "v?fat" || $3 == "hfs" || $3 == "ntfs" ||
- $3 ~ "nfs[4-9]?" || $3 == "smbfs" || $3 == "cifs") {
- print $2
- }' /proc/mounts |
- head -n26)"
- if [ -n "${mounts}" ]; then
- echo "You appear to have non-standard mount points that you"
- echo "might want to import into the chroot environment:"
- echo
- sel=
- while :; do
- # Print a menu, listing all non-default mounts of local or network
- # file systems.
- j=1; for m in ${mounts}; do
- c="$(printf $(printf '\\%03o' $((64+$j))))"
- echo "$sel" | grep -qs $c &&
- state="mounted in chroot" || state="$(tput el)"
- printf " $c) %-40s${state}\n" "$m"
- j=$(($j+1))
- done
- # Allow user to interactively (de-)select any of the entries
- echo
- printf "Select mount points that you want to be included or press %s" \
- "SPACE to continue"
- c="$(getkey | tr a-z A-Z)"
- [ "$c" == " " ] && { echo; echo; break; }
- if [ -z "$c" ] ||
- [ "$c" '<' 'A' -o $(ord "$c") -gt $((64 + $(ord "$j"))) ]; then
- # Invalid input, ring the console bell
- tput bel
- else
- # Toggle the selection for the given entry
- if echo "$sel" | grep -qs $c; then
- sel="$(printf "$sel" | sed "s/$c//")"
- else
- sel="$sel$c"
- fi
- fi
- # Reposition cursor to the top of the list of entries
- tput cuu $(($j + 1))
- echo
- done
- fi
- j=1; for m in ${mounts}; do
- c="$(chr $(($j + 64)))"
- if echo "$sel" | grep -qs $c; then
- bind_mounts="${bind_mounts}$m $m none rw,bind 0 0
-"
- fi
- j=$(($j+1))
- done
-fi
-
-# Remove stale entry from /etc/schroot/schroot.conf. Entries start
-# with the target name in square brackets, followed by an arbitrary
-# number of lines. The entry stops when either the end of file has
-# been reached, or when the beginning of a new target is encountered.
-# This means, we cannot easily match for a range of lines in
-# "sed". Instead, we actually have to iterate over each line and check
-# whether it is the beginning of a new entry.
-sudo sed -ni '/^[[]'"${target%bit}"']$/,${:1;n;/^[[]/b2;b1;:2;p;n;b2};p' \
- /etc/schroot/schroot.conf
-
-# Download base system. This takes some time
-if [ -z "${mirror}" ]; then
- grep -qs ubuntu.com /usr/share/debootstrap/scripts/"${distname}" &&
- mirror="http://archive.ubuntu.com/ubuntu" ||
- mirror="http://ftp.us.debian.org/debian"
-fi
-
-sudo ${http_proxy:+http_proxy="${http_proxy}"} debootstrap ${archflag} \
- "${distname}" "/var/lib/chroot/${target}" "$mirror"
-
-# Add new entry to /etc/schroot/schroot.conf
-grep -qs ubuntu.com /usr/share/debootstrap/scripts/"${distname}" &&
- brand="Ubuntu" || brand="Debian"
-if [ -z "${chroot_groups}" ]; then
- chroot_groups="${admin},$(id -gn)"
-fi
-
-if [ -d '/etc/schroot/default' ]; then
- new_version=1
- fstab="/etc/schroot/${target}/fstab"
-else
- new_version=0
- fstab="/etc/schroot/mount-${target}"
-fi
-
-if [ "$new_version" = "1" ]; then
- sudo cp -ar /etc/schroot/default /etc/schroot/${target}
-
- sudo sh -c 'cat >>/etc/schroot/schroot.conf' <<EOF
-[${target%bit}]
-description=${brand} ${distname} ${arch}
-type=directory
-directory=/var/lib/chroot/${target}
-users=root
-groups=${chroot_groups}
-root-groups=${chroot_groups}
-personality=linux$([ "${arch}" != 64bit ] && echo 32)
-profile=${target}
-
-EOF
- [ -n "${bind_mounts}" -a "${bind_mounts}" != "NONE" ] &&
- printf "${bind_mounts}" |
- sudo sh -c "cat >>${fstab}"
-else
- # Older versions of schroot wanted a "priority=" line, whereas recent
- # versions deprecate "priority=" and warn if they see it. We don't have
- # a good feature test, but scanning for the string "priority=" in the
- # existing "schroot.conf" file is a good indication of what to do.
- priority=$(grep -qs 'priority=' /etc/schroot/schroot.conf &&
- echo 'priority=3' || :)
- sudo sh -c 'cat >>/etc/schroot/schroot.conf' <<EOF
-[${target%bit}]
-description=${brand} ${distname} ${arch}
-type=directory
-directory=/var/lib/chroot/${target}
-users=root
-groups=${chroot_groups}
-root-groups=${chroot_groups}
-personality=linux$([ "${arch}" != 64bit ] && echo 32)
-script-config=script-${target}
-${priority}
-
-EOF
-
- # Set up a list of mount points that is specific to this
- # chroot environment.
- sed '/^FSTAB=/s,"[^"]*","'"${fstab}"'",' \
- /etc/schroot/script-defaults |
- sudo sh -c 'cat >/etc/schroot/script-'"${target}"
- sed '\,^/home[/[:space:]],s/\([,[:space:]]\)bind[[:space:]]/\1rbind /' \
- /etc/schroot/mount-defaults |
- sudo sh -c "cat > ${fstab}"
-fi
-
-# Add the extra mount points that the user told us about
-[ -n "${bind_mounts}" -a "${bind_mounts}" != "NONE" ] &&
- printf "${bind_mounts}" |
- sudo sh -c 'cat >>'"${fstab}"
-
-# If this system has a "/media" mountpoint, import it into the chroot
-# environment. Most modern distributions use this mount point to
-# automatically mount devices such as CDROMs, USB sticks, etc...
-if [ -d /media ] &&
- ! grep -qs '^/media' "${fstab}"; then
- echo '/media /media none rw,rbind 0 0' |
- sudo sh -c 'cat >>'"${fstab}"
-fi
-
-# Share /dev/shm, /run and /run/shm.
-grep -qs '^/dev/shm' "${fstab}" ||
- echo '/dev/shm /dev/shm none rw,bind 0 0' |
- sudo sh -c 'cat >>'"${fstab}"
-if [ ! -d "/var/lib/chroot/${target}/run" ] &&
- ! grep -qs '^/run' "${fstab}"; then
- echo '/run /run none rw,bind 0 0' |
- sudo sh -c 'cat >>'"${fstab}"
-fi
-if ! grep -qs '^/run/shm' "${fstab}"; then
- { [ -d /run ] && echo '/run/shm /run/shm none rw,bind 0 0' ||
- echo '/dev/shm /run/shm none rw,bind 0 0'; } |
- sudo sh -c 'cat >>'"${fstab}"
-fi
-
-# Set up a special directory that changes contents depending on the target
-# that is executing.
-d="$(readlink -f "${HOME}/chroot" 2>/dev/null || echo "${HOME}/chroot")"
-s="${d}/.${target}"
-echo "${s} ${d} none rw,bind 0 0" |
- sudo sh -c 'cat >>'"${target}"
-mkdir -p "${s}"
-
-# Install a helper script to launch commands in the chroot
-sudo sh -c 'cat >/usr/local/bin/'"${target%bit}" <<'EOF'
-#!/bin/bash
-
-chroot="${0##*/}"
-
-wrap() {
- # Word-wrap the text passed-in on stdin. Optionally, on continuation lines
- # insert the same number of spaces as the number of characters in the
- # parameter(s) passed to this function.
- # If the "fold" program cannot be found, or if the actual width of the
- # terminal cannot be determined, this function doesn't attempt to do any
- # wrapping.
- local f="$(type -P fold)"
- [ -z "${f}" ] && { cat; return; }
- local c="$(stty -a </dev/tty 2>/dev/null |
- sed 's/.*columns[[:space:]]*\([0-9]*\).*/\1/;t;d')"
- [ -z "${c}" ] && { cat; return; }
- local i="$(echo "$*"|sed 's/./ /g')"
- local j="$(printf %s "${i}"|wc -c)"
- if [ "${c}" -gt "${j}" ]; then
- dd bs=1 count="${j}" 2>/dev/null
- "${f}" -sw "$((${c}-${j}))" | sed '2,$s/^/'"${i}"'/'
- else
- "${f}" -sw "${c}"
- fi
-}
-
-help() {
- echo "Usage ${0##*/} [-h|--help] [-c|--clean] [-C|--clean-all] [-l|--list] [--] args" | wrap "Usage ${0##*/} "
- echo " help: print this message" | wrap " "
- echo " list: list all known chroot environments" | wrap " "
- echo " clean: remove all old chroot sessions for \"${chroot}\"" | wrap " "
- echo " clean-all: remove all old chroot sessions for all environments" | wrap " "
- exit 0
-}
-
-clean() {
- local s t rc
- rc=0
- for s in $(schroot -l --all-sessions); do
- if [ -n "$1" ]; then
- t="${s#session:}"
- [ "${t#${chroot}-}" == "${t}" ] && continue
- fi
- if ls -l /proc/*/{cwd,fd} 2>/dev/null |
- fgrep -qs "/var/lib/schroot/mount/${t}"; then
- echo "Session \"${t}\" still has active users, not cleaning up" | wrap
- rc=1
- continue
- fi
- sudo schroot -c "${s}" -e || rc=1
- done
- exit ${rc}
-}
-
-list() {
- for e in $(schroot -l); do
- e="${e#chroot:}"
- [ -x "/usr/local/bin/${e}" ] || continue
- if schroot -l --all-sessions 2>/dev/null |
- sed 's/^session://' |
- grep -qs "^${e}-"; then
- echo "${e} is currently active"
- else
- echo "${e}"
- fi
- done
- exit 0
-}
-
-while [ "$#" -ne 0 ]; do
- case "$1" in
- --) shift; break;;
- -h|--help) shift; help;;
- -l|--list) shift; list;;
- -c|--clean) shift; clean "${chroot}";;
- -C|--clean-all) shift; clean;;
- *) break;;
- esac
-done
-
-# Start a new chroot session and keep track of the session id. We inject this
-# id into all processes that run inside the chroot. Unless they go out of their
-# way to clear their environment, we can then later identify our child and
-# grand-child processes by scanning their environment.
-session="$(schroot -c "${chroot}" -b)"
-export CHROOT_SESSION_ID="${session}"
-
-# Set GOMA_TMP_DIR for better handling of goma inside chroot.
-export GOMA_TMP_DIR="/tmp/goma_tmp_$CHROOT_SESSION_ID"
-mkdir -p "$GOMA_TMP_DIR"
-
-if [ $# -eq 0 ]; then
- # Run an interactive shell session
- schroot -c "${session}" -r -p
-else
- # Run a command inside of the chroot environment
- p="$1"; shift
- schroot -c "${session}" -r -p "$p" -- "$@"
-fi
-rc=$?
-
-# Compute the inode of the root directory inside of the chroot environment.
-i=$(schroot -c "${session}" -r -p ls -- -id /proc/self/root/. |
- awk '{ print $1 }') 2>/dev/null
-other_pids=
-while [ -n "$i" ]; do
- # Identify processes by the inode number of their root directory. Then
- # remove all processes that we know belong to other sessions. We use
- # "sort | uniq -u" to do what amounts to a "set substraction operation".
- pids=$({ ls -id1 /proc/*/root/. 2>/dev/null |
- sed -e 's,^[^0-9]*'$i'.*/\([1-9][0-9]*\)/.*$,\1,
- t
- d';
- echo "${other_pids}";
- echo "${other_pids}"; } | sort | uniq -u) >/dev/null 2>&1
- # Kill all processes that are still left running in the session. This is
- # typically an assortment of daemon processes that were started
- # automatically. They result in us being unable to tear down the session
- # cleanly.
- [ -z "${pids}" ] && break
- for j in $pids; do
- # Unfortunately, the way that schroot sets up sessions has the
- # side-effect of being unable to tell one session apart from another.
- # This can result in us attempting to kill processes in other sessions.
- # We make a best-effort to avoid doing so.
- k="$( ( xargs -0 -n1 </proc/$j/environ ) 2>/dev/null |
- sed 's/^CHROOT_SESSION_ID=/x/;t1;d;:1;q')"
- if [ -n "${k}" -a "${k#x}" != "${session}" ]; then
- other_pids="${other_pids}
-${j}"
- continue
- fi
- kill -9 $pids
- done
-done
-# End the chroot session. This should clean up all temporary files. But if we
-# earlier failed to terminate all (daemon) processes inside of the session,
-# deleting the session could fail. When that happens, the user has to manually
-# clean up the stale files by invoking us with "--clean" after having killed
-# all running processes.
-schroot -c "${session}" -e
-# Since no goma processes are running, we can remove goma directory.
-rm -rf "$GOMA_TMP_DIR"
-exit $rc
-EOF
-sudo chown root:root /usr/local/bin/"${target%bit}"
-sudo chmod 755 /usr/local/bin/"${target%bit}"
-
-# Add the standard Ubuntu update repositories if requested.
-[ "${alt_repos}" = "y" -a \
- -r "/var/lib/chroot/${target}/etc/apt/sources.list" ] &&
-sudo sed -i '/^deb .* [^ -]\+ main$/p
- s/^\(deb .* [^ -]\+\) main/\1-security main/
- p
- t1
- d
- :1;s/-security main/-updates main/
- t
- d' "/var/lib/chroot/${target}/etc/apt/sources.list"
-
-# Add a few more repositories to the chroot
-[ -r "/var/lib/chroot/${target}/etc/apt/sources.list" ] &&
-sudo sed -i 's/ main$/ main restricted universe multiverse/' \
- "/var/lib/chroot/${target}/etc/apt/sources.list"
-
-# Add the Ubuntu "partner" repository, if available
-if [ -r "/var/lib/chroot/${target}/etc/apt/sources.list" ] &&
- HEAD "http://archive.canonical.com/ubuntu/dists/${distname}/partner" \
- >&/dev/null; then
- sudo sh -c '
- echo "deb http://archive.canonical.com/ubuntu" \
- "'"${distname}"' partner" \
- >>"/var/lib/chroot/'"${target}"'/etc/apt/sources.list"'
-fi
-
-# Add source repositories, if the user requested we do so
-[ "${add_srcs}" = "y" -a \
- -r "/var/lib/chroot/${target}/etc/apt/sources.list" ] &&
-sudo sed -i '/^deb[^-]/p
- s/^deb\([^-]\)/deb-src\1/' \
- "/var/lib/chroot/${target}/etc/apt/sources.list"
-
-# Set apt proxy if host has set http_proxy
-if [ -n "${http_proxy}" ]; then
- sudo sh -c '
- echo "Acquire::http::proxy \"'"${http_proxy}"'\";" \
- >>"/var/lib/chroot/'"${target}"'/etc/apt/apt.conf"'
-fi
-
-# Update packages
-sudo "/usr/local/bin/${target%bit}" /bin/sh -c '
- apt-get update; apt-get -y dist-upgrade' || :
-
-# Install a couple of missing packages
-for i in debian-keyring ubuntu-keyring locales sudo; do
- [ -d "/var/lib/chroot/${target}/usr/share/doc/$i" ] ||
- sudo "/usr/local/bin/${target%bit}" apt-get -y install "$i" || :
-done
-
-# Configure locales
-sudo "/usr/local/bin/${target%bit}" /bin/sh -c '
- l='"${LANG:-en_US}"'; l="${l%%.*}"
- [ -r /etc/locale.gen ] &&
- sed -i "s/^# \($l\)/\1/" /etc/locale.gen
- locale-gen $LANG en_US en_US.UTF-8' || :
-
-# Enable multi-arch support, if available
-sudo "/usr/local/bin/${target%bit}" dpkg --assert-multi-arch >&/dev/null &&
- [ -r "/var/lib/chroot/${target}/etc/apt/sources.list" ] && {
- sudo sed -i 's/ / [arch=amd64,i386] /' \
- "/var/lib/chroot/${target}/etc/apt/sources.list"
- [ -d /var/lib/chroot/${target}/etc/dpkg/dpkg.cfg.d/ ] &&
- sudo "/usr/local/bin/${target%bit}" dpkg --add-architecture \
- $([ "${arch}" = "32bit" ] && echo amd64 || echo i386) >&/dev/null ||
- echo foreign-architecture \
- $([ "${arch}" = "32bit" ] && echo amd64 || echo i386) |
- sudo sh -c \
- "cat >'/var/lib/chroot/${target}/etc/dpkg/dpkg.cfg.d/multiarch'"
-}
-
-# Configure "sudo" package
-sudo "/usr/local/bin/${target%bit}" /bin/sh -c '
- egrep -qs '"'^$(id -nu) '"' /etc/sudoers ||
- echo '"'$(id -nu) ALL=(ALL) ALL'"' >>/etc/sudoers'
-
-# Install a few more commonly used packages
-sudo "/usr/local/bin/${target%bit}" apt-get -y install \
- autoconf automake1.9 dpkg-dev g++-multilib gcc-multilib gdb less libtool \
- lsof strace
-
-# If running a 32bit environment on a 64bit machine, install a few binaries
-# as 64bit. This is only done automatically if the chroot distro is the same as
-# the host, otherwise there might be incompatibilities in build settings or
-# runtime dependencies. The user can force it with the '-c' flag.
-host_distro=$(grep -s DISTRIB_CODENAME /etc/lsb-release | \
- cut -d "=" -f 2)
-if [ "${copy_64}" = "y" -o \
- "${host_distro}" = "${distname}" -a "${arch}" = 32bit ] && \
- file /bin/bash 2>/dev/null | grep -q x86-64; then
- readlinepkg=$(sudo "/usr/local/bin/${target%bit}" sh -c \
- 'apt-cache search "lib64readline.\$" | sort | tail -n 1 | cut -d " " -f 1')
- sudo "/usr/local/bin/${target%bit}" apt-get -y install \
- lib64expat1 lib64ncurses5 ${readlinepkg} lib64z1 lib64stdc++6
- dep=
- for i in binutils gdb; do
- [ -d /usr/share/doc/"$i" ] || dep="$dep $i"
- done
- [ -n "$dep" ] && sudo apt-get -y install $dep
- sudo mkdir -p "/var/lib/chroot/${target}/usr/local/lib/amd64"
- for i in libbfd libpython; do
- lib="$({ ldd /usr/bin/ld; ldd /usr/bin/gdb; } |
- grep -s "$i" | awk '{ print $3 }')"
- if [ -n "$lib" -a -r "$lib" ]; then
- sudo cp "$lib" "/var/lib/chroot/${target}/usr/local/lib/amd64"
- fi
- done
- for lib in libssl libcrypt; do
- for path in /usr/lib /usr/lib/x86_64-linux-gnu; do
- sudo cp $path/$lib* \
- "/var/lib/chroot/${target}/usr/local/lib/amd64/" >&/dev/null || :
- done
- done
- for i in gdb ld; do
- sudo cp /usr/bin/$i "/var/lib/chroot/${target}/usr/local/lib/amd64/"
- sudo sh -c "cat >'/var/lib/chroot/${target}/usr/local/bin/$i'" <<EOF
-#!/bin/sh
-exec /lib64/ld-linux-x86-64.so.2 --library-path /usr/local/lib/amd64 \
- /usr/local/lib/amd64/$i "\$@"
-EOF
- sudo chmod 755 "/var/lib/chroot/${target}/usr/local/bin/$i"
- done
-fi
-
-
-# If the install-build-deps.sh script can be found, offer to run it now
-script="$(dirname $(readlink -f "$0"))/install-build-deps.sh"
-if [ -x "${script}" ]; then
- while :; do
- echo
- echo "If you plan on building Chrome inside of the new chroot environment,"
- echo "you now have to install the build dependencies. Do you want me to"
- printf "start the script that does this for you (y/n)? "
- read install_deps
- case "${install_deps}" in
- y|Y)
- echo
- # We prefer running the script in-place, but this might not be
- # possible, if it lives on a network filesystem that denies
- # access to root.
- tmp_script=
- if ! sudo /usr/local/bin/"${target%bit}" \
- sh -c "[ -x '${script}' ]" >&/dev/null; then
- tmp_script="/tmp/${script##*/}"
- cp "${script}" "${tmp_script}"
- fi
- # Some distributions automatically start an instance of the system-
- # wide dbus daemon, cron daemon or of the logging daemon, when
- # installing the Chrome build depencies. This prevents the chroot
- # session from being closed. So, we always try to shut down any running
- # instance of dbus and rsyslog.
- sudo /usr/local/bin/"${target%bit}" sh -c "${script};
- rc=$?;
- /etc/init.d/cron stop >/dev/null 2>&1 || :;
- /etc/init.d/rsyslog stop >/dev/null 2>&1 || :;
- /etc/init.d/dbus stop >/dev/null 2>&1 || :;
- exit $rc"
- rc=$?
- [ -n "${tmp_script}" ] && rm -f "${tmp_script}"
- [ $rc -ne 0 ] && exit $rc
- break
- ;;
- n|N)
- break
- ;;
- esac
- done
- echo
-fi
-
-# Check whether ~/chroot is on a (slow) network file system and offer to
-# relocate it. Also offer relocation, if the user appears to have multiple
-# spindles (as indicated by "${bind_mount}" being non-empty).
-# We only offer this option, if it doesn't look as if a chroot environment
-# is currently active. Otherwise, relocation is unlikely to work and it
-# can be difficult for the user to recover from the failed attempt to relocate
-# the ~/chroot directory.
-# We don't aim to solve this problem for every configuration,
-# but try to help with the common cases. For more advanced configuration
-# options, the user can always manually adjust things.
-mkdir -p "${HOME}/chroot/"
-if [ ! -h "${HOME}/chroot" ] &&
- ! egrep -qs '^[^[:space:]]*/chroot' /etc/fstab &&
- { [ -n "${bind_mounts}" -a "${bind_mounts}" != "NONE" ] ||
- is_network_drive "${HOME}/chroot"; } &&
- ! egrep -qs '/var/lib/[^/]*chroot/.*/chroot' /proc/mounts; then
- echo "${HOME}/chroot is currently located on the same device as your"
- echo "home directory."
- echo "This might not be what you want. Do you want me to move it somewhere"
- echo "else?"
- # If the computer has multiple spindles, many users configure all or part of
- # the secondary hard disk to be writable by the primary user of this machine.
- # Make some reasonable effort to detect this type of configuration and
- # then offer a good location for where to put the ~/chroot directory.
- suggest=
- for i in $(echo "${bind_mounts}"|cut -d ' ' -f 1); do
- if [ -d "$i" -a -w "$i" -a \( ! -a "$i/chroot" -o -w "$i/chroot/." \) ] &&
- ! is_network_drive "$i"; then
- suggest="$i"
- else
- for j in "$i/"*; do
- if [ -d "$j" -a -w "$j" -a \
- \( ! -a "$j/chroot" -o -w "$j/chroot/." \) ] &&
- ! is_network_drive "$j"; then
- suggest="$j"
- else
- for k in "$j/"*; do
- if [ -d "$k" -a -w "$k" -a \
- \( ! -a "$k/chroot" -o -w "$k/chroot/." \) ] &&
- ! is_network_drive "$k"; then
- suggest="$k"
- break
- fi
- done
- fi
- [ -n "${suggest}" ] && break
- done
- fi
- [ -n "${suggest}" ] && break
- done
- def_suggest="${HOME}"
- if [ -n "${suggest}" ]; then
- # For home directories that reside on network drives, make our suggestion
- # the default option. For home directories that reside on a local drive,
- # require that the user manually enters the new location.
- if is_network_drive "${HOME}"; then
- def_suggest="${suggest}"
- else
- echo "A good location would probably be in \"${suggest}\""
- fi
- fi
- while :; do
- printf "Physical location [${def_suggest}]: "
- read dir
- [ -z "${dir}" ] && dir="${def_suggest}"
- [ "${dir%%/}" == "${HOME%%/}" ] && break
- if ! [ -d "${dir}" -a -w "${dir}" ] ||
- [ -a "${dir}/chroot" -a ! -w "${dir}/chroot/." ]; then
- echo "Cannot write to ${dir}/chroot. Please try again"
- else
- mv "${HOME}/chroot" "${dir}/chroot"
- ln -s "${dir}/chroot" "${HOME}/chroot"
- for i in $(list_all_chroots); do
- sudo "$i" mkdir -p "${dir}/chroot"
- done
- sudo sed -i "s,${HOME}/chroot,${dir}/chroot,g" /etc/schroot/mount-*
- break
- fi
- done
-fi
-
-# Clean up package files
-sudo schroot -c "${target%bit}" -p -- apt-get clean
-sudo apt-get clean
-
-trap '' INT TERM QUIT HUP
-trap '' EXIT
-
-# Let the user know what we did
-cat <<EOF
-
-
-Successfully installed ${distname} ${arch}
-
-You can run programs inside of the chroot by invoking the
-"/usr/local/bin/${target%bit}" command.
-
-This command can be used with arguments, in order to just run a single
-program inside of the chroot environment (e.g. "${target%bit} make chrome")
-or without arguments, in order to run an interactive shell session inside
-of the chroot environment.
-
-If you need to run things as "root", you can use "sudo" (e.g. try
-"sudo ${target%bit} apt-get update").
-
-Your home directory is shared between the host and the chroot. But I
-configured "${HOME}/chroot" to be private to the chroot environment.
-You can use it for files that need to differ between environments. This
-would be a good place to store binaries that you have built from your
-source files.
-
-For Chrome, this probably means you want to make your "out" directory a
-symbolic link that points somewhere inside of "${HOME}/chroot".
-
-You still need to run "gclient runhooks" whenever you switch from building
-outside of the chroot to inside of the chroot. But you will find that you
-don't have to repeatedly erase and then completely rebuild all your object
-and binary files.
-
-EOF
diff --git a/build/internal/README.chromium b/build/internal/README.chromium
deleted file mode 100644
index 4624830..0000000
--- a/build/internal/README.chromium
+++ /dev/null
@@ -1,24 +0,0 @@
-Internal property sheets:
- essential.vsprops
- Contains the common settings used throughout the projects. Is included by either ..\debug.vsprops or ..\release.vsprops, so in general, it is not included directly.
-
- release_defaults.vsprops
- Included by ..\release.vsprops. Its settings are overriden by release_impl$(CHROME_BUILD_TYPE).vsprops. Uses the default VS setting which is "Maximize Speed". Results in relatively fast build with reasonable optimization level but without whole program optimization to reduce build time.
-
- release_impl.vsprops
- Included by ..\release.vsprops by default when CHROME_BUILD_TYPE is undefined. Includes release_defaults.vsprops.
-
- release_impl_checksenabled.vsprops
- Included by ..\release.vsprops when CHROME_BUILD_TYPE=_checksenabled. Matches what release_defaults.vsprops does, but doesn't actually inherit from it as we couldn't quite get that working. The only difference is that _DEBUG is set instead of NDEBUG. Used for keeping debug checks enabled with a build that is fast enough to dogfood with.
-
- release_impl_official.vsprops
- Included by ..\release.vsprops when CHROME_BUILD_TYPE=_official. Includes release_defaults.vsprops. Enables Whole Program Optimizations (WPO), which doubles the build time. Results in much more optimized build. Uses "Full Optimization" and "Flavor small code".
-
- release_impl_pgo_instrument.vsprops
- Included by ..\release.vsprops when CHROME_BUILD_TYPE=_pgo_instrument. Includes release_defaults.vsprops. Enables Profile Guided Optimization (PGO) instrumentation (first pass). Uses "Full Optimization" and "Flavor small code".
-
- release_impl_pgo_optimize.vsprops
- Included by ..\release.vsprops when CHROME_BUILD_TYPE=_pgo_optimize. Includes release_defaults.vsprops. Enables Profile Guided Optimization (PGO) optimization (second pass). Uses "Full Optimization" and "Flavor small code".
-
- release_impl_purify.vsprops
- Included by ..\release.vsprops when CHROME_BUILD_TYPE=_purify. Includes release_defaults.vsprops. Disables optimizations. Used with Purify to test without debug tools and without optimization; i.e. NDEBUG is defined but the compiler doesn't optimize the binary.
diff --git a/build/internal/release_defaults.gypi b/build/internal/release_defaults.gypi
deleted file mode 100644
index 1bf674a..0000000
--- a/build/internal/release_defaults.gypi
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright (c) 2011 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-{
- 'msvs_settings': {
- 'VCCLCompilerTool': {
- 'StringPooling': 'true',
- },
- 'VCLinkerTool': {
- # No incremental linking.
- 'LinkIncremental': '1',
- # Eliminate Unreferenced Data (/OPT:REF).
- 'OptimizeReferences': '2',
- # Folding on (/OPT:ICF).
- 'EnableCOMDATFolding': '2',
- },
- },
-}
diff --git a/build/internal/release_impl.gypi b/build/internal/release_impl.gypi
deleted file mode 100644
index 5ac0e09..0000000
--- a/build/internal/release_impl.gypi
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright (c) 2011 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-{
- 'includes': ['release_defaults.gypi'],
- 'msvs_settings': {
- 'VCCLCompilerTool': {
- 'OmitFramePointers': 'false',
- # The above is not sufficient (http://crbug.com/106711): it
- # simply eliminates an explicit "/Oy", but both /O2 and /Ox
- # perform FPO regardless, so we must explicitly disable.
- # We still want the false setting above to avoid having
- # "/Oy /Oy-" and warnings about overriding.
- 'AdditionalOptions': ['/Oy-'],
- },
- },
-}
diff --git a/build/internal/release_impl_official.gypi b/build/internal/release_impl_official.gypi
deleted file mode 100644
index 36d5d78..0000000
--- a/build/internal/release_impl_official.gypi
+++ /dev/null
@@ -1,41 +0,0 @@
-# Copyright (c) 2011 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-{
- 'includes': ['release_defaults.gypi'],
- 'defines': ['OFFICIAL_BUILD'],
- 'msvs_settings': {
- 'VCCLCompilerTool': {
- 'InlineFunctionExpansion': '2',
- 'EnableIntrinsicFunctions': 'true',
- 'OmitFramePointers': 'false',
- # The above is not sufficient (http://crbug.com/106711): it
- # simply eliminates an explicit "/Oy", but both /O2 and /Ox
- # perform FPO regardless, so we must explicitly disable.
- # We still want the false setting above to avoid having
- # "/Oy /Oy-" and warnings about overriding.
- 'AdditionalOptions': ['/Oy-'],
- },
- 'VCLibrarianTool': {
- 'AdditionalOptions': [
- '/ltcg',
- '/expectedoutputsize:120000000'
- ],
- },
- 'VCLinkerTool': {
- 'AdditionalOptions': [
- '/time',
- # This may reduce memory fragmentation during linking.
- # The expected size is 40*1024*1024, which gives us about 10M of
- # headroom as of Dec 16, 2011.
- '/expectedoutputsize:41943040',
- ],
- # The /PROFILE flag causes the linker to add a "FIXUP" debug stream to
- # the generated PDB. According to MSDN documentation, this flag is only
- # available (or perhaps supported) in the Enterprise (team development)
- # version of Visual Studio. If this blocks your official build, simply
- # comment out this line, then re-run "gclient runhooks".
- 'Profile': 'true',
- },
- },
-}
diff --git a/build/inverse_depth.py b/build/inverse_depth.py
deleted file mode 100755
index ce7a6ab..0000000
--- a/build/inverse_depth.py
+++ /dev/null
@@ -1,24 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import sys
-
-
-def DoMain(argv):
- depth = argv[0]
- return os.path.relpath(os.getcwd(), os.path.abspath(depth))
-
-
-def main(argv):
- if len(argv) < 2:
- print "USAGE: inverse_depth.py depth"
- return 1
- print DoMain(argv[1:])
- return 0
-
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv))
diff --git a/build/ios/OWNERS b/build/ios/OWNERS
deleted file mode 100644
index 4caf405..0000000
--- a/build/ios/OWNERS
+++ /dev/null
@@ -1,4 +0,0 @@
-rohitrao@chromium.org
-stuartmorgan@chromium.org
-
-per-file grit_whitelist.txt=*
diff --git a/build/ios/PRESUBMIT.py b/build/ios/PRESUBMIT.py
deleted file mode 100644
index bbd17b3..0000000
--- a/build/ios/PRESUBMIT.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-
-"""Chromium presubmit script for src/tools/ios.
-
-See http://dev.chromium.org/developers/how-tos/depottools/presubmit-scripts
-for more details on the presubmit API built into depot_tools.
-"""
-
-WHITELIST_FILE = 'build/ios/grit_whitelist.txt'
-
-def _CheckWhitelistSorted(input_api, output_api):
- for path in input_api.LocalPaths():
- if WHITELIST_FILE == path:
- lines = open(os.path.join('../..', WHITELIST_FILE)).readlines()
- i = 0
- while i < len(lines) - 1 and lines[i] <= lines[i + 1]:
- i += 1
- if i < len(lines) - 1:
- return [output_api.PresubmitError(
- 'The file ' + WHITELIST_FILE + ' must be sorted. ' +
- 'First offending line: #' + str(i + 2))]
- return []
-
-def _CommonChecks(input_api, output_api):
- """Checks common to both upload and commit."""
- results = []
- results.extend(_CheckWhitelistSorted(input_api, output_api))
- return results
-
-def CheckChangeOnUpload(input_api, output_api):
- results = []
- results.extend(_CommonChecks(input_api, output_api))
- return results
-
-def CheckChangeOnCommit(input_api, output_api):
- results = []
- results.extend(_CommonChecks(input_api, output_api))
- return results
diff --git a/build/ios/chrome_ios.croc b/build/ios/chrome_ios.croc
deleted file mode 100644
index 938a2e9..0000000
--- a/build/ios/chrome_ios.croc
+++ /dev/null
@@ -1,71 +0,0 @@
-# -*- python -*-
-# Crocodile config file for Chromium iOS.
-#
-# Note that Chromium iOS also uses the config file at src/build/common.croc.
-#
-# See src/tools/code_coverage/example.croc for more info on config files.
-
-{
- # List of rules, applied in order
- 'rules' : [
- # Specify inclusions before exclusions, since rules are in order.
-
- # Exclude everything to negate whatever is in src/build/common.croc
- {
- 'regexp' : '.*',
- 'include' : 0,
- },
-
- # Include all directories (but not the files in the directories).
- # This is a workaround for how croc.py walks the directory tree. See the
- # TODO in the AddFiles method of src/tools/code_coverage/croc.py
- {
- 'regexp' : '.*/$',
- 'include' : 1,
- },
-
- # Include any file with an 'ios' directory in the path.
- {
- 'regexp' : '.*/ios/.*',
- 'include' : 1,
- 'add_if_missing' : 1,
- },
-
- # Include any file that ends with _ios.
- {
- 'regexp' : '.*_ios\\.(c|cc|m|mm)$',
- 'include' : 1,
- 'add_if_missing' : 1,
- },
-
- # Include any file that ends with _ios_unittest (and label it a test).
- {
- 'regexp' : '.*_ios_unittest\\.(c|cc|m|mm)$',
- 'include' : 1,
- 'add_if_missing' : 1,
- 'group' : 'test',
- },
-
- # Don't scan for executable lines in uninstrumented header files
- {
- 'regexp' : '.*\\.(h|hpp)$',
- 'add_if_missing' : 0,
- },
-
- # Don't measure coverage of perftests.
- {
- 'regexp' : '.*perftest\\.(c|cc|m|mm)$',
- 'include' : 0,
- },
-
- # Languages
- {
- 'regexp' : '.*\\.m$',
- 'language' : 'ObjC',
- },
- {
- 'regexp' : '.*\\.mm$',
- 'language' : 'ObjC++',
- },
- ],
-}
diff --git a/build/ios/clean_env.py b/build/ios/clean_env.py
deleted file mode 100755
index 548e2b9..0000000
--- a/build/ios/clean_env.py
+++ /dev/null
@@ -1,77 +0,0 @@
-#!/usr/bin/python
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import os
-import sys
-
-def Main(argv):
- """This is like 'env -i', but it uses a whitelist of env variables to allow
- through to the command being run. It attempts to strip off Xcode-added
- values from PATH.
- """
- # Note: An attempt was made to do something like: env -i bash -lc '[command]'
- # but that fails to set the things set by login (USER, etc.), so instead
- # the only approach that seems to work is to have a whitelist.
- env_key_whitelist = (
- 'HOME',
- 'LOGNAME',
- # 'PATH' added below (but filtered).
- 'PWD',
- 'SHELL',
- 'TEMP',
- 'TMPDIR',
- 'USER'
- )
-
- # Need something to run.
- # TODO(lliabraa): Make this output a usage string and exit (here and below).
- assert(len(argv) > 0)
-
- add_to_path = [];
- first_entry = argv[0];
- if first_entry.startswith('ADD_TO_PATH='):
- argv = argv[1:];
- add_to_path = first_entry.replace('ADD_TO_PATH=', '', 1).split(':')
-
- # Still need something to run.
- assert(len(argv) > 0)
-
- clean_env = {}
-
- # Pull over the whitelisted keys.
- for key in env_key_whitelist:
- val = os.environ.get(key, None)
- if not val is None:
- clean_env[key] = val
-
- # Collect the developer dir as set via Xcode, defaulting it.
- dev_prefix = os.environ.get('DEVELOPER_DIR', '/Developer/')
- if dev_prefix[-1:] != '/':
- dev_prefix += '/'
-
- # Now pull in PATH, but remove anything Xcode might have added.
- initial_path = os.environ.get('PATH', '')
- filtered_chunks = \
- [x for x in initial_path.split(':') if not x.startswith(dev_prefix)]
- if filtered_chunks:
- clean_env['PATH'] = ':'.join(add_to_path + filtered_chunks)
-
- # Add any KEY=VALUE args before the command to the cleaned environment.
- args = argv[:]
- while '=' in args[0]:
- (key, val) = args[0].split('=', 1)
- clean_env[key] = val
- args = args[1:]
-
- # Still need something to run.
- assert(len(args) > 0)
-
- # Off it goes...
- os.execvpe(args[0], args, clean_env)
- # Should never get here, so return a distinctive, non-zero status code.
- return 66
-
-if __name__ == '__main__':
- sys.exit(Main(sys.argv[1:]))
diff --git a/build/ios/coverage.gypi b/build/ios/coverage.gypi
deleted file mode 100644
index e822089..0000000
--- a/build/ios/coverage.gypi
+++ /dev/null
@@ -1,32 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
- 'variables': {
- 'enable_coverage%': 0,
- },
- 'conditions': [
- ['enable_coverage', {
- 'target_defaults': {
- 'defines': [
- 'ENABLE_TEST_CODE_COVERAGE=1'
- ],
- 'link_settings': {
- 'xcode_settings': {
- 'OTHER_LDFLAGS': [
- '-fprofile-arcs',
- ],
- },
- },
- 'xcode_settings': {
- 'OTHER_CFLAGS': [
- '-fprofile-arcs',
- '-ftest-coverage',
- ],
- },
- },
- }],
- ],
-}
-
diff --git a/build/ios/grit_whitelist.txt b/build/ios/grit_whitelist.txt
deleted file mode 100644
index a976daf..0000000
--- a/build/ios/grit_whitelist.txt
+++ /dev/null
@@ -1,1155 +0,0 @@
-IDR_ABOUT_DOM_DISTILLER_CSS
-IDR_ABOUT_DOM_DISTILLER_HTML
-IDR_ABOUT_DOM_DISTILLER_JS
-IDR_ABOUT_STATS_HTML
-IDR_ABOUT_STATS_JS
-IDR_ABOUT_VERSION_CSS
-IDR_ABOUT_VERSION_HTML
-IDR_ABOUT_VERSION_JS
-IDR_CONTEXTUAL_SEARCH_PROMO_HTML
-IDR_CONTROLLED_SETTING_MANDATORY
-IDR_CRASHES_HTML
-IDR_CRASHES_JS
-IDR_CREDITS_HTML
-IDR_CREDITS_JS
-IDR_CREDIT_CARD_CVC_HINT
-IDR_CREDIT_CARD_CVC_HINT_AMEX
-IDR_DATA_REDUCTION_PROXY_INTERSTITIAL_HTML
-IDR_DEFAULT_FAVICON
-IDR_DEFAULT_FAVICON_32
-IDR_DEFAULT_FAVICON_64
-IDR_DIR_HEADER_HTML
-IDR_DISTILLABLE_PAGE_SERIALIZED_MODEL
-IDR_DISTILLER_CSS
-IDR_DISTILLER_IOS_CSS
-IDR_DISTILLER_JS
-IDR_DOM_DISTILLER_VIEWER_HTML
-IDR_DOM_DISTILLER_VIEWER_JS
-IDR_EXTRACT_PAGE_FEATURES_JS
-IDR_FLAGS_FAVICON
-IDR_FLAGS_HTML
-IDR_FLAGS_JS
-IDR_GCM_INTERNALS_CSS
-IDR_GCM_INTERNALS_HTML
-IDR_GCM_INTERNALS_JS
-IDR_HISTORY_FAVICON
-IDR_HISTORY_HTML
-IDR_HISTORY_JS
-IDR_INCOGNITO_TAB_HTML
-IDR_INFOBAR_AUTOFILL_CC
-IDR_INFOBAR_AUTOLOGIN
-IDR_INFOBAR_RESTORE_SESSION
-IDR_INFOBAR_SAVE_PASSWORD
-IDR_INFOBAR_TRANSLATE_IOS
-IDR_INFOBAR_WARNING
-IDR_IS_DISTILLABLE_JS
-IDR_LOCATION_BAR_HTTP
-IDR_NET_ERROR_HTML
-IDR_NET_EXPORT_HTML
-IDR_NET_EXPORT_JS
-IDR_NET_INTERNALS_INDEX_HTML
-IDR_NET_INTERNALS_INDEX_JS
-IDR_OMAHA_HTML
-IDR_OMAHA_JS
-IDR_OMNIBOX_CALCULATOR
-IDR_OMNIBOX_CLEAR_IOS
-IDR_OMNIBOX_CLEAR_OTR_IOS
-IDR_OMNIBOX_CLEAR_OTR_PRESSED_IOS
-IDR_OMNIBOX_CLEAR_PRESSED_IOS
-IDR_OMNIBOX_EXTENSION_APP
-IDR_OMNIBOX_HISTORY
-IDR_OMNIBOX_HISTORY_INCOGNITO
-IDR_OMNIBOX_HTTP
-IDR_OMNIBOX_HTTPS_INVALID
-IDR_OMNIBOX_HTTPS_POLICY_WARNING
-IDR_OMNIBOX_HTTPS_VALID
-IDR_OMNIBOX_HTTPS_WARNING
-IDR_OMNIBOX_HTTP_INCOGNITO
-IDR_OMNIBOX_KEYBOARD_VIEW_APPEND
-IDR_OMNIBOX_KEYBOARD_VIEW_APPEND_HIGHLIGHTED
-IDR_OMNIBOX_KEYBOARD_VIEW_APPEND_INCOGNITO
-IDR_OMNIBOX_KEYBOARD_VIEW_APPEND_INCOGNITO_HIGHLIGHTED
-IDR_OMNIBOX_SEARCH
-IDR_OMNIBOX_SEARCH_INCOGNITO
-IDR_OMNIBOX_SEARCH_SECURED
-IDR_OMNIBOX_STAR
-IDR_OMNIBOX_STAR_INCOGNITO
-IDR_OTHER_DEVICES_JS
-IDR_PAGEINFO_BAD
-IDR_PAGEINFO_GOOD
-IDR_PAGEINFO_INFO
-IDR_PAGEINFO_WARNING_MAJOR
-IDR_PAGEINFO_WARNING_MINOR
-IDR_POLICY_CSS
-IDR_POLICY_HTML
-IDR_POLICY_JS
-IDR_PRINTER_FAVICON
-IDR_SAD_FAVICON
-IDR_SAD_TAB
-IDR_SECURITY_INTERSTITIAL_HTML
-IDR_SIGNIN_INTERNALS_INDEX_HTML
-IDR_SIGNIN_INTERNALS_INDEX_JS
-IDR_SYNC_INTERNALS_ABOUT_JS
-IDR_SYNC_INTERNALS_CHROME_SYNC_JS
-IDR_SYNC_INTERNALS_DATA_JS
-IDR_SYNC_INTERNALS_EVENTS_JS
-IDR_SYNC_INTERNALS_INDEX_HTML
-IDR_SYNC_INTERNALS_INDEX_JS
-IDR_SYNC_INTERNALS_SEARCH_JS
-IDR_SYNC_INTERNALS_SYNC_LOG_JS
-IDR_SYNC_INTERNALS_SYNC_NODE_BROWSER_JS
-IDR_SYNC_INTERNALS_SYNC_SEARCH_JS
-IDR_SYNC_INTERNALS_TYPES_JS
-IDR_TOOLBAR_SHADOW_FULL_BLEED
-IDR_TRANSLATE_JS
-IDR_UBER_UTILS_JS
-IDR_WEBUI_CSS_TEXT_DEFAULTS
-IDR_WEBUI_I18N_TEMPLATE_JS
-IDR_WEBUI_JSTEMPLATE_JS
-IDR_WEBUI_JS_LOAD_TIME_DATA
-IDS_ABOUT_MAC
-IDS_ABOUT_VERSION_COMMAND_LINE
-IDS_ABOUT_VERSION_COMPANY_NAME
-IDS_ABOUT_VERSION_COPYRIGHT
-IDS_ABOUT_VERSION_EXECUTABLE_PATH
-IDS_ABOUT_VERSION_OFFICIAL
-IDS_ABOUT_VERSION_OS
-IDS_ABOUT_VERSION_PATH_NOTFOUND
-IDS_ABOUT_VERSION_PROFILE_PATH
-IDS_ABOUT_VERSION_REVISION
-IDS_ABOUT_VERSION_TITLE
-IDS_ABOUT_VERSION_UNOFFICIAL
-IDS_ABOUT_VERSION_USER_AGENT
-IDS_ABOUT_VERSION_VARIATIONS
-IDS_ACCEPT_LANGUAGES
-IDS_ACCNAME_BACK
-IDS_ACCNAME_CLEAR_TEXT
-IDS_ACCNAME_FORWARD
-IDS_ACCNAME_LOCATION
-IDS_ACCNAME_VOICE_SEARCH
-IDS_ALLOW_INSECURE_CONTENT_BUTTON
-IDS_ALTERNATE_NAV_URL_VIEW_LABEL
-IDS_ANNOTATED_SUGGESTION
-IDS_APP_CANCEL
-IDS_APP_OK
-IDS_APP_UNTITLED_SHORTCUT_FILE_NAME
-IDS_AUTOCOMPLETE_SEARCH_DESCRIPTION
-IDS_AUTOFILL_ADDRESS_LINE_SEPARATOR
-IDS_AUTOFILL_ADDRESS_SUMMARY_SEPARATOR
-IDS_AUTOFILL_CARD_UNMASK_PROMPT_ERROR_NETWORK
-IDS_AUTOFILL_CARD_UNMASK_PROMPT_ERROR_PERMANENT
-IDS_AUTOFILL_CARD_UNMASK_PROMPT_ERROR_TRY_AGAIN
-IDS_AUTOFILL_CARD_UNMASK_PROMPT_INSTRUCTIONS
-IDS_AUTOFILL_CARD_UNMASK_PROMPT_INSTRUCTIONS_AMEX
-IDS_AUTOFILL_CARD_UNMASK_PROMPT_INSTRUCTIONS_EXPIRED
-IDS_AUTOFILL_CARD_UNMASK_PROMPT_INSTRUCTIONS_EXPIRED_AMEX
-IDS_AUTOFILL_CC_AMEX
-IDS_AUTOFILL_CC_AMEX_SHORT
-IDS_AUTOFILL_CC_DINERS
-IDS_AUTOFILL_CC_DISCOVER
-IDS_AUTOFILL_CC_GENERIC
-IDS_AUTOFILL_CC_INFOBAR_ACCEPT
-IDS_AUTOFILL_CC_INFOBAR_DENY
-IDS_AUTOFILL_CC_INFOBAR_TEXT
-IDS_AUTOFILL_CC_JCB
-IDS_AUTOFILL_CC_MASTERCARD
-IDS_AUTOFILL_CC_UNION_PAY
-IDS_AUTOFILL_CC_VISA
-IDS_AUTOFILL_CLEAR_FORM_MENU_ITEM
-IDS_AUTOFILL_DELETE_AUTOCOMPLETE_SUGGESTION_CONFIRMATION_BODY
-IDS_AUTOFILL_DELETE_CREDIT_CARD_SUGGESTION_CONFIRMATION_BODY
-IDS_AUTOFILL_DELETE_PROFILE_SUGGESTION_CONFIRMATION_BODY
-IDS_AUTOFILL_DIALOG_PRIVACY_POLICY_LINK
-IDS_AUTOFILL_FIELD_LABEL_AREA
-IDS_AUTOFILL_FIELD_LABEL_COUNTY
-IDS_AUTOFILL_FIELD_LABEL_DEPARTMENT
-IDS_AUTOFILL_FIELD_LABEL_DISTRICT
-IDS_AUTOFILL_FIELD_LABEL_EMIRATE
-IDS_AUTOFILL_FIELD_LABEL_ISLAND
-IDS_AUTOFILL_FIELD_LABEL_PARISH
-IDS_AUTOFILL_FIELD_LABEL_POSTAL_CODE
-IDS_AUTOFILL_FIELD_LABEL_PREFECTURE
-IDS_AUTOFILL_FIELD_LABEL_PROVINCE
-IDS_AUTOFILL_FIELD_LABEL_STATE
-IDS_AUTOFILL_FIELD_LABEL_ZIP_CODE
-IDS_AUTOFILL_OPTIONS_POPUP
-IDS_AUTOFILL_PASSWORD_FIELD_SUGGESTIONS_TITLE
-IDS_AUTOFILL_SCAN_CREDIT_CARD
-IDS_AUTOFILL_WARNING_FORM_DISABLED
-IDS_AUTOFILL_WARNING_INSECURE_CONNECTION
-IDS_AUTOLOGIN_INFOBAR_CANCEL_BUTTON
-IDS_AUTOLOGIN_INFOBAR_MESSAGE
-IDS_AUTOLOGIN_INFOBAR_OK_BUTTON
-IDS_BLOCKED_DISPLAYING_INSECURE_CONTENT
-IDS_BLOCK_INSECURE_CONTENT_BUTTON
-IDS_BOOKMARK_ADD_EDITOR_TITLE
-IDS_BOOKMARK_ALL_TABS_DIALOG_TITLE
-IDS_BOOKMARK_BAR_FOLDER_NAME
-IDS_BOOKMARK_BAR_MANAGED_FOLDER_DEFAULT_NAME
-IDS_BOOKMARK_BAR_MANAGED_FOLDER_DOMAIN_NAME
-IDS_BOOKMARK_BAR_MOBILE_FOLDER_NAME
-IDS_BOOKMARK_BAR_OTHER_FOLDER_NAME
-IDS_BOOKMARK_BAR_REDO
-IDS_BOOKMARK_BAR_REDO_ADD
-IDS_BOOKMARK_BAR_REDO_DELETE
-IDS_BOOKMARK_BAR_REDO_EDIT
-IDS_BOOKMARK_BAR_REDO_MOVE
-IDS_BOOKMARK_BAR_REDO_REORDER
-IDS_BOOKMARK_BAR_SUPERVISED_FOLDER_DEFAULT_NAME
-IDS_BOOKMARK_BAR_UNDO
-IDS_BOOKMARK_BAR_UNDO_ADD
-IDS_BOOKMARK_BAR_UNDO_DELETE
-IDS_BOOKMARK_BAR_UNDO_EDIT
-IDS_BOOKMARK_BAR_UNDO_MOVE
-IDS_BOOKMARK_BAR_UNDO_REORDER
-IDS_BOOKMARK_BUBBLE_CHOOSER_ANOTHER_FOLDER
-IDS_BOOKMARK_BUBBLE_REMOVE_BOOKMARK
-IDS_BOOKMARK_EDITOR_CONFIRM_DELETE
-IDS_BOOKMARK_EDITOR_NEW_FOLDER_NAME
-IDS_BOOKMARK_EDITOR_TITLE
-IDS_BOOKMARK_FOLDER_CHOOSER_TITLE
-IDS_BOOKMARK_FOLDER_EDITOR_TITLE
-IDS_BOOKMARK_FOLDER_EDITOR_WINDOW_TITLE
-IDS_BOOKMARK_FOLDER_EDITOR_WINDOW_TITLE_NEW
-IDS_BOOKMARK_MANAGER_FOLDER_SECTION
-IDS_BOOKMARK_MANAGER_FOLDER_TITLE
-IDS_BOOKMARK_MANAGER_NAME_INPUT_PLACE_HOLDER
-IDS_BOOKMARK_MANAGER_REMOVE_TITLE
-IDS_BOOKMARK_MANAGER_URL_INPUT_PLACE_HOLDER
-IDS_BOOKMARK_NEW_FOLDER_BUTTON_TITLE
-IDS_CANCEL
-IDS_CERT_ERROR_AUTHORITY_INVALID_DESCRIPTION
-IDS_CERT_ERROR_AUTHORITY_INVALID_DETAILS
-IDS_CERT_ERROR_AUTHORITY_INVALID_EXTRA_INFO_2
-IDS_CERT_ERROR_AUTHORITY_INVALID_TITLE
-IDS_CERT_ERROR_CHAIN_EXPIRED_DESCRIPTION
-IDS_CERT_ERROR_CHAIN_EXPIRED_DETAILS
-IDS_CERT_ERROR_COMMON_NAME_INVALID_DESCRIPTION
-IDS_CERT_ERROR_COMMON_NAME_INVALID_DETAILS
-IDS_CERT_ERROR_COMMON_NAME_INVALID_EXTRA_INFO_2
-IDS_CERT_ERROR_COMMON_NAME_INVALID_TITLE
-IDS_CERT_ERROR_CONTAINS_ERRORS_DESCRIPTION
-IDS_CERT_ERROR_CONTAINS_ERRORS_DETAILS
-IDS_CERT_ERROR_CONTAINS_ERRORS_EXTRA_INFO_2
-IDS_CERT_ERROR_CONTAINS_ERRORS_TITLE
-IDS_CERT_ERROR_EXPIRED_DESCRIPTION
-IDS_CERT_ERROR_EXPIRED_DETAILS
-IDS_CERT_ERROR_EXPIRED_DETAILS_EXTRA_INFO_2
-IDS_CERT_ERROR_EXPIRED_TITLE
-IDS_CERT_ERROR_EXTRA_INFO_1
-IDS_CERT_ERROR_EXTRA_INFO_TITLE
-IDS_CERT_ERROR_INVALID_CERT_DESCRIPTION
-IDS_CERT_ERROR_INVALID_CERT_DETAILS
-IDS_CERT_ERROR_INVALID_CERT_EXTRA_INFO_2
-IDS_CERT_ERROR_INVALID_CERT_TITLE
-IDS_CERT_ERROR_NAME_CONSTRAINT_VIOLATION_DESCRIPTION
-IDS_CERT_ERROR_NAME_CONSTRAINT_VIOLATION_DETAILS
-IDS_CERT_ERROR_NAME_CONSTRAINT_VIOLATION_TITLE
-IDS_CERT_ERROR_NOT_YET_VALID_DESCRIPTION
-IDS_CERT_ERROR_NOT_YET_VALID_DETAILS
-IDS_CERT_ERROR_NOT_YET_VALID_DETAILS_EXTRA_INFO_2
-IDS_CERT_ERROR_NOT_YET_VALID_TITLE
-IDS_CERT_ERROR_NO_REVOCATION_MECHANISM_DESCRIPTION
-IDS_CERT_ERROR_NO_REVOCATION_MECHANISM_DETAILS
-IDS_CERT_ERROR_NO_REVOCATION_MECHANISM_TITLE
-IDS_CERT_ERROR_REVOKED_CERT_DESCRIPTION
-IDS_CERT_ERROR_REVOKED_CERT_DETAILS
-IDS_CERT_ERROR_REVOKED_CERT_EXTRA_INFO_2
-IDS_CERT_ERROR_REVOKED_CERT_TITLE
-IDS_CERT_ERROR_UNABLE_TO_CHECK_REVOCATION_DESCRIPTION
-IDS_CERT_ERROR_UNABLE_TO_CHECK_REVOCATION_DETAILS
-IDS_CERT_ERROR_UNABLE_TO_CHECK_REVOCATION_TITLE
-IDS_CERT_ERROR_UNKNOWN_ERROR_DESCRIPTION
-IDS_CERT_ERROR_UNKNOWN_ERROR_DETAILS
-IDS_CERT_ERROR_UNKNOWN_ERROR_TITLE
-IDS_CERT_ERROR_WEAK_KEY_DESCRIPTION
-IDS_CERT_ERROR_WEAK_KEY_DETAILS
-IDS_CERT_ERROR_WEAK_KEY_EXTRA_INFO_2
-IDS_CERT_ERROR_WEAK_KEY_TITLE
-IDS_CERT_ERROR_WEAK_SIGNATURE_ALGORITHM_DESCRIPTION
-IDS_CERT_ERROR_WEAK_SIGNATURE_ALGORITHM_DETAILS
-IDS_CERT_ERROR_WEAK_SIGNATURE_ALGORITHM_EXTRA_INFO_2
-IDS_CERT_ERROR_WEAK_SIGNATURE_ALGORITHM_TITLE
-IDS_CHROME_TO_DEVICE_PRINT_TO_PHONE
-IDS_CHROME_TO_DEVICE_SNAPSHOTS
-IDS_CLOSE
-IDS_CONTEXTUAL_SEARCH_HEADER
-IDS_CONTEXTUAL_SEARCH_PROMO_DESCRIPTION_1
-IDS_CONTEXTUAL_SEARCH_PROMO_DESCRIPTION_2
-IDS_CONTEXTUAL_SEARCH_PROMO_FEATURE_NAME
-IDS_CONTEXTUAL_SEARCH_PROMO_OPTIN
-IDS_CONTEXTUAL_SEARCH_PROMO_OPTOUT
-IDS_COULDNT_OPEN_PROFILE_ERROR
-IDS_CRASHES_BUG_LINK_LABEL
-IDS_CRASHES_CRASH_COUNT_BANNER_FORMAT
-IDS_CRASHES_CRASH_HEADER_FORMAT
-IDS_CRASHES_CRASH_TIME_FORMAT
-IDS_CRASHES_DISABLED_HEADER
-IDS_CRASHES_DISABLED_MESSAGE
-IDS_CRASHES_NO_CRASHES_MESSAGE
-IDS_CRASHES_TITLE
-IDS_CRASHES_UPLOAD_MESSAGE
-IDS_DATA_REDUCTION_PROXY_BACK_BUTTON
-IDS_DATA_REDUCTION_PROXY_CANNOT_PROXY_HEADING
-IDS_DATA_REDUCTION_PROXY_CANNOT_PROXY_PRIMARY_PARAGRAPH
-IDS_DATA_REDUCTION_PROXY_CANNOT_PROXY_SECONDARY_PARAGRAPH
-IDS_DATA_REDUCTION_PROXY_CONTINUE_BUTTON
-IDS_DATA_REDUCTION_PROXY_TITLE
-IDS_DEFAULT_AVATAR_NAME_10
-IDS_DEFAULT_AVATAR_NAME_11
-IDS_DEFAULT_AVATAR_NAME_12
-IDS_DEFAULT_AVATAR_NAME_13
-IDS_DEFAULT_AVATAR_NAME_14
-IDS_DEFAULT_AVATAR_NAME_15
-IDS_DEFAULT_AVATAR_NAME_16
-IDS_DEFAULT_AVATAR_NAME_17
-IDS_DEFAULT_AVATAR_NAME_18
-IDS_DEFAULT_AVATAR_NAME_19
-IDS_DEFAULT_AVATAR_NAME_20
-IDS_DEFAULT_AVATAR_NAME_21
-IDS_DEFAULT_AVATAR_NAME_22
-IDS_DEFAULT_AVATAR_NAME_23
-IDS_DEFAULT_AVATAR_NAME_24
-IDS_DEFAULT_AVATAR_NAME_25
-IDS_DEFAULT_AVATAR_NAME_26
-IDS_DEFAULT_AVATAR_NAME_8
-IDS_DEFAULT_AVATAR_NAME_9
-IDS_DEFAULT_ENCODING
-IDS_DEFAULT_PROFILE_NAME
-IDS_DEFAULT_TAB_TITLE
-IDS_DELETE
-IDS_DISABLE_TOUCH_ADJUSTMENT_DESCRIPTION
-IDS_DISABLE_TOUCH_ADJUSTMENT_NAME
-IDS_DOM_DISTILLER_JAVASCRIPT_DISABLED_CONTENT
-IDS_DOM_DISTILLER_QUALITY_ANSWER_NO
-IDS_DOM_DISTILLER_QUALITY_ANSWER_YES
-IDS_DOM_DISTILLER_QUALITY_QUESTION
-IDS_DOM_DISTILLER_VIEWER_CLOSE_READER_VIEW
-IDS_DOM_DISTILLER_VIEWER_FAILED_TO_FIND_ARTICLE_CONTENT
-IDS_DOM_DISTILLER_VIEWER_FAILED_TO_FIND_ARTICLE_TITLE
-IDS_DOM_DISTILLER_VIEWER_LOADING_STRING
-IDS_DOM_DISTILLER_VIEWER_LOADING_TITLE
-IDS_DOM_DISTILLER_VIEWER_NO_DATA_CONTENT
-IDS_DOM_DISTILLER_VIEWER_NO_DATA_TITLE
-IDS_DOM_DISTILLER_VIEWER_VIEW_ORIGINAL
-IDS_DOM_DISTILLER_WEBUI_ENTRY_ADD
-IDS_DOM_DISTILLER_WEBUI_ENTRY_ADD_FAILED
-IDS_DOM_DISTILLER_WEBUI_ENTRY_URL
-IDS_DOM_DISTILLER_WEBUI_FETCHING_ENTRIES
-IDS_DOM_DISTILLER_WEBUI_REFRESH
-IDS_DOM_DISTILLER_WEBUI_TITLE
-IDS_DOM_DISTILLER_WEBUI_VIEW_URL
-IDS_DOM_DISTILLER_WEBUI_VIEW_URL_FAILED
-IDS_DONE
-IDS_EASY_UNLOCK_SCREENLOCK_USER_POD_AUTH_VALUE
-IDS_EDIT_FIND_MAC
-IDS_EMPTY_KEYWORD_VALUE
-IDS_ERRORPAGES_BUTTON_LESS
-IDS_ERRORPAGES_BUTTON_MORE
-IDS_ERRORPAGES_BUTTON_RELOAD
-IDS_ERRORPAGES_BUTTON_SHOW_SAVED_COPY
-IDS_ERRORPAGES_BUTTON_SHOW_SAVED_COPY_HELP
-IDS_ERRORPAGES_DETAILS_ADDRESS_UNREACHABLE
-IDS_ERRORPAGES_DETAILS_BAD_GATEWAY
-IDS_ERRORPAGES_DETAILS_BAD_SSL_CLIENT_AUTH_CERT
-IDS_ERRORPAGES_DETAILS_BLOCKED
-IDS_ERRORPAGES_DETAILS_BLOCKED_BY_ADMINISTRATOR
-IDS_ERRORPAGES_DETAILS_BLOCKED_ENROLLMENT_CHECK_PENDING
-IDS_ERRORPAGES_DETAILS_CACHE_MISS
-IDS_ERRORPAGES_DETAILS_CACHE_READ_FAILURE
-IDS_ERRORPAGES_DETAILS_CONNECTION_CLOSED
-IDS_ERRORPAGES_DETAILS_CONNECTION_FAILED
-IDS_ERRORPAGES_DETAILS_CONNECTION_REFUSED
-IDS_ERRORPAGES_DETAILS_CONNECTION_RESET
-IDS_ERRORPAGES_DETAILS_DNS_PROBE_RUNNING
-IDS_ERRORPAGES_DETAILS_DOWNLOAD_FILE_TYPE_ERROR
-IDS_ERRORPAGES_DETAILS_EMPTY_RESPONSE
-IDS_ERRORPAGES_DETAILS_FILE_ACCESS_DENIED
-IDS_ERRORPAGES_DETAILS_FILE_NOT_FOUND
-IDS_ERRORPAGES_DETAILS_FORBIDDEN
-IDS_ERRORPAGES_DETAILS_GATEWAY_TIMEOUT
-IDS_ERRORPAGES_DETAILS_GONE
-IDS_ERRORPAGES_DETAILS_HTTP_VERSION_NOT_SUPPORTED
-IDS_ERRORPAGES_DETAILS_ICANN_NAME_COLLISION
-IDS_ERRORPAGES_DETAILS_INTERNAL_SERVER_ERROR
-IDS_ERRORPAGES_DETAILS_INTERNET_DISCONNECTED
-IDS_ERRORPAGES_DETAILS_NAME_NOT_RESOLVED
-IDS_ERRORPAGES_DETAILS_NETWORK_ACCESS_DENIED
-IDS_ERRORPAGES_DETAILS_NETWORK_CHANGED
-IDS_ERRORPAGES_DETAILS_NETWORK_IO_SUSPENDED
-IDS_ERRORPAGES_DETAILS_NOT_IMPLEMENTED
-IDS_ERRORPAGES_DETAILS_PINNING_FAILURE
-IDS_ERRORPAGES_DETAILS_PROXY_CONNECTION_FAILED
-IDS_ERRORPAGES_DETAILS_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION
-IDS_ERRORPAGES_DETAILS_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH
-IDS_ERRORPAGES_DETAILS_RESPONSE_HEADERS_MULTIPLE_LOCATION
-IDS_ERRORPAGES_DETAILS_SERVICE_UNAVAILABLE
-IDS_ERRORPAGES_DETAILS_SSL_FALLBACK_BEYOND_MINIMUM_VERSION
-IDS_ERRORPAGES_DETAILS_SSL_PROTOCOL_ERROR
-IDS_ERRORPAGES_DETAILS_SSL_VERSION_OR_CIPHER_MISMATCH
-IDS_ERRORPAGES_DETAILS_TEMPORARILY_THROTTLED
-IDS_ERRORPAGES_DETAILS_TIMED_OUT
-IDS_ERRORPAGES_DETAILS_TOO_MANY_REDIRECTS
-IDS_ERRORPAGES_DETAILS_UNKNOWN
-IDS_ERRORPAGES_ERROR_CODE
-IDS_ERRORPAGES_HEADING_ACCESS_DENIED
-IDS_ERRORPAGES_HEADING_BAD_SSL_CLIENT_AUTH_CERT
-IDS_ERRORPAGES_HEADING_BLOCKED
-IDS_ERRORPAGES_HEADING_BLOCKED_BY_ADMINISTRATOR
-IDS_ERRORPAGES_HEADING_CACHE_MISS
-IDS_ERRORPAGES_HEADING_CACHE_READ_FAILURE
-IDS_ERRORPAGES_HEADING_DOWNLOAD_FILE_TYPE_ERROR
-IDS_ERRORPAGES_HEADING_DUPLICATE_HEADERS
-IDS_ERRORPAGES_HEADING_EMPTY_RESPONSE
-IDS_ERRORPAGES_HEADING_FILE_ACCESS_DENIED
-IDS_ERRORPAGES_HEADING_HTTP_SERVER_ERROR
-IDS_ERRORPAGES_HEADING_INTERNET_DISCONNECTED
-IDS_ERRORPAGES_HEADING_NETWORK_ACCESS_DENIED
-IDS_ERRORPAGES_HEADING_NETWORK_IO_SUSPENDED
-IDS_ERRORPAGES_HEADING_NOT_AVAILABLE
-IDS_ERRORPAGES_HEADING_NOT_FOUND
-IDS_ERRORPAGES_HEADING_PINNING_FAILURE
-IDS_ERRORPAGES_HEADING_PROXY_CONNECTION_FAILED
-IDS_ERRORPAGES_HEADING_SSL_FALLBACK_BEYOND_MINIMUM_VERSION
-IDS_ERRORPAGES_HEADING_SSL_PROTOCOL_ERROR
-IDS_ERRORPAGES_HEADING_SSL_VERSION_OR_CIPHER_MISMATCH
-IDS_ERRORPAGES_HEADING_TOO_MANY_REDIRECTS
-IDS_ERRORPAGES_HEADING_WEAK_SERVER_EPHEMERAL_DH_KEY
-IDS_ERRORPAGES_HTTP_POST_WARNING
-IDS_ERRORPAGES_SUGGESTION_CHECK_CONNECTION_BODY
-IDS_ERRORPAGES_SUGGESTION_CHECK_CONNECTION_HEADER
-IDS_ERRORPAGES_SUGGESTION_CONTACT_ADMINISTRATOR
-IDS_ERRORPAGES_SUGGESTION_DNS_CONFIG
-IDS_ERRORPAGES_SUGGESTION_FIREWALL_CONFIG
-IDS_ERRORPAGES_SUGGESTION_GOOGLE_SEARCH
-IDS_ERRORPAGES_SUGGESTION_LEARNMORE_BODY
-IDS_ERRORPAGES_SUGGESTION_NETWORK_PREDICTION
-IDS_ERRORPAGES_SUGGESTION_PROXY_CONFIG
-IDS_ERRORPAGES_SUGGESTION_PROXY_DISABLE_PLATFORM
-IDS_ERRORPAGES_SUGGESTION_RELOAD
-IDS_ERRORPAGES_SUGGESTION_RELOAD_REPOST_BODY
-IDS_ERRORPAGES_SUGGESTION_RELOAD_REPOST_HEADER
-IDS_ERRORPAGES_SUGGESTION_VIEW_POLICIES
-IDS_ERRORPAGES_SUMMARY_ADDRESS_UNREACHABLE
-IDS_ERRORPAGES_SUMMARY_BAD_GATEWAY
-IDS_ERRORPAGES_SUMMARY_BAD_SSL_CLIENT_AUTH_CERT
-IDS_ERRORPAGES_SUMMARY_BLOCKED
-IDS_ERRORPAGES_SUMMARY_BLOCKED_BY_ADMINISTRATOR
-IDS_ERRORPAGES_SUMMARY_BLOCKED_ENROLLMENT_CHECK_PENDING
-IDS_ERRORPAGES_SUMMARY_CACHE_MISS
-IDS_ERRORPAGES_SUMMARY_CACHE_READ_FAILURE
-IDS_ERRORPAGES_SUMMARY_CONNECTION_REFUSED
-IDS_ERRORPAGES_SUMMARY_CONNECTION_RESET
-IDS_ERRORPAGES_SUMMARY_DNS_PROBE_RUNNING
-IDS_ERRORPAGES_SUMMARY_DOWNLOAD_FILE_TYPE_ERROR
-IDS_ERRORPAGES_SUMMARY_DUPLICATE_HEADERS
-IDS_ERRORPAGES_SUMMARY_EMPTY_RESPONSE
-IDS_ERRORPAGES_SUMMARY_FILE_ACCESS_DENIED
-IDS_ERRORPAGES_SUMMARY_FORBIDDEN
-IDS_ERRORPAGES_SUMMARY_GATEWAY_TIMEOUT
-IDS_ERRORPAGES_SUMMARY_GONE
-IDS_ERRORPAGES_SUMMARY_ICANN_NAME_COLLISION
-IDS_ERRORPAGES_SUMMARY_INTERNAL_SERVER_ERROR
-IDS_ERRORPAGES_SUMMARY_INTERNET_DISCONNECTED
-IDS_ERRORPAGES_SUMMARY_INTERNET_DISCONNECTED_INSTRUCTIONS_TEMPLATE
-IDS_ERRORPAGES_SUMMARY_INTERNET_DISCONNECTED_PLATFORM
-IDS_ERRORPAGES_SUMMARY_NAME_NOT_RESOLVED
-IDS_ERRORPAGES_SUMMARY_NETWORK_ACCESS_DENIED
-IDS_ERRORPAGES_SUMMARY_NETWORK_CHANGED
-IDS_ERRORPAGES_SUMMARY_NETWORK_IO_SUSPENDED
-IDS_ERRORPAGES_SUMMARY_NOT_AVAILABLE
-IDS_ERRORPAGES_SUMMARY_NOT_FOUND
-IDS_ERRORPAGES_SUMMARY_PINNING_FAILURE
-IDS_ERRORPAGES_SUMMARY_PROXY_CONNECTION_FAILED
-IDS_ERRORPAGES_SUMMARY_SERVICE_UNAVAILABLE
-IDS_ERRORPAGES_SUMMARY_SSL_FALLBACK_BEYOND_MINIMUM_VERSION
-IDS_ERRORPAGES_SUMMARY_SSL_PROTOCOL_ERROR
-IDS_ERRORPAGES_SUMMARY_SSL_VERSION_OR_CIPHER_MISMATCH
-IDS_ERRORPAGES_SUMMARY_TEMPORARILY_THROTTLED
-IDS_ERRORPAGES_SUMMARY_TIMED_OUT
-IDS_ERRORPAGES_SUMMARY_TOO_MANY_REDIRECTS
-IDS_ERRORPAGES_SUMMARY_WEAK_SERVER_EPHEMERAL_DH_KEY
-IDS_ERRORPAGES_SUMMARY_WEBSITE_CANNOT_HANDLE
-IDS_ERRORPAGES_TITLE_ACCESS_DENIED
-IDS_ERRORPAGES_TITLE_BLOCKED
-IDS_ERRORPAGES_TITLE_LOAD_FAILED
-IDS_ERRORPAGES_TITLE_NOT_AVAILABLE
-IDS_ERRORPAGES_TITLE_NOT_FOUND
-IDS_ERRORPAGE_NET_BUTTON_DETAILS
-IDS_ERRORPAGE_NET_BUTTON_HIDE_DETAILS
-IDS_EXTENSION_KEYWORD_COMMAND
-IDS_FEEDBACK_REPORT_PAGE_TITLE
-IDS_FEEDBACK_REPORT_URL_LABEL
-IDS_FEEDBACK_SEND_REPORT
-IDS_FEEDBACK_USER_EMAIL_LABEL
-IDS_FIND_IN_PAGE_CLOSE_TOOLTIP
-IDS_FIND_IN_PAGE_COUNT
-IDS_FIND_IN_PAGE_NEXT_TOOLTIP
-IDS_FIND_IN_PAGE_PREVIOUS_TOOLTIP
-IDS_FLAGS_ACCELERATED_FIXED_ROOT_BACKGROUND_DESCRIPTION
-IDS_FLAGS_ACCELERATED_FIXED_ROOT_BACKGROUND_NAME
-IDS_FLAGS_ALLOW_NACL_SOCKET_API_DESCRIPTION
-IDS_FLAGS_ALLOW_NACL_SOCKET_API_NAME
-IDS_FLAGS_ALLOW_TOUCHPAD_THREE_FINGER_CLICK_DESCRIPTION
-IDS_FLAGS_ALLOW_TOUCHPAD_THREE_FINGER_CLICK_NAME
-IDS_FLAGS_COMPOSITED_LAYER_BORDERS
-IDS_FLAGS_COMPOSITED_LAYER_BORDERS_DESCRIPTION
-IDS_FLAGS_COMPOSITING_FOR_FIXED_POSITION_DESCRIPTION
-IDS_FLAGS_COMPOSITING_FOR_FIXED_POSITION_HIGH_DPI
-IDS_FLAGS_COMPOSITING_FOR_FIXED_POSITION_NAME
-IDS_FLAGS_CONFLICTS_CHECK_DESCRIPTION
-IDS_FLAGS_CONFLICTS_CHECK_NAME
-IDS_FLAGS_DEBUG_PACKED_APP_DESCRIPTION
-IDS_FLAGS_DEBUG_PACKED_APP_NAME
-IDS_FLAGS_DEBUG_SHORTCUTS_DESCRIPTION
-IDS_FLAGS_DEBUG_SHORTCUTS_NAME
-IDS_FLAGS_DEFAULT_TILE_HEIGHT_DESCRIPTION
-IDS_FLAGS_DEFAULT_TILE_HEIGHT_GRANDE
-IDS_FLAGS_DEFAULT_TILE_HEIGHT_NAME
-IDS_FLAGS_DEFAULT_TILE_HEIGHT_SHORT
-IDS_FLAGS_DEFAULT_TILE_HEIGHT_TALL
-IDS_FLAGS_DEFAULT_TILE_HEIGHT_VENTI
-IDS_FLAGS_DEFAULT_TILE_WIDTH_DESCRIPTION
-IDS_FLAGS_DEFAULT_TILE_WIDTH_GRANDE
-IDS_FLAGS_DEFAULT_TILE_WIDTH_NAME
-IDS_FLAGS_DEFAULT_TILE_WIDTH_SHORT
-IDS_FLAGS_DEFAULT_TILE_WIDTH_TALL
-IDS_FLAGS_DEFAULT_TILE_WIDTH_VENTI
-IDS_FLAGS_DISABLE
-IDS_FLAGS_DISABLE_ACCELERATED_2D_CANVAS_DESCRIPTION
-IDS_FLAGS_DISABLE_ACCELERATED_2D_CANVAS_NAME
-IDS_FLAGS_DISABLE_ACCELERATED_VIDEO_DECODE_DESCRIPTION
-IDS_FLAGS_DISABLE_ACCELERATED_VIDEO_DECODE_NAME
-IDS_FLAGS_DISABLE_BOOT_ANIMATION
-IDS_FLAGS_DISABLE_BOOT_ANIMATION_DESCRIPTION
-IDS_FLAGS_DISABLE_GESTURE_REQUIREMENT_FOR_MEDIA_PLAYBACK_DESCRIPTION
-IDS_FLAGS_DISABLE_GESTURE_REQUIREMENT_FOR_MEDIA_PLAYBACK_NAME
-IDS_FLAGS_DISABLE_HYPERLINK_AUDITING_DESCRIPTION
-IDS_FLAGS_DISABLE_HYPERLINK_AUDITING_NAME
-IDS_FLAGS_DISABLE_PNACL_DESCRIPTION
-IDS_FLAGS_DISABLE_PNACL_NAME
-IDS_FLAGS_DISABLE_SOFTWARE_RASTERIZER_DESCRIPTION
-IDS_FLAGS_DISABLE_SOFTWARE_RASTERIZER_NAME
-IDS_FLAGS_DISABLE_WEBGL_DESCRIPTION
-IDS_FLAGS_DISABLE_WEBGL_NAME
-IDS_FLAGS_DISABLE_WEBRTC_DESCRIPTION
-IDS_FLAGS_DISABLE_WEBRTC_NAME
-IDS_FLAGS_ENABLE
-IDS_FLAGS_ENABLE_ACCELERATED_MJPEG_DECODE_DESCRIPTION
-IDS_FLAGS_ENABLE_ACCELERATED_MJPEG_DECODE_NAME
-IDS_FLAGS_ENABLE_APPS_SHOW_ON_FIRST_PAINT_DESCRIPTION
-IDS_FLAGS_ENABLE_APPS_SHOW_ON_FIRST_PAINT_NAME
-IDS_FLAGS_ENABLE_CONTEXTUAL_SEARCH
-IDS_FLAGS_ENABLE_CONTEXTUAL_SEARCH_DESCRIPTION
-IDS_FLAGS_ENABLE_DEVTOOLS_EXPERIMENTS_DESCRIPTION
-IDS_FLAGS_ENABLE_DEVTOOLS_EXPERIMENTS_NAME
-IDS_FLAGS_ENABLE_DOWNLOAD_RESUMPTION_DESCRIPTION
-IDS_FLAGS_ENABLE_DOWNLOAD_RESUMPTION_NAME
-IDS_FLAGS_ENABLE_ENHANCED_BOOKMARKS_DESCRIPTION
-IDS_FLAGS_ENABLE_ENHANCED_BOOKMARKS_NAME
-IDS_FLAGS_ENABLE_EXPERIMENTAL_CANVAS_FEATURES_DESCRIPTION
-IDS_FLAGS_ENABLE_EXPERIMENTAL_CANVAS_FEATURES_NAME
-IDS_FLAGS_ENABLE_GESTURE_TAP_HIGHLIGHTING_DESCRIPTION
-IDS_FLAGS_ENABLE_GESTURE_TAP_HIGHLIGHTING_NAME
-IDS_FLAGS_ENABLE_ICON_NTP_DESCRIPTION
-IDS_FLAGS_ENABLE_ICON_NTP_NAME
-IDS_FLAGS_ENABLE_JAVASCRIPT_HARMONY_DESCRIPTION
-IDS_FLAGS_ENABLE_JAVASCRIPT_HARMONY_NAME
-IDS_FLAGS_ENABLE_NACL_DEBUG_DESCRIPTION
-IDS_FLAGS_ENABLE_NACL_DEBUG_NAME
-IDS_FLAGS_ENABLE_NACL_DESCRIPTION
-IDS_FLAGS_ENABLE_NACL_NAME
-IDS_FLAGS_ENABLE_PANELS_DESCRIPTION
-IDS_FLAGS_ENABLE_PANELS_NAME
-IDS_FLAGS_ENABLE_PASSWORD_GENERATION_DESCRIPTION
-IDS_FLAGS_ENABLE_PASSWORD_GENERATION_NAME
-IDS_FLAGS_ENABLE_PINCH_SCALE_DESCRIPTION
-IDS_FLAGS_ENABLE_PINCH_SCALE_NAME
-IDS_FLAGS_ENABLE_REQUEST_TABLET_SITE_DESCRIPTION
-IDS_FLAGS_ENABLE_REQUEST_TABLET_SITE_NAME
-IDS_FLAGS_ENABLE_SCREEN_CAPTURE_DESCRIPTION
-IDS_FLAGS_ENABLE_SCREEN_CAPTURE_NAME
-IDS_FLAGS_ENABLE_SIMPLE_CACHE_BACKEND_DESCRIPTION
-IDS_FLAGS_ENABLE_SIMPLE_CACHE_BACKEND_NAME
-IDS_FLAGS_ENABLE_SMOOTH_SCROLLING_DESCRIPTION
-IDS_FLAGS_ENABLE_SMOOTH_SCROLLING_NAME
-IDS_FLAGS_ENABLE_STALE_WHILE_REVALIDATE_DESCRIPTION
-IDS_FLAGS_ENABLE_STALE_WHILE_REVALIDATE_NAME
-IDS_FLAGS_ENABLE_SUGGESTIONS_SERVICE_DESCRIPTION
-IDS_FLAGS_ENABLE_SUGGESTIONS_SERVICE_NAME
-IDS_FLAGS_ENABLE_SYNCED_NOTIFICATIONS_DESCRIPTION
-IDS_FLAGS_ENABLE_SYNCED_NOTIFICATIONS_NAME
-IDS_FLAGS_ENABLE_TCP_FAST_OPEN_DESCRIPTION
-IDS_FLAGS_ENABLE_TCP_FAST_OPEN_NAME
-IDS_FLAGS_ENABLE_TOUCH_DRAG_DROP_DESCRIPTION
-IDS_FLAGS_ENABLE_TOUCH_DRAG_DROP_NAME
-IDS_FLAGS_ENABLE_TOUCH_EDITING_DESCRIPTION
-IDS_FLAGS_ENABLE_TOUCH_EDITING_NAME
-IDS_FLAGS_ENABLE_TRANSLATE_NEW_UX_DESCRIPTION
-IDS_FLAGS_ENABLE_TRANSLATE_NEW_UX_NAME
-IDS_FLAGS_EXPERIMENTAL_EXTENSION_APIS_DESCRIPTION
-IDS_FLAGS_EXPERIMENTAL_EXTENSION_APIS_NAME
-IDS_FLAGS_EXPERIMENTAL_WEB_PLATFORM_FEATURES_DESCRIPTION
-IDS_FLAGS_EXPERIMENTAL_WEB_PLATFORM_FEATURES_NAME
-IDS_FLAGS_EXTENSIONS_ON_CHROME_URLS_DESCRIPTION
-IDS_FLAGS_EXTENSIONS_ON_CHROME_URLS_NAME
-IDS_FLAGS_FORCE_ACCELERATED_OVERFLOW_SCROLL_MODE_DESCRIPTION
-IDS_FLAGS_FORCE_ACCELERATED_OVERFLOW_SCROLL_MODE_NAME
-IDS_FLAGS_FORCE_HIGH_DPI_DESCRIPTION
-IDS_FLAGS_FORCE_HIGH_DPI_NAME
-IDS_FLAGS_IGNORE_GPU_BLACKLIST_DESCRIPTION
-IDS_FLAGS_IGNORE_GPU_BLACKLIST_NAME
-IDS_FLAGS_LONG_TITLE
-IDS_FLAGS_NACL_DEBUG_MASK_DESCRIPTION
-IDS_FLAGS_NACL_DEBUG_MASK_NAME
-IDS_FLAGS_NOT_AVAILABLE
-IDS_FLAGS_NO_EXPERIMENTS_AVAILABLE
-IDS_FLAGS_NO_UNSUPPORTED_EXPERIMENTS
-IDS_FLAGS_NTP_OTHER_SESSIONS_MENU_DESCRIPTION
-IDS_FLAGS_NTP_OTHER_SESSIONS_MENU_NAME
-IDS_FLAGS_PERFORMANCE_MONITOR_GATHERING_DESCRIPTION
-IDS_FLAGS_PERFORMANCE_MONITOR_GATHERING_NAME
-IDS_FLAGS_RELAUNCH_BUTTON
-IDS_FLAGS_RELAUNCH_NOTICE
-IDS_FLAGS_RESET_ALL_BUTTON
-IDS_FLAGS_SAVE_PAGE_AS_MHTML_DESCRIPTION
-IDS_FLAGS_SAVE_PAGE_AS_MHTML_NAME
-IDS_FLAGS_SHOW_AUTOFILL_TYPE_PREDICTIONS_DESCRIPTION
-IDS_FLAGS_SHOW_AUTOFILL_TYPE_PREDICTIONS_NAME
-IDS_FLAGS_SHOW_FPS_COUNTER
-IDS_FLAGS_SHOW_FPS_COUNTER_DESCRIPTION
-IDS_FLAGS_SHOW_TOUCH_HUD_DESCRIPTION
-IDS_FLAGS_SHOW_TOUCH_HUD_NAME
-IDS_FLAGS_SILENT_DEBUGGER_EXTENSION_API_DESCRIPTION
-IDS_FLAGS_SILENT_DEBUGGER_EXTENSION_API_NAME
-IDS_FLAGS_SPELLCHECK_AUTOCORRECT
-IDS_FLAGS_SPELLCHECK_AUTOCORRECT_DESCRIPTION
-IDS_FLAGS_STACKED_TAB_STRIP_DESCRIPTION
-IDS_FLAGS_STACKED_TAB_STRIP_NAME
-IDS_FLAGS_TABLE_TITLE
-IDS_FLAGS_THREADED_COMPOSITING_MODE_DESCRIPTION
-IDS_FLAGS_THREADED_COMPOSITING_MODE_NAME
-IDS_FLAGS_TOUCH_SCROLLING_MODE_ABSORB_TOUCHMOVE
-IDS_FLAGS_TOUCH_SCROLLING_MODE_DESCRIPTION
-IDS_FLAGS_TOUCH_SCROLLING_MODE_NAME
-IDS_FLAGS_TOUCH_SCROLLING_MODE_SYNC_TOUCHMOVE
-IDS_FLAGS_TOUCH_SCROLLING_MODE_TOUCHCANCEL
-IDS_FLAGS_UNSUPPORTED_TABLE_TITLE
-IDS_FLAGS_WALLET_SERVICE_USE_SANDBOX_DESCRIPTION
-IDS_FLAGS_WALLET_SERVICE_USE_SANDBOX_NAME
-IDS_FLAGS_WARNING_HEADER
-IDS_FLAGS_WARNING_TEXT
-IDS_FULLSCREEN
-IDS_GENERIC_EXPERIMENT_CHOICE_AUTOMATIC
-IDS_GENERIC_EXPERIMENT_CHOICE_DEFAULT
-IDS_GENERIC_EXPERIMENT_CHOICE_DISABLED
-IDS_GENERIC_EXPERIMENT_CHOICE_ENABLED
-IDS_GROUP_BY_DOMAIN_LABEL
-IDS_GUEST_PROFILE_NAME
-IDS_HARMFUL_V3_EXPLANATION_PARAGRAPH
-IDS_HARMFUL_V3_HEADING
-IDS_HARMFUL_V3_PRIMARY_PARAGRAPH
-IDS_HARMFUL_V3_PROCEED_PARAGRAPH
-IDS_HISTORY_ACTION_MENU_DESCRIPTION
-IDS_HISTORY_BLOCKED_VISIT_TEXT
-IDS_HISTORY_BROWSERESULTS
-IDS_HISTORY_CONTINUED
-IDS_HISTORY_DATE_WITH_RELATIVE_TIME
-IDS_HISTORY_DELETE_PRIOR_VISITS_CONFIRM_BUTTON
-IDS_HISTORY_DELETE_PRIOR_VISITS_WARNING
-IDS_HISTORY_FILTER_ALLOWED
-IDS_HISTORY_FILTER_ALLOW_ITEMS
-IDS_HISTORY_FILTER_BLOCKED
-IDS_HISTORY_FILTER_BLOCK_ITEMS
-IDS_HISTORY_HAS_SYNCED_RESULTS
-IDS_HISTORY_INTERVAL
-IDS_HISTORY_IN_CONTENT_PACK
-IDS_HISTORY_LOADING
-IDS_HISTORY_LOCK_BUTTON
-IDS_HISTORY_MORE_FROM_SITE
-IDS_HISTORY_NEWER
-IDS_HISTORY_NEWEST
-IDS_HISTORY_NO_RESULTS
-IDS_HISTORY_NO_SEARCH_RESULTS
-IDS_HISTORY_NO_SYNCED_RESULTS
-IDS_HISTORY_NUMBER_VISITS
-IDS_HISTORY_OLDER
-IDS_HISTORY_OPEN_CLEAR_BROWSING_DATA_DIALOG
-IDS_HISTORY_OTHER_SESSIONS_COLLAPSE_SESSION
-IDS_HISTORY_OTHER_SESSIONS_EXPAND_SESSION
-IDS_HISTORY_OTHER_SESSIONS_OPEN_ALL
-IDS_HISTORY_RANGE_ALL_TIME
-IDS_HISTORY_RANGE_LABEL
-IDS_HISTORY_RANGE_MONTH
-IDS_HISTORY_RANGE_NEXT
-IDS_HISTORY_RANGE_PREVIOUS
-IDS_HISTORY_RANGE_TODAY
-IDS_HISTORY_RANGE_WEEK
-IDS_HISTORY_REMOVE_BOOKMARK
-IDS_HISTORY_REMOVE_PAGE
-IDS_HISTORY_REMOVE_SELECTED_ITEMS
-IDS_HISTORY_SEARCHRESULTSFOR
-IDS_HISTORY_SEARCH_BUTTON
-IDS_HISTORY_TITLE
-IDS_HISTORY_UNKNOWN_DEVICE
-IDS_HISTORY_UNLOCK_BUTTON
-IDS_HTTP_POST_WARNING
-IDS_HTTP_POST_WARNING_RESEND
-IDS_HTTP_POST_WARNING_TITLE
-IDS_IMPORT_FROM_FIREFOX
-IDS_IMPORT_FROM_ICEWEASEL
-IDS_JAVASCRIPT_ALERT_DEFAULT_TITLE
-IDS_JAVASCRIPT_ALERT_TITLE
-IDS_JAVASCRIPT_MESSAGEBOX_DEFAULT_TITLE
-IDS_JAVASCRIPT_MESSAGEBOX_TITLE
-IDS_KEYWORD_SEARCH
-IDS_LEARN_MORE
-IDS_LEGACY_DEFAULT_PROFILE_NAME
-IDS_LIBADDRESSINPUT_ADDRESS_LINE_1_LABEL
-IDS_LIBADDRESSINPUT_AREA
-IDS_LIBADDRESSINPUT_COUNTRY_OR_REGION_LABEL
-IDS_LIBADDRESSINPUT_COUNTY
-IDS_LIBADDRESSINPUT_DEPARTMENT
-IDS_LIBADDRESSINPUT_DISTRICT
-IDS_LIBADDRESSINPUT_DO_SI
-IDS_LIBADDRESSINPUT_EMIRATE
-IDS_LIBADDRESSINPUT_ISLAND
-IDS_LIBADDRESSINPUT_LOCALITY_LABEL
-IDS_LIBADDRESSINPUT_MISMATCHING_VALUE_POSTAL_CODE
-IDS_LIBADDRESSINPUT_MISMATCHING_VALUE_POSTAL_CODE_URL
-IDS_LIBADDRESSINPUT_MISMATCHING_VALUE_ZIP
-IDS_LIBADDRESSINPUT_MISMATCHING_VALUE_ZIP_URL
-IDS_LIBADDRESSINPUT_MISSING_REQUIRED_FIELD
-IDS_LIBADDRESSINPUT_MISSING_REQUIRED_POSTAL_CODE_EXAMPLE
-IDS_LIBADDRESSINPUT_MISSING_REQUIRED_POSTAL_CODE_EXAMPLE_AND_URL
-IDS_LIBADDRESSINPUT_MISSING_REQUIRED_ZIP_CODE_EXAMPLE
-IDS_LIBADDRESSINPUT_MISSING_REQUIRED_ZIP_CODE_EXAMPLE_AND_URL
-IDS_LIBADDRESSINPUT_NEIGHBORHOOD
-IDS_LIBADDRESSINPUT_OBLAST
-IDS_LIBADDRESSINPUT_ORGANIZATION_LABEL
-IDS_LIBADDRESSINPUT_PARISH
-IDS_LIBADDRESSINPUT_PIN_CODE_LABEL
-IDS_LIBADDRESSINPUT_POSTAL_CODE_LABEL
-IDS_LIBADDRESSINPUT_POST_TOWN
-IDS_LIBADDRESSINPUT_PO_BOX_FORBIDDEN_VALUE
-IDS_LIBADDRESSINPUT_PREFECTURE
-IDS_LIBADDRESSINPUT_PROVINCE
-IDS_LIBADDRESSINPUT_RECIPIENT_LABEL
-IDS_LIBADDRESSINPUT_STATE
-IDS_LIBADDRESSINPUT_SUBURB
-IDS_LIBADDRESSINPUT_UNKNOWN_VALUE
-IDS_LIBADDRESSINPUT_UNRECOGNIZED_FORMAT_POSTAL_CODE
-IDS_LIBADDRESSINPUT_UNRECOGNIZED_FORMAT_POSTAL_CODE_EXAMPLE
-IDS_LIBADDRESSINPUT_UNRECOGNIZED_FORMAT_POSTAL_CODE_EXAMPLE_AND_URL
-IDS_LIBADDRESSINPUT_UNRECOGNIZED_FORMAT_ZIP
-IDS_LIBADDRESSINPUT_UNRECOGNIZED_FORMAT_ZIP_CODE_EXAMPLE
-IDS_LIBADDRESSINPUT_UNRECOGNIZED_FORMAT_ZIP_CODE_EXAMPLE_AND_URL
-IDS_LIBADDRESSINPUT_VILLAGE_TOWNSHIP
-IDS_LIBADDRESSINPUT_ZIP_CODE_LABEL
-IDS_LINK_FROM_CLIPBOARD
-IDS_LOGIN_DIALOG_OK_BUTTON_LABEL
-IDS_LOGIN_DIALOG_PASSWORD_FIELD
-IDS_LOGIN_DIALOG_TITLE
-IDS_LOGIN_DIALOG_USERNAME_FIELD
-IDS_MALWARE_V3_ADVICE_HEADING
-IDS_MALWARE_V3_EXPLANATION_PARAGRAPH
-IDS_MALWARE_V3_EXPLANATION_PARAGRAPH_ADVICE
-IDS_MALWARE_V3_EXPLANATION_PARAGRAPH_HISTORY
-IDS_MALWARE_V3_EXPLANATION_PARAGRAPH_SUBRESOURCE
-IDS_MALWARE_V3_EXPLANATION_PARAGRAPH_SUBRESOURCE_ADVICE
-IDS_MALWARE_V3_EXPLANATION_PARAGRAPH_SUBRESOURCE_HISTORY
-IDS_MALWARE_V3_HEADING
-IDS_MALWARE_V3_PRIMARY_PARAGRAPH
-IDS_MALWARE_V3_PROCEED_PARAGRAPH
-IDS_MALWARE_V3_PROCEED_PARAGRAPH_NOT_RECOMMEND
-IDS_MALWARE_V3_PROCEED_PARAGRAPH_SOCIAL
-IDS_MANAGED_USER_AVATAR_LABEL
-IDS_MIDI_SYSEX_INFOBAR_QUESTION
-IDS_MIDI_SYSEX_PERMISSION_FRAGMENT
-IDS_MOBILE_WELCOME_URL
-IDS_NACL_DEBUG_MASK_CHOICE_DEBUG_ALL
-IDS_NACL_DEBUG_MASK_CHOICE_EXCLUDE_UTILS_PNACL
-IDS_NACL_DEBUG_MASK_CHOICE_INCLUDE_DEBUG
-IDS_NETWORK_PREDICTION_ENABLED_DESCRIPTION
-IDS_NET_EXPORT_NO_EMAIL_ACCOUNTS_ALERT_MESSAGE
-IDS_NET_EXPORT_NO_EMAIL_ACCOUNTS_ALERT_TITLE
-IDS_NEW_INCOGNITO_WINDOW_MAC
-IDS_NEW_NUMBERED_PROFILE_NAME
-IDS_NEW_TAB_CHROME_WELCOME_PAGE_TITLE
-IDS_NEW_TAB_MOST_VISITED
-IDS_NEW_TAB_RECENTLY_CLOSED
-IDS_NEW_TAB_RESTORE_THUMBNAILS_SHORT_LINK
-IDS_NEW_TAB_THUMBNAIL_REMOVED_NOTIFICATION
-IDS_NEW_TAB_TITLE
-IDS_NEW_TAB_UNDO_THUMBNAIL_REMOVE
-IDS_NUMBERED_PROFILE_NAME
-IDS_OK
-IDS_OMNIBOX_EMPTY_HINT
-IDS_ONE_CLICK_SIGNIN_CONFIRM_EMAIL_DIALOG_CANCEL_BUTTON
-IDS_OPEN_TABS_NOTYETSYNCED
-IDS_OPEN_TABS_PROMOCOMPUTER
-IDS_OPTIONS_ADVANCED_SECTION_TITLE_PRIVACY
-IDS_OPTIONS_DISABLE_WEB_SERVICES
-IDS_OPTIONS_ENABLE_LOGGING
-IDS_OPTIONS_IMPROVE_BROWSING_EXPERIENCE
-IDS_OPTIONS_PROXIES_CONFIGURE_BUTTON
-IDS_OTHER_DEVICES_X_MORE
-IDS_PAGEINFO_ADDRESS
-IDS_PAGEINFO_CERT_INFO_BUTTON
-IDS_PAGEINFO_PARTIAL_ADDRESS
-IDS_PAGE_INFO_HELP_CENTER_LINK
-IDS_PAGE_INFO_INTERNAL_PAGE
-IDS_PAGE_INFO_SECURITY_BUTTON_ACCESSIBILITY_LABEL
-IDS_PAGE_INFO_SECURITY_TAB_DEPRECATED_SIGNATURE_ALGORITHM
-IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_CONNECTION_TEXT
-IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_INSECURE_CONTENT_ERROR
-IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_INSECURE_CONTENT_WARNING
-IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTED_SENTENCE_LINK
-IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTION_DETAILS
-IDS_PAGE_INFO_SECURITY_TAB_ENCRYPTION_DETAILS_AEAD
-IDS_PAGE_INFO_SECURITY_TAB_FALLBACK_MESSAGE
-IDS_PAGE_INFO_SECURITY_TAB_FIRST_VISITED_TODAY
-IDS_PAGE_INFO_SECURITY_TAB_INSECURE_IDENTITY
-IDS_PAGE_INFO_SECURITY_TAB_NON_UNIQUE_NAME
-IDS_PAGE_INFO_SECURITY_TAB_NOT_ENCRYPTED_CONNECTION_TEXT
-IDS_PAGE_INFO_SECURITY_TAB_NO_REVOCATION_MECHANISM
-IDS_PAGE_INFO_SECURITY_TAB_RENEGOTIATION_MESSAGE
-IDS_PAGE_INFO_SECURITY_TAB_SECURE_IDENTITY_EV_NO_CT
-IDS_PAGE_INFO_SECURITY_TAB_SECURE_IDENTITY_NO_CT
-IDS_PAGE_INFO_SECURITY_TAB_SSL_VERSION
-IDS_PAGE_INFO_SECURITY_TAB_UNABLE_TO_CHECK_REVOCATION
-IDS_PAGE_INFO_SECURITY_TAB_UNKNOWN_PARTY
-IDS_PAGE_INFO_SECURITY_TAB_WEAK_ENCRYPTION_CONNECTION_TEXT
-IDS_PASSWORDS_EXCEPTIONS_TAB_TITLE
-IDS_PASSWORDS_SHOW_PASSWORDS_TAB_TITLE
-IDS_PASSWORD_MANAGER_BLACKLIST_BUTTON
-IDS_PASSWORD_MANAGER_EMPTY_LOGIN
-IDS_PASSWORD_MANAGER_SAVE_BUTTON
-IDS_PASSWORD_MANAGER_SAVE_PASSWORD_PROMPT
-IDS_PAST_TIME_TODAY
-IDS_PAST_TIME_YESTERDAY
-IDS_PDF_INFOBAR_ALWAYS_USE_READER_BUTTON
-IDS_PERMISSION_ALLOW
-IDS_PERMISSION_DENY
-IDS_PHISHING_V3_EXPLANATION_PARAGRAPH
-IDS_PHISHING_V3_HEADING
-IDS_PHISHING_V3_PRIMARY_PARAGRAPH
-IDS_PHISHING_V3_PROCEED_PARAGRAPH
-IDS_PLATFORM_LABEL
-IDS_PLUGIN_CONFIRM_INSTALL_DIALOG_ACCEPT_BUTTON
-IDS_PLUGIN_CONFIRM_INSTALL_DIALOG_TITLE
-IDS_PLUGIN_NOT_SUPPORTED
-IDS_POLICY_ASSOCIATION_STATE_ACTIVE
-IDS_POLICY_ASSOCIATION_STATE_DEPROVISIONED
-IDS_POLICY_ASSOCIATION_STATE_UNMANAGED
-IDS_POLICY_DEFAULT_SEARCH_DISABLED
-IDS_POLICY_DEPRECATED
-IDS_POLICY_DM_STATUS_HTTP_STATUS_ERROR
-IDS_POLICY_DM_STATUS_REQUEST_FAILED
-IDS_POLICY_DM_STATUS_REQUEST_INVALID
-IDS_POLICY_DM_STATUS_RESPONSE_DECODING_ERROR
-IDS_POLICY_DM_STATUS_SERVICE_ACTIVATION_PENDING
-IDS_POLICY_DM_STATUS_SERVICE_DEPROVISIONED
-IDS_POLICY_DM_STATUS_SERVICE_DEVICE_ID_CONFLICT
-IDS_POLICY_DM_STATUS_SERVICE_DEVICE_NOT_FOUND
-IDS_POLICY_DM_STATUS_SERVICE_DOMAIN_MISMATCH
-IDS_POLICY_DM_STATUS_SERVICE_INVALID_SERIAL_NUMBER
-IDS_POLICY_DM_STATUS_SERVICE_MANAGEMENT_NOT_SUPPORTED
-IDS_POLICY_DM_STATUS_SERVICE_MANAGEMENT_TOKEN_INVALID
-IDS_POLICY_DM_STATUS_SERVICE_MISSING_LICENSES
-IDS_POLICY_DM_STATUS_SERVICE_POLICY_NOT_FOUND
-IDS_POLICY_DM_STATUS_SUCCESS
-IDS_POLICY_DM_STATUS_TEMPORARY_UNAVAILABLE
-IDS_POLICY_DM_STATUS_UNKNOWN_ERROR
-IDS_POLICY_FILTER_PLACEHOLDER
-IDS_POLICY_HEADER_LEVEL
-IDS_POLICY_HEADER_NAME
-IDS_POLICY_HEADER_SCOPE
-IDS_POLICY_HEADER_STATUS
-IDS_POLICY_HEADER_VALUE
-IDS_POLICY_HIDE_EXPANDED_VALUE
-IDS_POLICY_INVALID_BOOKMARK
-IDS_POLICY_INVALID_PROXY_MODE_ERROR
-IDS_POLICY_INVALID_SEARCH_URL_ERROR
-IDS_POLICY_LABEL_ASSET_ID
-IDS_POLICY_LABEL_CLIENT_ID
-IDS_POLICY_LABEL_DIRECTORY_API_ID
-IDS_POLICY_LABEL_DOMAIN
-IDS_POLICY_LABEL_LOCATION
-IDS_POLICY_LABEL_REFRESH_INTERVAL
-IDS_POLICY_LABEL_STATUS
-IDS_POLICY_LABEL_TIME_SINCE_LAST_REFRESH
-IDS_POLICY_LABEL_USERNAME
-IDS_POLICY_LEVEL_ERROR
-IDS_POLICY_LEVEL_MANDATORY
-IDS_POLICY_LEVEL_RECOMMENDED
-IDS_POLICY_LIST_ENTRY_ERROR
-IDS_POLICY_NEVER_FETCHED
-IDS_POLICY_NOT_SPECIFIED
-IDS_POLICY_NOT_SPECIFIED_ERROR
-IDS_POLICY_NO_POLICIES_SET
-IDS_POLICY_OK
-IDS_POLICY_OUT_OF_RANGE_ERROR
-IDS_POLICY_OVERRIDDEN
-IDS_POLICY_PROXY_BOTH_SPECIFIED_ERROR
-IDS_POLICY_PROXY_MODE_AUTO_DETECT_ERROR
-IDS_POLICY_PROXY_MODE_DISABLED_ERROR
-IDS_POLICY_PROXY_MODE_FIXED_SERVERS_ERROR
-IDS_POLICY_PROXY_MODE_PAC_URL_ERROR
-IDS_POLICY_PROXY_MODE_SYSTEM_ERROR
-IDS_POLICY_PROXY_NEITHER_SPECIFIED_ERROR
-IDS_POLICY_RELOAD_POLICIES
-IDS_POLICY_SCHEMA_VALIDATION_ERROR
-IDS_POLICY_SCOPE_DEVICE
-IDS_POLICY_SCOPE_USER
-IDS_POLICY_SHOW_EXPANDED_VALUE
-IDS_POLICY_SHOW_UNSET
-IDS_POLICY_STATUS
-IDS_POLICY_STATUS_DEVICE
-IDS_POLICY_STATUS_USER
-IDS_POLICY_STORE_STATUS_BAD_STATE
-IDS_POLICY_STORE_STATUS_LOAD_ERROR
-IDS_POLICY_STORE_STATUS_OK
-IDS_POLICY_STORE_STATUS_PARSE_ERROR
-IDS_POLICY_STORE_STATUS_SERIALIZE_ERROR
-IDS_POLICY_STORE_STATUS_STORE_ERROR
-IDS_POLICY_STORE_STATUS_UNKNOWN_ERROR
-IDS_POLICY_STORE_STATUS_VALIDATION_ERROR
-IDS_POLICY_SUBKEY_ERROR
-IDS_POLICY_TITLE
-IDS_POLICY_TYPE_ERROR
-IDS_POLICY_UNKNOWN
-IDS_POLICY_UNSET
-IDS_POLICY_VALIDATION_BAD_INITIAL_SIGNATURE
-IDS_POLICY_VALIDATION_BAD_KEY_VERIFICATION_SIGNATURE
-IDS_POLICY_VALIDATION_BAD_SIGNATURE
-IDS_POLICY_VALIDATION_BAD_TIMESTAMP
-IDS_POLICY_VALIDATION_BAD_USERNAME
-IDS_POLICY_VALIDATION_ERROR_CODE_PRESENT
-IDS_POLICY_VALIDATION_OK
-IDS_POLICY_VALIDATION_PAYLOAD_PARSE_ERROR
-IDS_POLICY_VALIDATION_POLICY_PARSE_ERROR
-IDS_POLICY_VALIDATION_UNKNOWN_ERROR
-IDS_POLICY_VALIDATION_WRONG_POLICY_TYPE
-IDS_POLICY_VALIDATION_WRONG_SETTINGS_ENTITY_ID
-IDS_POLICY_VALIDATION_WRONG_TOKEN
-IDS_PREFERENCES_CORRUPT_ERROR
-IDS_PREFERENCES_UNREADABLE_ERROR
-IDS_PRINT
-IDS_PRIVACY_POLICY_URL
-IDS_PRODUCT_NAME
-IDS_PROFILES_GUEST_PROFILE_NAME
-IDS_PROFILES_LOCAL_PROFILE_STATE
-IDS_PROFILE_TOO_NEW_ERROR
-IDS_PUSH_MESSAGES_BUBBLE_FRAGMENT
-IDS_PUSH_MESSAGES_BUBBLE_TEXT
-IDS_PUSH_MESSAGES_PERMISSION_QUESTION
-IDS_RECENT_TABS_MENU
-IDS_SAD_TAB_MESSAGE
-IDS_SAD_TAB_RELOAD_LABEL
-IDS_SAD_TAB_TITLE
-IDS_SAFEBROWSING_OVERRIDABLE_SAFETY_BUTTON
-IDS_SAFEBROWSING_V3_CLOSE_DETAILS_BUTTON
-IDS_SAFEBROWSING_V3_OPEN_DETAILS_BUTTON
-IDS_SAFEBROWSING_V3_TITLE
-IDS_SAFE_BROWSING_MALWARE_BACK_BUTTON
-IDS_SAFE_BROWSING_MALWARE_BACK_HEADLINE
-IDS_SAFE_BROWSING_MALWARE_COLLAB_HEADLINE
-IDS_SAFE_BROWSING_MALWARE_DIAGNOSTIC_PAGE
-IDS_SAFE_BROWSING_MALWARE_FEAR_HEADLINE
-IDS_SAFE_BROWSING_MALWARE_HEADLINE
-IDS_SAFE_BROWSING_MALWARE_LABEL
-IDS_SAFE_BROWSING_MALWARE_QUESTION_HEADLINE
-IDS_SAFE_BROWSING_MALWARE_REPORTING_AGREE
-IDS_SAFE_BROWSING_MALWARE_TITLE
-IDS_SAFE_BROWSING_MALWARE_V2_DESCRIPTION1
-IDS_SAFE_BROWSING_MALWARE_V2_DESCRIPTION1_SUBRESOURCE
-IDS_SAFE_BROWSING_MALWARE_V2_DESCRIPTION2
-IDS_SAFE_BROWSING_MALWARE_V2_DESCRIPTION2_SUBRESOURCE
-IDS_SAFE_BROWSING_MALWARE_V2_DESCRIPTION3
-IDS_SAFE_BROWSING_MALWARE_V2_DETAILS
-IDS_SAFE_BROWSING_MALWARE_V2_DETAILS_SUBRESOURCE
-IDS_SAFE_BROWSING_MALWARE_V2_HEADLINE
-IDS_SAFE_BROWSING_MALWARE_V2_HEADLINE_SUBRESOURCE
-IDS_SAFE_BROWSING_MALWARE_V2_LEARN_MORE
-IDS_SAFE_BROWSING_MALWARE_V2_PROCEED_LINK
-IDS_SAFE_BROWSING_MALWARE_V2_REPORTING_AGREE
-IDS_SAFE_BROWSING_MALWARE_V2_SEE_MORE
-IDS_SAFE_BROWSING_MALWARE_V2_TITLE
-IDS_SAFE_BROWSING_MULTI_MALWARE_DESCRIPTION1
-IDS_SAFE_BROWSING_MULTI_MALWARE_DESCRIPTION2
-IDS_SAFE_BROWSING_MULTI_MALWARE_DESCRIPTION3
-IDS_SAFE_BROWSING_MULTI_MALWARE_DESCRIPTION_AGREE
-IDS_SAFE_BROWSING_MULTI_MALWARE_PROCEED_BUTTON
-IDS_SAFE_BROWSING_MULTI_PHISHING_DESCRIPTION1
-IDS_SAFE_BROWSING_MULTI_THREAT_DESCRIPTION1
-IDS_SAFE_BROWSING_MULTI_THREAT_DESCRIPTION2
-IDS_SAFE_BROWSING_MULTI_THREAT_TITLE
-IDS_SAFE_BROWSING_PHISHING_BACK_HEADLINE
-IDS_SAFE_BROWSING_PHISHING_COLLAB_HEADLINE
-IDS_SAFE_BROWSING_PHISHING_FEAR_HEADLINE
-IDS_SAFE_BROWSING_PHISHING_HEADLINE
-IDS_SAFE_BROWSING_PHISHING_LABEL
-IDS_SAFE_BROWSING_PHISHING_QUESTION_HEADLINE
-IDS_SAFE_BROWSING_PHISHING_REPORT_ERROR
-IDS_SAFE_BROWSING_PHISHING_TITLE
-IDS_SAFE_BROWSING_PHISHING_V2_DESCRIPTION1
-IDS_SAFE_BROWSING_PHISHING_V2_DESCRIPTION2
-IDS_SAFE_BROWSING_PHISHING_V2_HEADLINE
-IDS_SAFE_BROWSING_PHISHING_V2_REPORT_ERROR
-IDS_SAFE_BROWSING_PHISHING_V2_TITLE
-IDS_SAFE_BROWSING_PRIVACY_POLICY_PAGE
-IDS_SAFE_BROWSING_PRIVACY_POLICY_PAGE_V2
-IDS_SAFE_BROWSING_PRIVACY_POLICY_URL
-IDS_SAVE
-IDS_SEARCH_BOX_EMPTY_HINT
-IDS_SECURE_CONNECTION_EV
-IDS_SESSION_CRASHED_VIEW_MESSAGE
-IDS_SESSION_CRASHED_VIEW_RESTORE_BUTTON
-IDS_SETTINGS_SHOW_ADVANCED_SETTINGS
-IDS_SHORT_PRODUCT_NAME
-IDS_SHOW_HISTORY
-IDS_SIGNED_IN_WITH_SYNC_DISABLED
-IDS_SIGNED_IN_WITH_SYNC_SUPPRESSED
-IDS_SIGNIN_ERROR_BUBBLE_VIEW_TITLE
-IDS_SINGLE_PROFILE_DISPLAY_NAME
-IDS_SSL_CLOCK_ERROR
-IDS_SSL_CLOCK_ERROR_EXPLANATION
-IDS_SSL_NONOVERRIDABLE_HSTS
-IDS_SSL_NONOVERRIDABLE_INVALID
-IDS_SSL_NONOVERRIDABLE_MORE
-IDS_SSL_NONOVERRIDABLE_MORE_INVALID_SP3
-IDS_SSL_NONOVERRIDABLE_PINNED
-IDS_SSL_NONOVERRIDABLE_REVOKED
-IDS_SSL_OVERRIDABLE_PRIMARY_PARAGRAPH
-IDS_SSL_OVERRIDABLE_PROCEED_LINK_TEXT
-IDS_SSL_OVERRIDABLE_PROCEED_PARAGRAPH
-IDS_SSL_OVERRIDABLE_SAFETY_BUTTON
-IDS_SSL_OVERRIDABLE_TITLE
-IDS_SSL_RELOAD
-IDS_SSL_V2_CLOCK_AHEAD_HEADING
-IDS_SSL_V2_CLOCK_BEHIND_HEADING
-IDS_SSL_V2_CLOCK_PRIMARY_PARAGRAPH
-IDS_SSL_V2_CLOCK_TITLE
-IDS_SSL_V2_CLOCK_UPDATE_DATE_AND_TIME
-IDS_SSL_V2_CLOSE_DETAILS_BUTTON
-IDS_SSL_V2_HEADING
-IDS_SSL_V2_OPEN_DETAILS_BUTTON
-IDS_SSL_V2_PRIMARY_PARAGRAPH
-IDS_SSL_V2_TITLE
-IDS_STARS_PROMO_LABEL_IOS
-IDS_SUPERVISED_USER_AVATAR_LABEL
-IDS_SUPERVISED_USER_NEW_AVATAR_LABEL
-IDS_SYNC_ACCOUNT_DETAILS_NOT_ENTERED
-IDS_SYNC_ACCOUNT_SYNCING_TO_USER
-IDS_SYNC_ACCOUNT_SYNCING_TO_USER_WITH_MANAGE_LINK
-IDS_SYNC_AUTHENTICATING_LABEL
-IDS_SYNC_BASIC_ENCRYPTION_DATA
-IDS_SYNC_CLEAR_USER_DATA
-IDS_SYNC_CONFIGURE_ENCRYPTION
-IDS_SYNC_DATATYPE_AUTOFILL
-IDS_SYNC_DATATYPE_BOOKMARKS
-IDS_SYNC_DATATYPE_PASSWORDS
-IDS_SYNC_DATATYPE_PREFERENCES
-IDS_SYNC_DATATYPE_TABS
-IDS_SYNC_DATATYPE_TYPED_URLS
-IDS_SYNC_EMPTY_PASSPHRASE_ERROR
-IDS_SYNC_ENABLE_SYNC_ON_ACCOUNT
-IDS_SYNC_ENCRYPTION_SECTION_TITLE
-IDS_SYNC_ENTER_GOOGLE_PASSPHRASE_BODY
-IDS_SYNC_ENTER_PASSPHRASE_BODY
-IDS_SYNC_ENTER_PASSPHRASE_BODY_WITH_DATE
-IDS_SYNC_ENTER_PASSPHRASE_TITLE
-IDS_SYNC_ERROR_BUBBLE_VIEW_TITLE
-IDS_SYNC_ERROR_SIGNING_IN
-IDS_SYNC_FULL_ENCRYPTION_DATA
-IDS_SYNC_INVALID_USER_CREDENTIALS
-IDS_SYNC_LOGIN_INFO_OUT_OF_DATE
-IDS_SYNC_LOGIN_SETTING_UP
-IDS_SYNC_MENU_PRE_SYNCED_LABEL
-IDS_SYNC_MENU_SYNCED_LABEL
-IDS_SYNC_NTP_PASSWORD_ENABLE
-IDS_SYNC_NTP_PASSWORD_PROMO
-IDS_SYNC_NTP_PASSWORD_PROMO,
-IDS_SYNC_NTP_SETUP_IN_PROGRESS
-IDS_SYNC_OPTIONS_GROUP_NAME
-IDS_SYNC_OTHER_SIGN_IN_ERROR_BUBBLE_VIEW_MESSAGE
-IDS_SYNC_PASSPHRASE_ERROR_BUBBLE_VIEW_ACCEPT
-IDS_SYNC_PASSPHRASE_ERROR_BUBBLE_VIEW_MESSAGE
-IDS_SYNC_PASSPHRASE_ERROR_WRENCH_MENU_ITEM
-IDS_SYNC_PASSPHRASE_LABEL
-IDS_SYNC_PASSPHRASE_MISMATCH_ERROR
-IDS_SYNC_PASSPHRASE_MSG_EXPLICIT_POSTFIX
-IDS_SYNC_PASSPHRASE_MSG_EXPLICIT_PREFIX
-IDS_SYNC_PASSWORD_SYNC_ATTENTION
-IDS_SYNC_PROMO_NTP_BUBBLE_MESSAGE
-IDS_SYNC_PROMO_TAB_TITLE
-IDS_SYNC_RELOGIN_LINK_LABEL
-IDS_SYNC_SERVER_IS_UNREACHABLE
-IDS_SYNC_SERVICE_UNAVAILABLE
-IDS_SYNC_SETUP_ERROR
-IDS_SYNC_SIGN_IN_ERROR_BUBBLE_VIEW_ACCEPT
-IDS_SYNC_SIGN_IN_ERROR_BUBBLE_VIEW_MESSAGE
-IDS_SYNC_SIGN_IN_ERROR_WRENCH_MENU_ITEM
-IDS_SYNC_START_SYNC_BUTTON_LABEL
-IDS_SYNC_STATUS_UNRECOVERABLE_ERROR
-IDS_SYNC_STOP_AND_RESTART_SYNC
-IDS_SYNC_TIME_JUST_NOW
-IDS_SYNC_TIME_NEVER
-IDS_SYNC_UNAVAILABLE_ERROR_BUBBLE_VIEW_ACCEPT
-IDS_SYNC_UNAVAILABLE_ERROR_BUBBLE_VIEW_MESSAGE
-IDS_SYNC_UNRECOVERABLE_ERROR_HELP_URL
-IDS_SYNC_UPGRADE_CLIENT
-IDS_SYSTEM_FLAGS_OWNER_ONLY
-IDS_TERMS_HTML
-IDS_TIME_DAYS
-IDS_TIME_DAYS_1ST
-IDS_TIME_ELAPSED_DAYS
-IDS_TIME_ELAPSED_HOURS
-IDS_TIME_ELAPSED_MINS
-IDS_TIME_ELAPSED_SECS
-IDS_TIME_HOURS
-IDS_TIME_HOURS_1ST
-IDS_TIME_HOURS_2ND
-IDS_TIME_LONG_MINS
-IDS_TIME_LONG_MINS_1ST
-IDS_TIME_LONG_MINS_2ND
-IDS_TIME_LONG_SECS
-IDS_TIME_LONG_SECS_2ND
-IDS_TIME_MINS
-IDS_TIME_REMAINING_DAYS
-IDS_TIME_REMAINING_HOURS
-IDS_TIME_REMAINING_LONG_MINS
-IDS_TIME_REMAINING_LONG_SECS
-IDS_TIME_REMAINING_MINS
-IDS_TIME_REMAINING_SECS
-IDS_TIME_SECS
-IDS_TOOLTIP_STAR
-IDS_TOUCH_EVENTS_DESCRIPTION
-IDS_TOUCH_EVENTS_NAME
-IDS_TRANSLATE_INFOBAR_ACCEPT
-IDS_TRANSLATE_INFOBAR_AFTER_MESSAGE
-IDS_TRANSLATE_INFOBAR_AFTER_MESSAGE_AUTODETERMINED_SOURCE_LANGUAGE
-IDS_TRANSLATE_INFOBAR_ALWAYS_TRANSLATE
-IDS_TRANSLATE_INFOBAR_BEFORE_MESSAGE
-IDS_TRANSLATE_INFOBAR_BEFORE_MESSAGE_IOS
-IDS_TRANSLATE_INFOBAR_DENY
-IDS_TRANSLATE_INFOBAR_ERROR_CANT_CONNECT
-IDS_TRANSLATE_INFOBAR_ERROR_CANT_TRANSLATE
-IDS_TRANSLATE_INFOBAR_ERROR_SAME_LANGUAGE
-IDS_TRANSLATE_INFOBAR_NEVER_MESSAGE_IOS
-IDS_TRANSLATE_INFOBAR_NEVER_TRANSLATE
-IDS_TRANSLATE_INFOBAR_OPTIONS_ABOUT
-IDS_TRANSLATE_INFOBAR_OPTIONS_ALWAYS
-IDS_TRANSLATE_INFOBAR_OPTIONS_NEVER_TRANSLATE_LANG
-IDS_TRANSLATE_INFOBAR_OPTIONS_NEVER_TRANSLATE_SITE
-IDS_TRANSLATE_INFOBAR_OPTIONS_REPORT_ERROR
-IDS_TRANSLATE_INFOBAR_RETRY
-IDS_TRANSLATE_INFOBAR_REVERT
-IDS_TRANSLATE_INFOBAR_TRANSLATING_TO
-IDS_TRANSLATE_INFOBAR_UNKNOWN_PAGE_LANGUAGE
-IDS_TRANSLATE_INFOBAR_UNSUPPORTED_PAGE_LANGUAGE
-IDS_UPGRADE_AVAILABLE
-IDS_UPGRADE_AVAILABLE_BUTTON
-IDS_WEB_FONT_FAMILY
-IDS_WEB_FONT_SIZE
diff --git a/build/ios/mac_build.gypi b/build/ios/mac_build.gypi
deleted file mode 100644
index 4da21eb..0000000
--- a/build/ios/mac_build.gypi
+++ /dev/null
@@ -1,83 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# Xcode throws an error if an iOS target depends on a Mac OS X target. So
-# any place a utility program needs to be build and run, an action is
-# used to run ninja as script to work around this.
-# Example:
-# {
-# 'target_name': 'foo',
-# 'type': 'none',
-# 'variables': {
-# # The name of a directory used for ninja. This cannot be shared with
-# # another mac build.
-# 'ninja_output_dir': 'ninja-foo',
-# # The full path to the location in which the ninja executable should be
-# # placed. This cannot be shared with another mac build.
-# 'ninja_product_dir':
-# '<(DEPTH)/xcodebuild/<(ninja_output_dir)/<(CONFIGURATION_NAME)',
-# # The list of all the gyp files that contain the targets to run.
-# 're_run_targets': [
-# 'foo.gyp',
-# ],
-# },
-# 'includes': ['path_to/mac_build.gypi'],
-# 'actions': [
-# {
-# 'action_name': 'compile foo',
-# 'inputs': [],
-# 'outputs': [],
-# 'action': [
-# '<@(ninja_cmd)',
-# # All the targets to build.
-# 'foo1',
-# 'foo2',
-# ],
-# },
-# ],
-# }
-{
- 'variables': {
- 'variables': {
- 'parent_generator%': '<(GENERATOR)',
- },
- 'parent_generator%': '<(parent_generator)',
- # Common ninja command line flags.
- 'ninja_cmd': [
- # Bounce through clean_env to clean up the environment so things
- # set by the iOS build don't pollute the Mac build.
- '<(DEPTH)/build/ios/clean_env.py',
- # ninja must be found in the PATH.
- 'ADD_TO_PATH=<!(echo $PATH)',
- 'ninja',
- '-C',
- '<(ninja_product_dir)',
- ],
-
- # Common syntax to rerun gyp to generate the Mac projects.
- 're_run_gyp': [
- 'build/gyp_chromium',
- '--depth=.',
- # Don't use anything set for the iOS side of things.
- '--ignore-environment',
- # Generate for ninja
- '--format=ninja',
- # Generate files into xcodebuild/ninja
- '-Goutput_dir=xcodebuild/<(ninja_output_dir)',
- # nacl isn't in the iOS checkout, make sure it's turned off
- '-Ddisable_nacl=1',
- # Pass through the Mac SDK version.
- '-Dmac_sdk=<(mac_sdk)',
- '-Dparent_generator=<(parent_generator)'
- ],
-
- # Rerun gyp for each of the projects needed. This is what actually
- # generates the projects on disk.
- 're_run_gyp_execution':
- '<!(cd <(DEPTH) && <@(re_run_gyp) <@(re_run_targets))',
- },
- # Since these are used to generate things needed by other targets, make
- # them hard dependencies so they are always built first.
- 'hard_dependency': 1,
-}
diff --git a/build/isolate.gypi b/build/isolate.gypi
deleted file mode 100644
index 69af5b0..0000000
--- a/build/isolate.gypi
+++ /dev/null
@@ -1,125 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included into a target to provide a rule
-# to "build" .isolate files into a .isolated file.
-#
-# To use this, create a gyp target with the following form:
-# 'conditions': [
-# ['test_isolation_mode != "noop"', {
-# 'targets': [
-# {
-# 'target_name': 'foo_test_run',
-# 'type': 'none',
-# 'dependencies': [
-# 'foo_test',
-# ],
-# 'includes': [
-# '../build/isolate.gypi',
-# ],
-# 'sources': [
-# 'foo_test.isolate',
-# ],
-# },
-# ],
-# }],
-# ],
-#
-# Note: foo_test.isolate is included and a source file. It is an inherent
-# property of the .isolate format. This permits to define GYP variables but is
-# a stricter format than GYP so isolate.py can read it.
-#
-# The generated .isolated file will be:
-# <(PRODUCT_DIR)/foo_test.isolated
-#
-# See http://dev.chromium.org/developers/testing/isolated-testing/for-swes
-# for more information.
-
-{
- 'includes': [
- '../build/util/version.gypi',
- ],
- 'rules': [
- {
- 'rule_name': 'isolate',
- 'extension': 'isolate',
- 'inputs': [
- # Files that are known to be involved in this step.
- '<(DEPTH)/tools/isolate_driver.py',
- '<(DEPTH)/tools/swarming_client/isolate.py',
- '<(DEPTH)/tools/swarming_client/run_isolated.py',
- ],
- 'outputs': [],
- 'action': [
- 'python',
- '<(DEPTH)/tools/isolate_driver.py',
- '<(test_isolation_mode)',
- '--isolated', '<(PRODUCT_DIR)/<(RULE_INPUT_ROOT).isolated',
- '--isolate', '<(RULE_INPUT_PATH)',
-
- # Variables should use the -V FOO=<(FOO) form so frequent values,
- # like '0' or '1', aren't stripped out by GYP. Run 'isolate.py help' for
- # more details.
-
- # Path variables are used to replace file paths when loading a .isolate
- # file
- '--path-variable', 'DEPTH', '<(DEPTH)',
- '--path-variable', 'PRODUCT_DIR', '<(PRODUCT_DIR) ',
-
- # Extra variables are replaced on the 'command' entry and on paths in
- # the .isolate file but are not considered relative paths.
- '--extra-variable', 'version_full=<(version_full)',
-
- # Note: This list must match DefaultConfigVariables()
- # in build/android/pylib/utils/isolator.py
- '--config-variable', 'CONFIGURATION_NAME=<(CONFIGURATION_NAME)',
- '--config-variable', 'OS=<(OS)',
- '--config-variable', 'asan=<(asan)',
- '--config-variable', 'branding=<(branding)',
- '--config-variable', 'chromeos=<(chromeos)',
- '--config-variable', 'component=<(component)',
- '--config-variable', 'disable_nacl=<(disable_nacl)',
- '--config-variable', 'enable_pepper_cdms=<(enable_pepper_cdms)',
- '--config-variable', 'enable_plugins=<(enable_plugins)',
- '--config-variable', 'fastbuild=<(fastbuild)',
- '--config-variable', 'icu_use_data_file_flag=<(icu_use_data_file_flag)',
- # TODO(kbr): move this to chrome_tests.gypi:gles2_conform_tests_run
- # once support for user-defined config variables is added.
- '--config-variable',
- 'internal_gles2_conform_tests=<(internal_gles2_conform_tests)',
- '--config-variable', 'kasko=<(kasko)',
- '--config-variable', 'libpeer_target_type=<(libpeer_target_type)',
- '--config-variable', 'lsan=<(lsan)',
- '--config-variable', 'msan=<(msan)',
- '--config-variable', 'target_arch=<(target_arch)',
- '--config-variable', 'tsan=<(tsan)',
- '--config-variable', 'use_custom_libcxx=<(use_custom_libcxx)',
- '--config-variable', 'use_instrumented_libraries=<(use_instrumented_libraries)',
- '--config-variable',
- 'use_prebuilt_instrumented_libraries=<(use_prebuilt_instrumented_libraries)',
- '--config-variable', 'use_openssl=<(use_openssl)',
- '--config-variable', 'use_ozone=<(use_ozone)',
- '--config-variable', 'use_x11=<(use_x11)',
- '--config-variable', 'v8_use_external_startup_data=<(v8_use_external_startup_data)',
- ],
- 'conditions': [
- # Note: When gyp merges lists, it appends them to the old value.
- ['OS=="mac"', {
- 'action': [
- '--extra-variable', 'mac_product_name=<(mac_product_name)',
- ],
- }],
- ["test_isolation_mode == 'prepare'", {
- 'outputs': [
- '<(PRODUCT_DIR)/<(RULE_INPUT_ROOT).isolated.gen.json',
- ],
- }, {
- 'outputs': [
- '<(PRODUCT_DIR)/<(RULE_INPUT_ROOT).isolated',
- ],
- }],
- ],
- },
- ],
-}
diff --git a/build/jar_file_jni_generator.gypi b/build/jar_file_jni_generator.gypi
deleted file mode 100644
index 3d95b28..0000000
--- a/build/jar_file_jni_generator.gypi
+++ /dev/null
@@ -1,67 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included into a target to provide a rule
-# to generate jni bindings for system Java-files in a consistent manner.
-#
-# To use this, create a gyp target with the following form:
-# {
-# 'target_name': 'android_jar_jni_headers',
-# 'type': 'none',
-# 'variables': {
-# 'jni_gen_package': 'chrome',
-# 'input_java_class': 'java/io/InputStream.class',
-# },
-# 'includes': [ '../build/jar_file_jni_generator.gypi' ],
-# },
-#
-# Optional variables:
-# input_jar_file - The input jar file, if omitted, android_sdk_jar will be used.
-
-{
- 'variables': {
- 'jni_generator': '<(DEPTH)/base/android/jni_generator/jni_generator.py',
- # A comma separated string of include files.
- 'jni_generator_includes%': (
- 'base/android/jni_generator/jni_generator_helper.h'
- ),
- 'native_exports%': '--native_exports_optional',
- },
- 'actions': [
- {
- 'action_name': 'generate_jni_headers_from_jar_file',
- 'inputs': [
- '<(jni_generator)',
- '<(input_jar_file)',
- '<(android_sdk_jar)',
- ],
- 'variables': {
- 'java_class_name': '<!(basename <(input_java_class)|sed "s/\.class//")',
- 'input_jar_file%': '<(android_sdk_jar)'
- },
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/<(jni_gen_package)/jni/<(java_class_name)_jni.h',
- ],
- 'action': [
- '<(jni_generator)',
- '-j',
- '<(input_jar_file)',
- '--input_file',
- '<(input_java_class)',
- '--output_dir',
- '<(SHARED_INTERMEDIATE_DIR)/<(jni_gen_package)/jni',
- '--includes',
- '<(jni_generator_includes)',
- '--optimize_generation',
- '<(optimize_jni_generation)',
- '<(native_exports)',
- ],
- 'message': 'Generating JNI bindings from <(input_jar_file)/<(input_java_class)',
- 'process_outputs_as_sources': 1,
- },
- ],
- # This target exports a hard dependency because it generates header
- # files.
- 'hard_dependency': 1,
-}
diff --git a/build/java.gypi b/build/java.gypi
deleted file mode 100644
index 73c550d..0000000
--- a/build/java.gypi
+++ /dev/null
@@ -1,368 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included into a target to provide a rule
-# to build Java in a consistent manner.
-#
-# To use this, create a gyp target with the following form:
-# {
-# 'target_name': 'my-package_java',
-# 'type': 'none',
-# 'variables': {
-# 'java_in_dir': 'path/to/package/root',
-# },
-# 'includes': ['path/to/this/gypi/file'],
-# }
-#
-# Required variables:
-# java_in_dir - The top-level java directory. The src should be in
-# <java_in_dir>/src.
-# Optional/automatic variables:
-# add_to_dependents_classpaths - Set to 0 if the resulting jar file should not
-# be added to its dependents' classpaths.
-# additional_input_paths - These paths will be included in the 'inputs' list to
-# ensure that this target is rebuilt when one of these paths changes.
-# additional_src_dirs - Additional directories with .java files to be compiled
-# and included in the output of this target.
-# generated_src_dirs - Same as additional_src_dirs except used for .java files
-# that are generated at build time. This should be set automatically by a
-# target's dependencies. The .java files in these directories are not
-# included in the 'inputs' list (unlike additional_src_dirs).
-# input_jars_paths - The path to jars to be included in the classpath. This
-# should be filled automatically by depending on the appropriate targets.
-# javac_includes - A list of specific files to include. This is by default
-# empty, which leads to inclusion of all files specified. May include
-# wildcard, and supports '**/' for recursive path wildcards, ie.:
-# '**/MyFileRegardlessOfDirectory.java', '**/IncludedPrefix*.java'.
-# has_java_resources - Set to 1 if the java target contains an
-# Android-compatible resources folder named res. If 1, R_package and
-# R_package_relpath must also be set.
-# R_package - The java package in which the R class (which maps resources to
-# integer IDs) should be generated, e.g. org.chromium.content.
-# R_package_relpath - Same as R_package, but replace each '.' with '/'.
-# res_extra_dirs - A list of extra directories containing Android resources.
-# These directories may be generated at build time.
-# res_extra_files - A list of the files in res_extra_dirs.
-# never_lint - Set to 1 to not run lint on this target.
-
-{
- 'dependencies': [
- '<(DEPTH)/build/android/setup.gyp:build_output_dirs'
- ],
- 'variables': {
- 'add_to_dependents_classpaths%': 1,
- 'android_jar': '<(android_sdk)/android.jar',
- 'input_jars_paths': [ '<(android_jar)' ],
- 'additional_src_dirs': [],
- 'javac_includes': [],
- 'jar_name': '<(_target_name).jar',
- 'jar_dir': '<(PRODUCT_DIR)/lib.java',
- 'jar_path': '<(intermediate_dir)/<(jar_name)',
- 'jar_final_path': '<(jar_dir)/<(jar_name)',
- 'jar_excluded_classes': [ '*/R.class', '*/R##*.class' ],
- 'instr_stamp': '<(intermediate_dir)/instr.stamp',
- 'additional_input_paths': [],
- 'dex_path': '<(PRODUCT_DIR)/lib.java/<(_target_name).dex.jar',
- 'generated_src_dirs': ['>@(generated_R_dirs)'],
- 'generated_R_dirs': [],
- 'has_java_resources%': 0,
- 'res_extra_dirs': [],
- 'res_extra_files': [],
- 'res_v14_skip%': 0,
- 'resource_input_paths': ['>@(res_extra_files)'],
- 'intermediate_dir': '<(SHARED_INTERMEDIATE_DIR)/<(_target_name)',
- 'compile_stamp': '<(intermediate_dir)/compile.stamp',
- 'lint_stamp': '<(intermediate_dir)/lint.stamp',
- 'lint_result': '<(intermediate_dir)/lint_result.xml',
- 'lint_config': '<(intermediate_dir)/lint_config.xml',
- 'never_lint%': 0,
- 'findbugs_stamp': '<(intermediate_dir)/findbugs.stamp',
- 'run_findbugs%': 0,
- 'java_in_dir_suffix%': '/src',
- 'proguard_config%': '',
- 'proguard_preprocess%': '0',
- 'enable_errorprone%': '0',
- 'errorprone_exe_path': '<(PRODUCT_DIR)/bin.java/chromium_errorprone',
- 'variables': {
- 'variables': {
- 'proguard_preprocess%': 0,
- 'emma_never_instrument%': 0,
- },
- 'conditions': [
- ['proguard_preprocess == 1', {
- 'javac_jar_path': '<(intermediate_dir)/<(_target_name).pre.jar'
- }, {
- 'javac_jar_path': '<(jar_path)'
- }],
- ['chromium_code != 0 and emma_coverage != 0 and emma_never_instrument == 0', {
- 'emma_instrument': 1,
- }, {
- 'emma_instrument': 0,
- }],
- ],
- },
- 'emma_instrument': '<(emma_instrument)',
- 'javac_jar_path': '<(javac_jar_path)',
- },
- 'conditions': [
- ['add_to_dependents_classpaths == 1', {
- # This all_dependent_settings is used for java targets only. This will add the
- # jar path to the classpath of dependent java targets.
- 'all_dependent_settings': {
- 'variables': {
- 'input_jars_paths': ['<(jar_final_path)'],
- 'library_dexed_jars_paths': ['<(dex_path)'],
- },
- },
- }],
- ['has_java_resources == 1', {
- 'variables': {
- 'resource_dir': '<(java_in_dir)/res',
- 'res_input_dirs': ['<(resource_dir)', '<@(res_extra_dirs)'],
- 'resource_input_paths': ['<!@(find <(resource_dir) -type f)'],
-
- 'R_dir': '<(intermediate_dir)/java_R',
- 'R_text_file': '<(R_dir)/R.txt',
-
- 'generated_src_dirs': ['<(R_dir)'],
- 'additional_input_paths': ['<(resource_zip_path)', ],
-
- 'dependencies_res_zip_paths': [],
- 'resource_zip_path': '<(PRODUCT_DIR)/res.java/<(_target_name).zip',
- },
- 'all_dependent_settings': {
- 'variables': {
- # Dependent libraries include this target's R.java file via
- # generated_R_dirs.
- 'generated_R_dirs': ['<(R_dir)'],
-
- # Dependent libraries and apks include this target's resources via
- # dependencies_res_zip_paths.
- 'additional_input_paths': ['<(resource_zip_path)'],
- 'dependencies_res_zip_paths': ['<(resource_zip_path)'],
-
- # additional_res_packages and additional_R_text_files are used to
- # create this packages R.java files when building the APK.
- 'additional_res_packages': ['<(R_package)'],
- 'additional_R_text_files': ['<(R_text_file)'],
- },
- },
- 'actions': [
- # Generate R.java and crunch image resources.
- {
- 'action_name': 'process_resources',
- 'message': 'processing resources for <(_target_name)',
- 'variables': {
- 'android_manifest': '<(DEPTH)/build/android/AndroidManifest.xml',
- # Write the inputs list to a file, so that its mtime is updated when
- # the list of inputs changes.
- 'inputs_list_file': '>|(java_resources.<(_target_name).gypcmd >@(resource_input_paths))',
- 'process_resources_options': [],
- 'conditions': [
- ['res_v14_skip == 1', {
- 'process_resources_options': ['--v14-skip']
- }],
- ],
- },
- 'inputs': [
- '<(DEPTH)/build/android/gyp/util/build_utils.py',
- '<(DEPTH)/build/android/gyp/process_resources.py',
- '<(DEPTH)/build/android/gyp/generate_v14_compatible_resources.py',
- '>@(resource_input_paths)',
- '>@(dependencies_res_zip_paths)',
- '>(inputs_list_file)',
- ],
- 'outputs': [
- '<(resource_zip_path)',
- ],
- 'action': [
- 'python', '<(DEPTH)/build/android/gyp/process_resources.py',
- '--android-sdk', '<(android_sdk)',
- '--aapt-path', '<(android_aapt_path)',
- '--non-constant-id',
-
- '--android-manifest', '<(android_manifest)',
- '--custom-package', '<(R_package)',
-
- '--dependencies-res-zips', '>(dependencies_res_zip_paths)',
- '--resource-dirs', '<(res_input_dirs)',
-
- '--R-dir', '<(R_dir)',
- '--resource-zip-out', '<(resource_zip_path)',
-
- '<@(process_resources_options)',
- ],
- },
- ],
- }],
- ['proguard_preprocess == 1', {
- 'actions': [
- {
- 'action_name': 'proguard_<(_target_name)',
- 'message': 'Proguard preprocessing <(_target_name) jar',
- 'inputs': [
- '<(android_sdk_root)/tools/proguard/lib/proguard.jar',
- '<(DEPTH)/build/android/gyp/util/build_utils.py',
- '<(DEPTH)/build/android/gyp/proguard.py',
- '<(javac_jar_path)',
- '<(proguard_config)',
- ],
- 'outputs': [
- '<(jar_path)',
- ],
- 'action': [
- 'python', '<(DEPTH)/build/android/gyp/proguard.py',
- '--proguard-path=<(android_sdk_root)/tools/proguard/lib/proguard.jar',
- '--input-path=<(javac_jar_path)',
- '--output-path=<(jar_path)',
- '--proguard-config=<(proguard_config)',
- '--classpath=<(android_sdk_jar) >(input_jars_paths)',
- ]
- },
- ],
- }],
- ['run_findbugs == 1', {
- 'actions': [
- {
- 'action_name': 'findbugs_<(_target_name)',
- 'message': 'Running findbugs on <(_target_name)',
- 'inputs': [
- '<(DEPTH)/build/android/findbugs_diff.py',
- '<(DEPTH)/build/android/findbugs_filter/findbugs_exclude.xml',
- '<(DEPTH)/build/android/pylib/utils/findbugs.py',
- '>@(input_jars_paths)',
- '<(jar_final_path)',
- '<(compile_stamp)',
- ],
- 'outputs': [
- '<(findbugs_stamp)',
- ],
- 'action': [
- 'python', '<(DEPTH)/build/android/findbugs_diff.py',
- '--auxclasspath-gyp', '>(input_jars_paths)',
- '--stamp', '<(findbugs_stamp)',
- '<(jar_final_path)',
- ],
- },
- ],
- }],
- ['enable_errorprone == 1', {
- 'dependencies': [
- '<(DEPTH)/third_party/errorprone/errorprone.gyp:chromium_errorprone',
- ],
- }],
- ],
- 'actions': [
- {
- 'action_name': 'javac_<(_target_name)',
- 'message': 'Compiling <(_target_name) java sources',
- 'variables': {
- 'extra_args': [],
- 'extra_inputs': [],
- 'java_sources': ['>!@(find >(java_in_dir)>(java_in_dir_suffix) >(additional_src_dirs) -name "*.java")'],
- 'conditions': [
- ['enable_errorprone == 1', {
- 'extra_inputs': [
- '<(errorprone_exe_path)',
- ],
- 'extra_args': [ '--use-errorprone-path=<(errorprone_exe_path)' ],
- }],
- ],
- },
- 'inputs': [
- '<(DEPTH)/build/android/gyp/util/build_utils.py',
- '<(DEPTH)/build/android/gyp/javac.py',
- '>@(java_sources)',
- '>@(input_jars_paths)',
- '>@(additional_input_paths)',
- '<@(extra_inputs)',
- ],
- 'outputs': [
- '<(compile_stamp)',
- '<(javac_jar_path)',
- ],
- 'action': [
- 'python', '<(DEPTH)/build/android/gyp/javac.py',
- '--bootclasspath=<(android_sdk_jar)',
- '--classpath=>(input_jars_paths)',
- '--src-gendirs=>(generated_src_dirs)',
- '--javac-includes=<(javac_includes)',
- '--chromium-code=<(chromium_code)',
- '--jar-path=<(javac_jar_path)',
- '--jar-excluded-classes=<(jar_excluded_classes)',
- '--stamp=<(compile_stamp)',
- '>@(java_sources)',
- '<@(extra_args)',
- ]
- },
- {
- 'action_name': 'instr_jar_<(_target_name)',
- 'message': 'Instrumenting <(_target_name) jar',
- 'variables': {
- 'input_path': '<(jar_path)',
- 'output_path': '<(jar_final_path)',
- 'stamp_path': '<(instr_stamp)',
- 'instr_type': 'jar',
- },
- 'outputs': [
- '<(jar_final_path)',
- ],
- 'inputs': [
- '<(jar_path)',
- ],
- 'includes': [ 'android/instr_action.gypi' ],
- },
- {
- 'variables': {
- 'src_dirs': [
- '<(java_in_dir)<(java_in_dir_suffix)',
- '>@(additional_src_dirs)',
- ],
- 'stamp_path': '<(lint_stamp)',
- 'result_path': '<(lint_result)',
- 'config_path': '<(lint_config)',
- 'lint_jar_path': '<(jar_final_path)',
- },
- 'inputs': [
- '<(jar_final_path)',
- '<(compile_stamp)',
- ],
- 'outputs': [
- '<(lint_stamp)',
- ],
- 'includes': [ 'android/lint_action.gypi' ],
- },
- {
- 'action_name': 'jar_toc_<(_target_name)',
- 'message': 'Creating <(_target_name) jar.TOC',
- 'inputs': [
- '<(DEPTH)/build/android/gyp/util/build_utils.py',
- '<(DEPTH)/build/android/gyp/util/md5_check.py',
- '<(DEPTH)/build/android/gyp/jar_toc.py',
- '<(jar_final_path)',
- ],
- 'outputs': [
- '<(jar_final_path).TOC',
- ],
- 'action': [
- 'python', '<(DEPTH)/build/android/gyp/jar_toc.py',
- '--jar-path=<(jar_final_path)',
- '--toc-path=<(jar_final_path).TOC',
- ]
- },
- {
- 'action_name': 'dex_<(_target_name)',
- 'variables': {
- 'conditions': [
- ['emma_instrument != 0', {
- 'dex_no_locals': 1,
- }],
- ],
- 'dex_input_paths': [ '<(jar_final_path)' ],
- 'output_path': '<(dex_path)',
- },
- 'includes': [ 'android/dex_action.gypi' ],
- },
- ],
-}
diff --git a/build/java_aidl.gypi b/build/java_aidl.gypi
deleted file mode 100644
index dda2894..0000000
--- a/build/java_aidl.gypi
+++ /dev/null
@@ -1,79 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included into a target to provide a rule
-# to build Java aidl files in a consistent manner.
-#
-# To use this, create a gyp target with the following form:
-# {
-# 'target_name': 'aidl_aidl-file-name',
-# 'type': 'none',
-# 'variables': {
-# 'aidl_interface_file': '<interface-path>/<interface-file>.aidl',
-# 'aidl_import_include': '<(DEPTH)/<path-to-src-dir>',
-# },
-# 'sources': {
-# '<input-path1>/<input-file1>.aidl',
-# '<input-path2>/<input-file2>.aidl',
-# ...
-# },
-# 'includes': ['<path-to-this-file>/java_aidl.gypi'],
-# }
-#
-#
-# The generated java files will be:
-# <(PRODUCT_DIR)/lib.java/<input-file1>.java
-# <(PRODUCT_DIR)/lib.java/<input-file2>.java
-# ...
-#
-# Optional variables:
-# aidl_import_include - This should be an absolute path to your java src folder
-# that contains the classes that are imported by your aidl files.
-#
-# TODO(cjhopman): dependents need to rebuild when this target's inputs have changed.
-
-{
- 'variables': {
- 'aidl_path%': '<(android_sdk_tools)/aidl',
- 'intermediate_dir': '<(SHARED_INTERMEDIATE_DIR)/<(_target_name)/aidl',
- 'aidl_import_include%': '',
- 'additional_aidl_arguments': [],
- 'additional_aidl_input_paths': [],
- },
- 'direct_dependent_settings': {
- 'variables': {
- 'generated_src_dirs': ['<(intermediate_dir)/'],
- },
- },
- 'conditions': [
- ['aidl_import_include != ""', {
- 'variables': {
- 'additional_aidl_arguments': [ '-I<(aidl_import_include)' ],
- 'additional_aidl_input_paths': [ '<!@(find <(aidl_import_include) -name "*.java" | sort)' ],
- }
- }],
- ],
- 'rules': [
- {
- 'rule_name': 'compile_aidl',
- 'extension': 'aidl',
- 'inputs': [
- '<(android_sdk)/framework.aidl',
- '<(aidl_interface_file)',
- '<@(additional_aidl_input_paths)',
- ],
- 'outputs': [
- '<(intermediate_dir)/<(RULE_INPUT_ROOT).java',
- ],
- 'action': [
- '<(aidl_path)',
- '-p<(android_sdk)/framework.aidl',
- '-p<(aidl_interface_file)',
- '<@(additional_aidl_arguments)',
- '<(RULE_INPUT_PATH)',
- '<(intermediate_dir)/<(RULE_INPUT_ROOT).java',
- ],
- },
- ],
-}
diff --git a/build/java_apk.gypi b/build/java_apk.gypi
deleted file mode 100644
index ff837c3..0000000
--- a/build/java_apk.gypi
+++ /dev/null
@@ -1,1063 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included into a target to provide a rule
-# to build Android APKs in a consistent manner.
-#
-# To use this, create a gyp target with the following form:
-# {
-# 'target_name': 'my_package_apk',
-# 'type': 'none',
-# 'variables': {
-# 'apk_name': 'MyPackage',
-# 'java_in_dir': 'path/to/package/root',
-# 'resource_dir': 'path/to/package/root/res',
-# },
-# 'includes': ['path/to/this/gypi/file'],
-# }
-#
-# Required variables:
-# apk_name - The final apk will be named <apk_name>.apk
-# java_in_dir - The top-level java directory. The src should be in
-# <(java_in_dir)/src.
-# Optional/automatic variables:
-# additional_input_paths - These paths will be included in the 'inputs' list to
-# ensure that this target is rebuilt when one of these paths changes.
-# additional_res_packages - Package names of R.java files generated in addition
-# to the default package name defined in AndroidManifest.xml.
-# additional_src_dirs - Additional directories with .java files to be compiled
-# and included in the output of this target.
-# additional_bundled_libs - Additional libraries what will be stripped and
-# bundled in the apk.
-# asset_location - The directory where assets are located.
-# create_abi_split - Whether to create abi-based spilts. Splits
-# are supported only for minSdkVersion >= 21.
-# create_density_splits - Whether to create density-based apk splits.
-# language_splits - List of languages to create apk splits for.
-# generated_src_dirs - Same as additional_src_dirs except used for .java files
-# that are generated at build time. This should be set automatically by a
-# target's dependencies. The .java files in these directories are not
-# included in the 'inputs' list (unlike additional_src_dirs).
-# input_jars_paths - The path to jars to be included in the classpath. This
-# should be filled automatically by depending on the appropriate targets.
-# is_test_apk - Set to 1 if building a test apk. This prevents resources from
-# dependencies from being re-included.
-# native_lib_target - The target_name of the target which generates the final
-# shared library to be included in this apk. A stripped copy of the
-# library will be included in the apk.
-# resource_dir - The directory for resources.
-# shared_resources - Make a resource package that can be loaded by a different
-# application at runtime to access the package's resources.
-# R_package - A custom Java package to generate the resource file R.java in.
-# By default, the package given in AndroidManifest.xml will be used.
-# include_all_resources - Set to 1 to include all resource IDs in all generated
-# R.java files.
-# use_chromium_linker - Enable the content dynamic linker that allows sharing the
-# RELRO section of the native libraries between the different processes.
-# load_library_from_zip - When using the dynamic linker, load the library
-# directly out of the zip file.
-# use_relocation_packer - Enable relocation packing. Relies on the chromium
-# linker, so use_chromium_linker must also be enabled.
-# enable_chromium_linker_tests - Enable the content dynamic linker test support
-# code. This allows a test APK to inject a Linker.TestRunner instance at
-# runtime. Should only be used by the chromium_linker_test_apk target!!
-# never_lint - Set to 1 to not run lint on this target.
-# java_in_dir_suffix - To override the /src suffix on java_in_dir.
-# app_manifest_version_name - set the apps 'human readable' version number.
-# app_manifest_version_code - set the apps version number.
-{
- 'variables': {
- 'tested_apk_obfuscated_jar_path%': '/',
- 'tested_apk_dex_path%': '/',
- 'additional_input_paths': [],
- 'create_density_splits%': 0,
- 'language_splits': [],
- 'input_jars_paths': [],
- 'library_dexed_jars_paths': [],
- 'additional_src_dirs': [],
- 'generated_src_dirs': [],
- 'app_manifest_version_name%': '<(android_app_version_name)',
- 'app_manifest_version_code%': '<(android_app_version_code)',
- # aapt generates this proguard.txt.
- 'generated_proguard_file': '<(intermediate_dir)/proguard.txt',
- 'proguard_enabled%': 'false',
- 'proguard_flags_paths': ['<(generated_proguard_file)'],
- 'jar_name': 'chromium_apk_<(_target_name).jar',
- 'resource_dir%':'<(DEPTH)/build/android/ant/empty/res',
- 'R_package%':'',
- 'include_all_resources%': 0,
- 'additional_R_text_files': [],
- 'dependencies_res_zip_paths': [],
- 'additional_res_packages': [],
- 'additional_bundled_libs%': [],
- 'is_test_apk%': 0,
- # Allow icu data, v8 snapshots, and pak files to be loaded directly from the .apk.
- # Note: These are actually suffix matches, not necessarily extensions.
- 'extensions_to_not_compress%': '.dat,.bin,.pak',
- 'resource_input_paths': [],
- 'intermediate_dir': '<(PRODUCT_DIR)/<(_target_name)',
- 'asset_location%': '<(intermediate_dir)/assets',
- 'codegen_stamp': '<(intermediate_dir)/codegen.stamp',
- 'package_input_paths': [],
- 'ordered_libraries_file': '<(intermediate_dir)/native_libraries.json',
- 'additional_ordered_libraries_file': '<(intermediate_dir)/additional_native_libraries.json',
- 'native_libraries_template': '<(DEPTH)/base/android/java/templates/NativeLibraries.template',
- 'native_libraries_java_dir': '<(intermediate_dir)/native_libraries_java/',
- 'native_libraries_java_file': '<(native_libraries_java_dir)/NativeLibraries.java',
- 'native_libraries_java_stamp': '<(intermediate_dir)/native_libraries_java.stamp',
- 'native_libraries_template_data_dir': '<(intermediate_dir)/native_libraries/',
- 'native_libraries_template_data_file': '<(native_libraries_template_data_dir)/native_libraries_array.h',
- 'native_libraries_template_version_file': '<(native_libraries_template_data_dir)/native_libraries_version.h',
- 'compile_stamp': '<(intermediate_dir)/compile.stamp',
- 'lint_stamp': '<(intermediate_dir)/lint.stamp',
- 'lint_result': '<(intermediate_dir)/lint_result.xml',
- 'lint_config': '<(intermediate_dir)/lint_config.xml',
- 'never_lint%': 0,
- 'findbugs_stamp': '<(intermediate_dir)/findbugs.stamp',
- 'run_findbugs%': 0,
- 'java_in_dir_suffix%': '/src',
- 'instr_stamp': '<(intermediate_dir)/instr.stamp',
- 'jar_stamp': '<(intermediate_dir)/jar.stamp',
- 'obfuscate_stamp': '<(intermediate_dir)/obfuscate.stamp',
- 'pack_relocations_stamp': '<(intermediate_dir)/pack_relocations.stamp',
- 'strip_stamp': '<(intermediate_dir)/strip.stamp',
- 'stripped_libraries_dir': '<(intermediate_dir)/stripped_libraries',
- 'strip_additional_stamp': '<(intermediate_dir)/strip_additional.stamp',
- 'version_stamp': '<(intermediate_dir)/version.stamp',
- 'javac_includes': [],
- 'jar_excluded_classes': [],
- 'javac_jar_path': '<(intermediate_dir)/<(_target_name).javac.jar',
- 'jar_path': '<(PRODUCT_DIR)/lib.java/<(jar_name)',
- 'obfuscated_jar_path': '<(intermediate_dir)/obfuscated.jar',
- 'test_jar_path': '<(PRODUCT_DIR)/test.lib.java/<(apk_name).jar',
- 'dex_path': '<(intermediate_dir)/classes.dex',
- 'emma_device_jar': '<(android_sdk_root)/tools/lib/emma_device.jar',
- 'android_manifest_path%': '<(java_in_dir)/AndroidManifest.xml',
- 'split_android_manifest_path': '<(intermediate_dir)/split-manifests/<(android_app_abi)/AndroidManifest.xml',
- 'push_stamp': '<(intermediate_dir)/push.stamp',
- 'link_stamp': '<(intermediate_dir)/link.stamp',
- 'resource_zip_path': '<(intermediate_dir)/<(_target_name).resources.zip',
- 'shared_resources%': 0,
- 'final_apk_path%': '<(PRODUCT_DIR)/apks/<(apk_name).apk',
- 'final_apk_path_no_extension%': '<(PRODUCT_DIR)/apks/<(apk_name)',
- 'final_abi_split_apk_path%': '<(PRODUCT_DIR)/apks/<(apk_name)-abi-<(android_app_abi).apk',
- 'incomplete_apk_path': '<(intermediate_dir)/<(apk_name)-incomplete.apk',
- 'apk_install_record': '<(intermediate_dir)/apk_install.record.stamp',
- 'device_intermediate_dir': '/data/data/org.chromium.gyp_managed_install/<(_target_name)/<(CONFIGURATION_NAME)',
- 'symlink_script_host_path': '<(intermediate_dir)/create_symlinks.sh',
- 'symlink_script_device_path': '<(device_intermediate_dir)/create_symlinks.sh',
- 'create_standalone_apk%': 1,
- 'res_v14_skip%': 0,
- 'variables': {
- 'variables': {
- 'native_lib_target%': '',
- 'native_lib_version_name%': '',
- 'use_chromium_linker%' : 0,
- 'use_relocation_packer%' : 0,
- 'enable_chromium_linker_tests%': 0,
- 'is_test_apk%': 0,
- 'unsigned_apk_path': '<(intermediate_dir)/<(apk_name)-unsigned.apk',
- 'unsigned_abi_split_apk_path': '<(intermediate_dir)/<(apk_name)-abi-<(android_app_abi)-unsigned.apk',
- 'create_abi_split%': 0,
- },
- 'unsigned_apk_path': '<(unsigned_apk_path)',
- 'unsigned_abi_split_apk_path': '<(unsigned_abi_split_apk_path)',
- 'create_abi_split%': '<(create_abi_split)',
- 'conditions': [
- ['gyp_managed_install == 1 and native_lib_target != ""', {
- 'conditions': [
- ['create_abi_split == 0', {
- 'unsigned_standalone_apk_path': '<(intermediate_dir)/<(apk_name)-standalone-unsigned.apk',
- }, {
- 'unsigned_standalone_apk_path': '<(intermediate_dir)/<(apk_name)-abi-<(android_app_abi)-standalone-unsigned.apk',
- }],
- ],
- }, {
- 'unsigned_standalone_apk_path': '<(unsigned_apk_path)',
- }],
- ['gyp_managed_install == 1', {
- 'apk_package_native_libs_dir': '<(intermediate_dir)/libs.managed',
- }, {
- 'apk_package_native_libs_dir': '<(intermediate_dir)/libs',
- }],
- ['is_test_apk == 0 and emma_coverage != 0', {
- 'emma_instrument%': 1,
- },{
- 'emma_instrument%': 0,
- }],
- # When using abi splits, the abi split is modified by
- # gyp_managed_install rather than the main .apk
- ['create_abi_split == 1', {
- 'managed_input_apk_path': '<(unsigned_abi_split_apk_path)',
- }, {
- 'managed_input_apk_path': '<(unsigned_apk_path)',
- }],
- ],
- },
- 'native_lib_target%': '',
- 'native_lib_version_name%': '',
- 'use_chromium_linker%' : 0,
- 'load_library_from_zip%' : 0,
- 'use_relocation_packer%' : 0,
- 'enable_chromium_linker_tests%': 0,
- 'emma_instrument%': '<(emma_instrument)',
- 'apk_package_native_libs_dir': '<(apk_package_native_libs_dir)',
- 'unsigned_standalone_apk_path': '<(unsigned_standalone_apk_path)',
- 'unsigned_apk_path': '<(unsigned_apk_path)',
- 'unsigned_abi_split_apk_path': '<(unsigned_abi_split_apk_path)',
- 'create_abi_split%': '<(create_abi_split)',
- 'managed_input_apk_path': '<(managed_input_apk_path)',
- 'libchromium_android_linker': 'libchromium_android_linker.>(android_product_extension)',
- 'extra_native_libs': [],
- 'native_lib_placeholder_stamp': '<(apk_package_native_libs_dir)/<(android_app_abi)/native_lib_placeholder.stamp',
- 'native_lib_placeholders': [],
- 'main_apk_name': '<(apk_name)',
- 'enable_errorprone%': '0',
- 'errorprone_exe_path': '<(PRODUCT_DIR)/bin.java/chromium_errorprone',
- },
- # Pass the jar path to the apk's "fake" jar target. This would be better as
- # direct_dependent_settings, but a variable set by a direct_dependent_settings
- # cannot be lifted in a dependent to all_dependent_settings.
- 'all_dependent_settings': {
- 'conditions': [
- ['proguard_enabled == "true"', {
- 'variables': {
- 'proguard_enabled': 'true',
- }
- }],
- ],
- 'variables': {
- 'apk_output_jar_path': '<(jar_path)',
- 'tested_apk_obfuscated_jar_path': '<(obfuscated_jar_path)',
- 'tested_apk_dex_path': '<(dex_path)',
- },
- },
- 'conditions': [
- ['resource_dir!=""', {
- 'variables': {
- 'resource_input_paths': [ '<!@(find <(resource_dir) -name "*")' ]
- },
- }],
- ['R_package != ""', {
- 'variables': {
- # We generate R.java in package R_package (in addition to the package
- # listed in the AndroidManifest.xml, which is unavoidable).
- 'additional_res_packages': ['<(R_package)'],
- 'additional_R_text_files': ['<(intermediate_dir)/R.txt'],
- },
- }],
- ['native_lib_target != "" and component == "shared_library"', {
- 'dependencies': [
- '<(DEPTH)/build/android/setup.gyp:copy_system_libraries',
- ],
- }],
- ['use_chromium_linker == 1', {
- 'dependencies': [
- '<(DEPTH)/base/base.gyp:chromium_android_linker',
- ],
- }],
- ['enable_errorprone == 1', {
- 'dependencies': [
- '<(DEPTH)/third_party/errorprone/errorprone.gyp:chromium_errorprone',
- ],
- }],
- ['native_lib_target != ""', {
- 'variables': {
- 'conditions': [
- ['use_chromium_linker == 1', {
- 'variables': {
- 'chromium_linker_path': [
- '<(SHARED_LIB_DIR)/<(libchromium_android_linker)',
- ],
- }
- }, {
- 'variables': {
- 'chromium_linker_path': [],
- },
- }],
- ],
- 'generated_src_dirs': [ '<(native_libraries_java_dir)' ],
- 'native_libs_paths': [
- '<(SHARED_LIB_DIR)/<(native_lib_target).>(android_product_extension)',
- '<@(chromium_linker_path)'
- ],
- 'package_input_paths': [
- '<(apk_package_native_libs_dir)/<(android_app_abi)/gdbserver',
- ],
- },
- 'copies': [
- {
- # gdbserver is always copied into the APK's native libs dir. The ant
- # build scripts (apkbuilder task) will only include it in a debug
- # build.
- 'destination': '<(apk_package_native_libs_dir)/<(android_app_abi)',
- 'files': [
- '<(android_gdbserver)',
- ],
- },
- ],
- 'actions': [
- {
- 'variables': {
- 'input_libraries': [
- '<@(native_libs_paths)',
- '<@(extra_native_libs)',
- ],
- },
- 'includes': ['../build/android/write_ordered_libraries.gypi'],
- },
- {
- 'action_name': 'native_libraries_<(_target_name)',
- 'variables': {
- 'conditions': [
- ['use_chromium_linker == 1', {
- 'variables': {
- 'linker_gcc_preprocess_defines': [
- '--defines', 'ENABLE_CHROMIUM_LINKER',
- ],
- }
- }, {
- 'variables': {
- 'linker_gcc_preprocess_defines': [],
- },
- }],
- ['load_library_from_zip == 1', {
- 'variables': {
- 'linker_load_from_zip_file_preprocess_defines': [
- '--defines', 'ENABLE_CHROMIUM_LINKER_LIBRARY_IN_ZIP_FILE',
- ],
- }
- }, {
- 'variables': {
- 'linker_load_from_zip_file_preprocess_defines': [],
- },
- }],
- ['enable_chromium_linker_tests == 1', {
- 'variables': {
- 'linker_tests_gcc_preprocess_defines': [
- '--defines', 'ENABLE_CHROMIUM_LINKER_TESTS',
- ],
- }
- }, {
- 'variables': {
- 'linker_tests_gcc_preprocess_defines': [],
- },
- }],
- ],
- 'gcc_preprocess_defines': [
- '<@(linker_load_from_zip_file_preprocess_defines)',
- '<@(linker_gcc_preprocess_defines)',
- '<@(linker_tests_gcc_preprocess_defines)',
- ],
- },
- 'message': 'Creating NativeLibraries.java for <(_target_name)',
- 'inputs': [
- '<(DEPTH)/build/android/gyp/util/build_utils.py',
- '<(DEPTH)/build/android/gyp/gcc_preprocess.py',
- '<(ordered_libraries_file)',
- '<(native_libraries_template)',
- ],
- 'outputs': [
- '<(native_libraries_java_stamp)',
- ],
- 'action': [
- 'python', '<(DEPTH)/build/android/gyp/gcc_preprocess.py',
- '--include-path=',
- '--output=<(native_libraries_java_file)',
- '--template=<(native_libraries_template)',
- '--stamp=<(native_libraries_java_stamp)',
- '--defines', 'NATIVE_LIBRARIES_LIST=@FileArg(<(ordered_libraries_file):java_libraries_list)',
- '--defines', 'NATIVE_LIBRARIES_VERSION_NUMBER="<(native_lib_version_name)"',
- '<@(gcc_preprocess_defines)',
- ],
- },
- {
- 'action_name': 'strip_native_libraries',
- 'variables': {
- 'ordered_libraries_file%': '<(ordered_libraries_file)',
- 'stripped_libraries_dir%': '<(stripped_libraries_dir)',
- 'input_paths': [
- '<@(native_libs_paths)',
- '<@(extra_native_libs)',
- ],
- 'stamp': '<(strip_stamp)'
- },
- 'includes': ['../build/android/strip_native_libraries.gypi'],
- },
- {
- 'action_name': 'insert_chromium_version',
- 'variables': {
- 'ordered_libraries_file%': '<(ordered_libraries_file)',
- 'stripped_libraries_dir%': '<(stripped_libraries_dir)',
- 'version_string': '<(native_lib_version_name)',
- 'input_paths': [
- '<(strip_stamp)',
- ],
- 'stamp': '<(version_stamp)'
- },
- 'includes': ['../build/android/insert_chromium_version.gypi'],
- },
- {
- 'action_name': 'pack_relocations',
- 'variables': {
- 'conditions': [
- ['use_chromium_linker == 1 and use_relocation_packer == 1 and profiling != 1', {
- 'enable_packing': 1,
- }, {
- 'enable_packing': 0,
- }],
- ],
- 'exclude_packing_list': [
- '<(libchromium_android_linker)',
- ],
- 'ordered_libraries_file%': '<(ordered_libraries_file)',
- 'stripped_libraries_dir%': '<(stripped_libraries_dir)',
- 'packed_libraries_dir': '<(libraries_source_dir)',
- 'input_paths': [
- '<(version_stamp)'
- ],
- 'stamp': '<(pack_relocations_stamp)',
- },
- 'includes': ['../build/android/pack_relocations.gypi'],
- },
- {
- 'variables': {
- 'input_libraries': [
- '<@(additional_bundled_libs)',
- ],
- 'ordered_libraries_file': '<(additional_ordered_libraries_file)',
- 'subtarget': '_additional_libraries',
- },
- 'includes': ['../build/android/write_ordered_libraries.gypi'],
- },
- {
- 'action_name': 'strip_additional_libraries',
- 'variables': {
- 'ordered_libraries_file': '<(additional_ordered_libraries_file)',
- 'stripped_libraries_dir': '<(libraries_source_dir)',
- 'input_paths': [
- '<@(additional_bundled_libs)',
- '<(strip_stamp)',
- ],
- 'stamp': '<(strip_additional_stamp)'
- },
- 'includes': ['../build/android/strip_native_libraries.gypi'],
- },
- {
- 'action_name': 'Create native lib placeholder files for previous releases',
- 'variables': {
- 'placeholders': ['<@(native_lib_placeholders)'],
- 'conditions': [
- ['gyp_managed_install == 1', {
- # This "library" just needs to be put in the .apk. It is not loaded
- # at runtime.
- 'placeholders': ['libfix.crbug.384638.so'],
- }]
- ],
- },
- 'inputs': [
- '<(DEPTH)/build/android/gyp/create_placeholder_files.py',
- ],
- 'outputs': [
- '<(native_lib_placeholder_stamp)',
- ],
- 'action': [
- 'python', '<(DEPTH)/build/android/gyp/create_placeholder_files.py',
- '--dest-lib-dir=<(apk_package_native_libs_dir)/<(android_app_abi)/',
- '--stamp=<(native_lib_placeholder_stamp)',
- '<@(placeholders)',
- ],
- },
- ],
- 'conditions': [
- ['gyp_managed_install == 1', {
- 'variables': {
- 'libraries_top_dir': '<(intermediate_dir)/lib.stripped',
- 'libraries_source_dir': '<(libraries_top_dir)/lib/<(android_app_abi)',
- 'device_library_dir': '<(device_intermediate_dir)/lib.stripped',
- 'configuration_name': '<(CONFIGURATION_NAME)',
- },
- 'dependencies': [
- '<(DEPTH)/build/android/setup.gyp:get_build_device_configurations',
- '<(DEPTH)/build/android/pylib/device/commands/commands.gyp:chromium_commands',
- ],
- 'actions': [
- {
- 'includes': ['../build/android/push_libraries.gypi'],
- },
- {
- 'action_name': 'create device library symlinks',
- 'message': 'Creating links on device for <(_target_name)',
- 'inputs': [
- '<(DEPTH)/build/android/gyp/util/build_utils.py',
- '<(DEPTH)/build/android/gyp/create_device_library_links.py',
- '<(apk_install_record)',
- '<(build_device_config_path)',
- '<(ordered_libraries_file)',
- ],
- 'outputs': [
- '<(link_stamp)'
- ],
- 'action': [
- 'python', '<(DEPTH)/build/android/gyp/create_device_library_links.py',
- '--build-device-configuration=<(build_device_config_path)',
- '--libraries=@FileArg(<(ordered_libraries_file):libraries)',
- '--script-host-path=<(symlink_script_host_path)',
- '--script-device-path=<(symlink_script_device_path)',
- '--target-dir=<(device_library_dir)',
- '--apk=<(incomplete_apk_path)',
- '--stamp=<(link_stamp)',
- '--configuration-name=<(CONFIGURATION_NAME)',
- ],
- },
- ],
- 'conditions': [
- ['create_standalone_apk == 1', {
- 'actions': [
- {
- 'action_name': 'create standalone APK',
- 'variables': {
- 'inputs': [
- '<(ordered_libraries_file)',
- '<(strip_additional_stamp)',
- '<(pack_relocations_stamp)',
- ],
- 'output_apk_path': '<(unsigned_standalone_apk_path)',
- 'libraries_top_dir%': '<(libraries_top_dir)',
- 'input_apk_path': '<(managed_input_apk_path)',
- },
- 'includes': [ 'android/create_standalone_apk_action.gypi' ],
- },
- ],
- }],
- ],
- }, {
- # gyp_managed_install != 1
- 'variables': {
- 'libraries_source_dir': '<(apk_package_native_libs_dir)/<(android_app_abi)',
- 'package_input_paths': [
- '<(strip_additional_stamp)',
- '<(pack_relocations_stamp)',
- ],
- },
- }],
- ],
- }], # native_lib_target != ''
- ['gyp_managed_install == 0 or create_standalone_apk == 1 or create_abi_split == 1', {
- 'dependencies': [
- '<(DEPTH)/build/android/rezip.gyp:rezip_apk_jar',
- ],
- }],
- ['create_abi_split == 1 or gyp_managed_install == 0 or create_standalone_apk == 1', {
- 'actions': [
- {
- 'action_name': 'finalize_base',
- 'variables': {
- 'output_apk_path': '<(final_apk_path)',
- 'conditions': [
- ['create_abi_split == 0', {
- 'input_apk_path': '<(unsigned_standalone_apk_path)',
- }, {
- 'input_apk_path': '<(unsigned_apk_path)',
- 'load_library_from_zip': 0,
- }]
- ],
- },
- 'includes': [ 'android/finalize_apk_action.gypi']
- },
- ],
- }],
- ['create_abi_split == 1', {
- 'actions': [
- {
- 'action_name': 'generate_split_manifest_<(_target_name)',
- 'inputs': [
- '<(DEPTH)/build/android/gyp/util/build_utils.py',
- '<(DEPTH)/build/android/gyp/generate_split_manifest.py',
- '<(android_manifest_path)',
- ],
- 'outputs': [
- '<(split_android_manifest_path)',
- ],
- 'action': [
- 'python', '<(DEPTH)/build/android/gyp/generate_split_manifest.py',
- '--main-manifest', '<(android_manifest_path)',
- '--out-manifest', '<(split_android_manifest_path)',
- '--split', 'abi_<(android_app_abi)',
- ],
- },
- {
- 'variables': {
- 'apk_name': '<(main_apk_name)-abi-<(android_app_abi)',
- 'asset_location': '',
- 'android_manifest_path': '<(split_android_manifest_path)',
- 'create_density_splits': 0,
- 'language_splits=': [],
- },
- 'includes': [ 'android/package_resources_action.gypi' ],
- },
- {
- 'variables': {
- 'apk_name': '<(main_apk_name)-abi-<(android_app_abi)',
- 'apk_path': '<(unsigned_abi_split_apk_path)',
- 'has_code': 0,
- 'native_libs_dir': '<(apk_package_native_libs_dir)',
- 'extra_inputs': ['<(native_lib_placeholder_stamp)'],
- },
- 'includes': ['android/apkbuilder_action.gypi'],
- },
- ],
- }],
- ['create_abi_split == 1 and (gyp_managed_install == 0 or create_standalone_apk == 1)', {
- 'actions': [
- {
- 'action_name': 'finalize_split',
- 'variables': {
- 'output_apk_path': '<(final_abi_split_apk_path)',
- 'conditions': [
- ['gyp_managed_install == 1', {
- 'input_apk_path': '<(unsigned_standalone_apk_path)',
- }, {
- 'input_apk_path': '<(unsigned_abi_split_apk_path)',
- }],
- ],
- },
- 'includes': [ 'android/finalize_apk_action.gypi']
- },
- ],
- }],
- ['gyp_managed_install == 1', {
- 'actions': [
- {
- 'action_name': 'finalize incomplete apk',
- 'variables': {
- 'load_library_from_zip': 0,
- 'input_apk_path': '<(managed_input_apk_path)',
- 'output_apk_path': '<(incomplete_apk_path)',
- },
- 'includes': [ 'android/finalize_apk_action.gypi']
- },
- {
- 'action_name': 'apk_install_<(_target_name)',
- 'message': 'Installing <(apk_name).apk',
- 'inputs': [
- '<(DEPTH)/build/android/gyp/util/build_utils.py',
- '<(DEPTH)/build/android/gyp/apk_install.py',
- '<(build_device_config_path)',
- '<(incomplete_apk_path)',
- ],
- 'outputs': [
- '<(apk_install_record)',
- ],
- 'action': [
- 'python', '<(DEPTH)/build/android/gyp/apk_install.py',
- '--build-device-configuration=<(build_device_config_path)',
- '--install-record=<(apk_install_record)',
- '--configuration-name=<(CONFIGURATION_NAME)',
- '--android-sdk-tools', '<(android_sdk_tools)',
- ],
- 'conditions': [
- ['create_abi_split == 1', {
- 'inputs': [
- '<(final_apk_path)',
- ],
- 'action': [
- '--apk-path=<(final_apk_path)',
- '--split-apk-path=<(incomplete_apk_path)',
- ],
- }, {
- 'action': [
- '--apk-path=<(incomplete_apk_path)',
- ],
- }],
- ['create_density_splits == 1', {
- 'inputs': [
- '<(final_apk_path_no_extension)-density-hdpi.apk',
- '<(final_apk_path_no_extension)-density-xhdpi.apk',
- '<(final_apk_path_no_extension)-density-xxhdpi.apk',
- '<(final_apk_path_no_extension)-density-xxxhdpi.apk',
- '<(final_apk_path_no_extension)-density-tvdpi.apk',
- ],
- 'action': [
- '--split-apk-path=<(final_apk_path_no_extension)-density-hdpi.apk',
- '--split-apk-path=<(final_apk_path_no_extension)-density-xhdpi.apk',
- '--split-apk-path=<(final_apk_path_no_extension)-density-xxhdpi.apk',
- '--split-apk-path=<(final_apk_path_no_extension)-density-xxxhdpi.apk',
- '--split-apk-path=<(final_apk_path_no_extension)-density-tvdpi.apk',
- ],
- }],
- ['language_splits != []', {
- 'inputs': [
- "<!@(python <(DEPTH)/build/apply_locales.py '<(final_apk_path_no_extension)-lang-ZZLOCALE.apk' <(language_splits))",
- ],
- 'action': [
- "<!@(python <(DEPTH)/build/apply_locales.py -- '--split-apk-path=<(final_apk_path_no_extension)-lang-ZZLOCALE.apk' <(language_splits))",
- ],
- }],
- ],
- },
- ],
- }],
- ['create_density_splits == 1', {
- 'actions': [
- {
- 'action_name': 'finalize_density_splits',
- 'variables': {
- 'density_splits': 1,
- },
- 'includes': [ 'android/finalize_splits_action.gypi']
- },
- ],
- }],
- ['is_test_apk == 1', {
- 'dependencies': [
- '<(DEPTH)/build/android/pylib/device/commands/commands.gyp:chromium_commands',
- '<(DEPTH)/tools/android/android_tools.gyp:android_tools',
- ]
- }],
- ['run_findbugs == 1', {
- 'actions': [
- {
- 'action_name': 'findbugs_<(_target_name)',
- 'message': 'Running findbugs on <(_target_name)',
- 'inputs': [
- '<(DEPTH)/build/android/findbugs_diff.py',
- '<(DEPTH)/build/android/findbugs_filter/findbugs_exclude.xml',
- '<(DEPTH)/build/android/pylib/utils/findbugs.py',
- '>@(input_jars_paths)',
- '<(jar_path)',
- '<(compile_stamp)',
- ],
- 'outputs': [
- '<(findbugs_stamp)',
- ],
- 'action': [
- 'python', '<(DEPTH)/build/android/findbugs_diff.py',
- '--auxclasspath-gyp', '>(input_jars_paths)',
- '--stamp', '<(findbugs_stamp)',
- '<(jar_path)',
- ],
- },
- ],
- },
- ]
- ],
- 'dependencies': [
- '<(DEPTH)/tools/android/md5sum/md5sum.gyp:md5sum',
- ],
- 'actions': [
- {
- 'action_name': 'process_resources',
- 'message': 'processing resources for <(_target_name)',
- 'variables': {
- # Write the inputs list to a file, so that its mtime is updated when
- # the list of inputs changes.
- 'inputs_list_file': '>|(apk_codegen.<(_target_name).gypcmd >@(additional_input_paths) >@(resource_input_paths))',
- 'process_resources_options': [],
- 'conditions': [
- ['is_test_apk == 1', {
- 'dependencies_res_zip_paths=': [],
- 'additional_res_packages=': [],
- }],
- ['res_v14_skip == 1', {
- 'process_resources_options+': ['--v14-skip']
- }],
- ['shared_resources == 1', {
- 'process_resources_options+': ['--shared-resources']
- }],
- ['R_package != ""', {
- 'process_resources_options+': ['--custom-package', '<(R_package)']
- }],
- ['include_all_resources == 1', {
- 'process_resources_options+': ['--include-all-resources']
- }]
- ],
- },
- 'inputs': [
- '<(DEPTH)/build/android/gyp/util/build_utils.py',
- '<(DEPTH)/build/android/gyp/process_resources.py',
- '<(android_manifest_path)',
- '>@(additional_input_paths)',
- '>@(resource_input_paths)',
- '>@(dependencies_res_zip_paths)',
- '>(inputs_list_file)',
- ],
- 'outputs': [
- '<(resource_zip_path)',
- '<(generated_proguard_file)',
- '<(codegen_stamp)',
- ],
- 'action': [
- 'python', '<(DEPTH)/build/android/gyp/process_resources.py',
- '--android-sdk', '<(android_sdk)',
- '--aapt-path', '<(android_aapt_path)',
-
- '--android-manifest', '<(android_manifest_path)',
- '--dependencies-res-zips', '>(dependencies_res_zip_paths)',
-
- '--extra-res-packages', '>(additional_res_packages)',
- '--extra-r-text-files', '>(additional_R_text_files)',
-
- '--proguard-file', '<(generated_proguard_file)',
-
- '--resource-dirs', '<(resource_dir)',
- '--resource-zip-out', '<(resource_zip_path)',
-
- '--R-dir', '<(intermediate_dir)/gen',
-
- '--stamp', '<(codegen_stamp)',
-
- '<@(process_resources_options)',
- ],
- },
- {
- 'action_name': 'javac_<(_target_name)',
- 'message': 'Compiling java for <(_target_name)',
- 'variables': {
- 'extra_args': [],
- 'extra_inputs': [],
- 'gen_src_dirs': [
- '<(intermediate_dir)/gen',
- '>@(generated_src_dirs)',
- ],
- # If there is a separate find for additional_src_dirs, it will find the
- # wrong .java files when additional_src_dirs is empty.
- # TODO(thakis): Gyp caches >! evaluation by command. Both java.gypi and
- # java_apk.gypi evaluate the same command, and at the moment two targets
- # set java_in_dir to "java". Add a dummy comment here to make sure
- # that the two targets (one uses java.gypi, the other java_apk.gypi)
- # get distinct source lists. Medium-term, make targets list all their
- # Java files instead of using find. (As is, this will be broken if two
- # targets use the same java_in_dir and both use java_apk.gypi or
- # both use java.gypi.)
- 'java_sources': ['>!@(find >(java_in_dir)>(java_in_dir_suffix) >(additional_src_dirs) -name "*.java" # apk)'],
- 'conditions': [
- ['enable_errorprone == 1', {
- 'extra_inputs': [
- '<(errorprone_exe_path)',
- ],
- 'extra_args': [ '--use-errorprone-path=<(errorprone_exe_path)' ],
- }],
- ],
- },
- 'inputs': [
- '<(DEPTH)/build/android/gyp/util/build_utils.py',
- '<(DEPTH)/build/android/gyp/javac.py',
- '>@(java_sources)',
- '>@(input_jars_paths)',
- '<(codegen_stamp)',
- '<@(extra_inputs)',
- ],
- 'conditions': [
- ['native_lib_target != ""', {
- 'inputs': [ '<(native_libraries_java_stamp)' ],
- }],
- ],
- 'outputs': [
- '<(compile_stamp)',
- '<(javac_jar_path)',
- ],
- 'action': [
- 'python', '<(DEPTH)/build/android/gyp/javac.py',
- '--bootclasspath=<(android_sdk_jar)',
- '--classpath=>(input_jars_paths) <(android_sdk_jar)',
- '--src-gendirs=>(gen_src_dirs)',
- '--javac-includes=<(javac_includes)',
- '--chromium-code=<(chromium_code)',
- '--jar-path=<(javac_jar_path)',
- '--jar-excluded-classes=<(jar_excluded_classes)',
- '--stamp=<(compile_stamp)',
- '<@(extra_args)',
- '>@(java_sources)',
- ],
- },
- {
- 'action_name': 'instr_jar_<(_target_name)',
- 'message': 'Instrumenting <(_target_name) jar',
- 'variables': {
- 'input_path': '<(javac_jar_path)',
- 'output_path': '<(jar_path)',
- 'stamp_path': '<(instr_stamp)',
- 'instr_type': 'jar',
- },
- 'outputs': [
- '<(instr_stamp)',
- '<(jar_path)',
- ],
- 'inputs': [
- '<(javac_jar_path)',
- ],
- 'includes': [ 'android/instr_action.gypi' ],
- },
- {
- 'variables': {
- 'src_dirs': [
- '<(java_in_dir)<(java_in_dir_suffix)',
- '>@(additional_src_dirs)',
- ],
- 'lint_jar_path': '<(jar_path)',
- 'stamp_path': '<(lint_stamp)',
- 'result_path': '<(lint_result)',
- 'config_path': '<(lint_config)',
- },
- 'outputs': [
- '<(lint_stamp)',
- ],
- 'includes': [ 'android/lint_action.gypi' ],
- },
- {
- 'action_name': 'obfuscate_<(_target_name)',
- 'message': 'Obfuscating <(_target_name)',
- 'variables': {
- 'additional_obfuscate_options': [],
- 'additional_obfuscate_input_paths': [],
- 'proguard_out_dir': '<(intermediate_dir)/proguard',
- 'proguard_input_jar_paths': [
- '>@(input_jars_paths)',
- '<(jar_path)',
- ],
- 'target_conditions': [
- ['is_test_apk == 1', {
- 'additional_obfuscate_options': [
- '--testapp',
- ],
- }],
- ['is_test_apk == 1 and tested_apk_obfuscated_jar_path != "/"', {
- 'additional_obfuscate_options': [
- '--tested-apk-obfuscated-jar-path', '>(tested_apk_obfuscated_jar_path)',
- ],
- 'additional_obfuscate_input_paths': [
- '>(tested_apk_obfuscated_jar_path).info',
- ],
- }],
- ['proguard_enabled == "true"', {
- 'additional_obfuscate_options': [
- '--proguard-enabled',
- ],
- }],
- ],
- 'obfuscate_input_jars_paths': [
- '>@(input_jars_paths)',
- '<(jar_path)',
- ],
- },
- 'conditions': [
- ['is_test_apk == 1', {
- 'outputs': [
- '<(test_jar_path)',
- ],
- }],
- ],
- 'inputs': [
- '<(DEPTH)/build/android/gyp/apk_obfuscate.py',
- '<(DEPTH)/build/android/gyp/util/build_utils.py',
- '>@(proguard_flags_paths)',
- '>@(obfuscate_input_jars_paths)',
- '>@(additional_obfuscate_input_paths)',
- '<(instr_stamp)',
- ],
- 'outputs': [
- '<(obfuscate_stamp)',
-
- # In non-Release builds, these paths will all be empty files.
- '<(obfuscated_jar_path)',
- '<(obfuscated_jar_path).info',
- '<(obfuscated_jar_path).dump',
- '<(obfuscated_jar_path).seeds',
- '<(obfuscated_jar_path).mapping',
- '<(obfuscated_jar_path).usage',
- ],
- 'action': [
- 'python', '<(DEPTH)/build/android/gyp/apk_obfuscate.py',
-
- '--configuration-name', '<(CONFIGURATION_NAME)',
-
- '--android-sdk', '<(android_sdk)',
- '--android-sdk-tools', '<(android_sdk_tools)',
- '--android-sdk-jar', '<(android_sdk_jar)',
-
- '--input-jars-paths=>(proguard_input_jar_paths)',
- '--proguard-configs=>(proguard_flags_paths)',
-
- '--test-jar-path', '<(test_jar_path)',
- '--obfuscated-jar-path', '<(obfuscated_jar_path)',
-
- '--proguard-jar-path', '<(android_sdk_root)/tools/proguard/lib/proguard.jar',
-
- '--stamp', '<(obfuscate_stamp)',
-
- '>@(additional_obfuscate_options)',
- ],
- },
- {
- 'action_name': 'dex_<(_target_name)',
- 'variables': {
- 'dex_input_paths': [
- '>@(library_dexed_jars_paths)',
- '<(jar_path)',
- ],
- 'output_path': '<(dex_path)',
- 'proguard_enabled_input_path': '<(obfuscated_jar_path)',
- },
- 'target_conditions': [
- ['emma_instrument != 0', {
- 'variables': {
- 'dex_no_locals': 1,
- 'dex_input_paths': [
- '<(emma_device_jar)'
- ],
- },
- }],
- ['is_test_apk == 1 and tested_apk_dex_path != "/"', {
- 'variables': {
- 'dex_additional_options': [
- '--excluded-paths', '@FileArg(>(tested_apk_dex_path).inputs)'
- ],
- },
- 'inputs': [
- '>(tested_apk_dex_path).inputs',
- ],
- }],
- ['proguard_enabled == "true"', {
- 'inputs': [ '<(obfuscate_stamp)' ]
- }, {
- 'inputs': [ '<(instr_stamp)' ]
- }],
- ],
- 'includes': [ 'android/dex_action.gypi' ],
- },
- {
- 'variables': {
- 'extra_inputs': ['<(codegen_stamp)'],
- 'resource_zips': [
- '<(resource_zip_path)',
- ],
- 'conditions': [
- ['is_test_apk == 0', {
- 'resource_zips': [
- '>@(dependencies_res_zip_paths)',
- ],
- }],
- ],
- },
- 'includes': [ 'android/package_resources_action.gypi' ],
- },
- {
- 'variables': {
- 'apk_path': '<(unsigned_apk_path)',
- 'conditions': [
- ['native_lib_target != ""', {
- 'extra_inputs': ['<(native_lib_placeholder_stamp)'],
- }],
- ['create_abi_split == 0', {
- 'native_libs_dir': '<(apk_package_native_libs_dir)',
- }, {
- 'native_libs_dir': '<(DEPTH)/build/android/ant/empty/res',
- }],
- ],
- },
- 'includes': ['android/apkbuilder_action.gypi'],
- },
- ],
-}
diff --git a/build/java_prebuilt.gypi b/build/java_prebuilt.gypi
deleted file mode 100644
index 8efc4ef..0000000
--- a/build/java_prebuilt.gypi
+++ /dev/null
@@ -1,102 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included into a target to provide a rule
-# to package prebuilt Java JARs in a consistent manner.
-#
-# To use this, create a gyp target with the following form:
-# {
-# 'target_name': 'my-package_java',
-# 'type': 'none',
-# 'variables': {
-# 'jar_path': 'path/to/your.jar',
-# },
-# 'includes': ['path/to/this/gypi/file'],
-# }
-#
-# Required variables:
-# jar_path - The path to the prebuilt Java JAR file.
-
-{
- 'dependencies': [
- '<(DEPTH)/build/android/setup.gyp:build_output_dirs'
- ],
- 'variables': {
- 'dex_path': '<(PRODUCT_DIR)/lib.java/<(_target_name).dex.jar',
- 'intermediate_dir': '<(SHARED_INTERMEDIATE_DIR)/<(_target_name)',
- 'android_jar': '<(android_sdk)/android.jar',
- 'input_jars_paths': [ '<(android_jar)' ],
- 'neverlink%': 0,
- 'proguard_config%': '',
- 'proguard_preprocess%': '0',
- 'variables': {
- 'variables': {
- 'proguard_preprocess%': 0,
- },
- 'conditions': [
- ['proguard_preprocess == 1', {
- 'dex_input_jar_path': '<(intermediate_dir)/<(_target_name).pre.jar'
- }, {
- 'dex_input_jar_path': '<(jar_path)'
- }],
- ],
- },
- 'dex_input_jar_path': '<(dex_input_jar_path)',
- },
- 'all_dependent_settings': {
- 'variables': {
- 'input_jars_paths': ['<(dex_input_jar_path)'],
- 'conditions': [
- ['neverlink == 1', {
- 'library_dexed_jars_paths': [],
- }, {
- 'library_dexed_jars_paths': ['<(dex_path)'],
- }],
- ],
- },
- },
- 'conditions' : [
- ['proguard_preprocess == 1', {
- 'actions': [
- {
- 'action_name': 'proguard_<(_target_name)',
- 'message': 'Proguard preprocessing <(_target_name) jar',
- 'inputs': [
- '<(android_sdk_root)/tools/proguard/lib/proguard.jar',
- '<(DEPTH)/build/android/gyp/util/build_utils.py',
- '<(DEPTH)/build/android/gyp/proguard.py',
- '<(jar_path)',
- '<(proguard_config)',
- ],
- 'outputs': [
- '<(dex_input_jar_path)',
- ],
- 'action': [
- 'python', '<(DEPTH)/build/android/gyp/proguard.py',
- '--proguard-path=<(android_sdk_root)/tools/proguard/lib/proguard.jar',
- '--input-path=<(jar_path)',
- '--output-path=<(dex_input_jar_path)',
- '--proguard-config=<(proguard_config)',
- '--classpath=>(input_jars_paths)',
- ]
- },
- ],
- }],
- ['neverlink == 0', {
- 'actions': [
- {
- 'action_name': 'dex_<(_target_name)',
- 'message': 'Dexing <(_target_name) jar',
- 'variables': {
- 'dex_input_paths': [
- '<(dex_input_jar_path)',
- ],
- 'output_path': '<(dex_path)',
- },
- 'includes': [ 'android/dex_action.gypi' ],
- },
- ],
- }],
- ],
-}
diff --git a/build/java_strings_grd.gypi b/build/java_strings_grd.gypi
deleted file mode 100644
index 7534be5..0000000
--- a/build/java_strings_grd.gypi
+++ /dev/null
@@ -1,62 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included into a target to provide a rule
-# to generate localized strings.xml from a grd file.
-#
-# To use this, create a gyp target with the following form:
-# {
-# 'target_name': 'my-package_strings_grd',
-# 'type': 'none',
-# 'variables': {
-# 'grd_file': 'path/to/grd/file',
-# },
-# 'includes': ['path/to/this/gypi/file'],
-# }
-#
-# Required variables:
-# grd_file - The path to the grd file to use.
-{
- 'variables': {
- 'res_grit_dir': '<(INTERMEDIATE_DIR)/<(_target_name)/res_grit',
- 'grit_grd_file': '<(grd_file)',
- 'resource_zip_path': '<(PRODUCT_DIR)/res.java/<(_target_name).zip',
- 'grit_additional_defines': ['-E', 'ANDROID_JAVA_TAGGED_ONLY=false'],
- 'grit_out_dir': '<(res_grit_dir)',
- # resource_ids is unneeded since we don't generate .h headers.
- 'grit_resource_ids': '',
- 'grit_outputs': [
- '<!@pymod_do_main(grit_info <@(grit_defines) <@(grit_additional_defines) '
- '--outputs \'<(grit_out_dir)\' '
- '<(grit_grd_file) -f "<(grit_resource_ids)")',
- ]
- },
- 'all_dependent_settings': {
- 'variables': {
- 'additional_input_paths': ['<(resource_zip_path)'],
- 'dependencies_res_zip_paths': ['<(resource_zip_path)'],
- },
- },
- 'actions': [
- {
- 'action_name': 'generate_localized_strings_xml',
- 'includes': ['../build/grit_action.gypi'],
- },
- {
- 'action_name': 'create_resources_zip',
- 'inputs': [
- '<(DEPTH)/build/android/gyp/zip.py',
- '<@(grit_outputs)',
- ],
- 'outputs': [
- '<(resource_zip_path)',
- ],
- 'action': [
- 'python', '<(DEPTH)/build/android/gyp/zip.py',
- '--input-dir', '<(res_grit_dir)',
- '--output', '<(resource_zip_path)',
- ],
- }
- ],
-}
diff --git a/build/jni_generator.gypi b/build/jni_generator.gypi
deleted file mode 100644
index 7a9e333..0000000
--- a/build/jni_generator.gypi
+++ /dev/null
@@ -1,87 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included into a target to provide a rule
-# to generate jni bindings for Java-files in a consistent manner.
-#
-# To use this, create a gyp target with the following form:
-# {
-# 'target_name': 'base_jni_headers',
-# 'type': 'none',
-# 'sources': [
-# 'android/java/src/org/chromium/base/BuildInfo.java',
-# ...
-# ...
-# 'android/java/src/org/chromium/base/SystemMessageHandler.java',
-# ],
-# 'variables': {
-# 'jni_gen_package': 'base',
-# },
-# 'includes': [ '../build/jni_generator.gypi' ],
-# },
-#
-# The generated file name pattern can be seen on the "outputs" section below.
-# (note that RULE_INPUT_ROOT is the basename for the java file).
-#
-# See base/android/jni_generator/jni_generator.py for more info about the
-# format of generating JNI bindings.
-
-{
- 'variables': {
- 'jni_generator': '<(DEPTH)/base/android/jni_generator/jni_generator.py',
- 'jni_generator_jarjar_file%': '',
- 'jni_generator_ptr_type%': 'long',
- # A comma separated string of include files.
- 'jni_generator_includes%': (
- 'base/android/jni_generator/jni_generator_helper.h'
- ),
- 'native_exports%': '--native_exports_optional',
- },
- 'rules': [
- {
- 'rule_name': 'generate_jni_headers',
- 'extension': 'java',
- 'inputs': [
- '<(jni_generator)',
- ],
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/<(jni_gen_package)/jni/<(RULE_INPUT_ROOT)_jni.h',
- ],
- 'action': [
- '<(jni_generator)',
- '--input_file',
- '<(RULE_INPUT_PATH)',
- '--output_dir',
- '<(SHARED_INTERMEDIATE_DIR)/<(jni_gen_package)/jni',
- '--includes',
- '<(jni_generator_includes)',
- '--optimize_generation',
- '<(optimize_jni_generation)',
- '--jarjar',
- '<(jni_generator_jarjar_file)',
- '--ptr_type',
- '<(jni_generator_ptr_type)',
- '<(native_exports)',
- ],
- 'message': 'Generating JNI bindings from <(RULE_INPUT_PATH)',
- 'process_outputs_as_sources': 1,
- 'conditions': [
- ['jni_generator_jarjar_file != ""', {
- 'inputs': [
- '<(jni_generator_jarjar_file)',
- ],
- }]
- ],
- },
- ],
- 'direct_dependent_settings': {
- 'include_dirs': [
- '<(SHARED_INTERMEDIATE_DIR)/<(jni_gen_package)',
- ],
- },
- # This target exports a hard dependency because it generates header
- # files.
- 'hard_dependency': 1,
-}
-
diff --git a/build/landmine_utils.py b/build/landmine_utils.py
deleted file mode 100644
index 6d18b6d..0000000
--- a/build/landmine_utils.py
+++ /dev/null
@@ -1,120 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-
-import functools
-import logging
-import os
-import shlex
-import sys
-
-
-def memoize(default=None):
- """This decorator caches the return value of a parameterless pure function"""
- def memoizer(func):
- val = []
- @functools.wraps(func)
- def inner():
- if not val:
- ret = func()
- val.append(ret if ret is not None else default)
- if logging.getLogger().isEnabledFor(logging.INFO):
- print '%s -> %r' % (func.__name__, val[0])
- return val[0]
- return inner
- return memoizer
-
-
-@memoize()
-def IsWindows():
- return sys.platform in ['win32', 'cygwin']
-
-
-@memoize()
-def IsLinux():
- return sys.platform.startswith(('linux', 'freebsd', 'openbsd'))
-
-
-@memoize()
-def IsMac():
- return sys.platform == 'darwin'
-
-
-@memoize()
-def gyp_defines():
- """Parses and returns GYP_DEFINES env var as a dictionary."""
- return dict(arg.split('=', 1)
- for arg in shlex.split(os.environ.get('GYP_DEFINES', '')))
-
-@memoize()
-def gyp_generator_flags():
- """Parses and returns GYP_GENERATOR_FLAGS env var as a dictionary."""
- return dict(arg.split('=', 1)
- for arg in shlex.split(os.environ.get('GYP_GENERATOR_FLAGS', '')))
-
-@memoize()
-def gyp_msvs_version():
- return os.environ.get('GYP_MSVS_VERSION', '')
-
-@memoize()
-def distributor():
- """
- Returns a string which is the distributed build engine in use (if any).
- Possible values: 'goma', 'ib', ''
- """
- if 'goma' in gyp_defines():
- return 'goma'
- elif IsWindows():
- if 'CHROME_HEADLESS' in os.environ:
- return 'ib' # use (win and !goma and headless) as approximation of ib
-
-
-@memoize()
-def platform():
- """
- Returns a string representing the platform this build is targetted for.
- Possible values: 'win', 'mac', 'linux', 'ios', 'android'
- """
- if 'OS' in gyp_defines():
- if 'android' in gyp_defines()['OS']:
- return 'android'
- else:
- return gyp_defines()['OS']
- elif IsWindows():
- return 'win'
- elif IsLinux():
- return 'linux'
- else:
- return 'mac'
-
-
-@memoize()
-def builder():
- """
- Returns a string representing the build engine (not compiler) to use.
- Possible values: 'make', 'ninja', 'xcode', 'msvs', 'scons'
- """
- if 'GYP_GENERATORS' in os.environ:
- # for simplicity, only support the first explicit generator
- generator = os.environ['GYP_GENERATORS'].split(',')[0]
- if generator.endswith('-android'):
- return generator.split('-')[0]
- elif generator.endswith('-ninja'):
- return 'ninja'
- else:
- return generator
- else:
- if platform() == 'android':
- # Good enough for now? Do any android bots use make?
- return 'ninja'
- elif platform() == 'ios':
- return 'xcode'
- elif IsWindows():
- return 'ninja'
- elif IsLinux():
- return 'ninja'
- elif IsMac():
- return 'ninja'
- else:
- assert False, 'Don\'t know what builder we\'re using!'
diff --git a/build/landmines.py b/build/landmines.py
deleted file mode 100755
index 0ea2b64..0000000
--- a/build/landmines.py
+++ /dev/null
@@ -1,134 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""
-This script runs every build as the first hook (See DEPS). If it detects that
-the build should be clobbered, it will delete the contents of the build
-directory.
-
-A landmine is tripped when a builder checks out a different revision, and the
-diff between the new landmines and the old ones is non-null. At this point, the
-build is clobbered.
-"""
-
-import difflib
-import errno
-import logging
-import optparse
-import os
-import sys
-import subprocess
-import time
-
-import clobber
-import landmine_utils
-
-
-SRC_DIR = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
-
-
-def get_build_dir(build_tool, is_iphone=False):
- """
- Returns output directory absolute path dependent on build and targets.
- Examples:
- r'c:\b\build\slave\win\build\src\out'
- '/mnt/data/b/build/slave/linux/build/src/out'
- '/b/build/slave/ios_rel_device/build/src/xcodebuild'
-
- Keep this function in sync with tools/build/scripts/slave/compile.py
- """
- ret = None
- if build_tool == 'xcode':
- ret = os.path.join(SRC_DIR, 'xcodebuild')
- elif build_tool in ['make', 'ninja', 'ninja-ios']: # TODO: Remove ninja-ios.
- if 'CHROMIUM_OUT_DIR' in os.environ:
- output_dir = os.environ.get('CHROMIUM_OUT_DIR').strip()
- if not output_dir:
- raise Error('CHROMIUM_OUT_DIR environment variable is set but blank!')
- else:
- output_dir = landmine_utils.gyp_generator_flags().get('output_dir', 'out')
- ret = os.path.join(SRC_DIR, output_dir)
- else:
- raise NotImplementedError('Unexpected GYP_GENERATORS (%s)' % build_tool)
- return os.path.abspath(ret)
-
-
-def clobber_if_necessary(new_landmines):
- """Does the work of setting, planting, and triggering landmines."""
- out_dir = get_build_dir(landmine_utils.builder())
- landmines_path = os.path.normpath(os.path.join(out_dir, '..', '.landmines'))
- try:
- os.makedirs(out_dir)
- except OSError as e:
- if e.errno == errno.EEXIST:
- pass
-
- if os.path.exists(landmines_path):
- with open(landmines_path, 'r') as f:
- old_landmines = f.readlines()
- if old_landmines != new_landmines:
- old_date = time.ctime(os.stat(landmines_path).st_ctime)
- diff = difflib.unified_diff(old_landmines, new_landmines,
- fromfile='old_landmines', tofile='new_landmines',
- fromfiledate=old_date, tofiledate=time.ctime(), n=0)
- sys.stdout.write('Clobbering due to:\n')
- sys.stdout.writelines(diff)
-
- clobber.clobber(out_dir)
-
- # Save current set of landmines for next time.
- with open(landmines_path, 'w') as f:
- f.writelines(new_landmines)
-
-
-def process_options():
- """Returns a list of landmine emitting scripts."""
- parser = optparse.OptionParser()
- parser.add_option(
- '-s', '--landmine-scripts', action='append',
- default=[os.path.join(SRC_DIR, 'build', 'get_landmines.py')],
- help='Path to the script which emits landmines to stdout. The target '
- 'is passed to this script via option -t. Note that an extra '
- 'script can be specified via an env var EXTRA_LANDMINES_SCRIPT.')
- parser.add_option('-v', '--verbose', action='store_true',
- default=('LANDMINES_VERBOSE' in os.environ),
- help=('Emit some extra debugging information (default off). This option '
- 'is also enabled by the presence of a LANDMINES_VERBOSE environment '
- 'variable.'))
-
- options, args = parser.parse_args()
-
- if args:
- parser.error('Unknown arguments %s' % args)
-
- logging.basicConfig(
- level=logging.DEBUG if options.verbose else logging.ERROR)
-
- extra_script = os.environ.get('EXTRA_LANDMINES_SCRIPT')
- if extra_script:
- return options.landmine_scripts + [extra_script]
- else:
- return options.landmine_scripts
-
-
-def main():
- landmine_scripts = process_options()
-
- if landmine_utils.builder() in ('dump_dependency_json', 'eclipse'):
- return 0
-
-
- landmines = []
- for s in landmine_scripts:
- proc = subprocess.Popen([sys.executable, s], stdout=subprocess.PIPE)
- output, _ = proc.communicate()
- landmines.extend([('%s\n' % l.strip()) for l in output.splitlines()])
- clobber_if_necessary(landmines)
-
- return 0
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/build/linux/OWNERS b/build/linux/OWNERS
deleted file mode 100644
index 4a60b79..0000000
--- a/build/linux/OWNERS
+++ /dev/null
@@ -1,3 +0,0 @@
-mmoss@chromium.org
-phajdan.jr@chromium.org
-thestig@chromium.org
diff --git a/build/linux/bin/eu-strip b/build/linux/bin/eu-strip
deleted file mode 100755
index 7f93eec..0000000
--- a/build/linux/bin/eu-strip
+++ /dev/null
Binary files differ
diff --git a/build/linux/bin/eu-strip.sha1 b/build/linux/bin/eu-strip.sha1
deleted file mode 100644
index 43f290a7..0000000
--- a/build/linux/bin/eu-strip.sha1
+++ /dev/null
@@ -1 +0,0 @@
-0a9b8f68615ce388b65201e6d22da7a9cf2e729c
\ No newline at end of file
diff --git a/build/linux/chrome_linux.croc b/build/linux/chrome_linux.croc
deleted file mode 100644
index f400306..0000000
--- a/build/linux/chrome_linux.croc
+++ /dev/null
@@ -1,29 +0,0 @@
-# -*- python -*-
-# Crocodile config file for Chromium linux
-
-# TODO(jhawkins): We'll need to add a chromeos.croc once we get a coverage bot
-# for that platform.
-
-{
- # List of rules, applied in order
- 'rules' : [
- # Specify inclusions before exclusions, since rules are in order.
-
- # Don't include non-Linux platform dirs
- {
- 'regexp' : '.*/(chromeos|views)/',
- 'include' : 0,
- },
- # Don't include chromeos, windows, or mac specific files
- {
- 'regexp' : '.*(_|/)(chromeos|mac|win|views)(\\.|_)',
- 'include' : 0,
- },
-
- # Groups
- {
- 'regexp' : '.*_test_linux\\.',
- 'group' : 'test',
- },
- ],
-}
diff --git a/build/linux/dump_app_syms.py b/build/linux/dump_app_syms.py
deleted file mode 100644
index c18bff7..0000000
--- a/build/linux/dump_app_syms.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# Helper script to run dump_syms on Chrome Linux executables and strip
-# them if needed.
-
-import os
-import subprocess
-import sys
-
-if len(sys.argv) != 5:
- print "dump_app_syms.py <dump_syms_exe> <strip_binary>"
- print " <binary_with_symbols> <symbols_output>"
- sys.exit(1)
-
-dumpsyms = sys.argv[1]
-strip_binary = sys.argv[2]
-infile = sys.argv[3]
-outfile = sys.argv[4]
-
-# Dump only when the output file is out-of-date.
-if not os.path.isfile(outfile) or \
- os.stat(outfile).st_mtime > os.stat(infile).st_mtime:
- with open(outfile, 'w') as outfileobj:
- subprocess.check_call([dumpsyms, '-r', infile], stdout=outfileobj)
-
-if strip_binary != '0':
- subprocess.check_call(['strip', infile])
diff --git a/build/linux/install-chromeos-fonts.py b/build/linux/install-chromeos-fonts.py
deleted file mode 100755
index a24adc9..0000000
--- a/build/linux/install-chromeos-fonts.py
+++ /dev/null
@@ -1,73 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# Script to install the Chrome OS fonts on Linux.
-# This script can be run manually (as root), but is also run as part
-# install-build-deps.sh.
-
-import os
-import shutil
-import subprocess
-import sys
-
-# Taken from the media-fonts/notofonts ebuild in chromiumos-overlay.
-VERSION = '20140815'
-URL = ('https://commondatastorage.googleapis.com/chromeos-localmirror/'
- 'distfiles/notofonts-%s.tar.bz2') % (VERSION)
-FONTS_DIR = '/usr/local/share/fonts'
-
-def main(args):
- if not sys.platform.startswith('linux'):
- print "Error: %s must be run on Linux." % __file__
- return 1
-
- if os.getuid() != 0:
- print "Error: %s must be run as root." % __file__
- return 1
-
- if not os.path.isdir(FONTS_DIR):
- print "Error: Destination directory does not exist: %s" % FONTS_DIR
- return 1
-
- dest_dir = os.path.join(FONTS_DIR, 'chromeos')
-
- stamp = os.path.join(dest_dir, ".stamp02")
- if os.path.exists(stamp):
- with open(stamp) as s:
- if s.read() == URL:
- print "Chrome OS fonts already up-to-date in %s." % dest_dir
- return 0
-
- if os.path.isdir(dest_dir):
- shutil.rmtree(dest_dir)
- os.mkdir(dest_dir)
- os.chmod(dest_dir, 0755)
-
- print "Installing Chrome OS fonts to %s." % dest_dir
- tarball = os.path.join(dest_dir, os.path.basename(URL))
- subprocess.check_call(['curl', '-L', URL, '-o', tarball])
- subprocess.check_call(['tar', '--no-same-owner', '--no-same-permissions',
- '-xf', tarball, '-C', dest_dir])
- os.remove(tarball)
-
- readme = os.path.join(dest_dir, "README")
- with open(readme, 'w') as s:
- s.write("This directory and its contents are auto-generated.\n")
- s.write("It may be deleted and recreated. Do not modify.\n")
- s.write("Script: %s\n" % __file__)
-
- with open(stamp, 'w') as s:
- s.write(URL)
-
- for base, dirs, files in os.walk(dest_dir):
- for dir in dirs:
- os.chmod(os.path.join(base, dir), 0755)
- for file in files:
- os.chmod(os.path.join(base, file), 0644)
-
- return 0
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv[1:]))
diff --git a/build/linux/pkg-config-wrapper b/build/linux/pkg-config-wrapper
deleted file mode 100755
index b759564..0000000
--- a/build/linux/pkg-config-wrapper
+++ /dev/null
@@ -1,59 +0,0 @@
-#!/bin/bash
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This program wraps around pkg-config to generate the correct include and
-# library paths when cross-compiling using a sysroot.
-# The assumption is that the sysroot contains the .pc files in usr/lib/pkgconfig
-# and usr/share/pkgconfig (relative to the sysroot) and that they output paths
-# relative to some parent path of the sysroot.
-# This assumption is valid for a range of sysroots, in particular: a
-# LSB-compliant root filesystem mounted at the sysroot, and a board build
-# directory of a Chromium OS chroot.
-# Additional directories containing .pc files may be specified by setting
-# the PKG_CONFIG_PATH environment variable- these will be prepended to the
-# generated paths.
-
-root="$1"
-shift
-target_arch="$1"
-shift
-libpath="$1"
-shift
-
-if [ -z "$root" -o -z "$target_arch" ]
-then
- echo "usage: $0 /path/to/sysroot target_arch libdir [pkg-config-arguments] package" >&2
- exit 1
-fi
-
-if [ "$target_arch" = "x64" ]
-then
- : ${libpath:="lib64"}
-else
- : ${libpath:="lib"}
-fi
-
-rewrite=`dirname $0`/rewrite_dirs.py
-package=${!#}
-
-config_path=$root/usr/$libpath/pkgconfig:$root/usr/share/pkgconfig
-
-# prepend any paths specified by the environment
-if [ -n "$PKG_CONFIG_PATH" ]
-then
- config_path="$PKG_CONFIG_PATH:$config_path"
-fi
-
-set -e
-# Some sysroots, like the Chromium OS ones, may generate paths that are not
-# relative to the sysroot. For example,
-# /path/to/chroot/build/x86-generic/usr/lib/pkgconfig/pkg.pc may have all paths
-# relative to /path/to/chroot (i.e. prefix=/build/x86-generic/usr) instead of
-# relative to /path/to/chroot/build/x86-generic (i.e prefix=/usr).
-# To support this correctly, it's necessary to extract the prefix to strip from
-# pkg-config's |prefix| variable.
-prefix=`PKG_CONFIG_PATH=$config_path pkg-config --variable=prefix "$package" | sed -e 's|/usr$||'`
-result=`PKG_CONFIG_PATH=$config_path pkg-config "$@"`
-echo "$result"| $rewrite --sysroot "$root" --strip-prefix "$prefix"
diff --git a/build/linux/rewrite_dirs.py b/build/linux/rewrite_dirs.py
deleted file mode 100755
index 30f22f0..0000000
--- a/build/linux/rewrite_dirs.py
+++ /dev/null
@@ -1,71 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2011 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Rewrites paths in -I, -L and other option to be relative to a sysroot."""
-
-import sys
-import os
-import optparse
-
-REWRITE_PREFIX = ['-I',
- '-idirafter',
- '-imacros',
- '-imultilib',
- '-include',
- '-iprefix',
- '-iquote',
- '-isystem',
- '-L']
-
-def RewritePath(path, opts):
- """Rewrites a path by stripping the prefix and prepending the sysroot."""
- sysroot = opts.sysroot
- prefix = opts.strip_prefix
- if os.path.isabs(path) and not path.startswith(sysroot):
- if path.startswith(prefix):
- path = path[len(prefix):]
- path = path.lstrip('/')
- return os.path.join(sysroot, path)
- else:
- return path
-
-
-def RewriteLine(line, opts):
- """Rewrites all the paths in recognized options."""
- args = line.split()
- count = len(args)
- i = 0
- while i < count:
- for prefix in REWRITE_PREFIX:
- # The option can be either in the form "-I /path/to/dir" or
- # "-I/path/to/dir" so handle both.
- if args[i] == prefix:
- i += 1
- try:
- args[i] = RewritePath(args[i], opts)
- except IndexError:
- sys.stderr.write('Missing argument following %s\n' % prefix)
- break
- elif args[i].startswith(prefix):
- args[i] = prefix + RewritePath(args[i][len(prefix):], opts)
- i += 1
-
- return ' '.join(args)
-
-
-def main(argv):
- parser = optparse.OptionParser()
- parser.add_option('-s', '--sysroot', default='/', help='sysroot to prepend')
- parser.add_option('-p', '--strip-prefix', default='', help='prefix to strip')
- opts, args = parser.parse_args(argv[1:])
-
- for line in sys.stdin.readlines():
- line = RewriteLine(line.strip(), opts)
- print line
- return 0
-
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv))
diff --git a/build/linux/system.gyp b/build/linux/system.gyp
deleted file mode 100644
index ab20951..0000000
--- a/build/linux/system.gyp
+++ /dev/null
@@ -1,1222 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
- 'variables': {
- # If any of the linux_link_FOO below are set to 1, then the corresponding
- # target will be linked against the FOO library (either dynamically or
- # statically, depending on the pkg-config files), as opposed to loading the
- # FOO library dynamically with dlopen.
- 'linux_link_libgps%': 0,
- 'linux_link_libpci%': 0,
- 'linux_link_libspeechd%': 0,
- 'linux_link_libbrlapi%': 0,
-
- # Used below for the various libraries. In this scope for sharing with GN.
- 'libbrlapi_functions': [
- 'brlapi_getHandleSize',
- 'brlapi_error_location',
- 'brlapi_strerror',
- 'brlapi__acceptKeys',
- 'brlapi__openConnection',
- 'brlapi__closeConnection',
- 'brlapi__getDisplaySize',
- 'brlapi__enterTtyModeWithPath',
- 'brlapi__leaveTtyMode',
- 'brlapi__writeDots',
- 'brlapi__readKey',
- ],
- 'libgio_functions': [
- 'g_settings_new',
- 'g_settings_get_child',
- 'g_settings_get_string',
- 'g_settings_get_boolean',
- 'g_settings_get_int',
- 'g_settings_get_strv',
- 'g_settings_list_schemas',
- ],
- 'libpci_functions': [
- 'pci_alloc',
- 'pci_init',
- 'pci_cleanup',
- 'pci_scan_bus',
- 'pci_fill_info',
- 'pci_lookup_name',
- ],
- 'libudev_functions': [
- 'udev_device_get_action',
- 'udev_device_get_devnode',
- 'udev_device_get_parent',
- 'udev_device_get_parent_with_subsystem_devtype',
- 'udev_device_get_property_value',
- 'udev_device_get_subsystem',
- 'udev_device_get_sysattr_value',
- 'udev_device_get_sysname',
- 'udev_device_get_syspath',
- 'udev_device_new_from_devnum',
- 'udev_device_new_from_subsystem_sysname',
- 'udev_device_new_from_syspath',
- 'udev_device_unref',
- 'udev_enumerate_add_match_subsystem',
- 'udev_enumerate_get_list_entry',
- 'udev_enumerate_new',
- 'udev_enumerate_scan_devices',
- 'udev_enumerate_unref',
- 'udev_list_entry_get_next',
- 'udev_list_entry_get_name',
- 'udev_monitor_enable_receiving',
- 'udev_monitor_filter_add_match_subsystem_devtype',
- 'udev_monitor_get_fd',
- 'udev_monitor_new_from_netlink',
- 'udev_monitor_receive_device',
- 'udev_monitor_unref',
- 'udev_new',
- 'udev_set_log_fn',
- 'udev_set_log_priority',
- 'udev_unref',
- ],
- },
- 'conditions': [
- [ 'chromeos==0 and use_ozone==0', {
- # Hide GTK and related dependencies for Chrome OS and Ozone, so they won't get
- # added back to Chrome OS and Ozone. Don't try to use GTK on Chrome OS and Ozone.
- 'targets': [
- {
- 'target_name': 'atk',
- 'type': 'none',
- 'conditions': [
- ['_toolset=="target"', {
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(<(pkg-config) --cflags atk)',
- ],
- 'defines': [
- 'ATK_LIB_DIR="<!@(<(pkg-config) --variable=libdir atk)"',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(<(pkg-config) --libs-only-L --libs-only-other atk)',
- ],
- 'libraries': [
- '<!@(<(pkg-config) --libs-only-l atk)',
- ],
- },
- }],
- ],
- },
- {
- 'target_name': 'gdk',
- 'type': 'none',
- 'conditions': [
- ['_toolset=="target"', {
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(<(pkg-config) --cflags gdk-2.0)',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(<(pkg-config) --libs-only-L --libs-only-other gdk-2.0)',
- ],
- 'libraries': [
- '<!@(<(pkg-config) --libs-only-l gdk-2.0)',
- ],
- },
- }],
- ],
- },
- {
- 'target_name': 'gtk',
- 'type': 'none',
- 'toolsets': ['host', 'target'],
- 'variables': {
- # gtk requires gmodule, but it does not list it as a dependency
- # in some misconfigured systems.
- 'gtk_packages': 'gmodule-2.0 gtk+-2.0 gthread-2.0',
- },
- 'conditions': [
- ['_toolset=="target"', {
- 'all_dependent_settings': {
- 'cflags': [
- '<!@(<(pkg-config) --cflags <(gtk_packages))',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(<(pkg-config) --libs-only-L --libs-only-other <(gtk_packages))',
- ],
- 'libraries': [
- '<!@(<(pkg-config) --libs-only-l <(gtk_packages))',
- ],
- },
- }, {
- 'all_dependent_settings': {
- 'cflags': [
- '<!@(pkg-config --cflags <(gtk_packages))',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(pkg-config --libs-only-L --libs-only-other <(gtk_packages))',
- ],
- 'libraries': [
- '<!@(pkg-config --libs-only-l <(gtk_packages))',
- ],
- },
- }],
- ],
- },
- {
- 'target_name': 'gtkprint',
- 'type': 'none',
- 'conditions': [
- ['_toolset=="target"', {
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(<(pkg-config) --cflags gtk+-unix-print-2.0)',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(<(pkg-config) --libs-only-L --libs-only-other gtk+-unix-print-2.0)',
- ],
- 'libraries': [
- '<!@(<(pkg-config) --libs-only-l gtk+-unix-print-2.0)',
- ],
- },
- }],
- ],
- },
- ], # targets
- }],
- [ 'use_x11==1 or ozone_platform_ozonex==1', {
- # Hide X11 and related dependencies when use_x11=0
- 'targets': [
- {
- 'target_name': 'x11',
- 'type': 'none',
- 'toolsets': ['host', 'target'],
- 'conditions': [
- ['_toolset=="target"', {
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(<(pkg-config) --cflags x11)',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(<(pkg-config) --libs-only-L --libs-only-other x11 xi)',
- ],
- 'libraries': [
- '<!@(<(pkg-config) --libs-only-l x11 xi)',
- ],
- },
- }, {
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(pkg-config --cflags x11)',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(pkg-config --libs-only-L --libs-only-other x11 xi)',
- ],
- 'libraries': [
- '<!@(pkg-config --libs-only-l x11 xi)',
- ],
- },
- }],
- ],
- },
- {
- 'target_name': 'xcursor',
- 'type': 'none',
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(<(pkg-config) --cflags xcursor)',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(<(pkg-config) --libs-only-L --libs-only-other xcursor)',
- ],
- 'libraries': [
- '<!@(<(pkg-config) --libs-only-l xcursor)',
- ],
- },
- },
- {
- 'target_name': 'xcomposite',
- 'type': 'none',
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(<(pkg-config) --cflags xcomposite)',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(<(pkg-config) --libs-only-L --libs-only-other xcomposite)',
- ],
- 'libraries': [
- '<!@(<(pkg-config) --libs-only-l xcomposite)',
- ],
- },
- },
- {
- 'target_name': 'xdamage',
- 'type': 'none',
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(<(pkg-config) --cflags xdamage)',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(<(pkg-config) --libs-only-L --libs-only-other xdamage)',
- ],
- 'libraries': [
- '<!@(<(pkg-config) --libs-only-l xdamage)',
- ],
- },
- },
- {
- 'target_name': 'xext',
- 'type': 'none',
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(<(pkg-config) --cflags xext)',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(<(pkg-config) --libs-only-L --libs-only-other xext)',
- ],
- 'libraries': [
- '<!@(<(pkg-config) --libs-only-l xext)',
- ],
- },
- },
- {
- 'target_name': 'xfixes',
- 'type': 'none',
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(<(pkg-config) --cflags xfixes)',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(<(pkg-config) --libs-only-L --libs-only-other xfixes)',
- ],
- 'libraries': [
- '<!@(<(pkg-config) --libs-only-l xfixes)',
- ],
- },
- },
- {
- 'target_name': 'xi',
- 'type': 'none',
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(<(pkg-config) --cflags xi)',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(<(pkg-config) --libs-only-L --libs-only-other xi)',
- ],
- 'libraries': [
- '<!@(<(pkg-config) --libs-only-l xi)',
- ],
- },
- },
- {
- 'target_name': 'xrandr',
- 'type': 'none',
- 'toolsets': ['host', 'target'],
- 'conditions': [
- ['_toolset=="target"', {
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(<(pkg-config) --cflags xrandr)',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(<(pkg-config) --libs-only-L --libs-only-other xrandr)',
- ],
- 'libraries': [
- '<!@(<(pkg-config) --libs-only-l xrandr)',
- ],
- },
- }, {
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(pkg-config --cflags xrandr)',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(pkg-config --libs-only-L --libs-only-other xrandr)',
- ],
- 'libraries': [
- '<!@(pkg-config --libs-only-l xrandr)',
- ],
- },
- }],
- ],
- },
- {
- 'target_name': 'xrender',
- 'type': 'none',
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(<(pkg-config) --cflags xrender)',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(<(pkg-config) --libs-only-L --libs-only-other xrender)',
- ],
- 'libraries': [
- '<!@(<(pkg-config) --libs-only-l xrender)',
- ],
- },
- },
- {
- 'target_name': 'xtst',
- 'type': 'none',
- 'toolsets': ['host', 'target'],
- 'conditions': [
- ['_toolset=="target"', {
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(<(pkg-config) --cflags xtst)',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(<(pkg-config) --libs-only-L --libs-only-other xtst)',
- ],
- 'libraries': [
- '<!@(<(pkg-config) --libs-only-l xtst)',
- ],
- },
- }, {
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(pkg-config --cflags xtst)',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(pkg-config --libs-only-L --libs-only-other xtst)',
- ],
- 'libraries': [
- '<!@(pkg-config --libs-only-l xtst)',
- ],
- },
- }]
- ]
- }
- ], # targets
- }],
- ['use_x11==1 and chromeos==0', {
- 'targets': [
- {
- 'target_name': 'xscrnsaver',
- 'type': 'none',
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(<(pkg-config) --cflags xscrnsaver)',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(<(pkg-config) --libs-only-L --libs-only-other xscrnsaver)',
- ],
- 'libraries': [
- '<!@(<(pkg-config) --libs-only-l xscrnsaver)',
- ],
- },
- },
- ], # targets
- }],
- ['use_evdev_gestures==1', {
- 'targets': [
- {
- 'target_name': 'libevdev-cros',
- 'type': 'none',
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(<(pkg-config) --cflags libevdev-cros)'
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(<(pkg-config) --libs-only-L --libs-only-other libevdev-cros)',
- ],
- 'libraries': [
- '<!@(<(pkg-config) --libs-only-l libevdev-cros)',
- ],
- },
- },
- {
- 'target_name': 'libgestures',
- 'type': 'none',
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(<(pkg-config) --cflags libgestures)'
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(<(pkg-config) --libs-only-L --libs-only-other libgestures)',
- ],
- 'libraries': [
- '<!@(<(pkg-config) --libs-only-l libgestures)',
- ],
- },
- },
- ],
- }],
- ['use_xkbcommon==1', {
- 'targets': [
- {
- 'target_name': 'xkbcommon',
- 'type': 'none',
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(<(pkg-config) --cflags xkbcommon)'
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(<(pkg-config) --libs-only-L --libs-only-other xkbcommon)',
- ],
- 'libraries': [
- '<!@(<(pkg-config) --libs-only-l xkbcommon)',
- ],
- },
- },
- ],
- }],
- ['ozone_platform_gbm==1', {
- 'targets': [
- {
- 'target_name': 'gbm',
- 'type': 'none',
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(<(pkg-config) --cflags gbm)',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(<(pkg-config) --libs-only-L --libs-only-other gbm)',
- ],
- 'libraries': [
- '<!@(<(pkg-config) --libs-only-l gbm)',
- ],
- },
- },
- ],
- }],
- ['ozone_platform_drm==1 or ozone_platform_gbm==1', {
- 'targets': [
- {
- 'target_name': 'libdrm',
- 'type': 'none',
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(<(pkg-config) --cflags libdrm)',
- ],
- },
- 'link_settings': {
- 'libraries': [
- '<!@(<(pkg-config) --libs-only-l libdrm)',
- ],
- },
- },
- ],
- }],
- ['use_udev==1', {
- 'targets': [
- {
- 'target_name': 'udev',
- 'type': 'static_library',
- 'conditions': [
- ['_toolset=="target"', {
- 'include_dirs': [
- '../..',
- ],
- 'hard_dependency': 1,
- 'actions': [
- {
- 'variables': {
- 'output_h': '<(SHARED_INTERMEDIATE_DIR)/library_loaders/libudev0.h',
- 'output_cc': '<(INTERMEDIATE_DIR)/libudev0_loader.cc',
- 'generator': '../../tools/generate_library_loader/generate_library_loader.py',
- },
- 'action_name': 'generate_libudev0_loader',
- 'inputs': [
- '<(generator)',
- ],
- 'outputs': [
- '<(output_h)',
- '<(output_cc)',
- ],
- 'action': ['python',
- '<(generator)',
- '--name', 'LibUdev0Loader',
- '--output-h', '<(output_h)',
- '--output-cc', '<(output_cc)',
- '--header', '"third_party/libudev/libudev0.h"',
- '--link-directly=0',
- '<@(libudev_functions)',
- ],
- 'message': 'Generating libudev0 library loader',
- 'process_outputs_as_sources': 1,
- },
- {
- 'variables': {
- 'output_h': '<(SHARED_INTERMEDIATE_DIR)/library_loaders/libudev1.h',
- 'output_cc': '<(INTERMEDIATE_DIR)/libudev1_loader.cc',
- 'generator': '../../tools/generate_library_loader/generate_library_loader.py',
- },
- 'action_name': 'generate_libudev1_loader',
- 'inputs': [
- '<(generator)',
- ],
- 'outputs': [
- '<(output_h)',
- '<(output_cc)',
- ],
- 'action': ['python',
- '<(generator)',
- '--name', 'LibUdev1Loader',
- '--output-h', '<(output_h)',
- '--output-cc', '<(output_cc)',
- '--header', '"third_party/libudev/libudev1.h"',
- '--link-directly=0',
- '<@(libudev_functions)',
- ],
- 'message': 'Generating libudev1 library loader',
- 'process_outputs_as_sources': 1,
- },
- ],
- }],
- ],
- },
- ],
- }],
- ['use_libpci==1', {
- 'targets': [
- {
- 'target_name': 'libpci',
- 'type': 'static_library',
- 'cflags': [
- '<!@(<(pkg-config) --cflags libpci)',
- ],
- 'direct_dependent_settings': {
- 'include_dirs': [
- '<(SHARED_INTERMEDIATE_DIR)',
- ],
- 'conditions': [
- ['linux_link_libpci==1', {
- 'link_settings': {
- 'ldflags': [
- '<!@(<(pkg-config) --libs-only-L --libs-only-other libpci)',
- ],
- 'libraries': [
- '<!@(<(pkg-config) --libs-only-l libpci)',
- ],
- }
- }],
- ],
- },
- 'include_dirs': [
- '../..',
- ],
- 'hard_dependency': 1,
- 'actions': [
- {
- 'variables': {
- 'output_h': '<(SHARED_INTERMEDIATE_DIR)/library_loaders/libpci.h',
- 'output_cc': '<(INTERMEDIATE_DIR)/libpci_loader.cc',
- 'generator': '../../tools/generate_library_loader/generate_library_loader.py',
- },
- 'action_name': 'generate_libpci_loader',
- 'inputs': [
- '<(generator)',
- ],
- 'outputs': [
- '<(output_h)',
- '<(output_cc)',
- ],
- 'action': ['python',
- '<(generator)',
- '--name', 'LibPciLoader',
- '--output-h', '<(output_h)',
- '--output-cc', '<(output_cc)',
- '--header', '<pci/pci.h>',
- # TODO(phajdan.jr): Report problem to pciutils project
- # and get it fixed so that we don't need --use-extern-c.
- '--use-extern-c',
- '--link-directly=<(linux_link_libpci)',
- '<@(libpci_functions)',
- ],
- 'message': 'Generating libpci library loader',
- 'process_outputs_as_sources': 1,
- },
- ],
- },
- ],
- }],
- ], # conditions
- 'targets': [
- {
- 'target_name': 'dbus',
- 'type': 'none',
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(<(pkg-config) --cflags dbus-1)',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(<(pkg-config) --libs-only-L --libs-only-other dbus-1)',
- ],
- 'libraries': [
- '<!@(<(pkg-config) --libs-only-l dbus-1)',
- ],
- },
- },
- {
- 'target_name': 'fontconfig',
- 'type': 'none',
- 'conditions': [
- ['_toolset=="target"', {
- 'conditions': [
- ['use_system_fontconfig==1', {
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(<(pkg-config) --cflags fontconfig)',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(<(pkg-config) --libs-only-L --libs-only-other fontconfig)',
- ],
- 'libraries': [
- '<!@(<(pkg-config) --libs-only-l fontconfig)',
- ],
- },
- }, { # use_system_fontconfig==0
- 'dependencies': [
- '../../third_party/fontconfig/fontconfig.gyp:fontconfig',
- ],
- 'export_dependent_settings' : [
- '../../third_party/fontconfig/fontconfig.gyp:fontconfig',
- ],
- }],
- ],
- }],
- ],
- },
- {
- 'target_name': 'freetype2',
- 'type': 'none',
- 'conditions': [
- ['_toolset=="target"', {
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(<(pkg-config) --cflags freetype2)',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(<(pkg-config) --libs-only-L --libs-only-other freetype2)',
- ],
- 'libraries': [
- '<!@(<(pkg-config) --libs-only-l freetype2)',
- ],
- },
- }],
- ],
- },
- {
- 'target_name': 'gconf',
- 'type': 'none',
- 'conditions': [
- ['use_gconf==1 and _toolset=="target"', {
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(<(pkg-config) --cflags gconf-2.0)',
- ],
- 'defines': [
- 'USE_GCONF',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(<(pkg-config) --libs-only-L --libs-only-other gconf-2.0)',
- ],
- 'libraries': [
- '<!@(<(pkg-config) --libs-only-l gconf-2.0)',
- ],
- },
- }],
- ],
- },
- {
- 'target_name': 'gio',
- 'type': 'static_library',
- 'conditions': [
- ['use_gio==1 and _toolset=="target"', {
- 'cflags': [
- '<!@(<(pkg-config) --cflags gio-2.0)',
- ],
- 'variables': {
- 'gio_warning_define': [
- # glib >=2.40 deprecate g_settings_list_schemas in favor of
- # g_settings_schema_source_list_schemas. This function is not
- # available on earlier versions that we still need to support
- # (specifically, 2.32), so disable the warning.
- # TODO(mgiuca): Remove this suppression (and variable) when we
- # drop support for Ubuntu 13.10 (saucy) and earlier. Update the
- # code to use g_settings_schema_source_list_schemas instead.
- 'GLIB_DISABLE_DEPRECATION_WARNINGS',
- ],
- },
- 'defines': [
- '<(gio_warning_define)',
- ],
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(<(pkg-config) --cflags gio-2.0)',
- ],
- 'defines': [
- 'USE_GIO',
- '<(gio_warning_define)',
- ],
- 'include_dirs': [
- '<(SHARED_INTERMEDIATE_DIR)',
- ],
- },
- 'include_dirs': [
- '../..',
- ],
- 'link_settings': {
- 'ldflags': [
- '<!@(<(pkg-config) --libs-only-L --libs-only-other gio-2.0)',
- ],
- 'libraries': [
- '<!@(<(pkg-config) --libs-only-l gio-2.0)',
- ],
- 'conditions': [
- ['linux_link_gsettings==0 and OS=="linux"', {
- 'libraries': [
- '-ldl',
- ],
- }],
- ],
- },
- 'hard_dependency': 1,
- 'actions': [
- {
- 'variables': {
- 'output_h': '<(SHARED_INTERMEDIATE_DIR)/library_loaders/libgio.h',
- 'output_cc': '<(INTERMEDIATE_DIR)/libgio_loader.cc',
- 'generator': '../../tools/generate_library_loader/generate_library_loader.py',
- },
- 'action_name': 'generate_libgio_loader',
- 'inputs': [
- '<(generator)',
- ],
- 'outputs': [
- '<(output_h)',
- '<(output_cc)',
- ],
- 'action': ['python',
- '<(generator)',
- '--name', 'LibGioLoader',
- '--output-h', '<(output_h)',
- '--output-cc', '<(output_cc)',
- '--header', '<gio/gio.h>',
- '--link-directly=<(linux_link_gsettings)',
- '<@(libgio_functions)',
- ],
- 'message': 'Generating libgio library loader',
- 'process_outputs_as_sources': 1,
- },
- ],
- }],
- ],
- },
- {
- 'target_name': 'glib',
- 'type': 'none',
- 'toolsets': ['host', 'target'],
- 'variables': {
- 'glib_packages': 'glib-2.0 gmodule-2.0 gobject-2.0 gthread-2.0',
- },
- 'conditions': [
- ['_toolset=="target"', {
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(<(pkg-config) --cflags <(glib_packages))',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(<(pkg-config) --libs-only-L --libs-only-other <(glib_packages))',
- ],
- 'libraries': [
- '<!@(<(pkg-config) --libs-only-l <(glib_packages))',
- ],
- },
- }, {
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(pkg-config --cflags <(glib_packages))',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(pkg-config --libs-only-L --libs-only-other <(glib_packages))',
- ],
- 'libraries': [
- '<!@(pkg-config --libs-only-l <(glib_packages))',
- ],
- },
- }],
- ],
- },
- {
- 'target_name': 'gnome_keyring',
- 'type': 'none',
- 'conditions': [
- ['use_gnome_keyring==1', {
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(<(pkg-config) --cflags gnome-keyring-1)',
- ],
- 'defines': [
- 'USE_GNOME_KEYRING',
- ],
- 'conditions': [
- ['linux_link_gnome_keyring==0', {
- 'defines': ['DLOPEN_GNOME_KEYRING'],
- }],
- ],
- },
- 'conditions': [
- ['linux_link_gnome_keyring!=0', {
- 'link_settings': {
- 'ldflags': [
- '<!@(<(pkg-config) --libs-only-L --libs-only-other gnome-keyring-1)',
- ],
- 'libraries': [
- '<!@(<(pkg-config) --libs-only-l gnome-keyring-1)',
- ],
- },
- }, {
- 'conditions': [
- ['OS=="linux"', {
- 'link_settings': {
- 'libraries': [
- '-ldl',
- ],
- },
- }],
- ],
- }],
- ],
- }],
- ],
- },
- {
- # The unit tests use a few convenience functions from the GNOME
- # Keyring library directly. We ignore linux_link_gnome_keyring and
- # link directly in this version of the target to allow this.
- # *** Do not use this target in the main binary! ***
- 'target_name': 'gnome_keyring_direct',
- 'type': 'none',
- 'conditions': [
- ['use_gnome_keyring==1', {
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(<(pkg-config) --cflags gnome-keyring-1)',
- ],
- 'defines': [
- 'USE_GNOME_KEYRING',
- ],
- 'conditions': [
- ['linux_link_gnome_keyring==0', {
- 'defines': ['DLOPEN_GNOME_KEYRING'],
- }],
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(<(pkg-config) --libs-only-L --libs-only-other gnome-keyring-1)',
- ],
- 'libraries': [
- '<!@(<(pkg-config) --libs-only-l gnome-keyring-1)',
- ],
- },
- }],
- ],
- },
- {
- 'target_name': 'libbrlapi',
- 'type': 'static_library',
- 'all_dependent_settings': {
- 'include_dirs': [
- '<(SHARED_INTERMEDIATE_DIR)',
- ],
- 'defines': [
- 'USE_BRLAPI',
- ],
- 'conditions': [
- ['linux_link_libbrlapi==1', {
- 'link_settings': {
- 'libraries': [
- '-lbrlapi',
- ],
- }
- }],
- ],
- },
- 'include_dirs': [
- '../..',
- ],
- 'hard_dependency': 1,
- 'actions': [
- {
- 'variables': {
- 'output_h': '<(SHARED_INTERMEDIATE_DIR)/library_loaders/libbrlapi.h',
- 'output_cc': '<(INTERMEDIATE_DIR)/libbrlapi_loader.cc',
- 'generator': '../../tools/generate_library_loader/generate_library_loader.py',
- },
- 'action_name': 'generate_brlapi_loader',
- 'inputs': [
- '<(generator)',
- ],
- 'outputs': [
- '<(output_h)',
- '<(output_cc)',
- ],
- 'action': ['python',
- '<(generator)',
- '--name', 'LibBrlapiLoader',
- '--output-h', '<(output_h)',
- '--output-cc', '<(output_cc)',
- '--header', '<brlapi.h>',
- '--link-directly=<(linux_link_libbrlapi)',
- '<@(libbrlapi_functions)',
- ],
- 'message': 'Generating libbrlapi library loader',
- 'process_outputs_as_sources': 1,
- },
- ],
- },
- {
- 'target_name': 'libcap',
- 'type': 'none',
- 'link_settings': {
- 'libraries': [
- '-lcap',
- ],
- },
- },
- {
- 'target_name': 'libresolv',
- 'type': 'none',
- 'link_settings': {
- 'libraries': [
- '-lresolv',
- ],
- },
- },
- {
- # GN version: //third_party/speech-dispatcher
- 'target_name': 'libspeechd',
- 'type': 'static_library',
- 'direct_dependent_settings': {
- 'include_dirs': [
- '<(SHARED_INTERMEDIATE_DIR)',
- ],
- 'conditions': [
- ['linux_link_libspeechd==1', {
- 'link_settings': {
- 'libraries': [
- '-lspeechd',
- ],
- }
- }],
- ],
- },
- 'include_dirs': [
- '../..',
- ],
- 'hard_dependency': 1,
- 'actions': [
- {
- 'variables': {
- 'output_h': '<(SHARED_INTERMEDIATE_DIR)/library_loaders/libspeechd.h',
- 'output_cc': '<(INTERMEDIATE_DIR)/libspeechd_loader.cc',
- 'generator': '../../tools/generate_library_loader/generate_library_loader.py',
-
- # speech-dispatcher >= 0.8 installs libspeechd.h into
- # speech-dispatcher/libspeechd.h, whereas speech-dispatcher < 0.8
- # puts libspeechd.h in the top-level include directory.
- # Since we need to support both cases for now, we ship a copy of
- # libspeechd.h in third_party/speech-dispatcher. If the user
- # prefers to link against the speech-dispatcher directly, the
- # `libspeechd_h_prefix' variable can be passed to gyp with a value
- # such as "speech-dispatcher/" that will be prepended to
- # "libspeechd.h" in the #include directive.
- # TODO(phaldan.jr): Once we do not need to support
- # speech-dispatcher < 0.8 we can get rid of all this (including
- # third_party/speech-dispatcher) and just include
- # speech-dispatcher/libspeechd.h unconditionally.
- 'libspeechd_h_prefix%': '',
- },
- 'action_name': 'generate_libspeechd_loader',
- 'inputs': [
- '<(generator)',
- ],
- 'outputs': [
- '<(output_h)',
- '<(output_cc)',
- ],
- 'action': ['python',
- '<(generator)',
- '--name', 'LibSpeechdLoader',
- '--output-h', '<(output_h)',
- '--output-cc', '<(output_cc)',
- '--header', '<<(libspeechd_h_prefix)libspeechd.h>',
- '--bundled-header',
- '"third_party/speech-dispatcher/libspeechd.h"',
- '--link-directly=<(linux_link_libspeechd)',
- 'spd_open',
- 'spd_say',
- 'spd_stop',
- 'spd_close',
- 'spd_pause',
- 'spd_resume',
- 'spd_set_notification_on',
- 'spd_set_voice_rate',
- 'spd_set_voice_pitch',
- 'spd_list_synthesis_voices',
- 'spd_set_synthesis_voice',
- 'spd_list_modules',
- 'spd_set_output_module',
- 'spd_set_language',
- ],
- 'message': 'Generating libspeechd library loader',
- 'process_outputs_as_sources': 1,
- },
- ],
- },
- {
- 'target_name': 'pangocairo',
- 'type': 'none',
- 'toolsets': ['host', 'target'],
- 'conditions': [
- ['use_pango==1 and use_cairo==1', {
- 'conditions': [
- ['_toolset=="target"', {
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(<(pkg-config) --cflags pangocairo pangoft2)',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(<(pkg-config) --libs-only-L --libs-only-other pangocairo pangoft2)',
- ],
- 'libraries': [
- '<!@(<(pkg-config) --libs-only-l pangocairo pangoft2)',
- ],
- },
- }, {
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(pkg-config --cflags pangocairo pangoft2)',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(pkg-config --libs-only-L --libs-only-other pangocairo pangoft2)',
- ],
- 'libraries': [
- '<!@(pkg-config --libs-only-l pangocairo pangoft2)',
- ],
- },
- }],
- ],
- }],
- ],
- },
- {
- 'target_name': 'ssl',
- 'type': 'none',
- 'conditions': [
- ['_toolset=="target"', {
- 'conditions': [
- ['use_openssl==1', {
- 'dependencies': [
- '../../third_party/boringssl/boringssl.gyp:boringssl',
- ],
- }, {
- 'dependencies': [
- '../../net/third_party/nss/ssl.gyp:libssl',
- ],
- 'direct_dependent_settings': {
- 'include_dirs+': [
- # We need for our local copies of the libssl3 headers to come
- # before other includes, as we are shadowing system headers.
- '<(DEPTH)/net/third_party/nss/ssl',
- ],
- },
- }],
- # Link in the system NSS if it is used for either the internal
- # crypto library (use_openssl==0) or platform certificate
- # library (use_nss_certs==1).
- ['use_openssl==0 or use_nss_certs==1', {
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(<(pkg-config) --cflags nss)',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(<(pkg-config) --libs-only-L --libs-only-other nss)',
- ],
- 'libraries': [
- '<!@(<(pkg-config) --libs-only-l nss | sed -e "s/-lssl3//")',
- ],
- },
- 'conditions': [
- ['clang==1', {
- 'direct_dependent_settings': {
- 'cflags': [
- # There is a broken header guard in /usr/include/nss/secmod.h:
- # https://bugzilla.mozilla.org/show_bug.cgi?id=884072
- '-Wno-header-guard',
- ],
- },
- }],
- ],
- }],
- ]
- }],
- ],
- },
- ],
-}
diff --git a/build/linux/unbundle/README b/build/linux/unbundle/README
deleted file mode 100644
index d1b2a96..0000000
--- a/build/linux/unbundle/README
+++ /dev/null
@@ -1,44 +0,0 @@
-This directory contains files that make it possible to use system libraries.
-
-For more info please read the following:
-
- - https://fedoraproject.org/wiki/Packaging:No_Bundled_Libraries
- - https://wiki.gentoo.org/wiki/Why_not_bundle_dependencies
- - http://www.debian.org/doc/debian-policy/ch-source.html#s-embeddedfiles
-
-For more Chromium-specific context please read
-http://spot.livejournal.com/312320.html .
-
-This directory is provided in the source tree to follow above guidelines.
-It is a compromise solution which takes into account Chromium developers
-who want to avoid the perceived burden of more conditional code in gyp,
-and expectations of Open Source community, where using system-provided
-libraries is the norm.
-
-Usage:
-
-1. remove_bundled_libraries.py <preserved-directories>
-
- For example: remove_bundled_libraries.py third_party/mesa
-
- The script scans sources looking for third_party directories.
- Everything that is not explicitly preserved is removed (except for
- gyp files), and the script fails if any directory passed on command
- line does not exist (to ensure list is kept up to date).
-
- This is intended to be used on sources extracted from a tarball,
- not a repository.
-
- NOTE: by default this will not remove anything (for safety). Pass
- --do-remove flag to actually remove files.
-
-2. replace_gyp_files.py <gyp-flags>
-
- For example: replace_gyp_files.py -Duse_system_harfbuzz=1
-
- The script ignores flags other than -D for convenience. This makes it
- possible to have a variable e.g. ${myconf} with all the options, and
- execute:
-
- build/linux/unbundle/replace_gyp_files.py ${myconf}
- build/gyp_chromium ${myconf}
diff --git a/build/linux/unbundle/expat.gyp b/build/linux/unbundle/expat.gyp
deleted file mode 100644
index 030fb85..0000000
--- a/build/linux/unbundle/expat.gyp
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
- 'targets': [
- {
- 'target_name': 'expat',
- 'type': 'none',
- 'link_settings': {
- 'libraries': [
- '-lexpat',
- ],
- },
- },
- ],
-}
diff --git a/build/linux/unbundle/ffmpeg.gyp b/build/linux/unbundle/ffmpeg.gyp
deleted file mode 100644
index e3c3723..0000000
--- a/build/linux/unbundle/ffmpeg.gyp
+++ /dev/null
@@ -1,54 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
- 'targets': [
- {
- 'target_name': 'ffmpeg',
- 'type': 'none',
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(pkg-config --cflags libavcodec libavformat libavutil)',
-
- '<!(python <(DEPTH)/tools/compile_test/compile_test.py '
- '--code "#define __STDC_CONSTANT_MACROS\n'
- '#include <libavcodec/avcodec.h>\n'
- 'int test() { return AV_CODEC_ID_OPUS; }" '
- '--on-failure -DCHROMIUM_OMIT_AV_CODEC_ID_OPUS=1)',
-
- '<!(python <(DEPTH)/tools/compile_test/compile_test.py '
- '--code "#define __STDC_CONSTANT_MACROS\n'
- '#include <libavcodec/avcodec.h>\n'
- 'int test() { return AV_CODEC_ID_VP9; }" '
- '--on-failure -DCHROMIUM_OMIT_AV_CODEC_ID_VP9=1)',
-
- '<!(python <(DEPTH)/tools/compile_test/compile_test.py '
- '--code "#define __STDC_CONSTANT_MACROS\n'
- '#include <libavcodec/avcodec.h>\n'
- 'int test() { return AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL; }" '
- '--on-failure -DCHROMIUM_OMIT_AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL=1)',
-
- '<!(python <(DEPTH)/tools/compile_test/compile_test.py '
- '--code "#define __STDC_CONSTANT_MACROS\n'
- '#include <libavcodec/avcodec.h>\n'
- 'int test() { struct AVFrame frame;\n'
- 'return av_frame_get_channels(&frame); }" '
- '--on-failure -DCHROMIUM_NO_AVFRAME_CHANNELS=1)',
- ],
- 'defines': [
- '__STDC_CONSTANT_MACROS',
- 'USE_SYSTEM_FFMPEG',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(pkg-config --libs-only-L --libs-only-other libavcodec libavformat libavutil)',
- ],
- 'libraries': [
- '<!@(pkg-config --libs-only-l libavcodec libavformat libavutil)',
- ],
- },
- },
- ],
-}
diff --git a/build/linux/unbundle/flac.gyp b/build/linux/unbundle/flac.gyp
deleted file mode 100644
index 9e4a664..0000000
--- a/build/linux/unbundle/flac.gyp
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
- 'targets': [
- {
- 'target_name': 'libflac',
- 'type': 'none',
- 'variables': {
- 'headers_root_path': 'include',
- 'header_filenames': [
- 'FLAC/callback.h',
- 'FLAC/metadata.h',
- 'FLAC/assert.h',
- 'FLAC/export.h',
- 'FLAC/format.h',
- 'FLAC/stream_decoder.h',
- 'FLAC/stream_encoder.h',
- 'FLAC/ordinals.h',
- 'FLAC/all.h',
- ],
- },
- 'includes': [
- '../../build/shim_headers.gypi',
- ],
- 'link_settings': {
- 'ldflags': [
- '<!@(pkg-config --libs-only-L --libs-only-other flac)',
- ],
- 'libraries': [
- '<!@(pkg-config --libs-only-l flac)',
- ],
- },
- },
- ],
-}
diff --git a/build/linux/unbundle/harfbuzz.gyp b/build/linux/unbundle/harfbuzz.gyp
deleted file mode 100644
index 3bc1744..0000000
--- a/build/linux/unbundle/harfbuzz.gyp
+++ /dev/null
@@ -1,47 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
- 'variables': {
- # Check for presence of harfbuzz-icu library, use it if present.
- 'harfbuzz_libraries':
- '<!(python <(DEPTH)/tools/compile_test/compile_test.py '
- '--code "int main() { return 0; }" '
- '--run-linker '
- '--on-success "harfbuzz harfbuzz-icu" '
- '--on-failure "harfbuzz" '
- '-- -lharfbuzz-icu)',
- },
- 'targets': [
- {
- 'target_name': 'harfbuzz-ng',
- 'type': 'none',
- 'cflags': [
- '<!@(pkg-config --cflags <(harfbuzz_libraries))',
- ],
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(pkg-config --cflags <(harfbuzz_libraries))',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(pkg-config --libs-only-L --libs-only-other <(harfbuzz_libraries))',
- ],
- 'libraries': [
- '<!@(pkg-config --libs-only-l <(harfbuzz_libraries))',
- ],
- },
- 'variables': {
- 'headers_root_path': 'src',
- 'header_filenames': [
- 'hb.h',
- ],
- },
- 'includes': [
- '../../build/shim_headers.gypi',
- ],
- },
- ],
-}
diff --git a/build/linux/unbundle/icu.gyp b/build/linux/unbundle/icu.gyp
deleted file mode 100644
index 16c36df..0000000
--- a/build/linux/unbundle/icu.gyp
+++ /dev/null
@@ -1,248 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
- 'targets': [
- {
- 'target_name': 'icudata',
- 'type': 'none',
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(pkg-config --cflags icu-uc)',
- ],
- 'defines': [
- 'U_USING_ICU_NAMESPACE=0',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(pkg-config --libs-only-L --libs-only-other icu-uc)',
- ],
- 'libraries': [
- '<!@(pkg-config --libs-only-l icu-uc)',
- ],
- },
- },
- {
- 'target_name': 'icui18n',
- 'type': 'none',
- 'toolsets': ['host', 'target'],
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(pkg-config --cflags icu-i18n)',
- ],
- 'defines': [
- 'U_USING_ICU_NAMESPACE=0',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(pkg-config --libs-only-L --libs-only-other icu-i18n)',
- ],
- 'libraries': [
- '<!@(pkg-config --libs-only-l icu-i18n)',
- ],
- },
- 'variables': {
- 'headers_root_path': 'source/i18n',
- 'header_filenames': [
- # This list can easily be updated using the command below:
- # find third_party/icu/source/i18n/unicode -iname '*.h' \
- # -printf "'%p',\n" | \
- # sed -e 's|third_party/icu/source/i18n/||' | sort -u
- 'unicode/basictz.h',
- 'unicode/bmsearch.h',
- 'unicode/bms.h',
- 'unicode/calendar.h',
- 'unicode/choicfmt.h',
- 'unicode/coleitr.h',
- 'unicode/colldata.h',
- 'unicode/coll.h',
- 'unicode/curramt.h',
- 'unicode/currpinf.h',
- 'unicode/currunit.h',
- 'unicode/datefmt.h',
- 'unicode/dcfmtsym.h',
- 'unicode/decimfmt.h',
- 'unicode/dtfmtsym.h',
- 'unicode/dtitvfmt.h',
- 'unicode/dtitvinf.h',
- 'unicode/dtptngen.h',
- 'unicode/dtrule.h',
- 'unicode/fieldpos.h',
- 'unicode/fmtable.h',
- 'unicode/format.h',
- 'unicode/fpositer.h',
- 'unicode/gregocal.h',
- 'unicode/locdspnm.h',
- 'unicode/measfmt.h',
- 'unicode/measunit.h',
- 'unicode/measure.h',
- 'unicode/msgfmt.h',
- 'unicode/numfmt.h',
- 'unicode/numsys.h',
- 'unicode/plurfmt.h',
- 'unicode/plurrule.h',
- 'unicode/rbnf.h',
- 'unicode/rbtz.h',
- 'unicode/regex.h',
- 'unicode/search.h',
- 'unicode/selfmt.h',
- 'unicode/simpletz.h',
- 'unicode/smpdtfmt.h',
- 'unicode/sortkey.h',
- 'unicode/stsearch.h',
- 'unicode/tblcoll.h',
- 'unicode/timezone.h',
- 'unicode/tmunit.h',
- 'unicode/tmutamt.h',
- 'unicode/tmutfmt.h',
- 'unicode/translit.h',
- 'unicode/tzrule.h',
- 'unicode/tztrans.h',
- 'unicode/ucal.h',
- 'unicode/ucoleitr.h',
- 'unicode/ucol.h',
- 'unicode/ucsdet.h',
- 'unicode/ucurr.h',
- 'unicode/udat.h',
- 'unicode/udatpg.h',
- 'unicode/uldnames.h',
- 'unicode/ulocdata.h',
- 'unicode/umsg.h',
- 'unicode/unirepl.h',
- 'unicode/unum.h',
- 'unicode/uregex.h',
- 'unicode/usearch.h',
- 'unicode/uspoof.h',
- 'unicode/utmscale.h',
- 'unicode/utrans.h',
- 'unicode/vtzone.h',
- ],
- },
- 'includes': [
- '../../build/shim_headers.gypi',
- ],
- },
- {
- 'target_name': 'icuuc',
- 'type': 'none',
- 'toolsets': ['host', 'target'],
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(pkg-config --cflags icu-uc)',
- ],
- 'defines': [
- 'U_USING_ICU_NAMESPACE=0',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(pkg-config --libs-only-L --libs-only-other icu-uc)',
- ],
- 'libraries': [
- '<!@(pkg-config --libs-only-l icu-uc)',
- ],
- },
- 'variables': {
- 'headers_root_path': 'source/common',
- 'header_filenames': [
- # This list can easily be updated using the command below:
- # find third_party/icu/source/common/unicode -iname '*.h' \
- # -printf "'%p',\n" | \
- # sed -e 's|third_party/icu/source/common/||' | sort -u
- 'unicode/brkiter.h',
- 'unicode/bytestream.h',
- 'unicode/caniter.h',
- 'unicode/chariter.h',
- 'unicode/dbbi.h',
- 'unicode/docmain.h',
- 'unicode/dtintrv.h',
- 'unicode/errorcode.h',
- 'unicode/icudataver.h',
- 'unicode/icuplug.h',
- 'unicode/idna.h',
- 'unicode/localpointer.h',
- 'unicode/locid.h',
- 'unicode/normalizer2.h',
- 'unicode/normlzr.h',
- 'unicode/pandroid.h',
- 'unicode/parseerr.h',
- 'unicode/parsepos.h',
- 'unicode/pfreebsd.h',
- 'unicode/plinux.h',
- 'unicode/pmac.h',
- 'unicode/popenbsd.h',
- 'unicode/ppalmos.h',
- 'unicode/ptypes.h',
- 'unicode/putil.h',
- 'unicode/pwin32.h',
- 'unicode/rbbi.h',
- 'unicode/rep.h',
- 'unicode/resbund.h',
- 'unicode/schriter.h',
- 'unicode/std_string.h',
- 'unicode/strenum.h',
- 'unicode/stringpiece.h',
- 'unicode/symtable.h',
- 'unicode/ubidi.h',
- 'unicode/ubrk.h',
- 'unicode/ucasemap.h',
- 'unicode/ucat.h',
- 'unicode/uchar.h',
- 'unicode/uchriter.h',
- 'unicode/uclean.h',
- 'unicode/ucnv_cb.h',
- 'unicode/ucnv_err.h',
- 'unicode/ucnv.h',
- 'unicode/ucnvsel.h',
- 'unicode/uconfig.h',
- 'unicode/udata.h',
- 'unicode/udeprctd.h',
- 'unicode/udraft.h',
- 'unicode/uenum.h',
- 'unicode/uidna.h',
- 'unicode/uintrnal.h',
- 'unicode/uiter.h',
- 'unicode/uloc.h',
- 'unicode/umachine.h',
- 'unicode/umisc.h',
- 'unicode/unifilt.h',
- 'unicode/unifunct.h',
- 'unicode/unimatch.h',
- 'unicode/uniset.h',
- 'unicode/unistr.h',
- 'unicode/unorm2.h',
- 'unicode/unorm.h',
- 'unicode/uobject.h',
- 'unicode/uobslete.h',
- 'unicode/urename.h',
- 'unicode/urep.h',
- 'unicode/ures.h',
- 'unicode/uscript.h',
- 'unicode/uset.h',
- 'unicode/usetiter.h',
- 'unicode/ushape.h',
- 'unicode/usprep.h',
- 'unicode/ustring.h',
- 'unicode/usystem.h',
- 'unicode/utext.h',
- 'unicode/utf16.h',
- 'unicode/utf32.h',
- 'unicode/utf8.h',
- 'unicode/utf.h',
- 'unicode/utf_old.h',
- 'unicode/utrace.h',
- 'unicode/utypeinfo.h',
- 'unicode/utypes.h',
- 'unicode/uvernum.h',
- 'unicode/uversion.h',
- ],
- },
- 'includes': [
- '../../build/shim_headers.gypi',
- ],
- },
- ],
-}
diff --git a/build/linux/unbundle/jsoncpp.gyp b/build/linux/unbundle/jsoncpp.gyp
deleted file mode 100644
index c397f64..0000000
--- a/build/linux/unbundle/jsoncpp.gyp
+++ /dev/null
@@ -1,39 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
- 'targets': [
- {
- 'target_name': 'jsoncpp',
- 'type': 'none',
- 'variables': {
- 'headers_root_path': 'source/include',
- 'header_filenames': [
- 'json/assertions.h',
- 'json/autolink.h',
- 'json/config.h',
- 'json/features.h',
- 'json/forwards.h',
- 'json/json.h',
- 'json/reader.h',
- 'json/value.h',
- 'json/writer.h',
- ],
- },
- 'includes': [
- '../../build/shim_headers.gypi',
- ],
- 'direct_dependent_settings': {
- 'include_dirs': [
- '/usr/include/jsoncpp',
- ],
- },
- 'link_settings': {
- 'libraries': [
- '-ljsoncpp',
- ],
- },
- }
- ],
-}
diff --git a/build/linux/unbundle/libXNVCtrl.gyp b/build/linux/unbundle/libXNVCtrl.gyp
deleted file mode 100644
index f076bdb..0000000
--- a/build/linux/unbundle/libXNVCtrl.gyp
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
- 'targets': [
- {
- 'target_name': 'libXNVCtrl',
- 'type': 'none',
- 'variables': {
- 'headers_root_path': '.',
- 'header_filenames': [
- 'NVCtrlLib.h',
- 'NVCtrl.h',
- ],
- },
- 'includes': [
- '../../build/shim_headers.gypi',
- ],
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(pkg-config --cflags libXNVCtrl)',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(pkg-config --libs-only-L --libs-only-other libXNVCtrl)',
- ],
- 'libraries': [
- '<!@(pkg-config --libs-only-l libXNVCtrl)',
- ],
- },
- }
- ],
-}
diff --git a/build/linux/unbundle/libevent.gyp b/build/linux/unbundle/libevent.gyp
deleted file mode 100644
index 99d7435..0000000
--- a/build/linux/unbundle/libevent.gyp
+++ /dev/null
@@ -1,27 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
- 'targets': [
- {
- 'target_name': 'libevent',
- 'type': 'none',
- 'toolsets': ['host', 'target'],
- 'variables': {
- 'headers_root_path': '.',
- 'header_filenames': [
- 'event.h',
- ],
- },
- 'includes': [
- '../../build/shim_headers.gypi',
- ],
- 'link_settings': {
- 'libraries': [
- '-levent',
- ],
- },
- }
- ],
-}
diff --git a/build/linux/unbundle/libjpeg.gyp b/build/linux/unbundle/libjpeg.gyp
deleted file mode 100644
index f56e7aa..0000000
--- a/build/linux/unbundle/libjpeg.gyp
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
- 'targets': [
- {
- 'target_name': 'libjpeg',
- 'type': 'none',
- 'direct_dependent_settings': {
- 'defines': [
- 'USE_SYSTEM_LIBJPEG',
- ],
- 'conditions': [
- ['os_bsd==1', {
- 'include_dirs': [
- '/usr/local/include',
- ],
- }],
- ],
- },
- 'link_settings': {
- 'libraries': [
- '-ljpeg',
- ],
- },
- }
- ],
-}
diff --git a/build/linux/unbundle/libpng.gyp b/build/linux/unbundle/libpng.gyp
deleted file mode 100644
index d6933fc..0000000
--- a/build/linux/unbundle/libpng.gyp
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
- 'targets': [
- {
- 'target_name': 'libpng',
- 'type': 'none',
- 'dependencies': [
- '../zlib/zlib.gyp:zlib',
- ],
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(pkg-config --cflags libpng)',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(pkg-config --libs-only-L --libs-only-other libpng)',
- ],
- 'libraries': [
- '<!@(pkg-config --libs-only-l libpng)',
- ],
- },
- 'variables': {
- 'headers_root_path': '.',
- 'header_filenames': [
- 'png.h',
- 'pngconf.h',
- ],
- },
- 'includes': [
- '../../build/shim_headers.gypi',
- ],
- },
- ],
-}
diff --git a/build/linux/unbundle/libusb.gyp b/build/linux/unbundle/libusb.gyp
deleted file mode 100644
index 1c18033..0000000
--- a/build/linux/unbundle/libusb.gyp
+++ /dev/null
@@ -1,34 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
- 'targets': [
- {
- 'target_name': 'libusb',
- 'type': 'none',
- 'variables': {
- 'headers_root_path': 'src/libusb',
- 'header_filenames': [
- 'libusb.h',
- ],
- },
- 'includes': [
- '../../build/shim_headers.gypi',
- ],
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(pkg-config --cflags libusb-1.0)',
- ],
- 'link_settings': {
- 'ldflags': [
- '<!@(pkg-config --libs-only-L --libs-only-other libusb-1.0)',
- ],
- 'libraries': [
- '<!@(pkg-config --libs-only-l libusb-1.0)',
- ],
- },
- },
- },
- ],
-}
diff --git a/build/linux/unbundle/libvpx.gyp b/build/linux/unbundle/libvpx.gyp
deleted file mode 100644
index 75671c5..0000000
--- a/build/linux/unbundle/libvpx.gyp
+++ /dev/null
@@ -1,43 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-{
- 'targets': [
- {
- 'target_name': 'libvpx',
- 'type': 'none',
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(pkg-config --cflags vpx)',
- ],
- },
- 'variables': {
- 'headers_root_path': 'source/libvpx',
- 'header_filenames': [
- 'vpx/vp8.h',
- 'vpx/vp8cx.h',
- 'vpx/vp8dx.h',
- 'vpx/vpx_codec.h',
- 'vpx/vpx_codec_impl_bottom.h',
- 'vpx/vpx_codec_impl_top.h',
- 'vpx/vpx_decoder.h',
- 'vpx/vpx_encoder.h',
- 'vpx/vpx_frame_buffer.h',
- 'vpx/vpx_image.h',
- 'vpx/vpx_integer.h',
- ],
- },
- 'includes': [
- '../../build/shim_headers.gypi',
- ],
- 'link_settings': {
- 'ldflags': [
- '<!@(pkg-config --libs-only-L --libs-only-other vpx)',
- ],
- 'libraries': [
- '<!@(pkg-config --libs-only-l vpx)',
- ],
- },
- },
- ],
-}
diff --git a/build/linux/unbundle/libwebp.gyp b/build/linux/unbundle/libwebp.gyp
deleted file mode 100644
index 6dbce2e..0000000
--- a/build/linux/unbundle/libwebp.gyp
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
- 'targets': [
- {
- 'target_name': 'libwebp',
- 'type': 'none',
- 'direct_dependent_settings': {
- 'defines': [
- 'ENABLE_WEBP',
- ],
- },
- 'link_settings': {
- 'libraries': [
- # Check for presence of webpdemux library, use it if present.
- '<!(python <(DEPTH)/tools/compile_test/compile_test.py '
- '--code "int main() { return 0; }" '
- '--run-linker '
- '--on-success "-lwebp -lwebpdemux" '
- '--on-failure "-lwebp" '
- '-- -lwebpdemux)',
- ],
- },
- }
- ],
-}
diff --git a/build/linux/unbundle/libxml.gyp b/build/linux/unbundle/libxml.gyp
deleted file mode 100644
index bc4f9fc..0000000
--- a/build/linux/unbundle/libxml.gyp
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
- 'targets': [
- {
- 'target_name': 'libxml',
- 'type': 'static_library',
- 'sources': [
- 'chromium/libxml_utils.h',
- 'chromium/libxml_utils.cc',
- ],
- 'cflags': [
- '<!@(pkg-config --cflags libxml-2.0)',
- ],
- 'defines': [
- 'USE_SYSTEM_LIBXML',
- ],
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(pkg-config --cflags libxml-2.0)',
- ],
- 'defines': [
- 'USE_SYSTEM_LIBXML',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(pkg-config --libs-only-L --libs-only-other libxml-2.0)',
- ],
- 'libraries': [
- '<!@(pkg-config --libs-only-l libxml-2.0)',
- ],
- },
- },
- ],
-}
diff --git a/build/linux/unbundle/libxslt.gyp b/build/linux/unbundle/libxslt.gyp
deleted file mode 100644
index f7f6bb9..0000000
--- a/build/linux/unbundle/libxslt.gyp
+++ /dev/null
@@ -1,25 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
- 'targets': [
- {
- 'target_name': 'libxslt',
- 'type': 'none',
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(pkg-config --cflags libxslt)',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(pkg-config --libs-only-L --libs-only-other libxslt)',
- ],
- 'libraries': [
- '<!@(pkg-config --libs-only-l libxslt)',
- ],
- },
- },
- ],
-}
diff --git a/build/linux/unbundle/opus.gyp b/build/linux/unbundle/opus.gyp
deleted file mode 100644
index e8c30ba..0000000
--- a/build/linux/unbundle/opus.gyp
+++ /dev/null
@@ -1,38 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
- 'targets': [
- {
- 'target_name': 'opus',
- 'type': 'none',
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(pkg-config --cflags opus)',
- ],
- },
- 'variables': {
- 'headers_root_path': 'src/include',
- 'header_filenames': [
- 'opus_custom.h',
- 'opus_defines.h',
- 'opus_multistream.h',
- 'opus_types.h',
- 'opus.h',
- ],
- },
- 'includes': [
- '../../build/shim_headers.gypi',
- ],
- 'link_settings': {
- 'ldflags': [
- '<!@(pkg-config --libs-only-L --libs-only-other opus)',
- ],
- 'libraries': [
- '<!@(pkg-config --libs-only-l opus)',
- ],
- },
- },
- ],
-}
diff --git a/build/linux/unbundle/protobuf.gyp b/build/linux/unbundle/protobuf.gyp
deleted file mode 100644
index 7bcd992..0000000
--- a/build/linux/unbundle/protobuf.gyp
+++ /dev/null
@@ -1,149 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
- 'targets': [
- {
- 'target_name': 'protobuf_lite',
- 'type': 'none',
- 'direct_dependent_settings': {
- 'cflags': [
- # Use full protobuf, because vanilla protobuf doesn't have
- # our custom patch to retain unknown fields in lite mode.
- '<!@(pkg-config --cflags protobuf)',
- ],
- 'defines': [
- 'USE_SYSTEM_PROTOBUF',
-
- # This macro must be defined to suppress the use
- # of dynamic_cast<>, which requires RTTI.
- 'GOOGLE_PROTOBUF_NO_RTTI',
- 'GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER',
- ],
- },
- 'link_settings': {
- # Use full protobuf, because vanilla protobuf doesn't have
- # our custom patch to retain unknown fields in lite mode.
- 'ldflags': [
- '<!@(pkg-config --libs-only-L --libs-only-other protobuf)',
- ],
- 'libraries': [
- '<!@(pkg-config --libs-only-l protobuf)',
- ],
- },
- 'variables': {
- 'headers_root_path': 'src',
- 'header_filenames': [
- # This list can easily be updated using the command below:
- # find third_party/protobuf/src -iname '*.h' -printf "'%p',\n" | \
- # sed -e 's|third_party/protobuf/src/||' | sort -u
- 'google/protobuf/compiler/code_generator.h',
- 'google/protobuf/compiler/command_line_interface.h',
- 'google/protobuf/compiler/cpp/cpp_enum_field.h',
- 'google/protobuf/compiler/cpp/cpp_enum.h',
- 'google/protobuf/compiler/cpp/cpp_extension.h',
- 'google/protobuf/compiler/cpp/cpp_field.h',
- 'google/protobuf/compiler/cpp/cpp_file.h',
- 'google/protobuf/compiler/cpp/cpp_generator.h',
- 'google/protobuf/compiler/cpp/cpp_helpers.h',
- 'google/protobuf/compiler/cpp/cpp_message_field.h',
- 'google/protobuf/compiler/cpp/cpp_message.h',
- 'google/protobuf/compiler/cpp/cpp_options.h',
- 'google/protobuf/compiler/cpp/cpp_primitive_field.h',
- 'google/protobuf/compiler/cpp/cpp_service.h',
- 'google/protobuf/compiler/cpp/cpp_string_field.h',
- 'google/protobuf/compiler/cpp/cpp_unittest.h',
- 'google/protobuf/compiler/importer.h',
- 'google/protobuf/compiler/java/java_doc_comment.h',
- 'google/protobuf/compiler/java/java_enum_field.h',
- 'google/protobuf/compiler/java/java_enum.h',
- 'google/protobuf/compiler/java/java_extension.h',
- 'google/protobuf/compiler/java/java_field.h',
- 'google/protobuf/compiler/java/java_file.h',
- 'google/protobuf/compiler/java/java_generator.h',
- 'google/protobuf/compiler/java/java_helpers.h',
- 'google/protobuf/compiler/java/java_message_field.h',
- 'google/protobuf/compiler/java/java_message.h',
- 'google/protobuf/compiler/java/java_primitive_field.h',
- 'google/protobuf/compiler/java/java_service.h',
- 'google/protobuf/compiler/java/java_string_field.h',
- 'google/protobuf/compiler/mock_code_generator.h',
- 'google/protobuf/compiler/package_info.h',
- 'google/protobuf/compiler/parser.h',
- 'google/protobuf/compiler/plugin.h',
- 'google/protobuf/compiler/plugin.pb.h',
- 'google/protobuf/compiler/python/python_generator.h',
- 'google/protobuf/compiler/subprocess.h',
- 'google/protobuf/compiler/zip_writer.h',
- 'google/protobuf/descriptor_database.h',
- 'google/protobuf/descriptor.h',
- 'google/protobuf/descriptor.pb.h',
- 'google/protobuf/dynamic_message.h',
- 'google/protobuf/extension_set.h',
- 'google/protobuf/generated_enum_reflection.h',
- 'google/protobuf/generated_message_reflection.h',
- 'google/protobuf/generated_message_util.h',
- 'google/protobuf/io/coded_stream.h',
- 'google/protobuf/io/coded_stream_inl.h',
- 'google/protobuf/io/gzip_stream.h',
- 'google/protobuf/io/package_info.h',
- 'google/protobuf/io/printer.h',
- 'google/protobuf/io/tokenizer.h',
- 'google/protobuf/io/zero_copy_stream.h',
- 'google/protobuf/io/zero_copy_stream_impl.h',
- 'google/protobuf/io/zero_copy_stream_impl_lite.h',
- 'google/protobuf/message.h',
- 'google/protobuf/message_lite.h',
- 'google/protobuf/package_info.h',
- 'google/protobuf/reflection_ops.h',
- 'google/protobuf/repeated_field.h',
- 'google/protobuf/service.h',
- 'google/protobuf/stubs/atomicops.h',
- 'google/protobuf/stubs/atomicops_internals_arm64_gcc.h',
- 'google/protobuf/stubs/atomicops_internals_arm_gcc.h',
- 'google/protobuf/stubs/atomicops_internals_arm_qnx.h',
- 'google/protobuf/stubs/atomicops_internals_atomicword_compat.h',
- 'google/protobuf/stubs/atomicops_internals_macosx.h',
- 'google/protobuf/stubs/atomicops_internals_mips_gcc.h',
- 'google/protobuf/stubs/atomicops_internals_pnacl.h',
- 'google/protobuf/stubs/atomicops_internals_tsan.h',
- 'google/protobuf/stubs/atomicops_internals_x86_gcc.h',
- 'google/protobuf/stubs/atomicops_internals_x86_msvc.h',
- 'google/protobuf/stubs/common.h',
- 'google/protobuf/stubs/hash.h',
- 'google/protobuf/stubs/map-util.h',
- 'google/protobuf/stubs/once.h',
- 'google/protobuf/stubs/platform_macros.h',
- 'google/protobuf/stubs/stl_util.h',
- 'google/protobuf/stubs/stringprintf.h',
- 'google/protobuf/stubs/strutil.h',
- 'google/protobuf/stubs/substitute.h',
- 'google/protobuf/stubs/template_util.h',
- 'google/protobuf/stubs/type_traits.h',
- 'google/protobuf/testing/file.h',
- 'google/protobuf/testing/googletest.h',
- 'google/protobuf/test_util.h',
- 'google/protobuf/test_util_lite.h',
- 'google/protobuf/text_format.h',
- 'google/protobuf/unknown_field_set.h',
- 'google/protobuf/wire_format.h',
- 'google/protobuf/wire_format_lite.h',
- 'google/protobuf/wire_format_lite_inl.h',
- ],
- },
- 'includes': [
- '../../build/shim_headers.gypi',
- ],
- },
- {
- 'target_name': 'protoc',
- 'type': 'none',
- 'toolsets': ['host', 'target'],
- },
- {
- 'target_name': 'py_proto',
- 'type': 'none',
- },
- ],
-}
diff --git a/build/linux/unbundle/re2.gyp b/build/linux/unbundle/re2.gyp
deleted file mode 100644
index e2e567a..0000000
--- a/build/linux/unbundle/re2.gyp
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
- 'targets': [
- {
- 'target_name': 're2',
- 'type': 'none',
- 'variables': {
- 'headers_root_path': '.',
- 'header_filenames': [
- 're2/filtered_re2.h',
- 're2/re2.h',
- 're2/set.h',
- 're2/stringpiece.h',
- 're2/variadic_function.h',
- ],
- 'shim_generator_additional_args': [
- # Chromium copy of re2 is patched to rename POSIX to POSIX_SYNTAX
- # because of collision issues that break the build.
- # Upstream refuses to make changes:
- # http://code.google.com/p/re2/issues/detail?id=73 .
- '--define', 'POSIX=POSIX_SYNTAX',
- ],
- },
- 'includes': [
- '../../build/shim_headers.gypi',
- ],
- 'link_settings': {
- 'libraries': [
- '-lre2',
- ],
- },
- }
- ],
-}
diff --git a/build/linux/unbundle/remove_bundled_libraries.py b/build/linux/unbundle/remove_bundled_libraries.py
deleted file mode 100755
index 69e76f5..0000000
--- a/build/linux/unbundle/remove_bundled_libraries.py
+++ /dev/null
@@ -1,102 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""
-Removes bundled libraries to make sure they are not used.
-
-See README for more details.
-"""
-
-
-import optparse
-import os.path
-import sys
-
-
-def DoMain(argv):
- my_dirname = os.path.abspath(os.path.dirname(__file__))
- source_tree_root = os.path.abspath(
- os.path.join(my_dirname, '..', '..', '..'))
-
- if os.path.join(source_tree_root, 'build', 'linux', 'unbundle') != my_dirname:
- print ('Sanity check failed: please run this script from ' +
- 'build/linux/unbundle directory.')
- return 1
-
- parser = optparse.OptionParser()
- parser.add_option('--do-remove', action='store_true')
-
- options, args = parser.parse_args(argv)
-
- exclusion_used = {}
- for exclusion in args:
- exclusion_used[exclusion] = False
-
- for root, dirs, files in os.walk(source_tree_root, topdown=False):
- # Only look at paths which contain a "third_party" component
- # (note that e.g. third_party.png doesn't count).
- root_relpath = os.path.relpath(root, source_tree_root)
- if 'third_party' not in root_relpath.split(os.sep):
- continue
-
- for f in files:
- path = os.path.join(root, f)
- relpath = os.path.relpath(path, source_tree_root)
-
- excluded = False
- for exclusion in args:
- # Require precise exclusions. Find the right-most third_party
- # in the relative path, and if there is more than one ignore
- # the exclusion if it's completely contained within the part
- # before right-most third_party path component.
- split = relpath.rsplit(os.sep + 'third_party' + os.sep, 1)
- if len(split) > 1 and split[0].startswith(exclusion):
- continue
-
- if relpath.startswith(exclusion):
- # Multiple exclusions can match the same path. Go through all of them
- # and mark each one as used.
- exclusion_used[exclusion] = True
- excluded = True
- if excluded:
- continue
-
- # Deleting gyp files almost always leads to gyp failures.
- # These files come from Chromium project, and can be replaced if needed.
- if f.endswith('.gyp') or f.endswith('.gypi'):
- continue
-
- # Deleting .isolate files leads to gyp failures. They are usually
- # not used by a distro build anyway.
- # See http://www.chromium.org/developers/testing/isolated-testing
- # for more info.
- if f.endswith('.isolate'):
- continue
-
- if options.do_remove:
- # Delete the file - best way to ensure it's not used during build.
- os.remove(path)
- else:
- # By default just print paths that would be removed.
- print path
-
- exit_code = 0
-
- # Fail if exclusion list contains stale entries - this helps keep it
- # up to date.
- for exclusion, used in exclusion_used.iteritems():
- if not used:
- print '%s does not exist' % exclusion
- exit_code = 1
-
- if not options.do_remove:
- print ('To actually remove files printed above, please pass ' +
- '--do-remove flag.')
-
- return exit_code
-
-
-if __name__ == '__main__':
- sys.exit(DoMain(sys.argv[1:]))
diff --git a/build/linux/unbundle/replace_gyp_files.py b/build/linux/unbundle/replace_gyp_files.py
deleted file mode 100755
index d06ae41..0000000
--- a/build/linux/unbundle/replace_gyp_files.py
+++ /dev/null
@@ -1,82 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""
-Replaces gyp files in tree with files from here that
-make the build use system libraries.
-"""
-
-
-import optparse
-import os.path
-import shutil
-import sys
-
-
-REPLACEMENTS = {
- 'use_system_expat': 'third_party/expat/expat.gyp',
- 'use_system_ffmpeg': 'third_party/ffmpeg/ffmpeg.gyp',
- 'use_system_flac': 'third_party/flac/flac.gyp',
- 'use_system_harfbuzz': 'third_party/harfbuzz-ng/harfbuzz.gyp',
- 'use_system_icu': 'third_party/icu/icu.gyp',
- 'use_system_jsoncpp': 'third_party/jsoncpp/jsoncpp.gyp',
- 'use_system_libevent': 'third_party/libevent/libevent.gyp',
- 'use_system_libjpeg': 'third_party/libjpeg/libjpeg.gyp',
- 'use_system_libpng': 'third_party/libpng/libpng.gyp',
- 'use_system_libusb': 'third_party/libusb/libusb.gyp',
- 'use_system_libvpx': 'third_party/libvpx/libvpx.gyp',
- 'use_system_libwebp': 'third_party/libwebp/libwebp.gyp',
- 'use_system_libxml': 'third_party/libxml/libxml.gyp',
- 'use_system_libxnvctrl' : 'third_party/libXNVCtrl/libXNVCtrl.gyp',
- 'use_system_libxslt': 'third_party/libxslt/libxslt.gyp',
- 'use_system_opus': 'third_party/opus/opus.gyp',
- 'use_system_protobuf': 'third_party/protobuf/protobuf.gyp',
- 'use_system_re2': 'third_party/re2/re2.gyp',
- 'use_system_snappy': 'third_party/snappy/snappy.gyp',
- 'use_system_speex': 'third_party/speex/speex.gyp',
- 'use_system_sqlite': 'third_party/sqlite/sqlite.gyp',
- 'use_system_v8': 'v8/tools/gyp/v8.gyp',
- 'use_system_zlib': 'third_party/zlib/zlib.gyp',
-}
-
-
-def DoMain(argv):
- my_dirname = os.path.dirname(__file__)
- source_tree_root = os.path.abspath(
- os.path.join(my_dirname, '..', '..', '..'))
-
- parser = optparse.OptionParser()
-
- # Accept arguments in gyp command-line syntax, so that the caller can re-use
- # command-line for this script and gyp.
- parser.add_option('-D', dest='defines', action='append')
-
- parser.add_option('--undo', action='store_true')
-
- options, args = parser.parse_args(argv)
-
- for flag, path in REPLACEMENTS.items():
- if '%s=1' % flag not in options.defines:
- continue
-
- if options.undo:
- # Restore original file, and also remove the backup.
- # This is meant to restore the source tree to its original state.
- os.rename(os.path.join(source_tree_root, path + '.orig'),
- os.path.join(source_tree_root, path))
- else:
- # Create a backup copy for --undo.
- shutil.copyfile(os.path.join(source_tree_root, path),
- os.path.join(source_tree_root, path + '.orig'))
-
- # Copy the gyp file from directory of this script to target path.
- shutil.copyfile(os.path.join(my_dirname, os.path.basename(path)),
- os.path.join(source_tree_root, path))
-
- return 0
-
-
-if __name__ == '__main__':
- sys.exit(DoMain(sys.argv))
diff --git a/build/linux/unbundle/snappy.gyp b/build/linux/unbundle/snappy.gyp
deleted file mode 100644
index ab856ed..0000000
--- a/build/linux/unbundle/snappy.gyp
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
- 'targets': [
- {
- 'target_name': 'snappy',
- 'type': 'none',
- 'variables': {
- 'headers_root_path': 'src',
- 'header_filenames': [
- 'snappy-c.h',
- 'snappy-sinksource.h',
- 'snappy-stubs-public.h',
- 'snappy.h',
- ],
- },
- 'includes': [
- '../../build/shim_headers.gypi',
- ],
- 'link_settings': {
- 'libraries': [
- '-lsnappy',
- ],
- },
- },
- ],
-}
diff --git a/build/linux/unbundle/speex.gyp b/build/linux/unbundle/speex.gyp
deleted file mode 100644
index 75376c8..0000000
--- a/build/linux/unbundle/speex.gyp
+++ /dev/null
@@ -1,45 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
- 'targets': [
- {
- 'target_name': 'libspeex',
- 'type': 'none',
- 'variables': {
- 'headers_root_path': 'include',
- 'header_filenames': [
- 'speex/speex_types.h',
- 'speex/speex_callbacks.h',
- 'speex/speex_config_types.h',
- 'speex/speex_stereo.h',
- 'speex/speex_echo.h',
- 'speex/speex_preprocess.h',
- 'speex/speex_jitter.h',
- 'speex/speex.h',
- 'speex/speex_resampler.h',
- 'speex/speex_buffer.h',
- 'speex/speex_header.h',
- 'speex/speex_bits.h',
- ],
- },
- 'includes': [
- '../../build/shim_headers.gypi',
- ],
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(pkg-config --cflags speex)',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(pkg-config --libs-only-L --libs-only-other speex)',
- ],
- 'libraries': [
- '<!@(pkg-config --libs-only-l speex)',
- ],
- },
- },
- ],
-}
diff --git a/build/linux/unbundle/sqlite.gyp b/build/linux/unbundle/sqlite.gyp
deleted file mode 100644
index 918da928..0000000
--- a/build/linux/unbundle/sqlite.gyp
+++ /dev/null
@@ -1,28 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
- 'targets': [
- {
- 'target_name': 'sqlite',
- 'type': 'none',
- 'direct_dependent_settings': {
- 'cflags': [
- '<!@(pkg-config --cflags sqlite3)',
- ],
- 'defines': [
- 'USE_SYSTEM_SQLITE',
- ],
- },
- 'link_settings': {
- 'ldflags': [
- '<!@(pkg-config --libs-only-L --libs-only-other sqlite3)',
- ],
- 'libraries': [
- '<!@(pkg-config --libs-only-l sqlite3)',
- ],
- },
- },
- ],
-}
diff --git a/build/linux/unbundle/v8.gyp b/build/linux/unbundle/v8.gyp
deleted file mode 100644
index 9b06347..0000000
--- a/build/linux/unbundle/v8.gyp
+++ /dev/null
@@ -1,64 +0,0 @@
-# Copyright 2013 the V8 project authors. All rights reserved.
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following
-# disclaimer in the documentation and/or other materials provided
-# with the distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived
-# from this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-{
- 'includes': ['../../build/toolchain.gypi', '../../build/features.gypi'],
- 'targets': [
- {
- 'target_name': 'v8',
- 'type': 'none',
- 'toolsets': ['host', 'target'],
- 'variables': {
- 'headers_root_path': '../../include',
- 'header_filenames': [
- 'v8-debug.h',
- 'v8-preparser.h',
- 'v8-profiler.h',
- 'v8-testing.h',
- 'v8.h',
- 'v8stdint.h',
- ],
- },
- 'includes': [
- '../../../build/shim_headers.gypi',
- ],
- 'link_settings': {
- 'libraries': [
- '-lv8',
- ],
- },
- },
- {
- 'target_name': 'v8_shell',
- 'type': 'none',
- 'toolsets': ['host', 'target'],
- 'dependencies': [
- 'v8'
- ],
- },
- ],
-}
diff --git a/build/linux/unbundle/zlib.gyp b/build/linux/unbundle/zlib.gyp
deleted file mode 100644
index 0a85ff0..0000000
--- a/build/linux/unbundle/zlib.gyp
+++ /dev/null
@@ -1,67 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
- 'targets': [
- {
- 'target_name': 'zlib',
- 'type': 'none',
- 'variables': {
- 'headers_root_path': '.',
- 'header_filenames': [
- 'zlib.h',
- ],
- },
- 'includes': [
- '../../build/shim_headers.gypi',
- ],
- 'direct_dependent_settings': {
- 'defines': [
- 'USE_SYSTEM_ZLIB',
- ],
- },
- 'link_settings': {
- 'libraries': [
- '-lz',
- ],
- },
- },
- {
- 'target_name': 'minizip',
- 'type': 'static_library',
- 'all_dependent_settings': {
- 'defines': [
- 'USE_SYSTEM_MINIZIP',
- ],
- },
- 'defines': [
- 'USE_SYSTEM_MINIZIP',
- ],
- 'link_settings': {
- 'libraries': [
- '-lminizip',
- ],
- },
- },
- {
- 'target_name': 'zip',
- 'type': 'static_library',
- 'dependencies': [
- 'minizip',
- '../../base/base.gyp:base',
- ],
- 'include_dirs': [
- '../..',
- ],
- 'sources': [
- 'google/zip.cc',
- 'google/zip.h',
- 'google/zip_internal.cc',
- 'google/zip_internal.h',
- 'google/zip_reader.cc',
- 'google/zip_reader.h',
- ],
- },
- ],
-}
diff --git a/build/ls.py b/build/ls.py
deleted file mode 100755
index 638c3bd..0000000
--- a/build/ls.py
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/usr/bin/python
-# Copyright 2015 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Recursively list files of the target directory. Ignores dot files."""
-
-import argparse
-import os
-import sys
-
-def main(target_directory):
- for root, dirs, files in os.walk(target_directory):
- files = [f for f in files if not f[0] == '.']
- dirs[:] = [d for d in dirs if not d[0] == '.']
- for f in files:
- path = os.path.join(root, f)
- print path
-
-if __name__ == '__main__':
- parser = argparse.ArgumentParser(
- description="Recursively list files of the target directory")
- parser.add_argument("--target-directory",
- dest="target_directory",
- metavar="<target-directory>",
- type=str,
- required=True,
- help="The target directory")
-
- args = parser.parse_args()
- sys.exit(main(args.target_directory))
diff --git a/build/nocompile.gypi b/build/nocompile.gypi
deleted file mode 100644
index 8c0f288..0000000
--- a/build/nocompile.gypi
+++ /dev/null
@@ -1,96 +0,0 @@
-# Copyright (c) 2011 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included into an target to create a unittest that
-# invokes a set of no-compile tests. A no-compile test is a test that asserts
-# a particular construct will not compile.
-#
-# Also see:
-# http://dev.chromium.org/developers/testing/no-compile-tests
-#
-# To use this, create a gyp target with the following form:
-# {
-# 'target_name': 'my_module_nc_unittests',
-# 'type': 'executable',
-# 'sources': [
-# 'nc_testset_1.nc',
-# 'nc_testset_2.nc',
-# ],
-# 'includes': ['path/to/this/gypi/file'],
-# }
-#
-# The .nc files are C++ files that contain code we wish to assert will not
-# compile. Each individual test case in the file should be put in its own
-# #ifdef section. The expected output should be appended with a C++-style
-# comment that has a python list of regular expressions. This will likely
-# be greater than 80-characters. Giving a solid expected output test is
-# important so that random compile failures do not cause the test to pass.
-#
-# Example .nc file:
-#
-# #if defined(TEST_NEEDS_SEMICOLON) // [r"expected ',' or ';' at end of input"]
-#
-# int a = 1
-#
-# #elif defined(TEST_NEEDS_CAST) // [r"invalid conversion from 'void*' to 'char*'"]
-#
-# void* a = NULL;
-# char* b = a;
-#
-# #endif
-#
-# If we needed disable TEST_NEEDS_SEMICOLON, then change the define to:
-#
-# DISABLE_TEST_NEEDS_SEMICOLON
-# TEST_NEEDS_CAST
-#
-# The lines above are parsed by a regexp so avoid getting creative with the
-# formatting or ifdef logic; it will likely just not work.
-#
-# Implementation notes:
-# The .nc files are actually processed by a python script which executes the
-# compiler and generates a .cc file that is empty on success, or will have a
-# series of #error lines on failure, and a set of trivially passing gunit
-# TEST() functions on success. This allows us to fail at the compile step when
-# something goes wrong, and know during the unittest run that the test was at
-# least processed when things go right.
-
-{
- # TODO(awong): Disabled until http://crbug.com/105388 is resolved.
- 'sources/': [['exclude', '\\.nc$']],
- 'conditions': [
- [ 'OS!="win" and clang==1', {
- 'rules': [
- {
- 'variables': {
- 'nocompile_driver': '<(DEPTH)/tools/nocompile_driver.py',
- 'nc_result_path': ('<(INTERMEDIATE_DIR)/<(module_dir)/'
- '<(RULE_INPUT_ROOT)_nc.cc'),
- },
- 'rule_name': 'run_nocompile',
- 'extension': 'nc',
- 'inputs': [
- '<(nocompile_driver)',
- ],
- 'outputs': [
- '<(nc_result_path)'
- ],
- 'action': [
- 'python',
- '<(nocompile_driver)',
- '4', # number of compilers to invoke in parallel.
- '<(RULE_INPUT_PATH)',
- '-Wall -Werror -Wfatal-errors -I<(DEPTH)',
- '<(nc_result_path)',
- ],
- 'message': 'Generating no compile results for <(RULE_INPUT_PATH)',
- 'process_outputs_as_sources': 1,
- },
- ],
- }, {
- 'sources/': [['exclude', '\\.nc$']]
- }], # 'OS!="win" and clang=="1"'
- ],
-}
-
diff --git a/build/output_dll_copy.rules b/build/output_dll_copy.rules
deleted file mode 100644
index c6e9051..0000000
--- a/build/output_dll_copy.rules
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<VisualStudioToolFile
- Name="Output DLL copy"
- Version="8.00"
- >
- <Rules>
- <CustomBuildRule
- Name="Output DLL copy"
- CommandLine="xcopy /R /C /Y $(InputPath) $(OutDir)"
- Outputs="$(OutDir)\$(InputFileName)"
- FileExtensions="*.dll"
- >
- <Properties>
- </Properties>
- </CustomBuildRule>
- </Rules>
-</VisualStudioToolFile>
diff --git a/build/precompile.cc b/build/precompile.cc
deleted file mode 100644
index db1ef6d..0000000
--- a/build/precompile.cc
+++ /dev/null
@@ -1,7 +0,0 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Precompiled header generator for Windows builds. No include is needed
-// in this file as the PCH include is forced via the "Forced Include File"
-// flag in the projects generated by GYP.
diff --git a/build/precompile.h b/build/precompile.h
deleted file mode 100644
index 32c2f11..0000000
--- a/build/precompile.h
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Precompiled header for Chromium project on Windows, not used by
-// other build configurations. Using precompiled headers speeds the
-// build up significantly, around 1/4th on VS 2010 on an HP Z600 with 12
-// GB of memory.
-//
-// Numeric comments beside includes are the number of times they were
-// included under src/chrome/browser on 2011/8/20, which was used as a
-// baseline for deciding what to include in the PCH. Includes without
-// a numeric comment are generally included at least 5 times. It may
-// be possible to tweak the speed of the build by commenting out or
-// removing some of the less frequently used headers.
-
-#if defined(BUILD_PRECOMPILE_H_)
-#error You shouldn't include the precompiled header file more than once.
-#endif
-
-#define BUILD_PRECOMPILE_H_
-
-#define _USE_MATH_DEFINES
-
-// The Windows header needs to come before almost all the other
-// Windows-specific headers.
-#include <Windows.h>
-#include <dwmapi.h>
-#include <shellapi.h>
-#include <wtypes.h> // 2
-
-// Defines in atlbase.h cause conflicts; if we could figure out how
-// this family of headers can be included in the PCH, it might speed
-// up the build as several of them are used frequently.
-/*
-#include <atlbase.h>
-#include <atlapp.h>
-#include <atlcom.h>
-#include <atlcrack.h> // 2
-#include <atlctrls.h> // 2
-#include <atlmisc.h> // 2
-#include <atlsafe.h> // 1
-#include <atltheme.h> // 1
-#include <atlwin.h> // 2
-*/
-
-// Objbase.h and other files that rely on it bring in [ #define
-// interface struct ] which can cause problems in a multi-platform
-// build like Chrome's. #undef-ing it does not work as there are
-// currently 118 targets that break if we do this, so leaving out of
-// the precompiled header for now.
-//#include <commctrl.h> // 2
-//#include <commdlg.h> // 3
-//#include <cryptuiapi.h> // 2
-//#include <Objbase.h> // 2
-//#include <objidl.h> // 1
-//#include <ole2.h> // 1
-//#include <oleacc.h> // 2
-//#include <oleauto.h> // 1
-//#include <oleidl.h> // 1
-//#include <propkey.h> // 2
-//#include <propvarutil.h> // 2
-//#include <pstore.h> // 2
-//#include <shlguid.h> // 1
-//#include <shlwapi.h> // 1
-//#include <shobjidl.h> // 4
-//#include <urlhist.h> // 2
-
-// Caused other conflicts in addition to the 'interface' issue above.
-// #include <shlobj.h>
-
-#include <errno.h>
-#include <fcntl.h>
-#include <limits.h> // 4
-#include <math.h>
-#include <memory.h> // 1
-#include <signal.h>
-#include <stdarg.h> // 1
-#include <stddef.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h> // 4
-
-#include <algorithm>
-#include <bitset> // 3
-#include <cmath>
-#include <cstddef>
-#include <cstdio> // 3
-#include <cstdlib> // 2
-#include <cstring>
-#include <deque>
-#include <fstream> // 3
-#include <functional>
-#include <iomanip> // 2
-#include <iosfwd> // 2
-#include <iterator>
-#include <limits>
-#include <list>
-#include <map>
-#include <numeric> // 2
-#include <ostream>
-#include <queue>
-#include <set>
-#include <sstream>
-#include <stack>
-#include <string>
-#include <utility>
-#include <vector>
diff --git a/build/protoc.gypi b/build/protoc.gypi
deleted file mode 100644
index fafdf9d..0000000
--- a/build/protoc.gypi
+++ /dev/null
@@ -1,123 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included into a target to provide a rule
-# to invoke protoc in a consistent manner. For Java-targets, see
-# protoc_java.gypi.
-#
-# To use this, create a gyp target with the following form:
-# {
-# 'target_name': 'my_proto_lib',
-# 'type': 'static_library',
-# 'sources': [
-# 'foo.proto',
-# 'bar.proto',
-# ],
-# 'variables': {
-# # Optional, see below: 'proto_in_dir': '.'
-# 'proto_out_dir': 'dir/for/my_proto_lib'
-# },
-# 'includes': ['path/to/this/gypi/file'],
-# }
-# If necessary, you may add normal .cc files to the sources list or other gyp
-# dependencies. The proto headers are guaranteed to be generated before any
-# source files, even within this target, are compiled.
-#
-# The 'proto_in_dir' variable must be the relative path to the
-# directory containing the .proto files. If left out, it defaults to '.'.
-#
-# The 'proto_out_dir' variable specifies the path suffix that output
-# files are generated under. Targets that gyp-depend on my_proto_lib
-# will be able to include the resulting proto headers with an include
-# like:
-# #include "dir/for/my_proto_lib/foo.pb.h"
-#
-# If you need to add an EXPORT macro to a protobuf's c++ header, set the
-# 'cc_generator_options' variable with the value: 'dllexport_decl=FOO_EXPORT:'
-# e.g. 'dllexport_decl=BASE_EXPORT:'
-#
-# It is likely you also need to #include a file for the above EXPORT macro to
-# work. You can do so with the 'cc_include' variable.
-# e.g. 'base/base_export.h'
-#
-# Implementation notes:
-# A proto_out_dir of foo/bar produces
-# <(SHARED_INTERMEDIATE_DIR)/protoc_out/foo/bar/{file1,file2}.pb.{cc,h}
-# <(SHARED_INTERMEDIATE_DIR)/pyproto/foo/bar/{file1,file2}_pb2.py
-
-{
- 'variables': {
- 'protoc_wrapper': '<(DEPTH)/tools/protoc_wrapper/protoc_wrapper.py',
- 'cc_dir': '<(SHARED_INTERMEDIATE_DIR)/protoc_out/<(proto_out_dir)',
- 'py_dir': '<(PRODUCT_DIR)/pyproto/<(proto_out_dir)',
- 'cc_generator_options%': '',
- 'cc_include%': '',
- 'proto_in_dir%': '.',
- 'conditions': [
- ['use_system_protobuf==0', {
- 'protoc': '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)protoc<(EXECUTABLE_SUFFIX)',
- }, { # use_system_protobuf==1
- 'protoc': '<!(which protoc)',
- }],
- ],
- },
- 'rules': [
- {
- 'rule_name': 'genproto',
- 'extension': 'proto',
- 'inputs': [
- '<(protoc_wrapper)',
- '<(protoc)',
- ],
- 'outputs': [
- '<(py_dir)/<(RULE_INPUT_ROOT)_pb2.py',
- '<(cc_dir)/<(RULE_INPUT_ROOT).pb.cc',
- '<(cc_dir)/<(RULE_INPUT_ROOT).pb.h',
- ],
- 'action': [
- 'python',
- '<(protoc_wrapper)',
- '--include',
- '<(cc_include)',
- '--protobuf',
- '<(cc_dir)/<(RULE_INPUT_ROOT).pb.h',
- # Using the --arg val form (instead of --arg=val) allows gyp's msvs rule
- # generation to correct 'val' which is a path.
- '--proto-in-dir','<(proto_in_dir)',
- # Naively you'd use <(RULE_INPUT_PATH) here, but protoc requires
- # --proto_path is a strict prefix of the path given as an argument.
- '--proto-in-file','<(RULE_INPUT_ROOT)<(RULE_INPUT_EXT)',
- '--use-system-protobuf=<(use_system_protobuf)',
- '--',
- '<(protoc)',
- '--cpp_out', '<(cc_generator_options)<(cc_dir)',
- '--python_out', '<(py_dir)',
- ],
- 'message': 'Generating C++ and Python code from <(RULE_INPUT_PATH)',
- 'process_outputs_as_sources': 1,
- },
- ],
- 'dependencies': [
- '<(DEPTH)/third_party/protobuf/protobuf.gyp:protoc#host',
- '<(DEPTH)/third_party/protobuf/protobuf.gyp:protobuf_lite',
- ],
- 'include_dirs': [
- '<(SHARED_INTERMEDIATE_DIR)/protoc_out',
- '<(DEPTH)',
- ],
- 'direct_dependent_settings': {
- 'include_dirs': [
- '<(SHARED_INTERMEDIATE_DIR)/protoc_out',
- '<(DEPTH)',
- ]
- },
- 'export_dependent_settings': [
- # The generated headers reference headers within protobuf_lite,
- # so dependencies must be able to find those headers too.
- '<(DEPTH)/third_party/protobuf/protobuf.gyp:protobuf_lite',
- ],
- # This target exports a hard dependency because it generates header
- # files.
- 'hard_dependency': 1,
-}
diff --git a/build/protoc_java.gypi b/build/protoc_java.gypi
deleted file mode 100644
index 6fd80d85..0000000
--- a/build/protoc_java.gypi
+++ /dev/null
@@ -1,83 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included into a target to provide a rule
-# to invoke protoc in a consistent manner. This is only to be included
-# for Java targets. When including this file, a .jar-file will be generated.
-# For other targets, see protoc.gypi.
-#
-# To use this, create a gyp target with the following form:
-# {
-# 'target_name': 'my_proto_lib',
-# 'sources': [
-# 'foo.proto',
-# 'bar.proto',
-# ],
-# 'variables': {
-# 'proto_in_dir': '.'
-# },
-# 'includes': ['path/to/this/gypi/file'],
-# }
-#
-# The 'proto_in_dir' variable must be the relative path to the
-# directory containing the .proto files. If left out, it defaults to '.'.
-#
-# The 'output_java_files' variable specifies a list of output files that will
-# be generated. It is based on the package and java_outer_classname fields in
-# the proto. All the values must be prefixed with >(java_out_dir), since that
-# is the root directory of all the output.
-#
-# Implementation notes:
-# A target_name of foo and proto-specified 'package' java.package.path produces:
-# <(PRODUCT_DIR)/java_proto/foo/{java/package/path/}{Foo,Bar}.java
-# where Foo and Bar are taken from 'java_outer_classname' of the protos.
-#
-# How the .jar-file is created is different than how protoc is used for other
-# targets, and as such, this lives in its own file.
-
-{
- 'variables': {
- 'protoc': '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)android_protoc<(EXECUTABLE_SUFFIX)',
- 'java_out_dir': '<(PRODUCT_DIR)/java_proto/<(_target_name)/src',
- 'proto_in_dir%': '.',
- 'stamp_file': '<(java_out_dir).stamp',
- 'script': '<(DEPTH)/build/protoc_java.py',
-
- # The rest of the variables here are for the java.gypi include.
- 'java_in_dir': '<(DEPTH)/build/android/empty',
- 'generated_src_dirs': ['<(java_out_dir)'],
- # Adding the |stamp_file| to |additional_input_paths| makes the actions in
- # the include of java.gypi depend on the genproto_java action.
- 'additional_input_paths': ['<(stamp_file)'],
- 'run_findbugs': 0,
- },
- 'actions': [
- {
- 'action_name': 'genproto_java',
- 'inputs': [
- '<(script)',
- '<(protoc)',
- '<@(_sources)',
- ],
- # We do not know the names of the generated files, so we use a stamp.
- 'outputs': [
- '<(stamp_file)',
- ],
- 'action': [
- '<(script)',
- '--protoc=<(protoc)',
- '--proto-path=<(proto_in_dir)',
- '--java-out-dir=<(java_out_dir)',
- '--stamp=<(stamp_file)',
- '<@(_sources)',
- ],
- 'message': 'Generating Java code from protobuf files in <(proto_in_dir)',
- },
- ],
- 'dependencies': [
- '<(DEPTH)/third_party/android_protobuf/android_protobuf.gyp:android_protoc#host',
- '<(DEPTH)/third_party/android_protobuf/android_protobuf.gyp:protobuf_nano_javalib',
- ],
- 'includes': [ 'java.gypi' ],
-}
diff --git a/build/protoc_java.py b/build/protoc_java.py
deleted file mode 100755
index 470667c..0000000
--- a/build/protoc_java.py
+++ /dev/null
@@ -1,68 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Generate java source files from protobuf files.
-
-This is a helper file for the genproto_java action in protoc_java.gypi.
-
-It performs the following steps:
-1. Deletes all old sources (ensures deleted classes are not part of new jars).
-2. Creates source directory.
-3. Generates Java files using protoc (output into either --java-out-dir or
- --srcjar).
-4. Creates a new stamp file.
-"""
-
-import os
-import optparse
-import shutil
-import subprocess
-import sys
-
-sys.path.append(os.path.join(os.path.dirname(__file__), "android", "gyp"))
-from util import build_utils
-
-def main(argv):
- parser = optparse.OptionParser()
- build_utils.AddDepfileOption(parser)
- parser.add_option("--protoc", help="Path to protoc binary.")
- parser.add_option("--proto-path", help="Path to proto directory.")
- parser.add_option("--java-out-dir",
- help="Path to output directory for java files.")
- parser.add_option("--srcjar", help="Path to output srcjar.")
- parser.add_option("--stamp", help="File to touch on success.")
- options, args = parser.parse_args(argv)
-
- build_utils.CheckOptions(options, parser, ['protoc', 'proto_path'])
- if not options.java_out_dir and not options.srcjar:
- print 'One of --java-out-dir or --srcjar must be specified.'
- return 1
-
- with build_utils.TempDir() as temp_dir:
- # Specify arguments to the generator.
- generator_args = ['optional_field_style=reftypes',
- 'store_unknown_fields=true']
- out_arg = '--javanano_out=' + ','.join(generator_args) + ':' + temp_dir
- # Generate Java files using protoc.
- build_utils.CheckOutput(
- [options.protoc, '--proto_path', options.proto_path, out_arg]
- + args)
-
- if options.java_out_dir:
- build_utils.DeleteDirectory(options.java_out_dir)
- shutil.copytree(temp_dir, options.java_out_dir)
- else:
- build_utils.ZipDir(options.srcjar, temp_dir)
-
- if options.depfile:
- build_utils.WriteDepfile(
- options.depfile,
- args + [options.protoc] + build_utils.GetPythonDependencies())
-
- if options.stamp:
- build_utils.Touch(options.stamp)
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv[1:]))
diff --git a/build/release.gypi b/build/release.gypi
deleted file mode 100644
index 9b8b11d..0000000
--- a/build/release.gypi
+++ /dev/null
@@ -1,29 +0,0 @@
-{
- 'conditions': [
- # Handle build types.
- ['buildtype=="Dev"', {
- 'includes': ['internal/release_impl.gypi'],
- }],
- ['buildtype=="Dev" and incremental_chrome_dll==1', {
- 'msvs_settings': {
- 'VCLinkerTool': {
- # Enable incremental linking and disable conflicting link options:
- # http://msdn.microsoft.com/en-us/library/4khtbfyf.aspx
- 'LinkIncremental': '2',
- 'OptimizeReferences': '1',
- 'EnableCOMDATFolding': '1',
- 'Profile': 'false',
- },
- },
- }],
- ['buildtype=="Official"', {
- 'includes': ['internal/release_impl_official.gypi'],
- }],
- # TODO(bradnelson): may also need:
- # checksenabled
- # coverage
- # dom_stats
- # pgo_instrument
- # pgo_optimize
- ],
-}
diff --git a/build/repack_action.gypi b/build/repack_action.gypi
deleted file mode 100644
index 04b982a..0000000
--- a/build/repack_action.gypi
+++ /dev/null
@@ -1,31 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included into an action to invoke grit repack in a
-# consistent manner. To use this the following variables need to be
-# defined:
-# pak_inputs: list: paths of pak files that need to be combined.
-# pak_output: string: the output pak file path.
-
-{
- # GYP version: //tools/grit/repack.gni
- 'variables': {
- 'repack_path': '<(DEPTH)/tools/grit/grit/format/repack.py',
- 'repack_options%': [],
- },
- 'inputs': [
- '<(repack_path)',
- '<@(pak_inputs)',
- ],
- 'outputs': [
- '<(pak_output)'
- ],
- 'action': [
- 'python',
- '<(repack_path)',
- '<@(repack_options)',
- '<(pak_output)',
- '<@(pak_inputs)',
- ],
-}
diff --git a/build/rmdir_and_stamp.py b/build/rmdir_and_stamp.py
deleted file mode 100755
index 6aa11f8..0000000
--- a/build/rmdir_and_stamp.py
+++ /dev/null
@@ -1,45 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Wipes out a directory recursively and then touches a stamp file.
-
-This odd pairing of operations is used to support build scripts which
-slurp up entire directories (e.g. build/android/javac.py when handling
-generated sources) as inputs.
-
-The general pattern of use is:
-
- - Add a target which generates |gen_sources| into |out_path| from |inputs|.
- - Include |stamp_file| as an input for that target or any of its rules which
- generate files in |out_path|.
- - Add an action which depends on |inputs| and which outputs |stamp_file|;
- the action should run this script and pass |out_path| and |stamp_file| as
- its arguments.
-
-The net result is that you will force |out_path| to be wiped and all
-|gen_sources| to be regenerated any time any file in |inputs| changes.
-
-See //third_party/mojo/mojom_bindings_generator.gypi for an example use case.
-
-"""
-
-import errno
-import os
-import shutil
-import sys
-
-
-def Main(dst_dir, stamp_file):
- try:
- shutil.rmtree(os.path.normpath(dst_dir))
- except OSError as e:
- # Ignore only "not found" errors.
- if e.errno != errno.ENOENT:
- raise e
- with open(stamp_file, 'a'):
- os.utime(stamp_file, None)
-
-if __name__ == '__main__':
- sys.exit(Main(sys.argv[1], sys.argv[2]))
diff --git a/build/sanitize-mac-build-log.sed b/build/sanitize-mac-build-log.sed
deleted file mode 100644
index b4111c7..0000000
--- a/build/sanitize-mac-build-log.sed
+++ /dev/null
@@ -1,33 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# Use this sed script to reduce a Mac build log into something readable.
-
-# Drop uninformative lines.
-/^distcc/d
-/^Check dependencies/d
-/^ setenv /d
-/^ cd /d
-/^make: Nothing to be done/d
-/^$/d
-
-# Xcode prints a short "compiling foobar.o" line followed by the lengthy
-# full command line. These deletions drop the command line.
-\|^ /Developer/usr/bin/|d
-\|^ /Developer/Library/PrivateFrameworks/DevToolsCore\.framework/|d
-\|^ /Developer/Library/Xcode/Plug-ins/CoreBuildTasks\.xcplugin/|d
-
-# Drop any goma command lines as well.
-\|^ .*/gomacc |d
-
-# And, if you've overridden something from your own bin directory, remove those
-# full command lines, too.
-\|^ /Users/[^/]*/bin/|d
-
-# There's already a nice note for bindings, don't need the command line.
-\|^python scripts/rule_binding\.py|d
-
-# Shorten the "compiling foobar.o" line.
-s|^Distributed-CompileC (.*) normal i386 c\+\+ com\.apple\.compilers\.gcc\.4_2| CC \1|
-s|^CompileC (.*) normal i386 c\+\+ com\.apple\.compilers\.gcc\.4_2| CC \1|
diff --git a/build/sanitize-mac-build-log.sh b/build/sanitize-mac-build-log.sh
deleted file mode 100755
index df5a7af..0000000
--- a/build/sanitize-mac-build-log.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/sh
-# Copyright (c) 2010 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-sed -r -f `dirname "${0}"`/`basename "${0}" sh`sed
diff --git a/build/sanitize-win-build-log.sed b/build/sanitize-win-build-log.sed
deleted file mode 100644
index c18e664..0000000
--- a/build/sanitize-win-build-log.sed
+++ /dev/null
@@ -1,15 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# Use this sed script to reduce a Windows build log into something
-# machine-parsable.
-
-# Drop uninformative lines.
-/The operation completed successfully\./d
-
-# Drop parallelization indicators on lines.
-s/^[0-9]+>//
-
-# Shorten bindings generation lines
-s/^.*"python".*idl_compiler\.py".*("[^"]+\.idl").*$/ idl_compiler \1/
diff --git a/build/sanitize-win-build-log.sh b/build/sanitize-win-build-log.sh
deleted file mode 100755
index df5a7af..0000000
--- a/build/sanitize-win-build-log.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/sh
-# Copyright (c) 2010 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-sed -r -f `dirname "${0}"`/`basename "${0}" sh`sed
diff --git a/build/secondary/third_party/android_tools/BUILD.gn b/build/secondary/third_party/android_tools/BUILD.gn
deleted file mode 100644
index afafffc..0000000
--- a/build/secondary/third_party/android_tools/BUILD.gn
+++ /dev/null
@@ -1,104 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/config/android/rules.gni")
-
-config("cpu_features_include") {
- include_dirs = [ "ndk/sources/android/cpufeatures" ]
-}
-
-# This is the GN version of
-# //build/android/ndk.gyp:cpu_features
-source_set("cpu_features") {
- sources = [
- "ndk/sources/android/cpufeatures/cpu-features.c",
- ]
- public_configs = [ ":cpu_features_include" ]
-
- configs -= [ "//build/config/compiler:chromium_code" ]
- configs += [ "//build/config/compiler:no_chromium_code" ]
-}
-
-android_java_prebuilt("android_gcm_java") {
- jar_path = "$android_sdk_root/extras/google/gcm/gcm-client/dist/gcm.jar"
-}
-
-android_java_prebuilt("uiautomator_java") {
- jar_path = "$android_sdk/uiautomator.jar"
-}
-
-android_java_prebuilt("android_support_annotations_javalib") {
- jar_path = "$android_sdk_root/extras/android/support/annotations/android-support-annotations.jar"
-}
-
-java_prebuilt("android_support_multidex_java") {
- jar_path = "$android_sdk_root/extras/android/support/multidex/library/libs/android-support-multidex.jar"
-}
-
-android_java_prebuilt("android_support_v13_java") {
- jar_path =
- "$android_sdk_root/extras/android/support/v13/android-support-v13.jar"
-}
-
-android_resources("android_support_v7_appcompat_resources") {
- v14_skip = true
- resource_dirs =
- [ "$android_sdk_root/extras/android/support/v7/appcompat/res" ]
- custom_package = "android.support.v7.appcompat"
-}
-
-android_java_prebuilt("android_support_v7_appcompat_java") {
- deps = [
- ":android_support_v7_appcompat_resources",
- ]
- jar_path = "$android_sdk_root/extras/android/support/v7/appcompat/libs/android-support-v7-appcompat.jar"
-}
-
-android_resources("android_support_v7_mediarouter_resources") {
- v14_skip = true
- resource_dirs =
- [ "$android_sdk_root/extras/android/support/v7/mediarouter/res" ]
- deps = [
- ":android_support_v7_appcompat_resources",
- ]
- custom_package = "android.support.v7.mediarouter"
-}
-
-android_java_prebuilt("android_support_v7_mediarouter_java") {
- deps = [
- ":android_support_v7_mediarouter_resources",
- ":android_support_v7_appcompat_java",
- ]
- jar_path = "$android_sdk_root/extras/android/support/v7/mediarouter/libs/android-support-v7-mediarouter.jar"
-}
-
-android_resources("android_support_v7_recyclerview_resources") {
- v14_skip = true
- resource_dirs =
- [ "$android_sdk_root/extras/android/support/v7/recyclerview/res" ]
- custom_package = "android.support.v7.recyclerview"
-}
-
-android_java_prebuilt("android_support_v7_recyclerview_java") {
- deps = [
- ":android_support_v7_appcompat_java",
- ":android_support_v7_recyclerview_resources",
- ]
- jar_path = "$android_sdk_root/extras/android/support/v7/recyclerview/libs/android-support-v7-recyclerview.jar"
-}
-
-android_resources("google_play_services_default_resources") {
- v14_skip = true
- resource_dirs = [ "$android_sdk_root/extras/google/google_play_services/libproject/google-play-services_lib/res" ]
- custom_package = "com.google.android.gms"
-}
-android_java_prebuilt("google_play_services_default_java") {
- deps = [
- ":android_support_v13_java",
- ":android_support_v7_mediarouter_java",
- ":google_play_services_default_resources",
- ]
- proguard_preprocess = false
- jar_path = "$android_sdk_root/extras/google/google_play_services/libproject/google-play-services_lib/libs/google-play-services.jar"
-}
diff --git a/build/set_clang_warning_flags.gypi b/build/set_clang_warning_flags.gypi
deleted file mode 100644
index f6d7aea..0000000
--- a/build/set_clang_warning_flags.gypi
+++ /dev/null
@@ -1,58 +0,0 @@
-# Copyright (c) 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included to set clang-specific compiler flags.
-# To use this the following variable can be defined:
-# clang_warning_flags: list: Compiler flags to pass to clang.
-# clang_warning_flags_unset: list: Compiler flags to not pass to clang.
-#
-# Only use this in third-party code. In chromium_code, fix your code to not
-# warn instead!
-#
-# Note that the gypi file is included in target_defaults, so it does not need
-# to be explicitly included.
-#
-# Warning flags set by this will be used on all platforms. If you want to set
-# warning flags on only some platforms, you have to do so manually.
-#
-# To use this, create a gyp target with the following form:
-# {
-# 'target_name': 'my_target',
-# 'variables': {
-# 'clang_warning_flags': ['-Wno-awesome-warning'],
-# 'clang_warning_flags_unset': ['-Wpreviously-set-flag'],
-# }
-# }
-
-{
- 'variables': {
- 'clang_warning_flags_unset%': [], # Provide a default value.
- },
- 'conditions': [
- ['clang==1', {
- # This uses >@ instead of @< to also see clang_warning_flags set in
- # targets directly, not just the clang_warning_flags in target_defaults.
- 'cflags': [ '>@(clang_warning_flags)' ],
- 'cflags!': [ '>@(clang_warning_flags_unset)' ],
- 'xcode_settings': {
- 'WARNING_CFLAGS': ['>@(clang_warning_flags)'],
- 'WARNING_CFLAGS!': ['>@(clang_warning_flags_unset)'],
- },
- 'msvs_settings': {
- 'VCCLCompilerTool': {
- 'AdditionalOptions': [ '>@(clang_warning_flags)' ],
- 'AdditionalOptions!': [ '>@(clang_warning_flags_unset)' ],
- },
- },
- }],
- ['clang==0 and host_clang==1', {
- 'target_conditions': [
- ['_toolset=="host"', {
- 'cflags': [ '>@(clang_warning_flags)' ],
- 'cflags!': [ '>@(clang_warning_flags_unset)' ],
- }],
- ],
- }],
- ],
-}
diff --git a/build/shim_headers.gypi b/build/shim_headers.gypi
deleted file mode 100644
index 56d8d3a..0000000
--- a/build/shim_headers.gypi
+++ /dev/null
@@ -1,60 +0,0 @@
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included into a target to handle shim headers
-# in a consistent manner. To use this the following variables need to be
-# defined:
-# headers_root_path: string: path to directory containing headers
-# header_filenames: list: list of header file names
-
-{
- 'variables': {
- 'shim_headers_path': '<(SHARED_INTERMEDIATE_DIR)/shim_headers/<(_target_name)/<(_toolset)',
- 'shim_generator_additional_args%': [],
- },
- 'include_dirs++': [
- '<(shim_headers_path)',
- ],
- 'all_dependent_settings': {
- # Repeating this with different numbers of plusses is unfortunately required
- # to make sure that even if this include is inside nested conditions/etc, it
- # still gets inserted at the beginning of the include_dirs list. See
- # http://crbug.com/263818 for details.
- 'include_dirs+++': [
- '<(shim_headers_path)',
- ],
- 'include_dirs++++': [
- '<(shim_headers_path)',
- ],
- 'include_dirs+++++': [
- '<(shim_headers_path)',
- ],
- },
- 'actions': [
- {
- 'variables': {
- 'generator_path': '<(DEPTH)/tools/generate_shim_headers/generate_shim_headers.py',
- 'generator_args': [
- '--headers-root', '<(headers_root_path)',
- '--output-directory', '<(shim_headers_path)',
- '<@(shim_generator_additional_args)',
- '<@(header_filenames)',
- ],
- },
- 'action_name': 'generate_<(_target_name)_shim_headers',
- 'inputs': [
- '<(generator_path)',
- ],
- 'outputs': [
- '<!@pymod_do_main(generate_shim_headers <@(generator_args) --outputs)',
- ],
- 'action': ['python',
- '<(generator_path)',
- '<@(generator_args)',
- '--generate',
- ],
- 'message': 'Generating <(_target_name) shim headers',
- },
- ],
-}
diff --git a/build/slave/OWNERS b/build/slave/OWNERS
deleted file mode 100644
index f562c92..0000000
--- a/build/slave/OWNERS
+++ /dev/null
@@ -1,20 +0,0 @@
-set noparent
-agable@chromium.org
-agable@google.com
-cmp@chromium.org
-cmp@google.com
-dpranke@chromium.org
-iannucci@chromium.org
-iannucci@google.com
-johnw@chromium.org
-johnw@google.com
-maruel@chromium.org
-maruel@google.com
-mmoss@chromium.org
-mmoss@google.com
-pschmidt@chromium.org
-pschmidt@google.com
-stip@chromium.org
-stip@google.com
-szager@chromium.org
-szager@google.com
diff --git a/build/slave/README b/build/slave/README
deleted file mode 100644
index e3718b2..0000000
--- a/build/slave/README
+++ /dev/null
@@ -1,8 +0,0 @@
-This is a directory which contains configuration information for the
-buildsystem.
-
-* Under recipes, the buildsystem should use only this directory as an
- entry point into src/.
-
-* Scripts in this directory must not import from outside this directory or shell
- to scripts outside this directory.
diff --git a/build/some.gyp b/build/some.gyp
deleted file mode 100644
index 44a1dd5..0000000
--- a/build/some.gyp
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright (c) 2011 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-{
- 'targets': [
- {
- 'target_name': 'some',
- 'type': 'none',
- 'dependencies': [
- # This file is intended to be locally modified. List the targets you use
- # regularly. The generated some.sln will contains projects for only
- # those targets and the targets they are transitively dependent on. This
- # can result in a solution that loads and unloads faster in Visual
- # Studio.
- #
- # Tip: Create a dummy CL to hold your local edits to this file, so they
- # don't accidentally get added to another CL that you are editing.
- #
- # Example:
- # '../chrome/chrome.gyp:chrome',
- ],
- },
- ],
-}
diff --git a/build/symlink.py b/build/symlink.py
deleted file mode 100755
index 1c5d3dd..0000000
--- a/build/symlink.py
+++ /dev/null
@@ -1,39 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-"""Make a symlink and optionally touch a file (to handle dependencies)."""
-import errno
-import optparse
-import os.path
-import shutil
-import sys
-def Main(argv):
- parser = optparse.OptionParser()
- parser.add_option('-f', '--force', action='store_true')
- parser.add_option('--touch')
- options, args = parser.parse_args(argv[1:])
- if len(args) < 2:
- parser.error('at least two arguments required.')
- target = args[-1]
- sources = args[:-1]
- for s in sources:
- t = os.path.join(target, os.path.basename(s))
- if len(sources) == 1 and not os.path.isdir(target):
- t = target
- try:
- os.symlink(s, t)
- except OSError, e:
- if e.errno == errno.EEXIST and options.force:
- if os.path.isdir(t):
- shutil.rmtree(t, ignore_errors=True)
- else:
- os.remove(t)
- os.symlink(s, t)
- else:
- raise
- if options.touch:
- with open(options.touch, 'w') as f:
- pass
-if __name__ == '__main__':
- sys.exit(Main(sys.argv))
diff --git a/build/temp_gyp/README.chromium b/build/temp_gyp/README.chromium
deleted file mode 100644
index 8045d61..0000000
--- a/build/temp_gyp/README.chromium
+++ /dev/null
@@ -1,3 +0,0 @@
-This directory will be removed once the files in it are committed upstream and
-Chromium imports an upstream revision with these files. Contact mark for
-details.
diff --git a/build/temp_gyp/pdfsqueeze.gyp b/build/temp_gyp/pdfsqueeze.gyp
deleted file mode 100644
index 2b3b1ff..0000000
--- a/build/temp_gyp/pdfsqueeze.gyp
+++ /dev/null
@@ -1,40 +0,0 @@
-# Copyright (c) 2009 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
- 'targets': [
- {
- 'target_name': 'pdfsqueeze',
- 'type': 'executable',
- 'sources': [
- '../../third_party/pdfsqueeze/pdfsqueeze.m',
- ],
- 'defines': [
- # Use defines to map the full path names that will be used for
- # the vars into the short forms expected by pdfsqueeze.m.
- '______third_party_pdfsqueeze_ApplyGenericRGB_qfilter=ApplyGenericRGB_qfilter',
- '______third_party_pdfsqueeze_ApplyGenericRGB_qfilter_len=ApplyGenericRGB_qfilter_len',
- ],
- 'include_dirs': [
- '<(INTERMEDIATE_DIR)',
- ],
- 'libraries': [
- '$(SDKROOT)/System/Library/Frameworks/Foundation.framework',
- '$(SDKROOT)/System/Library/Frameworks/Quartz.framework',
- ],
- 'actions': [
- {
- 'action_name': 'Generate inline filter data',
- 'inputs': [
- '../../third_party/pdfsqueeze/ApplyGenericRGB.qfilter',
- ],
- 'outputs': [
- '<(INTERMEDIATE_DIR)/ApplyGenericRGB.h',
- ],
- 'action': ['xxd', '-i', '<@(_inputs)', '<@(_outputs)'],
- },
- ],
- },
- ],
-}
diff --git a/build/toolchain/cros/BUILD.gn b/build/toolchain/cros/BUILD.gn
deleted file mode 100644
index 140958b..0000000
--- a/build/toolchain/cros/BUILD.gn
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/toolchain/clang.gni")
-import("//build/toolchain/gcc_toolchain.gni")
-
-declare_args() {
- # The CrOS build system supports many different kinds of targets across
- # many different architectures. Bringing your own toolchain is also supported,
- # so it's actually impossible to enumerate all toolchains for all targets
- # as GN toolchain specifications.
- # These arguments provide a mechanism for specifying your CC, CXX and AR at
- # buildfile-generation time, allowing the CrOS build system to always use
- # the right tools for the current target.
- cros_target_cc = ""
- cros_target_cxx = ""
- cros_target_ar = ""
-}
-
-gcc_toolchain("target") {
- assert(cros_target_cc != "", "Must provide target CC.")
- assert(cros_target_cxx != "", "Must provide target CXX.")
- assert(cros_target_ar != "", "Must provide target AR.")
-
- cc = "${cros_target_cc}"
- cxx = "${cros_target_cxx}"
-
- ar = "${cros_target_ar}"
- ld = cxx
-
- toolchain_cpu = "${target_cpu}"
- toolchain_os = "linux"
- is_clang = is_clang
-}
diff --git a/build/toolchain/mac/BUILD.gn b/build/toolchain/mac/BUILD.gn
index d77a921..b291f00 100644
--- a/build/toolchain/mac/BUILD.gn
+++ b/build/toolchain/mac/BUILD.gn
@@ -7,7 +7,6 @@
# Linux.
import("../goma.gni")
-import("//build/config/ios/ios_sdk.gni")
import("//build/config/mac/mac_sdk.gni")
assert(host_os == "mac")
@@ -25,7 +24,7 @@
# This will copy the gyp-mac-tool to the build directory. We pass in the source
# file of the win tool.
gyp_mac_tool_source =
- rebase_path("//tools/gyp/pylib/gyp/mac_tool.py", root_build_dir)
+ rebase_path("//third_party/gyp/pylib/gyp/mac_tool.py", root_build_dir)
exec_script("setup_toolchain.py", [ gyp_mac_tool_source ])
# Shared toolchain definition. Invocations should set toolchain_os to set the
@@ -208,32 +207,6 @@
}
}
-# Toolchain used for iOS device targets.
-mac_toolchain("ios_clang_arm") {
- toolchain_cpu = "arm"
- toolchain_os = "mac"
- prefix = rebase_path("//third_party/llvm-build/Release+Asserts/bin",
- root_build_dir)
- cc = "${goma_prefix}$prefix/clang"
- cxx = "${goma_prefix}$prefix/clang++"
- ld = cxx
- is_clang = true
- sysroot_flags = "-isysroot $ios_device_sdk_path -miphoneos-version-min=$ios_deployment_target"
-}
-
-# Toolchain used for iOS simulator targets.
-mac_toolchain("ios_clang_x64") {
- toolchain_cpu = "x64"
- toolchain_os = "mac"
- prefix = rebase_path("//third_party/llvm-build/Release+Asserts/bin",
- root_build_dir)
- cc = "${goma_prefix}$prefix/clang"
- cxx = "${goma_prefix}$prefix/clang++"
- ld = cxx
- is_clang = true
- sysroot_flags = "-isysroot $ios_simulator_sdk_path -mios-simulator-version-min=$ios_deployment_target"
-}
-
# Toolchain used for Mac host targets.
mac_toolchain("clang_x64") {
toolchain_cpu = "x64"
diff --git a/build/toolchain/nacl/BUILD.gn b/build/toolchain/nacl/BUILD.gn
deleted file mode 100644
index 5fa637c..0000000
--- a/build/toolchain/nacl/BUILD.gn
+++ /dev/null
@@ -1,63 +0,0 @@
-# Copyright (c) 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-toolchain("x86_newlib") {
- toolprefix = "gen/sdk/toolchain/linux_x86_newlib/bin/x86_64-nacl-"
- cc = toolprefix + "gcc"
- cxx = toolprefix + "g++"
- ld = toolprefix + "g++"
-
- tool("cc") {
- command = "$cc -MMD -MF \$out.d \$defines \$includes \$cflags \$cflags_c -c \$in -o \$out"
- description = "CC(NaCl x86 Newlib) \$out"
- depfile = "\$out.d"
- depsformat = "gcc"
- }
- tool("cxx") {
- # cflags_pch_cc
- command = "$cxx -MMD -MF \$out.d \$defines \$includes \$cflags \$cflags_cc -c \$in -o \$out"
- description = "CXX(NaCl x86 Newlib) \$out"
- depfile = "\$out.d"
- depsformat = "gcc"
- }
- tool("alink") {
- command = "rm -f \$out && ${toolprefix}ar rcs \$out \$in"
- description = "AR(NaCl x86 Newlib) \$out"
- }
- tool("solink") {
- command = "if [ ! -e \$lib -o ! -e \${lib}.TOC ]; then $ld -shared \$ldflags -o \$lib -Wl,-soname=\$soname -Wl,--whole-archive \$in \$solibs -Wl,--no-whole-archive \$libs && { readelf -d \${lib} | grep SONAME ; nm -gD -f p \${lib} | cut -f1-2 -d' '; } > \${lib}.TOC; else $ld -shared \$ldflags -o \$lib -Wl,-soname=\$soname -Wl,--whole-archive \$in \$solibs -Wl,--no-whole-archive \$libs && { readelf -d \${lib} | grep SONAME ; nm -gD -f p \${lib} | cut -f1-2 -d' '; } > \${lib}.tmp && if ! cmp -s \${lib}.tmp \${lib}.TOC; then mv \${lib}.tmp \${lib}.TOC ; fi; fi"
- description = "SOLINK(NaCl x86 Newlib) \$lib"
-
- #pool = "link_pool"
- restat = "1"
- }
- tool("link") {
- command = "$ld \$ldflags -o \$out -Wl,--start-group \$in \$solibs -Wl,--end-group \$libs"
- description = "LINK(NaCl x86 Newlib) \$out"
-
- #pool = "link_pool"
- }
-
- if (is_win) {
- tool("stamp") {
- command = "$python_path gyp-win-tool stamp \$out"
- description = "STAMP \$out"
- }
- } else {
- tool("stamp") {
- command = "touch \$out"
- description = "STAMP \$out"
- }
- }
-
- toolchain_args() {
- # Override the default OS detection. The build config will set the is_*
- # flags accordingly.
- current_os = "nacl"
-
- # Component build not supported in NaCl, since it does not support shared
- # libraries.
- is_component_build = false
- }
-}
diff --git a/build/toolchain/win/BUILD.gn b/build/toolchain/win/BUILD.gn
index d71098f..cf7b4a6 100644
--- a/build/toolchain/win/BUILD.gn
+++ b/build/toolchain/win/BUILD.gn
@@ -23,7 +23,7 @@
# "environment.x86" and "environment.x64" to the build directory and return a
# list to us.
gyp_win_tool_path =
- rebase_path("//tools/gyp/pylib/gyp/win_tool.py", root_build_dir)
+ rebase_path("//third_party/gyp/pylib/gyp/win_tool.py", root_build_dir)
toolchain_data = exec_script("setup_toolchain.py",
[
@@ -45,17 +45,10 @@
goma_prefix = ""
}
-# This value will be inherited in the toolchain below.
-concurrent_links = exec_script("../get_concurrent_links.py", [], "value")
-
# Parameters:
# current_cpu: current_cpu to pass as a build arg
# environment: File name of environment file.
template("msvc_toolchain") {
- if (defined(invoker.concurrent_links)) {
- concurrent_links = invoker.concurrent_links
- }
-
env = invoker.environment
if (is_debug) {
@@ -205,7 +198,7 @@
# When invoking this toolchain not as the default one, these args will be
# passed to the build. They are ignored when this is the default toolchain.
- toolchain_args() {
+ toolchain_args = {
current_cpu = invoker.current_cpu
if (defined(invoker.is_clang)) {
is_clang = invoker.is_clang
diff --git a/build/tree_truth.sh b/build/tree_truth.sh
deleted file mode 100755
index 617092d..0000000
--- a/build/tree_truth.sh
+++ /dev/null
@@ -1,102 +0,0 @@
-#!/bin/bash
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-#
-# Script for printing recent commits in a buildbot run.
-
-# Return the sha1 of the given tag. If not present, return "".
-# $1: path to repo
-# $2: tag name
-tt_sha1_for_tag() {
- oneline=$(cd $1 && git log -1 $2 --format='%H' 2>/dev/null)
- if [ $? -eq 0 ] ; then
- echo $oneline
- fi
-}
-
-# Return the sha1 of HEAD, or ""
-# $1: path to repo
-tt_sha1_for_head() {
- ( cd $1 && git log HEAD -n1 --format='%H' | cat )
-}
-
-# For the given repo, set tag to HEAD.
-# $1: path to repo
-# $2: tag name
-tt_tag_head() {
- ( cd $1 && git tag -f $2 )
-}
-
-# For the given repo, delete the tag.
-# $1: path to repo
-# $2: tag name
-tt_delete_tag() {
- ( cd $1 && git tag -d $2 )
-}
-
-# For the given repo, set tag to "three commits ago" (for testing).
-# $1: path to repo
-# $2: tag name
-tt_tag_three_ago() {
- local sh=$(cd $1 && git log --pretty=oneline -n 3 | tail -1 | awk '{print $1}')
- ( cd $1 && git tag -f $2 $sh )
-}
-
-# List the commits between the given tag and HEAD.
-# If the tag does not exist, only list the last few.
-# If the tag is at HEAD, list nothing.
-# Output format has distinct build steps for repos with changes.
-# $1: path to repo
-# $2: tag name
-# $3: simple/short repo name to use for display
-tt_list_commits() {
- local tag_sha1=$(tt_sha1_for_tag $1 $2)
- local head_sha1=$(tt_sha1_for_head $1)
- local display_name=$(echo $3 | sed 's#/#_#g')
- if [ "${tag_sha1}" = "${head_sha1}" ] ; then
- return
- fi
- if [ "${tag_sha1}" = "" ] ; then
- echo "@@@BUILD_STEP Recent commits in repo $display_name@@@"
- echo "NOTE: git tag was not found so we have no baseline."
- echo "Here are some recent commits, but they may not be new for this build."
- ( cd $1 && git log -n 10 --stat | cat)
- else
- echo "@@@BUILD_STEP New commits in repo $display_name@@@"
- ( cd $1 && git log -n 500 $2..HEAD --stat | cat)
- fi
-}
-
-# Clean out the tree truth tags in all repos. For testing.
-tt_clean_all() {
- for project in $@; do
- tt_delete_tag $CHROME_SRC/../$project tree_truth
- done
-}
-
-# Print tree truth for all clank repos.
-tt_print_all() {
- for project in $@; do
- local full_path=$CHROME_SRC/../$project
- tt_list_commits $full_path tree_truth $project
- tt_tag_head $full_path tree_truth
- done
-}
-
-# Print a summary of the last 10 commits for each repo.
-tt_brief_summary() {
- echo "@@@BUILD_STEP Brief summary of recent CLs in every branch@@@"
- for project in $@; do
- echo $project:
- local full_path=$CHROME_SRC/../$project
- (cd $full_path && git log -n 10 --format=" %H %s %an, %ad" | cat)
- echo "================================================================="
- done
-}
-
-CHROME_SRC=$1
-shift
-PROJECT_LIST=$@
-tt_brief_summary $PROJECT_LIST
-tt_print_all $PROJECT_LIST
diff --git a/build/uiautomator_test.gypi b/build/uiautomator_test.gypi
deleted file mode 100644
index e9bd0bf..0000000
--- a/build/uiautomator_test.gypi
+++ /dev/null
@@ -1,37 +0,0 @@
-# Copyright (c) 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# This file is meant to be included into a target to provide a rule
-# to build uiautomator dexed tests jar.
-#
-# To use this, create a gyp target with the following form:
-# {
-# 'target_name': 'test_suite_name',
-# 'type': 'none',
-# 'includes': ['path/to/this/gypi/file'],
-# }
-#
-
-{
- 'dependencies': [
- '<(DEPTH)/build/android/pylib/device/commands/commands.gyp:chromium_commands',
- '<(DEPTH)/tools/android/android_tools.gyp:android_tools',
- ],
- 'variables': {
- 'output_dex_path': '<(PRODUCT_DIR)/lib.java/<(_target_name).dex.jar',
- },
- 'actions': [
- {
- 'action_name': 'dex_<(_target_name)',
- 'message': 'Dexing <(_target_name) jar',
- 'variables': {
- 'dex_input_paths': [
- '>@(library_dexed_jars_paths)',
- ],
- 'output_path': '<(output_dex_path)',
- },
- 'includes': [ 'android/dex_action.gypi' ],
- },
- ],
-}
diff --git a/build/update-linux-sandbox.sh b/build/update-linux-sandbox.sh
deleted file mode 100755
index 735733a..0000000
--- a/build/update-linux-sandbox.sh
+++ /dev/null
@@ -1,75 +0,0 @@
-#!/bin/sh
-
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-BUILDTYPE="${BUILDTYPE:-Debug}"
-CHROME_SRC_DIR="${CHROME_SRC_DIR:-$(dirname -- $(readlink -fn -- "$0"))/..}"
-CHROME_OUT_DIR="${CHROME_SRC_DIR}/${CHROMIUM_OUT_DIR:-out}/${BUILDTYPE}"
-CHROME_SANDBOX_BUILD_PATH="${CHROME_OUT_DIR}/chrome_sandbox"
-CHROME_SANDBOX_INST_PATH="/usr/local/sbin/chrome-devel-sandbox"
-CHROME_SANDBOX_INST_DIR=$(dirname -- "$CHROME_SANDBOX_INST_PATH")
-
-TARGET_DIR_TYPE=$(stat -f -c %t -- "${CHROME_SANDBOX_INST_DIR}" 2>/dev/null)
-if [ $? -ne 0 ]; then
- echo "Could not get status of ${CHROME_SANDBOX_INST_DIR}"
- exit 1
-fi
-
-# Make sure the path is not on NFS.
-if [ "${TARGET_DIR_TYPE}" = "6969" ]; then
- echo "Please make sure ${CHROME_SANDBOX_INST_PATH} is not on NFS!"
- exit 1
-fi
-
-installsandbox() {
- echo "(using sudo so you may be asked for your password)"
- sudo -- cp "${CHROME_SANDBOX_BUILD_PATH}" \
- "${CHROME_SANDBOX_INST_PATH}" &&
- sudo -- chown root:root "${CHROME_SANDBOX_INST_PATH}" &&
- sudo -- chmod 4755 "${CHROME_SANDBOX_INST_PATH}"
- return $?
-}
-
-if [ ! -d "${CHROME_OUT_DIR}" ]; then
- echo -n "${CHROME_OUT_DIR} does not exist. Use \"BUILDTYPE=Release ${0}\" "
- echo "If you are building in Release mode"
- exit 1
-fi
-
-if [ ! -f "${CHROME_SANDBOX_BUILD_PATH}" ]; then
- echo -n "Could not find ${CHROME_SANDBOX_BUILD_PATH}, "
- echo "please make sure you build the chrome_sandbox target"
- exit 1
-fi
-
-if [ ! -f "${CHROME_SANDBOX_INST_PATH}" ]; then
- echo -n "Could not find ${CHROME_SANDBOX_INST_PATH}, "
- echo "installing it now."
- installsandbox
-fi
-
-if [ ! -f "${CHROME_SANDBOX_INST_PATH}" ]; then
- echo "Failed to install ${CHROME_SANDBOX_INST_PATH}"
- exit 1
-fi
-
-CURRENT_API=$("${CHROME_SANDBOX_BUILD_PATH}" --get-api)
-INSTALLED_API=$("${CHROME_SANDBOX_INST_PATH}" --get-api)
-
-if [ "${CURRENT_API}" != "${INSTALLED_API}" ]; then
- echo "Your installed setuid sandbox is too old, installing it now."
- if ! installsandbox; then
- echo "Failed to install ${CHROME_SANDBOX_INST_PATH}"
- exit 1
- fi
-else
- echo "Your setuid sandbox is up to date"
- if [ "${CHROME_DEVEL_SANDBOX}" != "${CHROME_SANDBOX_INST_PATH}" ]; then
- echo -n "Make sure you have \"export "
- echo -n "CHROME_DEVEL_SANDBOX=${CHROME_SANDBOX_INST_PATH}\" "
- echo "somewhere in your .bashrc"
- echo "This variable is currently: ${CHROME_DEVEL_SANDBOX:-empty}"
- fi
-fi
diff --git a/build/util/BUILD.gn b/build/util/BUILD.gn
deleted file mode 100644
index 29dd943..0000000
--- a/build/util/BUILD.gn
+++ /dev/null
@@ -1,48 +0,0 @@
-# Copyright (c) 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-action("webkit_version") {
- script = "version.py"
-
- lastchange_file = "LASTCHANGE.blink"
-
- # TODO(brettw) move from content to this directory.
- template_file = "//content/webkit_version.h.in"
- inputs = [
- lastchange_file,
- template_file,
- ]
-
- output_file = "$root_gen_dir/webkit_version.h"
- outputs = [
- output_file,
- ]
-
- args = [
- "-f",
- rebase_path(lastchange_file, root_build_dir),
- rebase_path(template_file, root_build_dir),
- rebase_path(output_file, root_build_dir),
- ]
-}
-
-action("chrome_version_json") {
- script = "version.py"
- _chrome_version_path = "//chrome/VERSION"
- inputs = [
- _chrome_version_path,
- ]
- _output_file = "$root_gen_dir/CHROME_VERSION.json"
- outputs = [
- _output_file,
- ]
- args = [
- "--file",
- rebase_path(_chrome_version_path, root_build_dir),
- "--template",
- "{\"full-quoted\": \"\\\"@MAJOR@.@MINOR@.@BUILD@.@PATCH@\\\"\"}",
- "--output",
- rebase_path(_output_file, root_build_dir),
- ]
-}
diff --git a/build/util/LASTCHANGE b/build/util/LASTCHANGE
deleted file mode 100644
index 438a0fe..0000000
--- a/build/util/LASTCHANGE
+++ /dev/null
@@ -1 +0,0 @@
-LASTCHANGE=a757125bae5bce3daacf60f00502f7dd6490b875
diff --git a/build/util/lastchange.py b/build/util/lastchange.py
deleted file mode 100755
index 3f3ee4a..0000000
--- a/build/util/lastchange.py
+++ /dev/null
@@ -1,309 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""
-lastchange.py -- Chromium revision fetching utility.
-"""
-
-import re
-import optparse
-import os
-import subprocess
-import sys
-
-_GIT_SVN_ID_REGEX = re.compile(r'.*git-svn-id:\s*([^@]*)@([0-9]+)', re.DOTALL)
-
-class VersionInfo(object):
- def __init__(self, url, revision):
- self.url = url
- self.revision = revision
-
-
-def FetchSVNRevision(directory, svn_url_regex):
- """
- Fetch the Subversion branch and revision for a given directory.
-
- Errors are swallowed.
-
- Returns:
- A VersionInfo object or None on error.
- """
- try:
- proc = subprocess.Popen(['svn', 'info'],
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- cwd=directory,
- shell=(sys.platform=='win32'))
- except OSError:
- # command is apparently either not installed or not executable.
- return None
- if not proc:
- return None
-
- attrs = {}
- for line in proc.stdout:
- line = line.strip()
- if not line:
- continue
- key, val = line.split(': ', 1)
- attrs[key] = val
-
- try:
- match = svn_url_regex.search(attrs['URL'])
- if match:
- url = match.group(2)
- else:
- url = ''
- revision = attrs['Revision']
- except KeyError:
- return None
-
- return VersionInfo(url, revision)
-
-
-def RunGitCommand(directory, command):
- """
- Launches git subcommand.
-
- Errors are swallowed.
-
- Returns:
- A process object or None.
- """
- command = ['git'] + command
- # Force shell usage under cygwin. This is a workaround for
- # mysterious loss of cwd while invoking cygwin's git.
- # We can't just pass shell=True to Popen, as under win32 this will
- # cause CMD to be used, while we explicitly want a cygwin shell.
- if sys.platform == 'cygwin':
- command = ['sh', '-c', ' '.join(command)]
- try:
- proc = subprocess.Popen(command,
- stdout=subprocess.PIPE,
- stderr=subprocess.PIPE,
- cwd=directory,
- shell=(sys.platform=='win32'))
- return proc
- except OSError:
- return None
-
-
-def FetchGitRevision(directory):
- """
- Fetch the Git hash for a given directory.
-
- Errors are swallowed.
-
- Returns:
- A VersionInfo object or None on error.
- """
- hsh = ''
- proc = RunGitCommand(directory, ['rev-parse', 'HEAD'])
- if proc:
- output = proc.communicate()[0].strip()
- if proc.returncode == 0 and output:
- hsh = output
- if not hsh:
- return None
- pos = ''
- proc = RunGitCommand(directory, ['cat-file', 'commit', 'HEAD'])
- if proc:
- output = proc.communicate()[0]
- if proc.returncode == 0 and output:
- for line in reversed(output.splitlines()):
- if line.startswith('Cr-Commit-Position:'):
- pos = line.rsplit()[-1].strip()
- break
- if not pos:
- return VersionInfo('git', hsh)
- return VersionInfo('git', '%s-%s' % (hsh, pos))
-
-
-def FetchGitSVNURLAndRevision(directory, svn_url_regex, go_deeper):
- """
- Fetch the Subversion URL and revision through Git.
-
- Errors are swallowed.
-
- Returns:
- A tuple containing the Subversion URL and revision.
- """
- git_args = ['log', '-1', '--format=%b']
- if go_deeper:
- git_args.append('--grep=git-svn-id')
- proc = RunGitCommand(directory, git_args)
- if proc:
- output = proc.communicate()[0].strip()
- if proc.returncode == 0 and output:
- # Extract the latest SVN revision and the SVN URL.
- # The target line is the last "git-svn-id: ..." line like this:
- # git-svn-id: svn://svn.chromium.org/chrome/trunk/src@85528 0039d316....
- match = _GIT_SVN_ID_REGEX.search(output)
- if match:
- revision = match.group(2)
- url_match = svn_url_regex.search(match.group(1))
- if url_match:
- url = url_match.group(2)
- else:
- url = ''
- return url, revision
- return None, None
-
-
-def FetchGitSVNRevision(directory, svn_url_regex, go_deeper):
- """
- Fetch the Git-SVN identifier for the local tree.
-
- Errors are swallowed.
- """
- url, revision = FetchGitSVNURLAndRevision(directory, svn_url_regex, go_deeper)
- if url and revision:
- return VersionInfo(url, revision)
- return None
-
-
-def FetchVersionInfo(default_lastchange, directory=None,
- directory_regex_prior_to_src_url='chrome|blink|svn',
- go_deeper=False):
- """
- Returns the last change (in the form of a branch, revision tuple),
- from some appropriate revision control system.
- """
- svn_url_regex = re.compile(
- r'.*/(' + directory_regex_prior_to_src_url + r')(/.*)')
-
- version_info = (FetchSVNRevision(directory, svn_url_regex) or
- FetchGitSVNRevision(directory, svn_url_regex, go_deeper) or
- FetchGitRevision(directory))
- if not version_info:
- if default_lastchange and os.path.exists(default_lastchange):
- revision = open(default_lastchange, 'r').read().strip()
- version_info = VersionInfo(None, revision)
- else:
- version_info = VersionInfo(None, None)
- return version_info
-
-def GetHeaderGuard(path):
- """
- Returns the header #define guard for the given file path.
- This treats everything after the last instance of "src/" as being a
- relevant part of the guard. If there is no "src/", then the entire path
- is used.
- """
- src_index = path.rfind('src/')
- if src_index != -1:
- guard = path[src_index + 4:]
- else:
- guard = path
- guard = guard.upper()
- return guard.replace('/', '_').replace('.', '_').replace('\\', '_') + '_'
-
-def GetHeaderContents(path, define, version):
- """
- Returns what the contents of the header file should be that indicate the given
- revision. Note that the #define is specified as a string, even though it's
- currently always a SVN revision number, in case we need to move to git hashes.
- """
- header_guard = GetHeaderGuard(path)
-
- header_contents = """/* Generated by lastchange.py, do not edit.*/
-
-#ifndef %(header_guard)s
-#define %(header_guard)s
-
-#define %(define)s "%(version)s"
-
-#endif // %(header_guard)s
-"""
- header_contents = header_contents % { 'header_guard': header_guard,
- 'define': define,
- 'version': version }
- return header_contents
-
-def WriteIfChanged(file_name, contents):
- """
- Writes the specified contents to the specified file_name
- iff the contents are different than the current contents.
- """
- try:
- old_contents = open(file_name, 'r').read()
- except EnvironmentError:
- pass
- else:
- if contents == old_contents:
- return
- os.unlink(file_name)
- open(file_name, 'w').write(contents)
-
-
-def main(argv=None):
- if argv is None:
- argv = sys.argv
-
- parser = optparse.OptionParser(usage="lastchange.py [options]")
- parser.add_option("-d", "--default-lastchange", metavar="FILE",
- help="Default last change input FILE.")
- parser.add_option("-m", "--version-macro",
- help="Name of C #define when using --header. Defaults to " +
- "LAST_CHANGE.",
- default="LAST_CHANGE")
- parser.add_option("-o", "--output", metavar="FILE",
- help="Write last change to FILE. " +
- "Can be combined with --header to write both files.")
- parser.add_option("", "--header", metavar="FILE",
- help="Write last change to FILE as a C/C++ header. " +
- "Can be combined with --output to write both files.")
- parser.add_option("--revision-only", action='store_true',
- help="Just print the SVN revision number. Overrides any " +
- "file-output-related options.")
- parser.add_option("-s", "--source-dir", metavar="DIR",
- help="Use repository in the given directory.")
- parser.add_option("--git-svn-go-deeper", action='store_true',
- help="In a Git-SVN repo, dig down to the last committed " +
- "SVN change (historic behaviour).")
- opts, args = parser.parse_args(argv[1:])
-
- out_file = opts.output
- header = opts.header
-
- while len(args) and out_file is None:
- if out_file is None:
- out_file = args.pop(0)
- if args:
- sys.stderr.write('Unexpected arguments: %r\n\n' % args)
- parser.print_help()
- sys.exit(2)
-
- if opts.source_dir:
- src_dir = opts.source_dir
- else:
- src_dir = os.path.dirname(os.path.abspath(__file__))
-
- version_info = FetchVersionInfo(opts.default_lastchange,
- directory=src_dir,
- go_deeper=opts.git_svn_go_deeper)
-
- if version_info.revision == None:
- version_info.revision = '0'
-
- if opts.revision_only:
- print version_info.revision
- else:
- contents = "LASTCHANGE=%s\n" % version_info.revision
- if not out_file and not opts.header:
- sys.stdout.write(contents)
- else:
- if out_file:
- WriteIfChanged(out_file, contents)
- if header:
- WriteIfChanged(header,
- GetHeaderContents(header, opts.version_macro,
- version_info.revision))
-
- return 0
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/build/util/lib/common/perf_result_data_type.py b/build/util/lib/common/perf_result_data_type.py
deleted file mode 100644
index 67b550a..0000000
--- a/build/util/lib/common/perf_result_data_type.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-DEFAULT = 'default'
-UNIMPORTANT = 'unimportant'
-HISTOGRAM = 'histogram'
-UNIMPORTANT_HISTOGRAM = 'unimportant-histogram'
-INFORMATIONAL = 'informational'
-
-ALL_TYPES = [DEFAULT, UNIMPORTANT, HISTOGRAM, UNIMPORTANT_HISTOGRAM,
- INFORMATIONAL]
-
-
-def IsValidType(datatype):
- return datatype in ALL_TYPES
-
-
-def IsHistogram(datatype):
- return (datatype == HISTOGRAM or datatype == UNIMPORTANT_HISTOGRAM)
diff --git a/build/util/lib/common/perf_tests_results_helper.py b/build/util/lib/common/perf_tests_results_helper.py
deleted file mode 100644
index 6cb058b..0000000
--- a/build/util/lib/common/perf_tests_results_helper.py
+++ /dev/null
@@ -1,166 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import re
-import sys
-
-import json
-import logging
-import math
-
-import perf_result_data_type
-
-
-# Mapping from result type to test output
-RESULT_TYPES = {perf_result_data_type.UNIMPORTANT: 'RESULT ',
- perf_result_data_type.DEFAULT: '*RESULT ',
- perf_result_data_type.INFORMATIONAL: '',
- perf_result_data_type.UNIMPORTANT_HISTOGRAM: 'HISTOGRAM ',
- perf_result_data_type.HISTOGRAM: '*HISTOGRAM '}
-
-
-def _EscapePerfResult(s):
- """Escapes |s| for use in a perf result."""
- return re.sub('[\:|=/#&,]', '_', s)
-
-
-def FlattenList(values):
- """Returns a simple list without sub-lists."""
- ret = []
- for entry in values:
- if isinstance(entry, list):
- ret.extend(FlattenList(entry))
- else:
- ret.append(entry)
- return ret
-
-
-def GeomMeanAndStdDevFromHistogram(histogram_json):
- histogram = json.loads(histogram_json)
- # Handle empty histograms gracefully.
- if not 'buckets' in histogram:
- return 0.0, 0.0
- count = 0
- sum_of_logs = 0
- for bucket in histogram['buckets']:
- if 'high' in bucket:
- bucket['mean'] = (bucket['low'] + bucket['high']) / 2.0
- else:
- bucket['mean'] = bucket['low']
- if bucket['mean'] > 0:
- sum_of_logs += math.log(bucket['mean']) * bucket['count']
- count += bucket['count']
-
- if count == 0:
- return 0.0, 0.0
-
- sum_of_squares = 0
- geom_mean = math.exp(sum_of_logs / count)
- for bucket in histogram['buckets']:
- if bucket['mean'] > 0:
- sum_of_squares += (bucket['mean'] - geom_mean) ** 2 * bucket['count']
- return geom_mean, math.sqrt(sum_of_squares / count)
-
-
-def _ValueToString(v):
- # Special case for floats so we don't print using scientific notation.
- if isinstance(v, float):
- return '%f' % v
- else:
- return str(v)
-
-
-def _MeanAndStdDevFromList(values):
- avg = None
- sd = None
- if len(values) > 1:
- try:
- value = '[%s]' % ','.join([_ValueToString(v) for v in values])
- avg = sum([float(v) for v in values]) / len(values)
- sqdiffs = [(float(v) - avg) ** 2 for v in values]
- variance = sum(sqdiffs) / (len(values) - 1)
- sd = math.sqrt(variance)
- except ValueError:
- value = ', '.join(values)
- else:
- value = values[0]
- return value, avg, sd
-
-
-def PrintPages(page_list):
- """Prints list of pages to stdout in the format required by perf tests."""
- print 'Pages: [%s]' % ','.join([_EscapePerfResult(p) for p in page_list])
-
-
-def PrintPerfResult(measurement, trace, values, units,
- result_type=perf_result_data_type.DEFAULT,
- print_to_stdout=True):
- """Prints numerical data to stdout in the format required by perf tests.
-
- The string args may be empty but they must not contain any colons (:) or
- equals signs (=).
- This is parsed by the buildbot using:
- http://src.chromium.org/viewvc/chrome/trunk/tools/build/scripts/slave/process_log_utils.py
-
- Args:
- measurement: A description of the quantity being measured, e.g. "vm_peak".
- On the dashboard, this maps to a particular graph. Mandatory.
- trace: A description of the particular data point, e.g. "reference".
- On the dashboard, this maps to a particular "line" in the graph.
- Mandatory.
- values: A list of numeric measured values. An N-dimensional list will be
- flattened and treated as a simple list.
- units: A description of the units of measure, e.g. "bytes".
- result_type: Accepts values of perf_result_data_type.ALL_TYPES.
- print_to_stdout: If True, prints the output in stdout instead of returning
- the output to caller.
-
- Returns:
- String of the formated perf result.
- """
- assert perf_result_data_type.IsValidType(result_type), \
- 'result type: %s is invalid' % result_type
-
- trace_name = _EscapePerfResult(trace)
-
- if (result_type == perf_result_data_type.UNIMPORTANT or
- result_type == perf_result_data_type.DEFAULT or
- result_type == perf_result_data_type.INFORMATIONAL):
- assert isinstance(values, list)
- assert '/' not in measurement
- flattened_values = FlattenList(values)
- assert len(flattened_values)
- value, avg, sd = _MeanAndStdDevFromList(flattened_values)
- output = '%s%s: %s%s%s %s' % (
- RESULT_TYPES[result_type],
- _EscapePerfResult(measurement),
- trace_name,
- # Do not show equal sign if the trace is empty. Usually it happens when
- # measurement is enough clear to describe the result.
- '= ' if trace_name else '',
- value,
- units)
- else:
- assert perf_result_data_type.IsHistogram(result_type)
- assert isinstance(values, list)
- # The histograms can only be printed individually, there's no computation
- # across different histograms.
- assert len(values) == 1
- value = values[0]
- output = '%s%s: %s= %s %s' % (
- RESULT_TYPES[result_type],
- _EscapePerfResult(measurement),
- trace_name,
- value,
- units)
- avg, sd = GeomMeanAndStdDevFromHistogram(value)
-
- if avg:
- output += '\nAvg %s: %f%s' % (measurement, avg, units)
- if sd:
- output += '\nSd %s: %f%s' % (measurement, sd, units)
- if print_to_stdout:
- print output
- sys.stdout.flush()
- return output
diff --git a/build/util/lib/common/unittest_util.py b/build/util/lib/common/unittest_util.py
deleted file mode 100644
index 189f587..0000000
--- a/build/util/lib/common/unittest_util.py
+++ /dev/null
@@ -1,153 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Utilities for dealing with the python unittest module."""
-
-import fnmatch
-import sys
-import unittest
-
-
-class _TextTestResult(unittest._TextTestResult):
- """A test result class that can print formatted text results to a stream.
-
- Results printed in conformance with gtest output format, like:
- [ RUN ] autofill.AutofillTest.testAutofillInvalid: "test desc."
- [ OK ] autofill.AutofillTest.testAutofillInvalid
- [ RUN ] autofill.AutofillTest.testFillProfile: "test desc."
- [ OK ] autofill.AutofillTest.testFillProfile
- [ RUN ] autofill.AutofillTest.testFillProfileCrazyCharacters: "Test."
- [ OK ] autofill.AutofillTest.testFillProfileCrazyCharacters
- """
- def __init__(self, stream, descriptions, verbosity):
- unittest._TextTestResult.__init__(self, stream, descriptions, verbosity)
- self._fails = set()
-
- def _GetTestURI(self, test):
- return '%s.%s.%s' % (test.__class__.__module__,
- test.__class__.__name__,
- test._testMethodName)
-
- def getDescription(self, test):
- return '%s: "%s"' % (self._GetTestURI(test), test.shortDescription())
-
- def startTest(self, test):
- unittest.TestResult.startTest(self, test)
- self.stream.writeln('[ RUN ] %s' % self.getDescription(test))
-
- def addSuccess(self, test):
- unittest.TestResult.addSuccess(self, test)
- self.stream.writeln('[ OK ] %s' % self._GetTestURI(test))
-
- def addError(self, test, err):
- unittest.TestResult.addError(self, test, err)
- self.stream.writeln('[ ERROR ] %s' % self._GetTestURI(test))
- self._fails.add(self._GetTestURI(test))
-
- def addFailure(self, test, err):
- unittest.TestResult.addFailure(self, test, err)
- self.stream.writeln('[ FAILED ] %s' % self._GetTestURI(test))
- self._fails.add(self._GetTestURI(test))
-
- def getRetestFilter(self):
- return ':'.join(self._fails)
-
-
-class TextTestRunner(unittest.TextTestRunner):
- """Test Runner for displaying test results in textual format.
-
- Results are displayed in conformance with google test output.
- """
-
- def __init__(self, verbosity=1):
- unittest.TextTestRunner.__init__(self, stream=sys.stderr,
- verbosity=verbosity)
-
- def _makeResult(self):
- return _TextTestResult(self.stream, self.descriptions, self.verbosity)
-
-
-def GetTestsFromSuite(suite):
- """Returns all the tests from a given test suite."""
- tests = []
- for x in suite:
- if isinstance(x, unittest.TestSuite):
- tests += GetTestsFromSuite(x)
- else:
- tests += [x]
- return tests
-
-
-def GetTestNamesFromSuite(suite):
- """Returns a list of every test name in the given suite."""
- return map(lambda x: GetTestName(x), GetTestsFromSuite(suite))
-
-
-def GetTestName(test):
- """Gets the test name of the given unittest test."""
- return '.'.join([test.__class__.__module__,
- test.__class__.__name__,
- test._testMethodName])
-
-
-def FilterTestSuite(suite, gtest_filter):
- """Returns a new filtered tests suite based on the given gtest filter.
-
- See http://code.google.com/p/googletest/wiki/AdvancedGuide
- for gtest_filter specification.
- """
- return unittest.TestSuite(FilterTests(GetTestsFromSuite(suite), gtest_filter))
-
-
-def FilterTests(all_tests, gtest_filter):
- """Filter a list of tests based on the given gtest filter.
-
- Args:
- all_tests: List of tests (unittest.TestSuite)
- gtest_filter: Filter to apply.
-
- Returns:
- Filtered subset of the given list of tests.
- """
- test_names = [GetTestName(test) for test in all_tests]
- filtered_names = FilterTestNames(test_names, gtest_filter)
- return [test for test in all_tests if GetTestName(test) in filtered_names]
-
-
-def FilterTestNames(all_tests, gtest_filter):
- """Filter a list of test names based on the given gtest filter.
-
- See http://code.google.com/p/googletest/wiki/AdvancedGuide
- for gtest_filter specification.
-
- Args:
- all_tests: List of test names.
- gtest_filter: Filter to apply.
-
- Returns:
- Filtered subset of the given list of test names.
- """
- pattern_groups = gtest_filter.split('-')
- positive_patterns = ['*']
- if pattern_groups[0]:
- positive_patterns = pattern_groups[0].split(':')
- negative_patterns = None
- if len(pattern_groups) > 1:
- negative_patterns = pattern_groups[1].split(':')
-
- tests = []
- for test in all_tests:
- # Test name must by matched by one positive pattern.
- for pattern in positive_patterns:
- if fnmatch.fnmatch(test, pattern):
- break
- else:
- continue
- # Test name must not be matched by any negative patterns.
- for pattern in negative_patterns or []:
- if fnmatch.fnmatch(test, pattern):
- break
- else:
- tests += [test]
- return tests
diff --git a/build/util/lib/common/util.py b/build/util/lib/common/util.py
deleted file mode 100644
index a415b1f..0000000
--- a/build/util/lib/common/util.py
+++ /dev/null
@@ -1,151 +0,0 @@
-# Copyright 2013 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Generic utilities for all python scripts."""
-
-import atexit
-import httplib
-import os
-import signal
-import stat
-import subprocess
-import sys
-import tempfile
-import urlparse
-
-
-def GetPlatformName():
- """Return a string to be used in paths for the platform."""
- if IsWindows():
- return 'win'
- if IsMac():
- return 'mac'
- if IsLinux():
- return 'linux'
- raise NotImplementedError('Unknown platform "%s".' % sys.platform)
-
-
-def IsWindows():
- return sys.platform == 'cygwin' or sys.platform.startswith('win')
-
-
-def IsLinux():
- return sys.platform.startswith('linux')
-
-
-def IsMac():
- return sys.platform.startswith('darwin')
-
-
-def _DeleteDir(path):
- """Deletes a directory recursively, which must exist."""
- # Don't use shutil.rmtree because it can't delete read-only files on Win.
- for root, dirs, files in os.walk(path, topdown=False):
- for name in files:
- filename = os.path.join(root, name)
- os.chmod(filename, stat.S_IWRITE)
- os.remove(filename)
- for name in dirs:
- os.rmdir(os.path.join(root, name))
- os.rmdir(path)
-
-
-def Delete(path):
- """Deletes the given file or directory (recursively), which must exist."""
- if os.path.isdir(path):
- _DeleteDir(path)
- else:
- os.remove(path)
-
-
-def MaybeDelete(path):
- """Deletes the given file or directory (recurisvely), if it exists."""
- if os.path.exists(path):
- Delete(path)
-
-
-def MakeTempDir(parent_dir=None):
- """Creates a temporary directory and returns an absolute path to it.
-
- The temporary directory is automatically deleted when the python interpreter
- exits normally.
-
- Args:
- parent_dir: the directory to create the temp dir in. If None, the system
- temp dir is used.
-
- Returns:
- The absolute path to the temporary directory.
- """
- path = tempfile.mkdtemp(dir=parent_dir)
- atexit.register(MaybeDelete, path)
- return path
-
-
-def Unzip(zip_path, output_dir):
- """Unzips the given zip file using a system installed unzip tool.
-
- Args:
- zip_path: zip file to unzip.
- output_dir: directory to unzip the contents of the zip file. The directory
- must exist.
-
- Raises:
- RuntimeError if the unzip operation fails.
- """
- if IsWindows():
- unzip_cmd = ['C:\\Program Files\\7-Zip\\7z.exe', 'x', '-y']
- else:
- unzip_cmd = ['unzip', '-o']
- unzip_cmd += [zip_path]
- if RunCommand(unzip_cmd, output_dir) != 0:
- raise RuntimeError('Unable to unzip %s to %s' % (zip_path, output_dir))
-
-
-def Kill(pid):
- """Terminate the given pid."""
- if IsWindows():
- subprocess.call(['taskkill.exe', '/T', '/F', '/PID', str(pid)])
- else:
- os.kill(pid, signal.SIGTERM)
-
-
-def RunCommand(cmd, cwd=None):
- """Runs the given command and returns the exit code.
-
- Args:
- cmd: list of command arguments.
- cwd: working directory to execute the command, or None if the current
- working directory should be used.
-
- Returns:
- The exit code of the command.
- """
- process = subprocess.Popen(cmd, cwd=cwd)
- process.wait()
- return process.returncode
-
-
-def DoesUrlExist(url):
- """Determines whether a resource exists at the given URL.
-
- Args:
- url: URL to be verified.
-
- Returns:
- True if url exists, otherwise False.
- """
- parsed = urlparse.urlparse(url)
- try:
- conn = httplib.HTTPConnection(parsed.netloc)
- conn.request('HEAD', parsed.path)
- response = conn.getresponse()
- except (socket.gaierror, socket.error):
- return False
- finally:
- conn.close()
- # Follow both permanent (301) and temporary (302) redirects.
- if response.status == 302 or response.status == 301:
- return DoesUrlExist(response.getheader('location'))
- return response.status == 200
diff --git a/build/util/version.gypi b/build/util/version.gypi
deleted file mode 100644
index 327a5c2..0000000
--- a/build/util/version.gypi
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-{
- 'variables': {
- 'variables': {
- 'version_py_path': '<(DEPTH)/build/util/version.py',
- 'version_path': '<(DEPTH)/chrome/VERSION',
- 'lastchange_path': '<(DEPTH)/build/util/LASTCHANGE',
- },
- 'version_py_path': '<(version_py_path)',
- 'version_path': '<(version_path)',
- 'lastchange_path': '<(lastchange_path)',
- 'version_full':
- '<!(python <(version_py_path) -f <(version_path) -t "@MAJOR@.@MINOR@.@BUILD@.@PATCH@")',
- 'version_mac_dylib':
- '<!(python <(version_py_path) -f <(version_path) -t "@BUILD@.@PATCH_HI@.@PATCH_LO@" -e "PATCH_HI=int(PATCH)/256" -e "PATCH_LO=int(PATCH)%256")',
- }, # variables
-}
diff --git a/build/util/version.py b/build/util/version.py
deleted file mode 100755
index 4d3691a..0000000
--- a/build/util/version.py
+++ /dev/null
@@ -1,166 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""
-version.py -- Chromium version string substitution utility.
-"""
-
-import argparse
-import os
-import sys
-
-
-def fetch_values_from_file(values_dict, file_name):
- """
- Fetches KEYWORD=VALUE settings from the specified file.
-
- Everything to the left of the first '=' is the keyword,
- everything to the right is the value. No stripping of
- white space, so beware.
-
- The file must exist, otherwise you get the Python exception from open().
- """
- for line in open(file_name, 'r').readlines():
- key, val = line.rstrip('\r\n').split('=', 1)
- values_dict[key] = val
-
-
-def fetch_values(file_list):
- """
- Returns a dictionary of values to be used for substitution, populating
- the dictionary with KEYWORD=VALUE settings from the files in 'file_list'.
-
- Explicitly adds the following value from internal calculations:
-
- OFFICIAL_BUILD
- """
- CHROME_BUILD_TYPE = os.environ.get('CHROME_BUILD_TYPE')
- if CHROME_BUILD_TYPE == '_official':
- official_build = '1'
- else:
- official_build = '0'
-
- values = dict(
- OFFICIAL_BUILD = official_build,
- )
-
- for file_name in file_list:
- fetch_values_from_file(values, file_name)
-
- return values
-
-
-def subst_template(contents, values):
- """
- Returns the template with substituted values from the specified dictionary.
-
- Keywords to be substituted are surrounded by '@': @KEYWORD@.
-
- No attempt is made to avoid recursive substitution. The order
- of evaluation is random based on the order of the keywords returned
- by the Python dictionary. So do NOT substitute a value that
- contains any @KEYWORD@ strings expecting them to be recursively
- substituted, okay?
- """
- for key, val in values.iteritems():
- try:
- contents = contents.replace('@' + key + '@', val)
- except TypeError:
- print repr(key), repr(val)
- return contents
-
-
-def subst_file(file_name, values):
- """
- Returns the contents of the specified file_name with substituted
- values from the specified dictionary.
-
- This is like subst_template, except it operates on a file.
- """
- template = open(file_name, 'r').read()
- return subst_template(template, values);
-
-
-def write_if_changed(file_name, contents):
- """
- Writes the specified contents to the specified file_name
- iff the contents are different than the current contents.
- """
- try:
- old_contents = open(file_name, 'r').read()
- except EnvironmentError:
- pass
- else:
- if contents == old_contents:
- return
- os.unlink(file_name)
- open(file_name, 'w').write(contents)
-
-
-def main():
- parser = argparse.ArgumentParser()
- parser.add_argument('-f', '--file', action='append', default=[],
- help='Read variables from FILE.')
- parser.add_argument('-i', '--input', default=None,
- help='Read strings to substitute from FILE.')
- parser.add_argument('-o', '--output', default=None,
- help='Write substituted strings to FILE.')
- parser.add_argument('-t', '--template', default=None,
- help='Use TEMPLATE as the strings to substitute.')
- parser.add_argument('-e', '--eval', action='append', default=[],
- help='Evaluate VAL after reading variables. Can be used '
- 'to synthesize variables. e.g. -e \'PATCH_HI=int('
- 'PATCH)/256.')
- parser.add_argument('args', nargs=argparse.REMAINDER,
- help='For compatibility: INPUT and OUTPUT can be '
- 'passed as positional arguments.')
- options = parser.parse_args()
-
- evals = {}
- for expression in options.eval:
- try:
- evals.update(dict([expression.split('=', 1)]))
- except ValueError:
- parser.error('-e requires VAR=VAL')
-
- # Compatibility with old versions that considered the first two positional
- # arguments shorthands for --input and --output.
- while len(options.args) and (options.input is None or \
- options.output is None):
- if options.input is None:
- options.input = options.args.pop(0)
- elif options.output is None:
- options.output = options.args.pop(0)
- if options.args:
- parser.error('Unexpected arguments: %r' % options.args)
-
- values = fetch_values(options.file)
- for key, val in evals.iteritems():
- values[key] = str(eval(val, globals(), values))
-
- if options.template is not None:
- contents = subst_template(options.template, values)
- elif options.input:
- contents = subst_file(options.input, values)
- else:
- # Generate a default set of version information.
- contents = """MAJOR=%(MAJOR)s
-MINOR=%(MINOR)s
-BUILD=%(BUILD)s
-PATCH=%(PATCH)s
-LASTCHANGE=%(LASTCHANGE)s
-OFFICIAL_BUILD=%(OFFICIAL_BUILD)s
-""" % values
-
- if options.output is not None:
- write_if_changed(options.output, contents)
- else:
- print contents
-
- return 0
-
-
-if __name__ == '__main__':
- sys.exit(main())
diff --git a/build/vs_toolchain.py b/build/vs_toolchain.py
index 16f4477..d8a7f4c 100644
--- a/build/vs_toolchain.py
+++ b/build/vs_toolchain.py
@@ -1,11 +1,15 @@
+#!/usr/bin/env python
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import glob
import json
import os
import pipes
+import platform
import shutil
+import stat
import subprocess
import sys
@@ -14,23 +18,32 @@
chrome_src = os.path.abspath(os.path.join(script_dir, os.pardir))
SRC_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(1, os.path.join(chrome_src, 'tools'))
-sys.path.insert(0, os.path.join(chrome_src, 'tools', 'gyp', 'pylib'))
+sys.path.insert(0, os.path.join(chrome_src, 'third_party', 'gyp', 'pylib'))
json_data_file = os.path.join(script_dir, 'win_toolchain.json')
import gyp
+# Use MSVS2015 as the default toolchain.
+CURRENT_DEFAULT_TOOLCHAIN_VERSION = '2015'
+
+
def SetEnvironmentAndGetRuntimeDllDirs():
"""Sets up os.environ to use the depot_tools VS toolchain with gyp, and
returns the location of the VS runtime DLLs so they can be copied into
the output directory after gyp generation.
+
+ Return value is [x64path, x86path] or None
"""
- vs2013_runtime_dll_dirs = None
+ vs_runtime_dll_dirs = None
depot_tools_win_toolchain = \
bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', '1')))
- if sys.platform in ('win32', 'cygwin') and depot_tools_win_toolchain:
- if not os.path.exists(json_data_file):
+ # When running on a non-Windows host, only do this if the SDK has explicitly
+ # been downloaded before (in which case json_data_file will exist).
+ if ((sys.platform in ('win32', 'cygwin') or os.path.exists(json_data_file))
+ and depot_tools_win_toolchain):
+ if ShouldUpdateToolchain():
Update()
with open(json_data_file, 'r') as tempf:
toolchain_data = json.load(tempf)
@@ -44,7 +57,7 @@
# TODO(scottmg): The order unfortunately matters in these. They should be
# split into separate keys for x86 and x64. (See CopyVsRuntimeDlls call
# below). http://crbug.com/345992
- vs2013_runtime_dll_dirs = toolchain_data['runtime_dirs']
+ vs_runtime_dll_dirs = toolchain_data['runtime_dirs']
os.environ['GYP_MSVS_OVERRIDE_PATH'] = toolchain
os.environ['GYP_MSVS_VERSION'] = version
@@ -59,33 +72,119 @@
os.environ['WINDOWSSDKDIR'] = win_sdk
os.environ['WDK_DIR'] = wdk
# Include the VS runtime in the PATH in case it's not machine-installed.
- runtime_path = ';'.join(vs2013_runtime_dll_dirs)
- os.environ['PATH'] = runtime_path + ';' + os.environ['PATH']
- return vs2013_runtime_dll_dirs
+ runtime_path = os.path.pathsep.join(vs_runtime_dll_dirs)
+ os.environ['PATH'] = runtime_path + os.path.pathsep + os.environ['PATH']
+ elif sys.platform == 'win32' and not depot_tools_win_toolchain:
+ if not 'GYP_MSVS_OVERRIDE_PATH' in os.environ:
+ os.environ['GYP_MSVS_OVERRIDE_PATH'] = DetectVisualStudioPath()
+ if not 'GYP_MSVS_VERSION' in os.environ:
+ os.environ['GYP_MSVS_VERSION'] = GetVisualStudioVersion()
+
+ # When using an installed toolchain these files aren't needed in the output
+ # directory in order to run binaries locally, but they are needed in order
+ # to create isolates or the mini_installer. Copying them to the output
+ # directory ensures that they are available when needed.
+ bitness = platform.architecture()[0]
+ # When running 64-bit python the x64 DLLs will be in System32
+ x64_path = 'System32' if bitness == '64bit' else 'Sysnative'
+ x64_path = os.path.join(r'C:\Windows', x64_path)
+ vs_runtime_dll_dirs = [x64_path, r'C:\Windows\SysWOW64']
+
+ return vs_runtime_dll_dirs
+
+
+def _RegistryGetValueUsingWinReg(key, value):
+ """Use the _winreg module to obtain the value of a registry key.
+
+ Args:
+ key: The registry key.
+ value: The particular registry value to read.
+ Return:
+ contents of the registry key's value, or None on failure. Throws
+ ImportError if _winreg is unavailable.
+ """
+ import _winreg
+ try:
+ root, subkey = key.split('\\', 1)
+ assert root == 'HKLM' # Only need HKLM for now.
+ with _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, subkey) as hkey:
+ return _winreg.QueryValueEx(hkey, value)[0]
+ except WindowsError:
+ return None
+
+
+def _RegistryGetValue(key, value):
+ try:
+ return _RegistryGetValueUsingWinReg(key, value)
+ except ImportError:
+ raise Exception('The python library _winreg not found.')
+
+
+def GetVisualStudioVersion():
+ """Return GYP_MSVS_VERSION of Visual Studio.
+ """
+ return os.environ.get('GYP_MSVS_VERSION', CURRENT_DEFAULT_TOOLCHAIN_VERSION)
+
+
+def DetectVisualStudioPath():
+ """Return path to the GYP_MSVS_VERSION of Visual Studio.
+ """
+
+ # Note that this code is used from
+ # build/toolchain/win/setup_toolchain.py as well.
+ version_as_year = GetVisualStudioVersion()
+ year_to_version = {
+ '2013': '12.0',
+ '2015': '14.0',
+ }
+ if version_as_year not in year_to_version:
+ raise Exception(('Visual Studio version %s (from GYP_MSVS_VERSION)'
+ ' not supported. Supported versions are: %s') % (
+ version_as_year, ', '.join(year_to_version.keys())))
+ version = year_to_version[version_as_year]
+ keys = [r'HKLM\Software\Microsoft\VisualStudio\%s' % version,
+ r'HKLM\Software\Wow6432Node\Microsoft\VisualStudio\%s' % version]
+ for key in keys:
+ path = _RegistryGetValue(key, 'InstallDir')
+ if not path:
+ continue
+ path = os.path.normpath(os.path.join(path, '..', '..'))
+ return path
+
+ raise Exception(('Visual Studio Version %s (from GYP_MSVS_VERSION)'
+ ' not found.') % (version_as_year))
def _VersionNumber():
"""Gets the standard version number ('120', '140', etc.) based on
GYP_MSVS_VERSION."""
- if os.environ['GYP_MSVS_VERSION'] == '2013':
+ vs_version = GetVisualStudioVersion()
+ if vs_version == '2013':
return '120'
- elif os.environ['GYP_MSVS_VERSION'] == '2015':
+ elif vs_version == '2015':
return '140'
else:
raise ValueError('Unexpected GYP_MSVS_VERSION')
-def _CopyRuntimeImpl(target, source):
- """Copy |source| to |target| if it doesn't already exist or if it
- needs to be updated.
+def _CopyRuntimeImpl(target, source, verbose=True):
+ """Copy |source| to |target| if it doesn't already exist or if it needs to be
+ updated (comparing last modified time as an approximate float match as for
+ some reason the values tend to differ by ~1e-07 despite being copies of the
+ same file... https://crbug.com/603603).
"""
if (os.path.isdir(os.path.dirname(target)) and
(not os.path.isfile(target) or
- os.stat(target).st_mtime != os.stat(source).st_mtime)):
- print 'Copying %s to %s...' % (source, target)
+ abs(os.stat(target).st_mtime - os.stat(source).st_mtime) >= 0.01)):
+ if verbose:
+ print 'Copying %s to %s...' % (source, target)
if os.path.exists(target):
+ # Make the file writable so that we can delete it now.
+ os.chmod(target, stat.S_IWRITE)
os.unlink(target)
shutil.copy2(source, target)
+ # Make the file writable so that we can overwrite or delete it later.
+ os.chmod(target, stat.S_IWRITE)
def _CopyRuntime2013(target_dir, source_dir, dll_pattern):
@@ -98,14 +197,57 @@
_CopyRuntimeImpl(target, source)
-def _CopyRuntime2015(target_dir, source_dir, dll_pattern):
+def _CopyRuntime2015(target_dir, source_dir, dll_pattern, suffix):
"""Copy both the msvcp and vccorlib runtime DLLs, only if the target doesn't
exist, but the target directory does exist."""
- for file_part in ('msvcp', 'vccorlib'):
+ for file_part in ('msvcp', 'vccorlib', 'vcruntime'):
dll = dll_pattern % file_part
target = os.path.join(target_dir, dll)
source = os.path.join(source_dir, dll)
_CopyRuntimeImpl(target, source)
+ # OS installs of Visual Studio (and all installs of Windows 10) put the
+ # universal CRT files in c:\Windows\System32\downlevel - look for them there
+ # to support DEPOT_TOOLS_WIN_TOOLCHAIN=0.
+ if os.path.exists(os.path.join(source_dir, 'downlevel')):
+ ucrt_src_glob = os.path.join(source_dir, 'downlevel', 'api-ms-win-*.dll')
+ else:
+ ucrt_src_glob = os.path.join(source_dir, 'api-ms-win-*.dll')
+ ucrt_files = glob.glob(ucrt_src_glob)
+ assert len(ucrt_files) > 0
+ for ucrt_src_file in ucrt_files:
+ file_part = os.path.basename(ucrt_src_file)
+ ucrt_dst_file = os.path.join(target_dir, file_part)
+ _CopyRuntimeImpl(ucrt_dst_file, ucrt_src_file, False)
+ _CopyRuntimeImpl(os.path.join(target_dir, 'ucrtbase' + suffix),
+ os.path.join(source_dir, 'ucrtbase' + suffix))
+
+
+def _CopyRuntime(target_dir, source_dir, target_cpu, debug):
+ """Copy the VS runtime DLLs, only if the target doesn't exist, but the target
+ directory does exist. Handles VS 2013 and VS 2015."""
+ suffix = "d.dll" if debug else ".dll"
+ if GetVisualStudioVersion() == '2015':
+ _CopyRuntime2015(target_dir, source_dir, '%s140' + suffix, suffix)
+ else:
+ _CopyRuntime2013(target_dir, source_dir, 'msvc%s120' + suffix)
+
+ # Copy the PGO runtime library to the release directories.
+ if not debug and os.environ.get('GYP_MSVS_OVERRIDE_PATH'):
+ pgo_x86_runtime_dir = os.path.join(os.environ.get('GYP_MSVS_OVERRIDE_PATH'),
+ 'VC', 'bin')
+ pgo_x64_runtime_dir = os.path.join(pgo_x86_runtime_dir, 'amd64')
+ pgo_runtime_dll = 'pgort' + _VersionNumber() + '.dll'
+ if target_cpu == "x86":
+ source_x86 = os.path.join(pgo_x86_runtime_dir, pgo_runtime_dll)
+ if os.path.exists(source_x86):
+ _CopyRuntimeImpl(os.path.join(target_dir, pgo_runtime_dll), source_x86)
+ elif target_cpu == "x64":
+ source_x64 = os.path.join(pgo_x64_runtime_dir, pgo_runtime_dll)
+ if os.path.exists(source_x64):
+ _CopyRuntimeImpl(os.path.join(target_dir, pgo_runtime_dll),
+ source_x64)
+ else:
+ raise NotImplementedError("Unexpected target_cpu value:" + target_cpu)
def CopyVsRuntimeDlls(output_dir, runtime_dirs):
@@ -115,9 +257,9 @@
This needs to be run after gyp has been run so that the expected target
output directories are already created.
- """
- assert sys.platform.startswith(('win32', 'cygwin'))
+ This is used for the GYP build and gclient runhooks.
+ """
x86, x64 = runtime_dirs
out_debug = os.path.join(output_dir, 'Debug')
out_debug_nacl64 = os.path.join(output_dir, 'Debug', 'x64')
@@ -130,35 +272,12 @@
os.makedirs(out_debug_nacl64)
if os.path.exists(out_release) and not os.path.exists(out_release_nacl64):
os.makedirs(out_release_nacl64)
- if os.environ.get('GYP_MSVS_VERSION') == '2015':
- _CopyRuntime2015(out_debug, x86, '%s140d.dll')
- _CopyRuntime2015(out_release, x86, '%s140.dll')
- _CopyRuntime2015(out_debug_x64, x64, '%s140d.dll')
- _CopyRuntime2015(out_release_x64, x64, '%s140.dll')
- _CopyRuntime2015(out_debug_nacl64, x64, '%s140d.dll')
- _CopyRuntime2015(out_release_nacl64, x64, '%s140.dll')
- else:
- # VS2013 is the default.
- _CopyRuntime2013(out_debug, x86, 'msvc%s120d.dll')
- _CopyRuntime2013(out_release, x86, 'msvc%s120.dll')
- _CopyRuntime2013(out_debug_x64, x64, 'msvc%s120d.dll')
- _CopyRuntime2013(out_release_x64, x64, 'msvc%s120.dll')
- _CopyRuntime2013(out_debug_nacl64, x64, 'msvc%s120d.dll')
- _CopyRuntime2013(out_release_nacl64, x64, 'msvc%s120.dll')
-
- # Copy the PGO runtime library to the release directories.
- if os.environ.get('GYP_MSVS_OVERRIDE_PATH'):
- pgo_x86_runtime_dir = os.path.join(os.environ.get('GYP_MSVS_OVERRIDE_PATH'),
- 'VC', 'bin')
- pgo_x64_runtime_dir = os.path.join(pgo_x86_runtime_dir, 'amd64')
- pgo_runtime_dll = 'pgort' + _VersionNumber() + '.dll'
- source_x86 = os.path.join(pgo_x86_runtime_dir, pgo_runtime_dll)
- if os.path.exists(source_x86):
- _CopyRuntimeImpl(os.path.join(out_release, pgo_runtime_dll), source_x86)
- source_x64 = os.path.join(pgo_x64_runtime_dir, pgo_runtime_dll)
- if os.path.exists(source_x64):
- _CopyRuntimeImpl(os.path.join(out_release_x64, pgo_runtime_dll),
- source_x64)
+ _CopyRuntime(out_debug, x86, "x86", debug=True)
+ _CopyRuntime(out_release, x86, "x86", debug=False)
+ _CopyRuntime(out_debug_x64, x64, "x64", debug=True)
+ _CopyRuntime(out_release_x64, x64, "x64", debug=False)
+ _CopyRuntime(out_debug_nacl64, x64, "x64", debug=True)
+ _CopyRuntime(out_release_nacl64, x64, "x64", debug=False)
def CopyDlls(target_dir, configuration, target_cpu):
@@ -169,42 +288,63 @@
The debug configuration gets both the debug and release DLLs; the
release config only the latter.
+
+ This is used for the GN build.
"""
- vs2013_runtime_dll_dirs = SetEnvironmentAndGetRuntimeDllDirs()
- if not vs2013_runtime_dll_dirs:
+ vs_runtime_dll_dirs = SetEnvironmentAndGetRuntimeDllDirs()
+ if not vs_runtime_dll_dirs:
return
- x64_runtime, x86_runtime = vs2013_runtime_dll_dirs
+ x64_runtime, x86_runtime = vs_runtime_dll_dirs
runtime_dir = x64_runtime if target_cpu == 'x64' else x86_runtime
- _CopyRuntime2013(
- target_dir, runtime_dir, 'msvc%s' + _VersionNumber() + '.dll')
+ _CopyRuntime(target_dir, runtime_dir, target_cpu, debug=False)
if configuration == 'Debug':
- _CopyRuntime2013(
- target_dir, runtime_dir, 'msvc%s' + _VersionNumber() + 'd.dll')
+ _CopyRuntime(target_dir, runtime_dir, target_cpu, debug=True)
def _GetDesiredVsToolchainHashes():
"""Load a list of SHA1s corresponding to the toolchains that we want installed
to build with."""
- # TODO(scottmg): If explicitly set to VS2015 override hashes to the VS2015 RC
- # toolchain. http://crbug.com/492774.
- if os.environ.get('GYP_MSVS_VERSION') == '2015':
- return ['40721575c85171cea5d7afe5ec17bd108a94796e']
+ if GetVisualStudioVersion() == '2015':
+ # Update 3 final with patches with 10.0.10586.0 SDK.
+ return ['d5dc33b15d1b2c086f2f6632e2fd15882f80dbd3']
else:
- # Default to VS2013.
- return ['ee7d718ec60c2dc5d255bbe325909c2021a7efef']
+ return ['03a4e939cd325d6bc5216af41b92d02dda1366a6']
-def Update():
+def ShouldUpdateToolchain():
+ """Check if the toolchain should be upgraded."""
+ if not os.path.exists(json_data_file):
+ return True
+ with open(json_data_file, 'r') as tempf:
+ toolchain_data = json.load(tempf)
+ version = toolchain_data['version']
+ env_version = GetVisualStudioVersion()
+ # If there's a mismatch between the version set in the environment and the one
+ # in the json file then the toolchain should be updated.
+ return version != env_version
+
+
+def Update(force=False):
"""Requests an update of the toolchain to the specific hashes we have at
this revision. The update outputs a .json of the various configuration
information required to pass to gyp which we use in |GetToolchainDir()|.
"""
+ if force != False and force != '--force':
+ print >>sys.stderr, 'Unknown parameter "%s"' % force
+ return 1
+ if force == '--force' or os.path.exists(json_data_file):
+ force = True
+
depot_tools_win_toolchain = \
bool(int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', '1')))
- if sys.platform in ('win32', 'cygwin') and depot_tools_win_toolchain:
+ if ((sys.platform in ('win32', 'cygwin') or force) and
+ depot_tools_win_toolchain):
import find_depot_tools
depot_tools_path = find_depot_tools.add_depot_tools_to_path()
+ # Necessary so that get_toolchain_if_necessary.py will put the VS toolkit
+ # in the correct directory.
+ os.environ['GYP_MSVS_VERSION'] = GetVisualStudioVersion()
get_toolchain_args = [
sys.executable,
os.path.join(depot_tools_path,
@@ -212,11 +352,19 @@
'get_toolchain_if_necessary.py'),
'--output-json', json_data_file,
] + _GetDesiredVsToolchainHashes()
+ if force:
+ get_toolchain_args.append('--force')
subprocess.check_call(get_toolchain_args)
return 0
+def NormalizePath(path):
+ while path.endswith("\\"):
+ path = path[:-1]
+ return path
+
+
def GetToolchainDir():
"""Gets location information about the current toolchain (must have been
previously updated by 'update'). This is used for the GN build."""
@@ -224,7 +372,7 @@
# If WINDOWSSDKDIR is not set, search the default SDK path and set it.
if not 'WINDOWSSDKDIR' in os.environ:
- default_sdk_path = 'C:\\Program Files (x86)\\Windows Kits\\8.1'
+ default_sdk_path = 'C:\\Program Files (x86)\\Windows Kits\\10'
if os.path.isdir(default_sdk_path):
os.environ['WINDOWSSDKDIR'] = default_sdk_path
@@ -234,16 +382,14 @@
wdk_dir = "%s"
runtime_dirs = "%s"
''' % (
- os.environ['GYP_MSVS_OVERRIDE_PATH'],
- os.environ['WINDOWSSDKDIR'],
- os.environ['GYP_MSVS_VERSION'],
- os.environ.get('WDK_DIR', ''),
- ';'.join(runtime_dll_dirs or ['None']))
+ NormalizePath(os.environ['GYP_MSVS_OVERRIDE_PATH']),
+ NormalizePath(os.environ['WINDOWSSDKDIR']),
+ GetVisualStudioVersion(),
+ NormalizePath(os.environ.get('WDK_DIR', '')),
+ os.path.pathsep.join(runtime_dll_dirs or ['None']))
def main():
- if not sys.platform.startswith(('win32', 'cygwin')):
- return 0
commands = {
'update': Update,
'get_toolchain_dir': GetToolchainDir,
diff --git a/build/whitespace_file.txt b/build/whitespace_file.txt
deleted file mode 100644
index ea82f4e..0000000
--- a/build/whitespace_file.txt
+++ /dev/null
@@ -1,156 +0,0 @@
-Copyright 2014 The Chromium Authors. All rights reserved.
-Use of this useless file is governed by a BSD-style license that can be
-found in the LICENSE file.
-
-
-This file is used for making non-code changes to trigger buildbot cycles. Make
-any modification below this line.
-
-======================================================================
-
-Let's make a story. Add zero+ sentences for every commit:
-
-CHÄPTER 1:
-It was a dark and blinky night; the rain fell in torrents -- except at
-occasional intervals, when it was checked by a violent gust of wind which
-swept up the streets (for it is in London that our scene lies), rattling along
-the housetops, and fiercely agitating the scanty flame of the lamps that
-struggled against the elements. A hooded figure emerged.
-
-It was a Domo-Kun.
-
-"What took you so long?", inquired his wife.
-
-Silence. Oblivious to his silence, she continued, "Did Mr. Usagi enjoy the
-waffles you brought him?" "You know him, he's not one to forego a waffle,
-no matter how burnt," he snickered.
-
-The pause was filled with the sound of compile errors.
-
-CHAPTER 2:
-The jelly was as dark as night, and just as runny.
-The Domo-Kun shuddered, remembering the way Mr. Usagi had speared his waffles
-with his fork, watching the runny jelly spread and pool across his plate,
-like the blood of a dying fawn. "It reminds me of that time --" he started, as
-his wife cut in quickly: "-- please. I can't bear to hear it.". A flury of
-images coming from the past flowed through his mind.
-
-"You recall what happened on Mulholland drive?" The ceiling fan rotated slowly
-overhead, barely disturbing the thick cigarette smoke. No doubt was left about
-when the fan was last cleaned.
-
-There was a poignant pause.
-
-CHAPTER 3:
-Mr. Usagi felt that something wasn't right. Shortly after the Domo-Kun left he
-began feeling sick. He thought out loud to himself, "No, he wouldn't have done
-that to me." He considered that perhaps he shouldn't have pushed so hard.
-Perhaps he shouldn't have been so cold and sarcastic, after the unimaginable
-horror that had occurred just the week before.
-
-Next time, there won't be any sushi. Why sushi with waffles anyway? It's like
-adorning breakfast cereal with halibut -- shameful.
-
-CHAPTER 4:
-The taste of stale sushi in his mouth the next morning was unbearable. He
-wondered where the sushi came from as he attempted to wash the taste away with
-a bottle of 3000¥ sake. He tries to recall the cook's face. Purple? Probably.
-
-CHAPTER 5:
-Many tears later, Mr. Usagi would laugh at the memory of the earnest,
-well-intentioned Domo-Kun. Another day in the life. That is when he realized that
-life goes on.
-
-TRUISMS (1978-1983)
-JENNY HOLZER
-A LITTLE KNOWLEDGE CAN GO A LONG WAY
-A LOT OF PROFESSIONALS ARE CRACKPOTS
-A MAN CAN'T KNOW WHAT IT IS TO BE A MOTHER
-A NAME MEANS A LOT JUST BY ITSELF
-A POSITIVE ATTITUDE MEANS ALL THE DIFFERENCE IN THE WORLD
-A RELAXED MAN IS NOT NECESSARILY A BETTER MAN
-NO ONE SHOULD EVER USE SVN
-AN INFLEXIBLE POSITION SOMETIMES IS A SIGN OF PARALYSIS
-IT IS MANS FATE TO OUTSMART HIMSELF
-BEING SURE OF YOURSELF MEANS YOU'RE A FOOL
-AM NOT
-ARE TOO
-IF AT FIRST YOU DON'T SUCCEED: TRY, EXCEPT, FINALLY
-AND THEN, TIME LEAPT BACKWARDS
-AAAAAAAAAAAAAAAAAAAAAAAAAAAAAaaaaaaaaaaaaaaaaaaaaaaaaaaaahhhh LOT
-I'm really tempted to change something above the line.
-Reeccciiiipppppeeeeeesssssss!!!!!!!!!
-PEOPLE SAY "FAILURE IS NOT AN OPTION", BUT FAILURE IS ALWAYS AN OPTION.
-WHAT GOES UP MUST HAVE A NON-ZERO VELOCITY
-
-I can feel the heat closing in, feel them out there making their moves...
-What could possibly go wrong? We've already ate our cake.
-
-Stand Still. Pause Clocks. We can make the World Stop.
-WUBWUBWUBWUBWUB
-
-I want a 1917 build and you will give me what I want.
-
-This sentence is false.
-
-Beauty is in the eyes of a Beholder.
-
-I'm the best at space.
-
-The first time Yossarian saw the chaplain, he fell madly in love with him.
-*
-*
-*
-Give not thyself up, then, to fire, lest it invert thee, deaden thee; as for
-the time it did me. There is a wisdom that is woe; but there is a woe that is
-madness. And there is a Catskill eagle in some souls that can alike dive down
-into the blackest gorges, and soar out of them again and become invisible in
-the sunny spaces. And even if he for ever flies within the gorge, that gorge
-is in the mountains; so that even in his lowest swoop the mountain eagle is
-still higher than other birds upon the plain, even though they soar.
-*
-*
-*
-
-I'm here to commit lines and drop rhymes
-*
-This is a line to test and try uploading a cl.
-
-And lo, in the year 2014, there was verily an attempt to upgrade to GCC 4.8 on
-the Android bots, and it was good. Except on one bot, where it was bad. And
-lo, the change was reverted, and GCC went back to 4.6, where code is slower
-and less optimized. And verily did it break the build, because artifacts had
-been created with 4.8, and alignment was no longer the same, and a great
-sadness descended upon the Android GN buildbot, and it did refuseth to build
-any more. But the sheriffs thought to themselves: Placebo! Let us clobber the
-bot, and perhaps it will rebuild with GCC 4.6, which hath worked for many many
-seasons. And so they modified the whitespace file with these immortal lines,
-and visited it upon the bots, that great destruction might be wrought upon
-their outdated binaries. In clobberus, veritas.
-
-As the git approaches, light begins to shine through the SCM thrice again...
-However, the git, is, after all, quite stupid.
-
-Suddenly Domo-Kun found itself in a room filled with dazzling mirrors.
-
-A herd of wild gits appears! Time for CQ :D
-And one more for sizes.py...
-
-Sigh.
-
-It was love at first sight. The moment Yossarian first laid eyes on the chaplain, he fell madly in love with him.
-
-Cool whitespace change for git-cl land
-
-Oh god the bots are red! I'm blind! Mmmm, cronuts.
-
-If you stand on your head, you will get footprints in your hair.
-
-sigh
-sigher
-pick up cls
-
-In the BUILD we trust.
-^_^
-
-In the masters we don't.
diff --git a/build/win_is_xtree_patched.py b/build/win_is_xtree_patched.py
deleted file mode 100755
index 3f1994f..0000000
--- a/build/win_is_xtree_patched.py
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/usr/bin/env python
-# Copyright 2014 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Determines if the VS xtree header has been patched to disable C4702."""
-
-import os
-
-
-def IsPatched():
- # TODO(scottmg): For now, just return if we're using the packaged toolchain
- # script (because we know it's patched). Another case could be added here to
- # query the active VS installation and actually check the contents of xtree.
- # http://crbug.com/346399.
- return int(os.environ.get('DEPOT_TOOLS_WIN_TOOLCHAIN', 1)) == 1
-
-
-def DoMain(_):
- """Hook to be called from gyp without starting a separate python
- interpreter."""
- return "1" if IsPatched() else "0"
-
-
-if __name__ == '__main__':
- print DoMain([])
diff --git a/build/win_precompile.gypi b/build/win_precompile.gypi
deleted file mode 100644
index fb86076..0000000
--- a/build/win_precompile.gypi
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (c) 2011 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-# Include this file to make targets in your .gyp use the default
-# precompiled header on Windows, in debug builds only as the official
-# builders blow up (out of memory) if precompiled headers are used for
-# release builds.
-
-{
- 'conditions': [
- ['OS=="win" and chromium_win_pch==1', {
- 'target_defaults': {
- 'msvs_precompiled_header': '<(DEPTH)/build/precompile.h',
- 'msvs_precompiled_source': '<(DEPTH)/build/precompile.cc',
- 'sources': ['<(DEPTH)/build/precompile.cc'],
- }
- }],
- ],
-}
diff --git a/docs/language/dartLangSpec.tex b/docs/language/dartLangSpec.tex
index e826260a..d0f62f2 100644
--- a/docs/language/dartLangSpec.tex
+++ b/docs/language/dartLangSpec.tex
@@ -592,7 +592,9 @@
One could allow modifiers for factories. A factory for \code{Future} could be modified by \ASYNC{}, a factory for \code{Stream} could be modified by \ASYNC* and a factory for \code{Iterable} could be modified by \SYNC*. No other scenario makes sense because the object returned by the factory would be of the wrong type. This situation is very unusual so it is not worth making an exception to the general rule for constructors in order to allow it.
}
\LMHash{}
-It is a static warning if the declared return type of a function marked \ASYNC{} may not be assigned to \code{Future}. It is a static warning if the declared return type of a function marked \SYNC* may not be assigned to \code{Iterable}. It is a static warning if the declared return type of a function marked \ASYNC* may not be assigned to \code{Stream}.
+It is a static warning if the declared return type of a function marked \ASYNC{} is not a supertype of \code{Future$<$\mbox{$T$}$>$} for some type $T$.
+It is a static warning if the declared return type of a function marked \SYNC* is not a supertype of \code{Iterable$<$\mbox{$T$}$>$} for some type $T$.
+It is a static warning if the declared return type of a function marked \ASYNC* is not a supertype of \code{Stream$<$\mbox{$T$}$>$} for some type $T$.
\subsection{Function Declarations}
\LMLabel{functionDeclarations}
@@ -739,14 +741,25 @@
\begin{grammar}
{\bf defaultFormalParameter:}
- normalFormalParameter ('=' expression)?
+ normalFormalParameter (`=' expression)?
.
-{\bf defaultNamedParameter:}
+{\bf defaultNamedParameter:}normalFormalParameter (`=' expression)?;
normalFormalParameter ( `{\escapegrammar :}' expression)?
.
\end{grammar}
+A {\bf defaultNamedParameter} on the form:
+\begin{code}
+ normalFormalParameter : expression
+\end{code}
+is equivalent to one on the form:
+\begin{code}
+ normalFormalParameter = expression
+\end{code}
+The colon-syntax is included only for backwards compatibility.
+It is deprecated and will be removed in a later version of the language specification.
+
\LMHash{}
It is a compile-time error if the default value of an optional parameter is not a compile-time constant (\ref{constants}). If no default is explicitly specified for an optional parameter an implicit default of \NULL{} is provided.
@@ -3148,7 +3161,7 @@
\LMHash{}
The static type of a function literal of the form
-$(T_1$ $a_1, \ldots, T_n$ $a_n, \{T_{n+1}$ $x_{n+1} : d_1, \ldots, T_{n+k}$ $x_{n+k} : d_k\}) => e$
+$(T_1$ $a_1, \ldots, T_n$ $a_n, \{T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{n+k} = d_k\}) => e$
is
$(T_1 \ldots, T_n, \{T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}\}) \rightarrow T_0$, where $T_0$ is the static type of $e$.
@@ -3156,7 +3169,7 @@
\LMHash{}
The static type of a function literal of the form
-$(T_1$ $a_1, \ldots, T_n$ $a_n, \{T_{n+1}$ $x_{n+1} : d_1, \ldots, T_{n+k}$ $x_{n+k} : d_k\})$ \ASYNC{} $=> e$
+$(T_1$ $a_1, \ldots, T_n$ $a_n, \{T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{n+k} = d_k\})$ \ASYNC{} $=> e$
is $(T_1 \ldots, T_n, \{T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}\}) \rightarrow Future<flatten(T_0)>$, where $T_0$ is the static type of $e$.
@@ -3197,21 +3210,21 @@
\LMHash{}
The static type of a function literal of the form
-$(T_1$ $a_1, \ldots, T_n$ $a_n, \{T_{n+1}$ $x_{n+1} : d_1, \ldots, T_{n+k}$ $x_{n+k} : d_k\})$ $\ASYNC{}$ $\{s\}$
+$(T_1$ $a_1, \ldots, T_n$ $a_n, \{T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{n+k} = d_k\})$ $\ASYNC{}$ $\{s\}$
is $(T_1 \ldots, T_n, \{T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}\}) \rightarrow Future{}$.
\LMHash{}
The static type of a function literal of the form
-$(T_1$ $a_1, \ldots, T_n$ $a_n, \{T_{n+1}$ $x_{n+1} : d_1, \ldots, T_{n+k}$ $x_{n+k} : d_k\})$ $\ASYNC*{}$ $\{s\}$
+$(T_1$ $a_1, \ldots, T_n$ $a_n, \{T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{n+k} = d_k\})$ $\ASYNC*{}$ $\{s\}$
is $(T_1 \ldots, T_n, \{T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}\}) \rightarrow Stream{}$.
\LMHash{}
The static type of a function literal of the form
-$(T_1$ $a_1, \ldots, T_n$ $a_n, \{T_{n+1}$ $x_{n+1} : d_1, \ldots, T_{n+k}$ $x_{n+k} : d_k\})$ $\SYNC*{}$ $\{s\}$
+$(T_1$ $a_1, \ldots, T_n$ $a_n, \{T_{n+1}$ $x_{n+1} = d_1, \ldots, T_{n+k}$ $x_{n+k} = d_k\})$ $\SYNC*{}$ $\{s\}$
is $(T_1 \ldots, T_n, \{T_{n+1}$ $x_{n+1}, \ldots, T_{n+k}$ $x_{n+k}\}) \rightarrow Iterable{}$.
@@ -3857,15 +3870,15 @@
If the method lookup has failed, then let $g$ be the result of looking up getter (\ref{getterAndSetterLookup}) $m$ in $v_o$ with respect to $L$.
If $v_o$ is an instance of \code{Type} but $o$ is not a constant type literal, then if $g$ is a getter that forwards to a static getter, getter lookup fails.
If the getter lookup succeeded, let $v_g$ be the value of the getter invocation $o.m$. Then the value of $i$ is the result of invoking
-the static method \code{Function.apply()} with arguments $v.g, [o_1, \ldots , o_n], \{x_{n+1}: o_{n+1}, \ldots , x_{n+k}: o_{n+k}\}$.
+the static method \code{Function.apply()} with arguments $v.g, [o_1, \ldots , o_n], \{\#x_{n+1}: o_{n+1}, \ldots , \#x_{n+k}: o_{n+k}\}$.
\LMHash{}
-If getter lookup has also failed, then a new instance $im$ of the predefined class \code{Invocation} is created, such that :
+If getter lookup has also failed, then a new instance $im$ of the predefined class \code{Invocation} is created, such that:
\begin{itemize}
\item \code{im.isMethod} evaluates to \code{\TRUE{}}.
\item \code{im.memberName} evaluates to the symbol \code{m}.
-\item \code{im.positionalArguments} evaluates to an immutable list with the same values as \code{[$o_1, \ldots, o_n$]}.
-\item \code{im.namedArguments} evaluates to an immutable map with the same keys and values as \code{\{$x_{n+1}: o_{n+1}, \ldots, x_{n+k} : o_{n+k}$\}}.
+\item \code{im.positionalArguments} evaluates to an immutable list with the same values as \code{[$o_1, \ldots, o_n$]}.
+\item \code{im.namedArguments} evaluates to an immutable map with the same keys and values as \code{\{$\#x_{n+1}: o_{n+1}, \ldots, \#x_{n+k} : o_{n+k}$\}}.
\end{itemize}
\LMHash{}
@@ -3958,7 +3971,7 @@
\LMHash{}
If the method lookup has failed, then let $g$ be the result of looking up getter (\ref{getterAndSetterLookup}) $m$ in $S_{dynamic}$ with respect to $L$. If the getter lookup succeeded, let $v_g$ be the value of the getter invocation $\SUPER{}.m$. Then the value of $i$ is the result of invoking
-the static method \code{Function.apply()} with arguments $v_g, [o_1, \ldots , o_n], \{x_{n+1}: o_{n+1}, \ldots , x_{n+k}: o_{n+k}\}$.
+the static method \code{Function.apply()} with arguments $v_g, [o_1, \ldots , o_n], \{x_{n+1} = o_{n+1}, \ldots , x_{n+k} = o_{n+k}\}$.
\LMHash{}
If getter lookup has also failed, then a new instance $im$ of the predefined class \code{Invocation} is created, such that :
@@ -3966,7 +3979,7 @@
\item \code{im.isMethod} evaluates to \code{\TRUE{}}.
\item \code{im.memberName} evaluates to the symbol \code{m}.
\item \code{im.positionalArguments} evaluates to an immutable list with the same values as \code{[$o_1, \ldots, o_n$]}.
-\item \code{im.namedArguments} evaluates to an immutable map with the same keys and values as \code{\{$x_{n+1}: o_{n+1}, \ldots, x_{n+k} : o_{n+k}$\}}.
+\item \code{im.namedArguments} evaluates to an immutable map with the same keys and values as \code{\{$\#x_{n+1}: o_{n+1}, \ldots, \#x_{n+k} : o_{n+k}$\}}.
\end{itemize}
Then the method \code{noSuchMethod()} is looked up in $S_{dynamic}$ and invoked on \THIS{} with argument $im$, and the result of this invocation is the result of evaluating $i$. However, if the implementation found cannot be invoked with a single positional argument, the implementation of \code{noSuchMethod()} in class \code{Object} is invoked on \THIS{} with argument $im'$, where $im'$ is an instance of \code{Invocation} such that :
\begin{itemize}
@@ -4271,7 +4284,7 @@
\item $(a, b) \{\RETURN{}$ $u[a] = b;$\} if $f$ is named $[]=$.
\item
\begin{dartCode}
-$(r_1, \ldots, r_n, \{p_1 : d_1, \ldots , p_k : d_k\})$ \{
+$(r_1, \ldots, r_n, \{p_1 = d_1, \ldots , p_k = d_k\})$ \{
\RETURN{} $ u.m(r_1, \ldots, r_n, p_1: p_1, \ldots, p_k: p_k);$
\}
\end{dartCode}
@@ -4321,7 +4334,7 @@
\begin{itemize}
\item
\begin{dartCode}
-$(r_1, \ldots, r_n, \{p_1 : d_1, \ldots , p_k : d_k\})$ \{
+$(r_1, \ldots, r_n, \{p_1 = d_1, \ldots , p_k = d_k\})$ \{
\RETURN{} \NEW{} $T.m(r_1, \ldots, r_n, p_1: p_1, \ldots, p_k: p_k);$
\}
\end{dartCode}
@@ -4352,7 +4365,7 @@
\begin{itemize}
\item
\begin{dartCode}
-$(r_1, \ldots, r_n, \{p_1 : d_1, \ldots , p_k : d_k\})$ \{
+$(r_1, \ldots, r_n, \{p_1 = d_1, \ldots , p_k = d_k\})$ \{
\RETURN{} \NEW{} $T(r_1, \ldots, r_n, p_1: p_1, \ldots, p_k: p_k);$
\}
\end{dartCode}
@@ -4386,7 +4399,7 @@
\item $(a, b) \{\RETURN{}$ $\SUPER[a] = b;$\} if $f$ is named $[]=$.
\item
\begin{dartCode}
-$(r_1, \ldots, r_n, \{p_1 : d_1, \ldots , p_k : d_k\})$ \{
+$(r_1, \ldots, r_n, \{p_1 = d_1, \ldots , p_k = d_k\})$ \{
\RETURN{} \SUPER$.m(r_1, \ldots, r_n, p_1: p_1, \ldots, p_k: p_k);$
\}
\end{dartCode}
@@ -6941,6 +6954,9 @@
\LMHash{}
Compiling a part directive of the form \code{\PART{} $s$;} causes the Dart system to attempt to compile the contents of the URI that is the value of $s$. The top-level declarations at that URI are then compiled by the Dart compiler in the scope of the current library. It is a compile-time error if the contents of the URI are not a valid part declaration. It is a static warning if the referenced part declaration $p$ names a library other than the current library as the library to which $p$ belongs.
+\LMHash{}
+It's a compile-time error if the same library contains two part directives with the same URI.
+
\subsection{Scripts}
\LMLabel{scripts}
diff --git a/pkg/BUILD.gn b/pkg/BUILD.gn
new file mode 100644
index 0000000..8dc602f
--- /dev/null
+++ b/pkg/BUILD.gn
@@ -0,0 +1,70 @@
+# 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("../utils/create_timestamp.gni")
+
+template("make_third_party_pkg_files_stamp") {
+ assert(defined(invoker.id), "Must define the stamp file id")
+ path = rebase_path("../third_party/pkg")
+ if (defined(invoker.path)) {
+ path = invoker.path
+ }
+ id = invoker.id
+ create_timestamp_file(target_name) {
+ if (defined(invoker.pattern)) {
+ pattern = invoker.pattern
+ }
+ path = path
+ new_base = "//"
+ output = "$target_gen_dir/third_party_pkg_files_$id.stamp"
+ }
+}
+
+make_third_party_pkg_files_stamp("make_third_party_pkg_files_0_stamp") {
+ path = rebase_path(".")
+ id = "0"
+}
+
+make_third_party_pkg_files_stamp("make_third_party_pkg_files_1_stamp") {
+ pattern = "[a-k].*"
+ id = "1"
+}
+
+make_third_party_pkg_files_stamp("make_third_party_pkg_files_2_stamp") {
+ pattern = "[l-r].*"
+ id = "2"
+}
+
+make_third_party_pkg_files_stamp("make_third_party_pkg_files_3_stamp") {
+ pattern = "[s-z].*"
+ id = "3"
+}
+
+action("pkg_files_stamp") {
+ deps = [
+ ":make_third_party_pkg_files_0_stamp",
+ ":make_third_party_pkg_files_1_stamp",
+ ":make_third_party_pkg_files_2_stamp",
+ ":make_third_party_pkg_files_3_stamp",
+ ]
+
+ stamp0_outputs = get_target_outputs(":make_third_party_pkg_files_0_stamp")
+ stamp1_outputs = get_target_outputs(":make_third_party_pkg_files_1_stamp")
+ stamp2_outputs = get_target_outputs(":make_third_party_pkg_files_2_stamp")
+ stamp3_outputs = get_target_outputs(":make_third_party_pkg_files_3_stamp")
+
+ inputs = stamp0_outputs +
+ stamp1_outputs +
+ stamp2_outputs +
+ stamp3_outputs
+
+ outputs = [
+ "$root_gen_dir/pkg_files.stamp"
+ ]
+
+ script = "../tools/create_timestamp_file.py"
+ args = [
+ rebase_path("$root_gen_dir/pkg_files.stamp"),
+ ]
+}
diff --git a/pkg/analysis_server/BUILD.gn b/pkg/analysis_server/BUILD.gn
new file mode 100644
index 0000000..9e65d54
--- /dev/null
+++ b/pkg/analysis_server/BUILD.gn
@@ -0,0 +1,25 @@
+# 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("//build/dart/dart_package.gni")
+
+dart_package("analysis_server") {
+ package_name = "analysis_server"
+
+ source_dir = "lib"
+
+ deps = [
+ "//dart/pkg/analyzer",
+ "//third_party/dart-pkg/pub/args",
+ "//third_party/dart-pkg/pub/dart_style",
+ "//third_party/dart-pkg/pub/isolate",
+ "//third_party/dart-pkg/pub/linter",
+ "//third_party/dart-pkg/pub/logging",
+ "//third_party/dart-pkg/pub/package_config",
+ "//third_party/dart-pkg/pub/path",
+ "//third_party/dart-pkg/pub/plugin",
+ "//third_party/dart-pkg/pub/watcher",
+ "//third_party/dart-pkg/pub/yaml",
+ ]
+}
diff --git a/pkg/analysis_server/benchmark/perf/analysis_timing_tests.dart b/pkg/analysis_server/benchmark/perf/analysis_timing_tests.dart
index 731bec5..a0d4116 100644
--- a/pkg/analysis_server/benchmark/perf/analysis_timing_tests.dart
+++ b/pkg/analysis_server/benchmark/perf/analysis_timing_tests.dart
@@ -9,9 +9,8 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:args/args.dart';
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
-import '../../test/utils.dart';
import 'performance_tests.dart';
/**
@@ -21,7 +20,6 @@
* `analysis`.
*/
main(List<String> arguments) {
- initializeTestEnvironment();
ArgParser parser = _createArgParser();
var args = parser.parse(arguments);
if (args[SOURCE_OPTION] == null) {
@@ -34,7 +32,6 @@
for (var name in names) {
metricNames.add(name as String);
}
- unittestConfiguration.timeout = new Duration(minutes: 20);
var test;
diff --git a/pkg/analysis_server/benchmark/perf/benchmark_scenario.dart b/pkg/analysis_server/benchmark/perf/benchmark_scenario.dart
index 3ec4c4c..134ed3a 100644
--- a/pkg/analysis_server/benchmark/perf/benchmark_scenario.dart
+++ b/pkg/analysis_server/benchmark/perf/benchmark_scenario.dart
@@ -9,8 +9,9 @@
import 'dart:math';
import 'package:analysis_server/plugin/protocol/protocol.dart';
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
+import '../../test/integration/integration_tests.dart';
import 'performance_tests.dart';
void printBenchmarkResults(String id, String description, List<int> times) {
@@ -46,10 +47,10 @@
String file,
FileChange fileChange,
int numOfRepeats}) async {
- expect(roots, isNotNull, reason: 'roots');
- expect(file, isNotNull, reason: 'file');
- expect(fileChange, isNotNull, reason: 'fileChange');
- expect(numOfRepeats, isNotNull, reason: 'numOfRepeats');
+ outOfTestExpect(roots, isNotNull, reason: 'roots');
+ outOfTestExpect(file, isNotNull, reason: 'file');
+ outOfTestExpect(fileChange, isNotNull, reason: 'fileChange');
+ outOfTestExpect(numOfRepeats, isNotNull, reason: 'numOfRepeats');
// Initialize Analysis Server.
await super.setUp();
await subscribeToStatusNotifications();
@@ -95,11 +96,11 @@
FileChange fileChange,
String completeAfterStr,
int numOfRepeats}) async {
- expect(roots, isNotNull, reason: 'roots');
- expect(file, isNotNull, reason: 'file');
- expect(fileChange, isNotNull, reason: 'fileChange');
- expect(completeAfterStr, isNotNull, reason: 'completeAfterStr');
- expect(numOfRepeats, isNotNull, reason: 'numOfRepeats');
+ outOfTestExpect(roots, isNotNull, reason: 'roots');
+ outOfTestExpect(file, isNotNull, reason: 'file');
+ outOfTestExpect(fileChange, isNotNull, reason: 'fileChange');
+ outOfTestExpect(completeAfterStr, isNotNull, reason: 'completeAfterStr');
+ outOfTestExpect(numOfRepeats, isNotNull, reason: 'numOfRepeats');
// Initialize Analysis Server.
await super.setUp();
await subscribeToStatusNotifications();
@@ -149,13 +150,14 @@
RefactoringKind refactoringKind,
RefactoringOptions refactoringOptions,
int numOfRepeats}) async {
- expect(roots, isNotNull, reason: 'roots');
- expect(file, isNotNull, reason: 'file');
- expect(fileChange, isNotNull, reason: 'fileChange');
- expect(refactoringAtStr, isNotNull, reason: 'refactoringAtStr');
- expect(refactoringKind, isNotNull, reason: 'refactoringKind');
- expect(refactoringOptions, isNotNull, reason: 'refactoringOptions');
- expect(numOfRepeats, isNotNull, reason: 'numOfRepeats');
+ outOfTestExpect(roots, isNotNull, reason: 'roots');
+ outOfTestExpect(file, isNotNull, reason: 'file');
+ outOfTestExpect(fileChange, isNotNull, reason: 'fileChange');
+ outOfTestExpect(refactoringAtStr, isNotNull, reason: 'refactoringAtStr');
+ outOfTestExpect(refactoringKind, isNotNull, reason: 'refactoringKind');
+ outOfTestExpect(refactoringOptions, isNotNull,
+ reason: 'refactoringOptions');
+ outOfTestExpect(numOfRepeats, isNotNull, reason: 'numOfRepeats');
// Initialize Analysis Server.
await super.setUp();
await subscribeToStatusNotifications();
@@ -243,8 +245,8 @@
*/
static Future<List<int>> start_waitInitialAnalysis_shutdown(
{List<String> roots, int numOfRepeats}) async {
- expect(roots, isNotNull, reason: 'roots');
- expect(numOfRepeats, isNotNull, reason: 'numOfRepeats');
+ outOfTestExpect(roots, isNotNull, reason: 'roots');
+ outOfTestExpect(numOfRepeats, isNotNull, reason: 'numOfRepeats');
// Repeat.
List<int> times = <int>[];
for (int i = 0; i < numOfRepeats; i++) {
@@ -265,7 +267,8 @@
static String _getFileContent(String path) {
File file = new File(path);
- expect(file.existsSync(), isTrue, reason: 'File $path does not exist.');
+ outOfTestExpect(file.existsSync(), isTrue,
+ reason: 'File $path does not exist.');
return file.readAsStringSync();
}
@@ -274,7 +277,7 @@
*/
static int _indexOf(String file, String where, String what) {
int index = where.indexOf(what);
- expect(index, isNot(-1), reason: 'Cannot find |$what| in $file.');
+ outOfTestExpect(index, isNot(-1), reason: 'Cannot find |$what| in $file.');
return index;
}
@@ -293,11 +296,16 @@
final String replaceWhat;
final String replaceWith;
- FileChange({this.afterStr, this.afterStrBack: 0, this.insertStr, this.replaceWhat, this.replaceWith}) {
+ FileChange(
+ {this.afterStr,
+ this.afterStrBack: 0,
+ this.insertStr,
+ this.replaceWhat,
+ this.replaceWith}) {
if (afterStr != null) {
- expect(insertStr, isNotNull, reason: 'insertStr');
+ outOfTestExpect(insertStr, isNotNull, reason: 'insertStr');
} else if (replaceWhat != null) {
- expect(replaceWith, isNotNull, reason: 'replaceWith');
+ outOfTestExpect(replaceWith, isNotNull, reason: 'replaceWith');
}
}
}
diff --git a/pkg/analysis_server/benchmark/perf/completion_timing_tests.dart b/pkg/analysis_server/benchmark/perf/completion_timing_tests.dart
index 7b9829a..d841521 100644
--- a/pkg/analysis_server/benchmark/perf/completion_timing_tests.dart
+++ b/pkg/analysis_server/benchmark/perf/completion_timing_tests.dart
@@ -8,9 +8,8 @@
import 'dart:io';
import 'package:args/args.dart';
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
-import '../../test/utils.dart';
import 'performance_tests.dart';
/**
@@ -19,7 +18,6 @@
* with a `--offset`.
*/
main(List<String> arguments) {
- initializeTestEnvironment();
ArgParser parser = _createArgParser();
var args = parser.parse(arguments);
if (args[SOURCE_OPTION] == null) {
diff --git a/pkg/analysis_server/benchmark/perf/memory_tests.dart b/pkg/analysis_server/benchmark/perf/memory_tests.dart
index a648344..4fb9b6c 100644
--- a/pkg/analysis_server/benchmark/perf/memory_tests.dart
+++ b/pkg/analysis_server/benchmark/perf/memory_tests.dart
@@ -8,7 +8,7 @@
import 'dart:math';
import 'package:analysis_server/plugin/protocol/protocol.dart';
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
import '../../test/integration/integration_tests.dart';
@@ -65,7 +65,7 @@
});
Completer serverConnected = new Completer();
onServerConnected.listen((_) {
- expect(serverConnected.isCompleted, isFalse);
+ outOfTestExpect(serverConnected.isCompleted, isFalse);
serverConnected.complete();
});
return startServer(servicesPort: vmServicePort).then((_) {
@@ -109,8 +109,8 @@
*/
static Future<List<int>> start_waitInitialAnalysis_shutdown(
{List<String> roots, int numOfRepeats}) async {
- expect(roots, isNotNull, reason: 'roots');
- expect(numOfRepeats, isNotNull, reason: 'numOfRepeats');
+ outOfTestExpect(roots, isNotNull, reason: 'roots');
+ outOfTestExpect(numOfRepeats, isNotNull, reason: 'numOfRepeats');
// Repeat.
List<int> sizes = <int>[];
for (int i = 0; i < numOfRepeats; i++) {
diff --git a/pkg/analysis_server/benchmark/perf/performance_tests.dart b/pkg/analysis_server/benchmark/perf/performance_tests.dart
index d6be917..742171e 100644
--- a/pkg/analysis_server/benchmark/perf/performance_tests.dart
+++ b/pkg/analysis_server/benchmark/perf/performance_tests.dart
@@ -8,7 +8,7 @@
import 'dart:io';
import 'package:analysis_server/plugin/protocol/protocol.dart';
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
import '../../test/integration/integration_tests.dart';
@@ -43,7 +43,7 @@
});
Completer serverConnected = new Completer();
onServerConnected.listen((_) {
- expect(serverConnected.isCompleted, isFalse);
+ outOfTestExpect(serverConnected.isCompleted, isFalse);
serverConnected.complete();
});
return startServer(checked: false).then((_) {
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index 9228c47..9855905 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -253,6 +253,34 @@
<h4>Options</h4>
<blockquote>
<dl>
+ <dt>--client-id</dt>
+ <dd>
+ <p>
+ Specifies an identifier associated with the client. Used when
+ generating error reports.
+ </p>
+ <p>
+ Clients are strongly encouraged to provide this information in
+ order to improve the quality of information that can be provided
+ to them.
+ </p>
+ </dd>
+ </dl>
+ <dl>
+ <dt>--client-version</dt>
+ <dd>
+ <p>
+ Specifies the version of the client that is communicating with
+ the server. Used when generating error reports.
+ </p>
+ <p>
+ Clients are strongly encouraged to provide this information in
+ order to improve the quality of information that can be provided
+ to them.
+ </p>
+ </dd>
+ </dl>
+ <dl>
<dt>--no-error-notification</dt>
<dd>
Disable notifications about errors (see analysis.error). If this
@@ -261,22 +289,6 @@
</dd>
</dl>
<dl>
- <dt>--file-read-mode</dt>
- <dd>
- An enumeration of the ways files can be read from disk. Some clients
- normalize end of line characters which would make the file offset and
- range information incorrect. The default option is <tt>as-is</tt>, but
- can also be set to <tt>normalize-eol-always</tt>. The default option
- (<tt>as-is</tt>) reads files as they are on disk. The
- <tt>normalize-eol-always</tt> option does the following:
- <ul>
- <li>'\r\n' is converted to '\n';</li>
- <li>'\r' by itself is converted to '\n';</li>
- <li>this happens regardless of the OS editor is running on.</li>
- </ul>
- </dd>
- </dl>
- <dl>
<dt>--no-index</dt>
<dd>
Disable the server from generating an index. If this flag is passed and an
@@ -286,6 +298,23 @@
</dd>
</dl>
+ <dl>
+ <dt>--file-read-mode</dt>
+ <dd>
+ <p><b>Deprecated</b></p>
+ An enumeration of the ways files can be read from disk. Some clients
+ normalize end of line characters which would make the file offset and
+ range information incorrect. The default option is <tt>as-is</tt>, but
+ can also be set to <tt>normalize-eol-always</tt>. The default option
+ (<tt>as-is</tt>) reads files as they are on disk. The
+ <tt>normalize-eol-always</tt> option does the following:
+ <ul>
+ <li>'\r\n' is converted to '\n';</li>
+ <li>'\r' by itself is converted to '\n';</li>
+ <li>this happens regardless of the OS editor is running on.</li>
+ </ul>
+ </dd>
+ </dl>
</blockquote>
<h2 class="domain"><a name="domain_server">server domain</a></h2>
<p>
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index d53d90b..ae1bb0a 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -38,7 +38,6 @@
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/generated/utilities_general.dart';
-import 'package:analyzer/src/summary/package_bundle_reader.dart';
import 'package:analyzer/src/summary/pub_summary.dart';
import 'package:analyzer/src/task/dart.dart';
import 'package:analyzer/src/util/glob.dart';
@@ -1603,21 +1602,6 @@
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);
- if (linkedBundles.isNotEmpty) {
- SummaryDataStore store = new SummaryDataStore([]);
- for (LinkedPubPackage package in linkedBundles) {
- store.addBundle(null, package.unlinked);
- store.addBundle(null, package.linked);
- }
- (context as InternalAnalysisContext).resultProvider =
- new InputPackagesResultProvider(context, store);
- }
- }
-
analysisServer.folderMap[folder] = context;
analysisServer._onContextsChangedController
.add(new ContextsChangedEvent(added: [context]));
@@ -1668,6 +1652,9 @@
builder.packageResolverProvider = analysisServer.packageResolverProvider;
builder.defaultPackageFilePath = defaultPackageFilePath;
builder.defaultPackagesDirectoryPath = defaultPackagesDirectoryPath;
+ if (analysisServer.options.enablePubSummaryManager) {
+ builder.pubSummaryManager = analysisServer.pubSummaryManager;
+ }
return builder;
}
diff --git a/pkg/analysis_server/lib/src/search/element_references.dart b/pkg/analysis_server/lib/src/search/element_references.dart
index 30ae422..399ea8b 100644
--- a/pkg/analysis_server/lib/src/search/element_references.dart
+++ b/pkg/analysis_server/lib/src/search/element_references.dart
@@ -6,7 +6,6 @@
import 'dart:async';
-import 'package:analysis_server/src/collections.dart';
import 'package:analysis_server/src/protocol_server.dart'
show SearchResult, newSearchResult_fromMatch;
import 'package:analysis_server/src/services/search/hierarchy.dart';
@@ -25,21 +24,23 @@
/**
* Computes [SearchResult]s for [element] references.
*/
- Future<List<SearchResult>> compute(Element element, bool withPotential) {
- var futureGroup = new _ConcatFutureGroup<SearchResult>();
- // find element references
- futureGroup.add(_findElementsReferences(element));
- // add potential references
+ Future<List<SearchResult>> compute(
+ Element element, bool withPotential) async {
+ List<SearchResult> results = <SearchResult>[];
+
+ // Add element references.
+ results.addAll(await _findElementsReferences(element));
+
+ // Add potential references.
if (withPotential && _isMemberElement(element)) {
String name = element.displayName;
- var matchesFuture = searchEngine.searchMemberReferences(name);
- var resultsFuture = matchesFuture.then((List<SearchMatch> matches) {
- return matches.where((match) => !match.isResolved).map(toResult);
- });
- futureGroup.add(resultsFuture);
+ List<SearchMatch> matches =
+ await searchEngine.searchMemberReferences(name);
+ matches = SearchMatch.withNotNullElement(matches);
+ results.addAll(matches.where((match) => !match.isResolved).map(toResult));
}
- // merge results
- return futureGroup.future;
+
+ return results;
}
/**
@@ -47,18 +48,20 @@
* to the corresponding hierarchy [Element]s.
*/
Future<List<SearchResult>> _findElementsReferences(Element element) async {
+ List<SearchResult> allResults = <SearchResult>[];
Iterable<Element> refElements = await _getRefElements(element);
- var futureGroup = new _ConcatFutureGroup<SearchResult>();
for (Element refElement in refElements) {
// add declaration
if (_isDeclarationInteresting(refElement)) {
SearchResult searchResult = _newDeclarationResult(refElement);
- futureGroup.add(searchResult);
+ allResults.add(searchResult);
}
// do search
- futureGroup.add(_findSingleElementReferences(refElement));
+ List<SearchResult> elementResults =
+ await _findSingleElementReferences(refElement);
+ allResults.addAll(elementResults);
}
- return futureGroup.future;
+ return allResults;
}
/**
@@ -67,6 +70,7 @@
Future<List<SearchResult>> _findSingleElementReferences(
Element element) async {
List<SearchMatch> matches = await searchEngine.searchReferences(element);
+ matches = SearchMatch.withNotNullElement(matches);
return matches.map(toResult).toList();
}
@@ -129,26 +133,3 @@
return element.enclosingElement is ClassElement;
}
}
-
-/**
- * A collection of [Future]s that concats [List] results of added [Future]s into
- * a single [List].
- */
-class _ConcatFutureGroup<E> {
- final List<Future<List<E>>> _futures = <Future<List<E>>>[];
-
- Future<List<E>> get future {
- return Future.wait(_futures).then(concatToList);
- }
-
- /**
- * Adds a [Future] or an [E] value to results.
- */
- void add(value) {
- if (value is Future) {
- _futures.add(value as Future<List<E>>);
- } else {
- _futures.add(new Future.value(<E>[value as E]));
- }
- }
-}
diff --git a/pkg/analysis_server/lib/src/search/search_domain.dart b/pkg/analysis_server/lib/src/search/search_domain.dart
index 37c58a69..cdd39a3 100644
--- a/pkg/analysis_server/lib/src/search/search_domain.dart
+++ b/pkg/analysis_server/lib/src/search/search_domain.dart
@@ -98,6 +98,7 @@
// search
List<SearchMatch> matches =
await searchEngine.searchMemberDeclarations(params.name);
+ matches = SearchMatch.withNotNullElement(matches);
_sendSearchNotification(searchId, true, matches.map(toResult));
}
@@ -112,6 +113,7 @@
// search
List<SearchMatch> matches =
await searchEngine.searchMemberReferences(params.name);
+ matches = SearchMatch.withNotNullElement(matches);
_sendSearchNotification(searchId, true, matches.map(toResult));
}
@@ -135,6 +137,7 @@
// search
List<SearchMatch> matches =
await searchEngine.searchTopLevelDeclarations(params.pattern);
+ matches = SearchMatch.withNotNullElement(matches);
_sendSearchNotification(searchId, true, matches.map(toResult));
}
diff --git a/pkg/analysis_server/lib/src/server/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart
index dc971b8..3095df8 100644
--- a/pkg/analysis_server/lib/src/server/driver.dart
+++ b/pkg/analysis_server/lib/src/server/driver.dart
@@ -422,19 +422,10 @@
.path;
}
bool useSummaries = analysisServerOptions.fileReadMode == 'as-is';
- SdkCreator defaultSdkCreator = (AnalysisOptions options) {
- PhysicalResourceProvider resourceProvider =
- PhysicalResourceProvider.INSTANCE;
- FolderBasedDartSdk sdk = new FolderBasedDartSdk(
- resourceProvider, resourceProvider.getFolder(defaultSdkPath));
- sdk.analysisOptions = options;
- sdk.useSummary = useSummaries;
- return sdk;
- };
// TODO(brianwilkerson) It would be nice to avoid creating an SDK that
// cannot be re-used, but the SDK is needed to create a package map provider
// in the case where we need to run `pub` in order to get the package map.
- DartSdk defaultSdk = defaultSdkCreator(null);
+ DartSdk defaultSdk = _createDefaultSdk(defaultSdkPath, useSummaries);
//
// Initialize the instrumentation service.
//
@@ -458,7 +449,7 @@
//
socketServer = new SocketServer(
analysisServerOptions,
- new DartSdkManager(defaultSdkPath, useSummaries, defaultSdkCreator),
+ new DartSdkManager(defaultSdkPath, useSummaries),
defaultSdk,
service,
serverPlugin,
@@ -586,6 +577,15 @@
return parser;
}
+ DartSdk _createDefaultSdk(String defaultSdkPath, bool useSummaries) {
+ PhysicalResourceProvider resourceProvider =
+ PhysicalResourceProvider.INSTANCE;
+ FolderBasedDartSdk sdk = new FolderBasedDartSdk(
+ resourceProvider, resourceProvider.getFolder(defaultSdkPath));
+ sdk.useSummary = useSummaries;
+ return sdk;
+ }
+
/**
* Print information about how to use the server.
*/
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
index 2a537bf..a57319a 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
@@ -29,6 +29,9 @@
CompletionSuggestionKind kind: CompletionSuggestionKind.INVOCATION,
int relevance: DART_RELEVANCE_DEFAULT,
Source importForSource}) {
+ if (element == null) {
+ return null;
+ }
if (element is ExecutableElement && element.isOperator) {
// Do not include operators in suggestions
return null;
diff --git a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
index 42ccd71..9899681 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -87,7 +87,18 @@
String get eol => utils.endOfLine;
Future<List<Assist>> compute() async {
- utils = new CorrectionUtils(unit);
+ // If the source was changed between the constructor and running
+ // this asynchronous method, it is not safe to use the unit.
+ if (analysisContext.getModificationStamp(source) != fileStamp) {
+ return const <Assist>[];
+ }
+
+ try {
+ utils = new CorrectionUtils(unit);
+ } catch (e) {
+ throw new CancelCorrectionException(exception: e);
+ }
+
node = new NodeLocator(selectionOffset, selectionEnd).searchWithin(unit);
if (node == null) {
return assists;
@@ -2239,9 +2250,13 @@
*/
class DefaultAssistContributor extends DartAssistContributor {
@override
- Future<List<Assist>> internalComputeAssists(DartAssistContext context) {
- AssistProcessor processor = new AssistProcessor(context);
- return processor.compute();
+ Future<List<Assist>> internalComputeAssists(DartAssistContext context) async {
+ try {
+ AssistProcessor processor = new AssistProcessor(context);
+ return processor.compute();
+ } on CancelCorrectionException {
+ return Assist.EMPTY_LIST;
+ }
}
}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index a0b6d10..0d49cf4 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -105,7 +105,9 @@
errorCode == StaticTypeWarningCode.UNDEFINED_GETTER ||
errorCode == StaticTypeWarningCode.UNDEFINED_METHOD ||
errorCode == StaticTypeWarningCode.UNDEFINED_SETTER ||
- (errorCode is LintCode && errorCode.name == LintNames.annotate_overrides);
+ (errorCode is LintCode &&
+ (errorCode.name == LintNames.annotate_overrides ||
+ errorCode.name == LintNames.unnecessary_brace_in_string_interp));
/**
* An enumeration of possible quick fix kinds.
@@ -179,6 +181,10 @@
const FixKind('INSERT_SEMICOLON', 50, "Insert ';'");
static const LINT_ADD_OVERRIDE =
const FixKind('LINT_ADD_OVERRIDE', 50, "Add '@override' annotation");
+ static const LINT_REMOVE_INTERPOLATION_BRACES = const FixKind(
+ 'LINT_REMOVE_INTERPOLATION_BRACES',
+ 50,
+ 'Remove unnecessary interpolation braces');
static const MAKE_CLASS_ABSTRACT =
const FixKind('MAKE_CLASS_ABSTRACT', 50, "Make class '{0}' abstract");
static const REMOVE_DEAD_CODE =
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 78939c5..1a99f8f 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -69,9 +69,13 @@
*/
class DefaultFixContributor extends DartFixContributor {
@override
- Future<List<Fix>> internalComputeFixes(DartFixContext context) {
- FixProcessor processor = new FixProcessor(context);
- return processor.compute();
+ Future<List<Fix>> internalComputeFixes(DartFixContext context) async {
+ try {
+ FixProcessor processor = new FixProcessor(context);
+ return processor.compute();
+ } on CancelCorrectionException {
+ return Fix.EMPTY_LIST;
+ }
}
}
@@ -135,7 +139,18 @@
String get eol => utils.endOfLine;
Future<List<Fix>> compute() async {
- utils = new CorrectionUtils(unit);
+ // If the source was changed between the constructor and running
+ // this asynchronous method, it is not safe to use the unit.
+ if (context.getModificationStamp(unitSource) != fileStamp) {
+ return const <Fix>[];
+ }
+
+ try {
+ utils = new CorrectionUtils(unit);
+ } catch (e) {
+ throw new CancelCorrectionException(exception: e);
+ }
+
errorOffset = error.offset;
errorLength = error.length;
errorEnd = errorOffset + errorLength;
@@ -356,6 +371,9 @@
if (errorCode.name == LintNames.annotate_overrides) {
_addLintFixAddOverrideAnnotation();
}
+ if (errorCode.name == LintNames.unnecessary_brace_in_string_interp) {
+ _addLintRemoveInterpolationBraces();
+ }
}
// done
return fixes;
@@ -2280,6 +2298,18 @@
_addFix(DartFixKind.LINT_ADD_OVERRIDE, []);
}
+ void _addLintRemoveInterpolationBraces() {
+ AstNode node = this.node;
+ if (node is InterpolationExpression) {
+ Token right = node.rightBracket;
+ if (node.expression != null && right != null) {
+ _addReplaceEdit(rf.rangeStartStart(node, node.expression), r'$');
+ _addRemoveEdit(rf.rangeToken(right));
+ _addFix(DartFixKind.LINT_REMOVE_INTERPOLATION_BRACES, []);
+ }
+ }
+ }
+
/**
* Prepares proposal for creating function corresponding to the given
* [FunctionType].
@@ -2896,6 +2926,8 @@
*/
class LintNames {
static const String annotate_overrides = 'annotate_overrides';
+ static const String unnecessary_brace_in_string_interp =
+ 'unnecessary_brace_in_string_interp';
}
/**
diff --git a/pkg/analysis_server/lib/src/services/correction/util.dart b/pkg/analysis_server/lib/src/services/correction/util.dart
index 8a357d6..82f2652 100644
--- a/pkg/analysis_server/lib/src/services/correction/util.dart
+++ b/pkg/analysis_server/lib/src/services/correction/util.dart
@@ -31,14 +31,19 @@
*/
void addLibraryImports(SourceChange change, LibraryElement targetLibrary,
Set<LibraryElement> libraries) {
- CompilationUnitElement libUnitElement = targetLibrary.definingCompilationUnit;
- CompilationUnit libUnit = getParsedUnit(libUnitElement);
- CorrectionUtils libUtils = new CorrectionUtils(libUnit);
+ CorrectionUtils libUtils;
+ try {
+ CompilationUnitElement unitElement = targetLibrary.definingCompilationUnit;
+ CompilationUnit unitAst = getParsedUnit(unitElement);
+ libUtils = new CorrectionUtils(unitAst);
+ } catch (e) {
+ throw new CancelCorrectionException(exception: e);
+ }
String eol = libUtils.endOfLine;
// Prepare information about existing imports.
LibraryDirective libraryDirective;
List<_ImportDirectiveInfo> importDirectives = <_ImportDirectiveInfo>[];
- for (Directive directive in libUnit.directives) {
+ for (Directive directive in libUtils.unit.directives) {
if (directive is LibraryDirective) {
libraryDirective = directive;
} else if (directive is ImportDirective) {
@@ -664,6 +669,17 @@
}
/**
+ * This exception is thrown to cancel the current correction operation,
+ * such as quick assist or quick fix because an inconsistency was detected.
+ * These inconsistencies may happen as a part of normal workflow, e.g. because
+ * a resource was deleted, or an analysis result was invalidated.
+ */
+class CancelCorrectionException {
+ final Object exception;
+ CancelCorrectionException({this.exception});
+}
+
+/**
* Describes the location for a newly created [ClassMember].
*/
class ClassMemberLocation {
@@ -689,8 +705,12 @@
CorrectionUtils(this.unit) {
CompilationUnitElement unitElement = unit.element;
+ AnalysisContext context = unitElement.context;
+ if (context == null) {
+ throw new CancelCorrectionException();
+ }
this._library = unitElement.library;
- this._buffer = unitElement.context.getContents(unitElement.source).data;
+ this._buffer = context.getContents(unitElement.source).data;
}
/**
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 72a29ce..80fd4b1 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart
@@ -40,7 +40,6 @@
@override
Future<RefactoringStatus> checkFinalConditions() {
RefactoringStatus result = new RefactoringStatus();
- _analyzePossibleConflicts(result);
return new Future.value(result);
}
@@ -48,6 +47,9 @@
RefactoringStatus checkNewName() {
RefactoringStatus result = super.checkNewName();
result.addStatus(validateConstructorName(newName));
+ if (newName != null) {
+ _analyzePossibleConflicts(result);
+ }
return result;
}
@@ -70,8 +72,13 @@
}
void _analyzePossibleConflicts(RefactoringStatus result) {
- // check if there are members with "newName" in the same ClassElement
ClassElement parentClass = element.enclosingElement;
+ // Check if the "newName" is the name of the enclosing class.
+ if (parentClass.name == newName) {
+ result.addError('The constructor should not have the same name '
+ 'as the name of the enclosing class.');
+ }
+ // check if there are members with "newName" in the same ClassElement
for (Element newNameMember in getChildren(parentClass, newName)) {
String message = format(
"Class '{0}' already declares {1} with name '{2}'.",
diff --git a/pkg/analysis_server/lib/src/services/search/search_engine.dart b/pkg/analysis_server/lib/src/services/search/search_engine.dart
index 72ca482..9f283fc 100644
--- a/pkg/analysis_server/lib/src/services/search/search_engine.dart
+++ b/pkg/analysis_server/lib/src/services/search/search_engine.dart
@@ -155,16 +155,20 @@
this.sourceRange, this.isResolved, this.isQualified);
/**
- * Return the [Element] containing the match.
+ * Return the [Element] containing the match. Can return `null` if the unit
+ * does not exist, or its element was invalidated, or the element cannot be
+ * found, etc.
*/
Element get element {
if (_element == null) {
CompilationUnitElement unitElement =
context.getCompilationUnitElement(unitSource, librarySource);
- _ContainingElementFinder finder =
- new _ContainingElementFinder(sourceRange.offset);
- unitElement.accept(finder);
- _element = finder.containingElement;
+ if (unitElement != null) {
+ _ContainingElementFinder finder =
+ new _ContainingElementFinder(sourceRange.offset);
+ unitElement.accept(finder);
+ _element = finder.containingElement;
+ }
}
return _element;
}
@@ -176,7 +180,8 @@
@override
int get hashCode {
- return JenkinsSmiHash.hash4(libraryUri, unitUri, kind, sourceRange);
+ return JenkinsSmiHash.hash4(libraryUri.hashCode, unitUri.hashCode,
+ kind.hashCode, sourceRange.hashCode);
}
/**
@@ -237,6 +242,16 @@
buffer.write(")");
return buffer.toString();
}
+
+ /**
+ * Return elements of [matches] which has not-null elements.
+ *
+ * When [SearchMatch.element] is not `null` we cache its value, so it cannot
+ * become `null` later.
+ */
+ static List<SearchMatch> withNotNullElement(List<SearchMatch> matches) {
+ return matches.where((match) => match.element != null).toList();
+ }
}
/**
diff --git a/pkg/analysis_server/lib/src/status/get_handler.dart b/pkg/analysis_server/lib/src/status/get_handler.dart
index b87a33e..c89a26f 100644
--- a/pkg/analysis_server/lib/src/status/get_handler.dart
+++ b/pkg/analysis_server/lib/src/status/get_handler.dart
@@ -1407,7 +1407,6 @@
buffer.write('<p>');
_writeOption(
buffer, 'Analyze functon bodies', options.analyzeFunctionBodies);
- _writeOption(buffer, 'Cache size', options.cacheSize);
_writeOption(
buffer, 'Enable generic methods', options.enableGenericMethods);
_writeOption(
diff --git a/pkg/analysis_server/lib/src/status/memory_use.dart b/pkg/analysis_server/lib/src/status/memory_use.dart
index 92657bc..8f68b0f 100644
--- a/pkg/analysis_server/lib/src/status/memory_use.dart
+++ b/pkg/analysis_server/lib/src/status/memory_use.dart
@@ -225,8 +225,10 @@
DartSdkManager manager = server.sdkManager;
List<SdkDescription> descriptors = manager.sdkDescriptors;
for (SdkDescription descriptor in descriptors) {
- _processAnalysisContext(
- manager.getSdk(descriptor, () => null).context, manager);
+ DartSdk sdk = manager.getSdk(descriptor, () => null);
+ if (sdk != null) {
+ _processAnalysisContext(sdk.context, manager);
+ }
}
}
diff --git a/pkg/analysis_server/pubspec.yaml b/pkg/analysis_server/pubspec.yaml
index 297a3b0..cb366f9 100644
--- a/pkg/analysis_server/pubspec.yaml
+++ b/pkg/analysis_server/pubspec.yaml
@@ -6,7 +6,7 @@
environment:
sdk: '>=1.12.0 <2.0.0'
dependencies:
- analyzer: ^0.27.0
+ analyzer: ^0.28.0
args: '>=0.13.0 <0.14.0'
dart_style: '>=0.2.0 <0.3.0'
isolate: ^0.2.2
@@ -19,7 +19,6 @@
yaml: any
dev_dependencies:
html: any
- mock: '>=0.11.0 <0.12.0'
- test_reflective_loader: '>=0.0.4 <0.1.0'
+ test_reflective_loader: ^0.1.0
typed_mock: '>=0.0.4 <1.0.0'
- unittest: '>=0.11.4 <0.12.0'
+ test: ^0.12.0
diff --git a/pkg/analysis_server/test/abstract_single_unit.dart b/pkg/analysis_server/test/abstract_single_unit.dart
index 307f251..bda1d20 100644
--- a/pkg/analysis_server/test/abstract_single_unit.dart
+++ b/pkg/analysis_server/test/abstract_single_unit.dart
@@ -10,7 +10,7 @@
import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/source.dart';
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
import 'abstract_context.dart';
diff --git a/pkg/analysis_server/test/analysis/get_errors_test.dart b/pkg/analysis_server/test/analysis/get_errors_test.dart
index a665cfa..f58aad9 100644
--- a/pkg/analysis_server/test/analysis/get_errors_test.dart
+++ b/pkg/analysis_server/test/analysis/get_errors_test.dart
@@ -8,15 +8,15 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/domain_analysis.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../analysis_abstract.dart';
-import '../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(GetErrorsTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(GetErrorsTest);
+ });
}
@reflectiveTest
@@ -26,7 +26,9 @@
@override
void setUp() {
super.setUp();
- server.handlers = [new AnalysisDomainHandler(server),];
+ server.handlers = [
+ new AnalysisDomainHandler(server),
+ ];
createProject();
}
diff --git a/pkg/analysis_server/test/analysis/get_hover_test.dart b/pkg/analysis_server/test/analysis/get_hover_test.dart
index bbf8cbf..f97ae90 100644
--- a/pkg/analysis_server/test/analysis/get_hover_test.dart
+++ b/pkg/analysis_server/test/analysis/get_hover_test.dart
@@ -7,15 +7,15 @@
import 'dart:async';
import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../analysis_abstract.dart';
-import '../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(AnalysisHoverTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AnalysisHoverTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/analysis/get_navigation_test.dart b/pkg/analysis_server/test/analysis/get_navigation_test.dart
index add8b90..5e262a7 100644
--- a/pkg/analysis_server/test/analysis/get_navigation_test.dart
+++ b/pkg/analysis_server/test/analysis/get_navigation_test.dart
@@ -7,15 +7,15 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/domain_analysis.dart';
import 'package:analyzer/file_system/file_system.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../utils.dart';
import 'notification_navigation_test.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(GetNavigationTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(GetNavigationTest);
+ });
}
@reflectiveTest
@@ -25,7 +25,9 @@
@override
void setUp() {
super.setUp();
- server.handlers = [new AnalysisDomainHandler(server),];
+ server.handlers = [
+ new AnalysisDomainHandler(server),
+ ];
createProject();
}
diff --git a/pkg/analysis_server/test/analysis/navigation_collector_test.dart b/pkg/analysis_server/test/analysis/navigation_collector_test.dart
index e0f118f..cf71283 100644
--- a/pkg/analysis_server/test/analysis/navigation_collector_test.dart
+++ b/pkg/analysis_server/test/analysis/navigation_collector_test.dart
@@ -6,14 +6,13 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/domains/analysis/navigation.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(NavigationCollectorImplTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(NavigationCollectorImplTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart b/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart
index b2d1add..7d08f0f 100644
--- a/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart
@@ -9,17 +9,17 @@
import 'package:analysis_server/src/domain_analysis.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/services/lint.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../analysis_abstract.dart';
import '../mocks.dart';
-import '../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(NewAnalysisOptionsFileNotificationTest);
- defineReflectiveTests(OldAnalysisOptionsFileNotificationTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(NewAnalysisOptionsFileNotificationTest);
+ defineReflectiveTests(OldAnalysisOptionsFileNotificationTest);
+ });
}
abstract class AnalysisOptionsFileNotificationTest
diff --git a/pkg/analysis_server/test/analysis/notification_analyzedFiles_test.dart b/pkg/analysis_server/test/analysis/notification_analyzedFiles_test.dart
index 0ce9e164..f9c95ae 100644
--- a/pkg/analysis_server/test/analysis/notification_analyzedFiles_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_analyzedFiles_test.dart
@@ -8,16 +8,16 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/constants.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../analysis_abstract.dart';
import '../mocks.dart';
-import '../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(AnalysisNotificationAnalyzedFilesTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AnalysisNotificationAnalyzedFilesTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/analysis/notification_errors_test.dart b/pkg/analysis_server/test/analysis/notification_errors_test.dart
index 02b05ec..3184665 100644
--- a/pkg/analysis_server/test/analysis/notification_errors_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_errors_test.dart
@@ -10,15 +10,15 @@
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/services/lint.dart';
import 'package:linter/src/linter.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../analysis_abstract.dart';
-import '../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(NotificationErrorsTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(NotificationErrorsTest);
+ });
}
@reflectiveTest
@@ -35,7 +35,9 @@
@override
void setUp() {
super.setUp();
- server.handlers = [new AnalysisDomainHandler(server),];
+ server.handlers = [
+ new AnalysisDomainHandler(server),
+ ];
}
test_importError() async {
diff --git a/pkg/analysis_server/test/analysis/notification_highlights_test.dart b/pkg/analysis_server/test/analysis/notification_highlights_test.dart
index 6c2b57a3..0106453 100644
--- a/pkg/analysis_server/test/analysis/notification_highlights_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_highlights_test.dart
@@ -8,16 +8,16 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/constants.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../analysis_abstract.dart';
-import '../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(AnalysisNotificationHighlightsTest);
- defineReflectiveTests(HighlightTypeTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AnalysisNotificationHighlightsTest);
+ defineReflectiveTests(HighlightTypeTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/analysis/notification_highlights_test2.dart b/pkg/analysis_server/test/analysis/notification_highlights_test2.dart
index 0342c89..2618777 100644
--- a/pkg/analysis_server/test/analysis/notification_highlights_test2.dart
+++ b/pkg/analysis_server/test/analysis/notification_highlights_test2.dart
@@ -8,16 +8,16 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/constants.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../analysis_abstract.dart';
-import '../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(AnalysisNotificationHighlightsTest);
- defineReflectiveTests(HighlightTypeTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AnalysisNotificationHighlightsTest);
+ defineReflectiveTests(HighlightTypeTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/analysis/notification_implemented_test.dart b/pkg/analysis_server/test/analysis/notification_implemented_test.dart
index ee3959a..fa18586 100644
--- a/pkg/analysis_server/test/analysis/notification_implemented_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_implemented_test.dart
@@ -9,15 +9,15 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/constants.dart';
import 'package:analysis_server/src/services/index/index.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../analysis_abstract.dart';
-import '../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(AnalysisNotificationImplementedTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AnalysisNotificationImplementedTest);
+ });
}
@reflectiveTest
@@ -432,6 +432,7 @@
return new Future.delayed(
new Duration(milliseconds: 1), () => waitForNotification(times - 1));
}
+
return waitForNotification(30000);
}
}
diff --git a/pkg/analysis_server/test/analysis/notification_navigation_test.dart b/pkg/analysis_server/test/analysis/notification_navigation_test.dart
index b1fd5f1..49b55ae 100644
--- a/pkg/analysis_server/test/analysis/notification_navigation_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_navigation_test.dart
@@ -8,15 +8,15 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/constants.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../analysis_abstract.dart';
-import '../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(AnalysisNotificationNavigationTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AnalysisNotificationNavigationTest);
+ });
}
class AbstractNavigationTest extends AbstractAnalysisTest {
diff --git a/pkg/analysis_server/test/analysis/notification_occurrences_test.dart b/pkg/analysis_server/test/analysis/notification_occurrences_test.dart
index c27fa10..933791e 100644
--- a/pkg/analysis_server/test/analysis/notification_occurrences_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_occurrences_test.dart
@@ -8,15 +8,15 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/constants.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../analysis_abstract.dart';
-import '../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(AnalysisNotificationOccurrencesTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AnalysisNotificationOccurrencesTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/analysis/notification_outline_test.dart b/pkg/analysis_server/test/analysis/notification_outline_test.dart
index 1230dbc..eaa88d1 100644
--- a/pkg/analysis_server/test/analysis/notification_outline_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_outline_test.dart
@@ -8,15 +8,15 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/constants.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../analysis_abstract.dart';
-import '../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(_AnalysisNotificationOutlineTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(_AnalysisNotificationOutlineTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/analysis/notification_overrides_test.dart b/pkg/analysis_server/test/analysis/notification_overrides_test.dart
index 61db513..c5f964e 100644
--- a/pkg/analysis_server/test/analysis/notification_overrides_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_overrides_test.dart
@@ -8,15 +8,15 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/constants.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../analysis_abstract.dart';
-import '../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(AnalysisNotificationOverridesTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AnalysisNotificationOverridesTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/analysis/reanalyze_test.dart b/pkg/analysis_server/test/analysis/reanalyze_test.dart
index b7f62d0..a6cbb89 100644
--- a/pkg/analysis_server/test/analysis/reanalyze_test.dart
+++ b/pkg/analysis_server/test/analysis/reanalyze_test.dart
@@ -7,15 +7,15 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/constants.dart';
import 'package:analyzer/src/generated/engine.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../analysis_abstract.dart';
-import '../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(ReanalyzeTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ReanalyzeTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/analysis/set_priority_files_test.dart b/pkg/analysis_server/test/analysis/set_priority_files_test.dart
index 9a1b5c9..5a870cc 100644
--- a/pkg/analysis_server/test/analysis/set_priority_files_test.dart
+++ b/pkg/analysis_server/test/analysis/set_priority_files_test.dart
@@ -9,16 +9,16 @@
import 'package:analyzer/src/generated/engine.dart'
show InternalAnalysisContext;
import 'package:analyzer/src/generated/source.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../analysis_abstract.dart';
import '../mocks.dart';
-import '../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(SetPriorityFilesTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(SetPriorityFilesTest);
+ });
}
@reflectiveTest
@@ -26,7 +26,9 @@
@override
void setUp() {
super.setUp();
- server.handlers = [new AnalysisDomainHandler(server),];
+ server.handlers = [
+ new AnalysisDomainHandler(server),
+ ];
createProject();
}
diff --git a/pkg/analysis_server/test/analysis/test_all.dart b/pkg/analysis_server/test/analysis/test_all.dart
index a0cd6d3..6f7817c 100644
--- a/pkg/analysis_server/test/analysis/test_all.dart
+++ b/pkg/analysis_server/test/analysis/test_all.dart
@@ -3,9 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library test.analysis;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../utils.dart';
import 'get_errors_test.dart' as get_errors_test;
import 'get_hover_test.dart' as get_hover_test;
import 'get_navigation_test.dart' as get_navigation_test;
@@ -29,8 +28,7 @@
* Utility for manually running all tests.
*/
main() {
- initializeTestEnvironment();
- group('analysis', () {
+ defineReflectiveSuite(() {
get_errors_test.main();
get_hover_test.main();
get_navigation_test.main();
@@ -47,5 +45,5 @@
notification_overrides_test.main();
set_priority_files_test.main();
update_content_test.main();
- });
+ }, name: 'analysis');
}
diff --git a/pkg/analysis_server/test/analysis/update_content_test.dart b/pkg/analysis_server/test/analysis/update_content_test.dart
index 6ab4706..b5d77c6 100644
--- a/pkg/analysis_server/test/analysis/update_content_test.dart
+++ b/pkg/analysis_server/test/analysis/update_content_test.dart
@@ -12,16 +12,16 @@
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:typed_mock/typed_mock.dart';
-import 'package:unittest/unittest.dart';
import '../analysis_abstract.dart';
-import '../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(UpdateContentTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(UpdateContentTest);
+ });
}
compilationUnitMatcher(String file) {
diff --git a/pkg/analysis_server/test/analysis_abstract.dart b/pkg/analysis_server/test/analysis_abstract.dart
index 0db5841..d9f8984 100644
--- a/pkg/analysis_server/test/analysis_abstract.dart
+++ b/pkg/analysis_server/test/analysis_abstract.dart
@@ -22,7 +22,7 @@
import 'package:linter/src/plugin/linter_plugin.dart';
import 'package:plugin/manager.dart';
import 'package:plugin/plugin.dart';
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
import 'mock_sdk.dart';
import 'mocks.dart';
@@ -57,9 +57,9 @@
<GeneralAnalysisService>[];
final Map<AnalysisService, List<String>> analysisSubscriptions = {};
- String projectPath = '/project';
- String testFolder = '/project/bin';
- String testFile = '/project/bin/test.dart';
+ String projectPath;
+ String testFolder;
+ String testFile;
String testCode;
AbstractAnalysisTest();
@@ -84,6 +84,7 @@
}
String addFile(String path, String content) {
+ path = resourceProvider.convertPath(path);
resourceProvider.newFile(path, content);
return path;
}
@@ -123,9 +124,12 @@
ExtensionManager manager = new ExtensionManager();
manager.processPlugins(plugins);
//
+ // Create an SDK in the mock file system.
+ //
+ new MockSdk(resourceProvider: resourceProvider);
+ //
// Create server
//
- MockSdk sdk = new MockSdk(resourceProvider: resourceProvider);
return new AnalysisServer(
serverChannel,
resourceProvider,
@@ -133,7 +137,7 @@
index,
serverPlugin,
new AnalysisServerOptions(),
- new DartSdkManager('/', false, (_) => sdk),
+ new DartSdkManager(resourceProvider.convertPath('/'), false),
InstrumentationService.NULL_SERVICE);
}
@@ -146,8 +150,9 @@
*/
void createProject({Map<String, String> packageRoots}) {
resourceProvider.newFolder(projectPath);
- Request request =
- new AnalysisSetAnalysisRootsParams([projectPath], [], packageRoots: packageRoots).toRequest('0');
+ Request request = new AnalysisSetAnalysisRootsParams([projectPath], [],
+ packageRoots: packageRoots)
+ .toRequest('0');
handleSuccessfulRequest(request, handler: analysisHandler);
}
@@ -206,6 +211,9 @@
void setUp() {
serverChannel = new MockServerChannel();
resourceProvider = new MemoryResourceProvider();
+ projectPath = resourceProvider.convertPath('/project');
+ testFolder = resourceProvider.convertPath('/project/bin');
+ testFile = resourceProvider.convertPath('/project/bin/test.dart');
packageMapProvider = new MockPackageMapProvider();
Index index = createIndex();
server = createAnalysisServer(index);
diff --git a/pkg/analysis_server/test/analysis_server_test.dart b/pkg/analysis_server/test/analysis_server_test.dart
index ed50563..a76d57b 100644
--- a/pkg/analysis_server/test/analysis_server_test.dart
+++ b/pkg/analysis_server/test/analysis_server_test.dart
@@ -23,17 +23,17 @@
import 'package:analyzer/src/generated/source.dart';
import 'package:plugin/manager.dart';
import 'package:plugin/plugin.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:typed_mock/typed_mock.dart';
-import 'package:unittest/unittest.dart';
import 'mock_sdk.dart';
import 'mocks.dart';
-import 'utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(AnalysisServerTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AnalysisServerTest);
+ });
}
@reflectiveTest
@@ -137,7 +137,8 @@
manager.processPlugins([plugin]);
channel = new MockServerChannel();
resourceProvider = new MemoryResourceProvider();
- MockSdk sdk = new MockSdk(resourceProvider: resourceProvider);
+ // Create an SDK in the mock file system.
+ new MockSdk(resourceProvider: resourceProvider);
packageMapProvider = new MockPackageMapProvider();
server = new AnalysisServer(
channel,
@@ -146,7 +147,7 @@
null,
plugin,
new AnalysisServerOptions(),
- new DartSdkManager('/', false, (_) => sdk),
+ new DartSdkManager('/', false),
InstrumentationService.NULL_SERVICE,
rethrowExceptions: true);
processRequiredPlugins();
diff --git a/pkg/analysis_server/test/channel/byte_stream_channel_test.dart b/pkg/analysis_server/test/channel/byte_stream_channel_test.dart
index d1887be..c4bab89 100644
--- a/pkg/analysis_server/test/channel/byte_stream_channel_test.dart
+++ b/pkg/analysis_server/test/channel/byte_stream_channel_test.dart
@@ -11,13 +11,11 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/channel/byte_stream_channel.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
import '../mocks.dart';
-import '../utils.dart';
main() {
- initializeTestEnvironment();
group('ByteStreamClientChannel', () {
setUp(ByteStreamClientChannelTest.setUp);
test('close', ByteStreamClientChannelTest.close);
diff --git a/pkg/analysis_server/test/channel/test_all.dart b/pkg/analysis_server/test/channel/test_all.dart
index d177863..2e1538d 100644
--- a/pkg/analysis_server/test/channel/test_all.dart
+++ b/pkg/analysis_server/test/channel/test_all.dart
@@ -4,9 +4,8 @@
library test.channel.all;
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
-import '../utils.dart';
import 'byte_stream_channel_test.dart' as byte_stream_channel_test;
import 'web_socket_channel_test.dart' as web_socket_channel_test;
@@ -14,7 +13,6 @@
* Utility for manually running all tests.
*/
main() {
- initializeTestEnvironment();
group('computer', () {
byte_stream_channel_test.main();
web_socket_channel_test.main();
diff --git a/pkg/analysis_server/test/channel/web_socket_channel_test.dart b/pkg/analysis_server/test/channel/web_socket_channel_test.dart
index 77c47bc..b9f2e43 100644
--- a/pkg/analysis_server/test/channel/web_socket_channel_test.dart
+++ b/pkg/analysis_server/test/channel/web_socket_channel_test.dart
@@ -9,13 +9,11 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/channel/web_socket_channel.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
import '../mocks.dart';
-import '../utils.dart';
main() {
- initializeTestEnvironment();
group('WebSocketChannel', () {
setUp(WebSocketChannelTest.setUp);
test('close', WebSocketChannelTest.close);
diff --git a/pkg/analysis_server/test/completion_test.dart b/pkg/analysis_server/test/completion_test.dart
index 778b1f0..93483ce 100644
--- a/pkg/analysis_server/test/completion_test.dart
+++ b/pkg/analysis_server/test/completion_test.dart
@@ -7,29 +7,16 @@
import 'dart:async';
import 'dart:collection';
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
import 'completion_test_support.dart';
-import 'utils.dart';
main() {
- initializeTestEnvironment();
CompletionTestBuilder builder = new CompletionTestBuilder();
builder.buildAll();
}
/**
- * Assigning the name of a single test to this string causes just that test to
- * be run. Assigning null to this string causes all tests to be run.
- */
-const String SOLO_TEST = null;
-
-/**
- * Type of functions used to create tests.
- */
-typedef void _Tester(String spec, TestFunction body);
-
-/**
* A builder that builds the completion tests.
*/
class CompletionTestBuilder {
@@ -2848,7 +2835,8 @@
// test analysis of untyped fields and top-level vars
buildTests('test035', '''class Y {final x='hi';mth() {x.!1length;}}''',
- <String>["1+length"], failingTests: '1');
+ <String>["1+length"],
+ failingTests: '1');
// TODO(scheglov) decide what to do with Type for untyped field (not
// supported by the new store)
@@ -2977,10 +2965,9 @@
}
for (LocationSpec spec in completionTests) {
String testName = '$baseName-${spec.id}';
- _Tester tester = testName == SOLO_TEST ? solo_test : test;
if (failingTests.contains(spec.id)) {
++expectedFailCount;
- tester("$testName (expected failure $expectedFailCount)", () {
+ test("$testName (expected failure $expectedFailCount)", () {
CompletionTestCase test = new CompletionTestCase();
return new Future(() => test.runTest(spec, extraFiles)).then((_) {
fail('Test passed - expected to fail.');
@@ -2988,7 +2975,7 @@
});
} else {
++expectedPassCount;
- tester(testName, () {
+ test(testName, () {
CompletionTestCase test = new CompletionTestCase();
return test.runTest(spec, extraFiles);
});
diff --git a/pkg/analysis_server/test/completion_test_support.dart b/pkg/analysis_server/test/completion_test_support.dart
index e477c5b..3121980 100644
--- a/pkg/analysis_server/test/completion_test_support.dart
+++ b/pkg/analysis_server/test/completion_test_support.dart
@@ -8,7 +8,7 @@
import 'dart:collection';
import 'package:analysis_server/plugin/protocol/protocol.dart';
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
import 'domain_completion_test.dart';
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index 87f62fd..46414f6 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -5,7 +5,6 @@
library test.context.directory.manager;
import 'dart:collection';
-import 'dart:io' as io;
import 'package:analysis_server/src/context_manager.dart';
import 'package:analyzer/error/error.dart';
@@ -28,18 +27,18 @@
import 'package:path/path.dart';
import 'package:plugin/manager.dart';
import 'package:plugin/plugin.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import 'mock_sdk.dart';
import 'mocks.dart';
-import 'utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(AbstractContextManagerTest);
- defineReflectiveTests(ContextManagerWithNewOptionsTest);
- defineReflectiveTests(ContextManagerWithOldOptionsTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AbstractContextManagerTest);
+ defineReflectiveTests(ContextManagerWithNewOptionsTest);
+ defineReflectiveTests(ContextManagerWithOldOptionsTest);
+ });
}
@reflectiveTest
@@ -156,10 +155,7 @@
var context = contexts[0];
var source = context.sourceFactory.forUri('dart:foobar');
expect(source, isNotNull);
- expect(
- source.fullName,
- '/my/proj/sdk_ext/entry.dart'
- .replaceAll('/', io.Platform.pathSeparator));
+ expect(source.fullName, '/my/proj/sdk_ext/entry.dart');
// We can't find dart:core because we didn't list it in our
// embedded_libs map.
expect(context.sourceFactory.forUri('dart:core'), isNull);
@@ -1795,8 +1791,9 @@
processRequiredPlugins();
resourceProvider = new MemoryResourceProvider();
packageMapProvider = new MockPackageMapProvider();
- DartSdk sdk = new MockSdk(resourceProvider: resourceProvider);
- DartSdkManager sdkManager = new DartSdkManager('/', false, (_) => sdk);
+ // Create an SDK in the mock file system.
+ new MockSdk(resourceProvider: resourceProvider);
+ DartSdkManager sdkManager = new DartSdkManager('/', false);
manager = new ContextManagerImpl(
resourceProvider,
sdkManager,
@@ -2164,10 +2161,7 @@
// Sanity check embedder libs.
var source = context.sourceFactory.forUri('dart:foobar');
expect(source, isNotNull);
- expect(
- source.fullName,
- '/my/proj/sdk_ext/entry.dart'
- .replaceAll('/', io.Platform.pathSeparator));
+ expect(source.fullName, '/my/proj/sdk_ext/entry.dart');
}
test_embedder_options() async {
@@ -2258,10 +2252,7 @@
// Sanity check embedder libs.
var source = context.sourceFactory.forUri('dart:foobar');
expect(source, isNotNull);
- expect(
- source.fullName,
- '/my/proj/sdk_ext/entry.dart'
- .replaceAll('/', io.Platform.pathSeparator));
+ expect(source.fullName, '/my/proj/sdk_ext/entry.dart');
}
test_error_filter_analysis_option() async {
@@ -2715,7 +2706,7 @@
@override
ContextBuilder createContextBuilder(Folder folder, AnalysisOptions options) {
- DartSdkManager sdkManager = new DartSdkManager('/', false, null);
+ DartSdkManager sdkManager = new DartSdkManager('/', false);
ContextBuilder builder =
new ContextBuilder(resourceProvider, sdkManager, new ContentCache());
builder.defaultOptions = options;
diff --git a/pkg/analysis_server/test/domain_analysis_test.dart b/pkg/analysis_server/test/domain_analysis_test.dart
index 485227d..76d12c8 100644
--- a/pkg/analysis_server/test/domain_analysis_test.dart
+++ b/pkg/analysis_server/test/domain_analysis_test.dart
@@ -15,19 +15,18 @@
import 'package:analyzer/instrumentation/instrumentation.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:plugin/manager.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import 'analysis_abstract.dart';
import 'mock_sdk.dart';
import 'mocks.dart';
-import 'utils.dart';
main() {
- initializeTestEnvironment();
-
- defineReflectiveTests(AnalysisDomainTest);
- defineReflectiveTests(SetSubscriptionsTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AnalysisDomainTest);
+ defineReflectiveTests(SetSubscriptionsTest);
+ });
MockServerChannel serverChannel;
MemoryResourceProvider resourceProvider;
@@ -40,7 +39,8 @@
ExtensionManager manager = new ExtensionManager();
ServerPlugin serverPlugin = new ServerPlugin();
manager.processPlugins([serverPlugin]);
- MockSdk sdk = new MockSdk(resourceProvider: resourceProvider);
+ // Create an SDK in the mock file system.
+ new MockSdk(resourceProvider: resourceProvider);
server = new AnalysisServer(
serverChannel,
resourceProvider,
@@ -48,7 +48,7 @@
null,
serverPlugin,
new AnalysisServerOptions(),
- new DartSdkManager('/', false, (_) => sdk),
+ new DartSdkManager('/', false),
InstrumentationService.NULL_SERVICE);
handler = new AnalysisDomainHandler(server);
});
@@ -435,7 +435,8 @@
ExtensionManager manager = new ExtensionManager();
ServerPlugin serverPlugin = new ServerPlugin();
manager.processPlugins([serverPlugin]);
- MockSdk sdk = new MockSdk(resourceProvider: resourceProvider);
+ // Create an SDK in the mock file system.
+ new MockSdk(resourceProvider: resourceProvider);
server = new AnalysisServer(
serverChannel,
resourceProvider,
@@ -443,7 +444,7 @@
null,
serverPlugin,
new AnalysisServerOptions(),
- new DartSdkManager('/', false, (_) => sdk),
+ new DartSdkManager('/', false),
InstrumentationService.NULL_SERVICE);
handler = new AnalysisDomainHandler(server);
// listen for notifications
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index 81d8a35..ef51507 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -12,18 +12,18 @@
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
import 'package:analysis_server/src/services/completion/dart/contribution_sorter.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import 'analysis_abstract.dart';
import 'domain_completion_util.dart';
import 'mocks.dart' show pumpEventQueue;
-import 'utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(CompletionDomainHandlerTest);
- defineReflectiveTests(_NoSearchEngine);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(CompletionDomainHandlerTest);
+ defineReflectiveTests(_NoSearchEngine);
+ });
}
@reflectiveTest
@@ -48,6 +48,15 @@
expect(suggestions, hasLength(2));
}
+ test_ArgumentList_imported_function_named_param2() async {
+ addTestFile('mainx() {A a = new A(); a.foo(one: 7, ^);}'
+ 'class A { foo({one, two}) {} }');
+ await getSuggestions();
+ assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'two: ',
+ relevance: DART_RELEVANCE_NAMED_PARAMETER);
+ expect(suggestions, hasLength(1));
+ }
+
test_ArgumentList_imported_function_named_param_label1() async {
addTestFile('main() { int.parse("16", r^: 16);}');
await getSuggestions();
@@ -68,15 +77,6 @@
expect(suggestions, hasLength(2));
}
- test_ArgumentList_imported_function_named_param2() async {
- addTestFile('mainx() {A a = new A(); a.foo(one: 7, ^);}'
- 'class A { foo({one, two}) {} }');
- await getSuggestions();
- assertHasResult(CompletionSuggestionKind.NAMED_ARGUMENT, 'two: ',
- relevance: DART_RELEVANCE_NAMED_PARAMETER);
- expect(suggestions, hasLength(1));
- }
-
test_html() {
testFile = '/project/web/test.html';
addTestFile('''
@@ -89,6 +89,20 @@
});
}
+ test_import_uri_with_trailing() {
+ addFile('/project/bin/testA.dart', 'library libA;');
+ addTestFile('''
+ import '/project/bin/t^.dart';
+ main() {}''');
+ return getSuggestions().then((_) {
+ expect(replacementOffset, equals(completionOffset - 14));
+ expect(replacementLength, equals(5 + 14));
+ assertHasResult(
+ CompletionSuggestionKind.IMPORT, '/project/bin/testA.dart');
+ assertNoResult('test');
+ });
+ }
+
test_imports() {
addTestFile('''
import 'dart:html';
@@ -561,20 +575,6 @@
assertNoResult('HtmlElement');
});
}
-
- test_import_uri_with_trailing() {
- addFile('/project/bin/testA.dart', 'library libA;');
- addTestFile('''
- import '/project/bin/t^.dart';
- main() {}''');
- return getSuggestions().then((_) {
- expect(replacementOffset, equals(completionOffset - 14));
- expect(replacementLength, equals(5 + 14));
- assertHasResult(
- CompletionSuggestionKind.IMPORT, '/project/bin/testA.dart');
- assertNoResult('test');
- });
- }
}
class MockRelevancySorter implements DartContributionSorter {
diff --git a/pkg/analysis_server/test/domain_completion_util.dart b/pkg/analysis_server/test/domain_completion_util.dart
index 6045aee..bd55b72 100644
--- a/pkg/analysis_server/test/domain_completion_util.dart
+++ b/pkg/analysis_server/test/domain_completion_util.dart
@@ -11,7 +11,7 @@
import 'package:analysis_server/src/domain_completion.dart';
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/index/index.dart';
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
import 'analysis_abstract.dart';
import 'mocks.dart';
diff --git a/pkg/analysis_server/test/domain_diagnostic_test.dart b/pkg/analysis_server/test/domain_diagnostic_test.dart
index 1c4ba4a..78080e8 100644
--- a/pkg/analysis_server/test/domain_diagnostic_test.dart
+++ b/pkg/analysis_server/test/domain_diagnostic_test.dart
@@ -14,19 +14,16 @@
import 'package:analyzer/src/generated/sdk.dart';
import 'package:plugin/manager.dart';
import 'package:plugin/plugin.dart';
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
import 'mock_sdk.dart';
import 'mocks.dart';
-import 'utils.dart';
main() {
AnalysisServer server;
DiagnosticDomainHandler handler;
MemoryResourceProvider resourceProvider;
- initializeTestEnvironment();
-
setUp(() {
//
// Collect plugins
@@ -47,7 +44,8 @@
//
var serverChannel = new MockServerChannel();
resourceProvider = new MemoryResourceProvider();
- MockSdk sdk = new MockSdk(resourceProvider: resourceProvider);
+ // Create an SDK in the mock file system.
+ new MockSdk(resourceProvider: resourceProvider);
server = new AnalysisServer(
serverChannel,
resourceProvider,
@@ -55,7 +53,7 @@
null,
serverPlugin,
new AnalysisServerOptions(),
- new DartSdkManager('/', false, (_) => sdk),
+ new DartSdkManager('/', false),
InstrumentationService.NULL_SERVICE);
handler = new DiagnosticDomainHandler(server);
});
diff --git a/pkg/analysis_server/test/domain_execution_test.dart b/pkg/analysis_server/test/domain_execution_test.dart
index fad6e1a..3ed91bd 100644
--- a/pkg/analysis_server/test/domain_execution_test.dart
+++ b/pkg/analysis_server/test/domain_execution_test.dart
@@ -20,19 +20,18 @@
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:plugin/manager.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:typed_mock/typed_mock.dart';
-import 'package:unittest/unittest.dart';
import 'analysis_abstract.dart';
-import 'mock_sdk.dart';
import 'mocks.dart';
import 'operation/operation_queue_test.dart';
-import 'utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(ExecutionDomainTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ExecutionDomainTest);
+ });
group('ExecutionDomainHandler', () {
MemoryResourceProvider provider = new MemoryResourceProvider();
AnalysisServer server;
@@ -49,7 +48,7 @@
null,
serverPlugin,
new AnalysisServerOptions(),
- new DartSdkManager('', false, (_) => new MockSdk()),
+ new DartSdkManager('', false),
InstrumentationService.NULL_SERVICE);
handler = new ExecutionDomainHandler(server);
});
diff --git a/pkg/analysis_server/test/domain_server_test.dart b/pkg/analysis_server/test/domain_server_test.dart
index 5ffd328..4fbb2b0 100644
--- a/pkg/analysis_server/test/domain_server_test.dart
+++ b/pkg/analysis_server/test/domain_server_test.dart
@@ -13,18 +13,14 @@
import 'package:analyzer/instrumentation/instrumentation.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:plugin/manager.dart';
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
-import 'mock_sdk.dart';
import 'mocks.dart';
-import 'utils.dart';
main() {
AnalysisServer server;
ServerDomainHandler handler;
- initializeTestEnvironment();
-
setUp(() {
var serverChannel = new MockServerChannel();
var resourceProvider = new MemoryResourceProvider();
@@ -38,7 +34,7 @@
null,
serverPlugin,
new AnalysisServerOptions(),
- new DartSdkManager('', false, (_) => new MockSdk()),
+ new DartSdkManager('', false),
InstrumentationService.NULL_SERVICE);
handler = new ServerDomainHandler(server);
});
diff --git a/pkg/analysis_server/test/edit/assists_test.dart b/pkg/analysis_server/test/edit/assists_test.dart
index 538a04e..0181c87 100644
--- a/pkg/analysis_server/test/edit/assists_test.dart
+++ b/pkg/analysis_server/test/edit/assists_test.dart
@@ -7,15 +7,15 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/edit/edit_domain.dart';
import 'package:plugin/manager.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart' hide ERROR;
import '../analysis_abstract.dart';
-import '../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(AssistsTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AssistsTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/edit/fixes_test.dart b/pkg/analysis_server/test/edit/fixes_test.dart
index 1b5cd87..3cd22c0 100644
--- a/pkg/analysis_server/test/edit/fixes_test.dart
+++ b/pkg/analysis_server/test/edit/fixes_test.dart
@@ -9,15 +9,15 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/edit/edit_domain.dart';
import 'package:plugin/manager.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart' hide ERROR;
import '../analysis_abstract.dart';
-import '../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(FixesTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(FixesTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/edit/format_test.dart b/pkg/analysis_server/test/edit/format_test.dart
index d864ef9..a7e7e4e 100644
--- a/pkg/analysis_server/test/edit/format_test.dart
+++ b/pkg/analysis_server/test/edit/format_test.dart
@@ -9,16 +9,16 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/edit/edit_domain.dart';
import 'package:plugin/manager.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart' hide ERROR;
import '../analysis_abstract.dart';
import '../mocks.dart';
-import '../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(FormatTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(FormatTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/edit/organize_directives_test.dart b/pkg/analysis_server/test/edit/organize_directives_test.dart
index 5223627..89b8c30 100644
--- a/pkg/analysis_server/test/edit/organize_directives_test.dart
+++ b/pkg/analysis_server/test/edit/organize_directives_test.dart
@@ -9,16 +9,16 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/edit/edit_domain.dart';
import 'package:plugin/manager.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart' hide ERROR;
import '../analysis_abstract.dart';
import '../mocks.dart';
-import '../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(OrganizeDirectivesTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(OrganizeDirectivesTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/edit/refactoring_test.dart b/pkg/analysis_server/test/edit/refactoring_test.dart
index 766e58f..ee97a1a 100644
--- a/pkg/analysis_server/test/edit/refactoring_test.dart
+++ b/pkg/analysis_server/test/edit/refactoring_test.dart
@@ -11,25 +11,25 @@
import 'package:analysis_server/src/services/index/index.dart';
import 'package:analyzer/task/dart.dart';
import 'package:plugin/manager.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart' hide ERROR;
import '../analysis_abstract.dart';
import '../mocks.dart';
-import '../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(ConvertGetterMethodToMethodTest);
- defineReflectiveTests(ConvertMethodToGetterTest);
- defineReflectiveTests(ExtractLocalVariableTest);
- defineReflectiveTests(ExtractMethodTest);
- defineReflectiveTests(GetAvailableRefactoringsTest);
- defineReflectiveTests(InlineLocalTest);
- defineReflectiveTests(InlineMethodTest);
- defineReflectiveTests(MoveFileTest);
- defineReflectiveTests(RenameTest);
- defineReflectiveTests(_NoSearchEngine);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConvertGetterMethodToMethodTest);
+ defineReflectiveTests(ConvertMethodToGetterTest);
+ defineReflectiveTests(ExtractLocalVariableTest);
+ defineReflectiveTests(ExtractMethodTest);
+ defineReflectiveTests(GetAvailableRefactoringsTest);
+ defineReflectiveTests(InlineLocalTest);
+ defineReflectiveTests(InlineMethodTest);
+ defineReflectiveTests(MoveFileTest);
+ defineReflectiveTests(RenameTest);
+ defineReflectiveTests(_NoSearchEngine);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/edit/sort_members_test.dart b/pkg/analysis_server/test/edit/sort_members_test.dart
index ee801df7..c5651fa 100644
--- a/pkg/analysis_server/test/edit/sort_members_test.dart
+++ b/pkg/analysis_server/test/edit/sort_members_test.dart
@@ -9,16 +9,16 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/edit/edit_domain.dart';
import 'package:plugin/manager.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart' hide ERROR;
import '../analysis_abstract.dart';
import '../mocks.dart';
-import '../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(SortMembersTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(SortMembersTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/edit/test_all.dart b/pkg/analysis_server/test/edit/test_all.dart
index ef861d8..16a89ed 100644
--- a/pkg/analysis_server/test/edit/test_all.dart
+++ b/pkg/analysis_server/test/edit/test_all.dart
@@ -4,9 +4,8 @@
library test.edit.all;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../utils.dart';
import 'assists_test.dart' as assists_test;
import 'fixes_test.dart' as fixes_test;
import 'format_test.dart' as format_test;
@@ -18,13 +17,12 @@
* Utility for manually running all tests.
*/
main() {
- initializeTestEnvironment();
- group('edit', () {
+ defineReflectiveSuite(() {
assists_test.main();
fixes_test.main();
format_test.main();
organize_directives_test.main();
refactoring_test.main();
sort_members_test.main();
- });
+ }, name: 'edit');
}
diff --git a/pkg/analysis_server/test/integration/analysis/analysis_options_test.dart b/pkg/analysis_server/test/integration/analysis/analysis_options_test.dart
index 4c55f82..a2ea8e7 100644
--- a/pkg/analysis_server/test/integration/analysis/analysis_options_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/analysis_options_test.dart
@@ -6,15 +6,15 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analyzer/src/generated/engine.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../utils.dart';
import '../integration_tests.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(OptionsIntegrationTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(OptionsIntegrationTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/integration/analysis/error_test.dart b/pkg/analysis_server/test/integration/analysis/error_test.dart
index b01f1d8..847f895 100644
--- a/pkg/analysis_server/test/integration/analysis/error_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/error_test.dart
@@ -5,15 +5,15 @@
library test.integration.analysis.error;
import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../utils.dart';
import '../integration_tests.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(AnalysisErrorIntegrationTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AnalysisErrorIntegrationTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/integration/analysis/get_errors.dart b/pkg/analysis_server/test/integration/analysis/get_errors.dart
index c21d242..d7aee3c 100644
--- a/pkg/analysis_server/test/integration/analysis/get_errors.dart
+++ b/pkg/analysis_server/test/integration/analysis/get_errors.dart
@@ -6,7 +6,7 @@
import 'dart:async';
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
import '../integration_tests.dart';
diff --git a/pkg/analysis_server/test/integration/analysis/get_errors_after_analysis_test.dart b/pkg/analysis_server/test/integration/analysis/get_errors_after_analysis_test.dart
index 2024194..37caf81 100644
--- a/pkg/analysis_server/test/integration/analysis/get_errors_after_analysis_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/get_errors_after_analysis_test.dart
@@ -6,12 +6,12 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../utils.dart';
import 'get_errors.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(Test);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(Test);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/integration/analysis/get_errors_before_analysis_test.dart b/pkg/analysis_server/test/integration/analysis/get_errors_before_analysis_test.dart
index 51ef942..4863a8d 100644
--- a/pkg/analysis_server/test/integration/analysis/get_errors_before_analysis_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/get_errors_before_analysis_test.dart
@@ -6,12 +6,12 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../utils.dart';
import 'get_errors.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(Test);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(Test);
+ });
}
@reflectiveTest
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 70bd7aa..9d34855 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
@@ -10,16 +10,16 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:path/path.dart' as path;
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../../mock_sdk.dart';
-import '../../utils.dart';
import '../integration_tests.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(AnalysisDomainGetErrorsTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AnalysisDomainGetErrorsTest);
+ });
}
/**
diff --git a/pkg/analysis_server/test/integration/analysis/get_hover_test.dart b/pkg/analysis_server/test/integration/analysis/get_hover_test.dart
index 7ed2989..921a266 100644
--- a/pkg/analysis_server/test/integration/analysis/get_hover_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/get_hover_test.dart
@@ -8,15 +8,15 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:path/path.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../utils.dart';
import '../integration_tests.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(AnalysisGetHoverIntegrationTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AnalysisGetHoverIntegrationTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/integration/analysis/highlights_test.dart b/pkg/analysis_server/test/integration/analysis/highlights_test.dart
index 7605ea3..bc20497 100644
--- a/pkg/analysis_server/test/integration/analysis/highlights_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/highlights_test.dart
@@ -5,15 +5,15 @@
library test.integration.analysis.highlights;
import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../utils.dart';
import '../integration_tests.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(AnalysisHighlightsTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AnalysisHighlightsTest);
+ });
}
@reflectiveTest
@@ -99,6 +99,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/analysis/highlights_test2.dart b/pkg/analysis_server/test/integration/analysis/highlights_test2.dart
index c8d75ee..b1a70c5 100644
--- a/pkg/analysis_server/test/integration/analysis/highlights_test2.dart
+++ b/pkg/analysis_server/test/integration/analysis/highlights_test2.dart
@@ -7,15 +7,15 @@
import 'dart:async';
import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../utils.dart';
import '../integration_tests.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(AnalysisHighlightsTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AnalysisHighlightsTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/integration/analysis/lint_test.dart b/pkg/analysis_server/test/integration/analysis/lint_test.dart
index a1cfeb6..b8d212e 100644
--- a/pkg/analysis_server/test/integration/analysis/lint_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/lint_test.dart
@@ -6,15 +6,15 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analyzer/src/generated/engine.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../utils.dart';
import '../integration_tests.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(LintIntegrationTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(LintIntegrationTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/integration/analysis/navigation_test.dart b/pkg/analysis_server/test/integration/analysis/navigation_test.dart
index 35dd9e2..d6ea41c 100644
--- a/pkg/analysis_server/test/integration/analysis/navigation_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/navigation_test.dart
@@ -5,15 +5,15 @@
library test.integration.analysis.navigation;
import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../utils.dart';
import '../integration_tests.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(AnalysisNavigationTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AnalysisNavigationTest);
+ });
}
@reflectiveTest
@@ -84,6 +84,7 @@
fail('No element found for index $index');
return null;
}
+
void checkLocal(
String source, String expectedTarget, ElementKind expectedKind) {
int sourceIndex = text1.indexOf(source);
@@ -93,6 +94,7 @@
expect(element.offset, equals(targetIndex));
expect(element.kind, equals(expectedKind));
}
+
void checkRemote(String source, String expectedTargetRegexp,
ElementKind expectedKind) {
int sourceIndex = text1.indexOf(source);
@@ -100,6 +102,7 @@
expect(targetFiles[element.fileIndex], matches(expectedTargetRegexp));
expect(element.kind, equals(expectedKind));
}
+
// TODO(paulberry): will the element type 'CLASS_TYPE_ALIAS' ever appear
// as a navigation target?
checkLocal('Class<int>', 'Class<TypeParameter>', ElementKind.CLASS);
diff --git a/pkg/analysis_server/test/integration/analysis/occurrences_test.dart b/pkg/analysis_server/test/integration/analysis/occurrences_test.dart
index 1bcb270..2234205 100644
--- a/pkg/analysis_server/test/integration/analysis/occurrences_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/occurrences_test.dart
@@ -5,15 +5,15 @@
library test.integration.analysis.occurrences;
import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../utils.dart';
import '../integration_tests.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(Test);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(Test);
+ });
}
@reflectiveTest
@@ -52,6 +52,7 @@
fail('No element found matching $elementName');
return null;
}
+
void check(String elementName, Iterable<String> expectedOccurrences) {
Set<int> expectedOffsets = expectedOccurrences
.map((String substring) => text.indexOf(substring))
@@ -59,6 +60,7 @@
Set<int> foundOffsets = findOffsets(elementName);
expect(foundOffsets, equals(expectedOffsets));
}
+
check('i', ['i = 0', 'i < 10', 'i++', 'i;']);
check('j', ['j = 0', 'j < i', 'j++', 'j;']);
check('sum', ['sum = 0', 'sum +=', 'sum)']);
diff --git a/pkg/analysis_server/test/integration/analysis/outline_test.dart b/pkg/analysis_server/test/integration/analysis/outline_test.dart
index 7d7d853..23f2cbd 100644
--- a/pkg/analysis_server/test/integration/analysis/outline_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/outline_test.dart
@@ -5,15 +5,15 @@
library test.integration.analysis.outline;
import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../utils.dart';
import '../integration_tests.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(Test);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(Test);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/integration/analysis/overrides_test.dart b/pkg/analysis_server/test/integration/analysis/overrides_test.dart
index e7b77dc..74c179f 100644
--- a/pkg/analysis_server/test/integration/analysis/overrides_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/overrides_test.dart
@@ -5,15 +5,15 @@
library test.integration.analysis.overrides;
import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../utils.dart';
import '../integration_tests.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(Test);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(Test);
+ });
}
@reflectiveTest
@@ -74,6 +74,7 @@
}
return null;
}
+
void checkOverrides(String methodName, bool expectedOverridesBase,
List<String> expectedOverridesInterfaces) {
Override override = findOverride(methodName);
@@ -109,6 +110,7 @@
expect(interfaceMembers, isNull);
}
}
+
checkOverrides('method0', true, ['Interface1', 'Interface2']);
checkOverrides('method1', false, ['Interface1', 'Interface2']);
checkOverrides('method2', true, ['Interface1']);
diff --git a/pkg/analysis_server/test/integration/analysis/package_root_test.dart b/pkg/analysis_server/test/integration/analysis/package_root_test.dart
index 7ce03d2..4febe5ad 100644
--- a/pkg/analysis_server/test/integration/analysis/package_root_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/package_root_test.dart
@@ -6,15 +6,15 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:path/path.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../utils.dart';
import '../integration_tests.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(Test);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(Test);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/integration/analysis/reanalyze_concurrent_test.dart b/pkg/analysis_server/test/integration/analysis/reanalyze_concurrent_test.dart
index 443bab1..abf05cf 100644
--- a/pkg/analysis_server/test/integration/analysis/reanalyze_concurrent_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/reanalyze_concurrent_test.dart
@@ -14,12 +14,12 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../utils.dart';
import '../integration_tests.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(Test);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(Test);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/integration/analysis/reanalyze_test.dart b/pkg/analysis_server/test/integration/analysis/reanalyze_test.dart
index df1250b..ac5b889 100644
--- a/pkg/analysis_server/test/integration/analysis/reanalyze_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/reanalyze_test.dart
@@ -5,15 +5,15 @@
library test.integration.analysis.reanalyze;
import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../utils.dart';
import '../integration_tests.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(Test);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(Test);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/integration/analysis/test_all.dart b/pkg/analysis_server/test/integration/analysis/test_all.dart
index eb8a06e..dcdc7c8 100644
--- a/pkg/analysis_server/test/integration/analysis/test_all.dart
+++ b/pkg/analysis_server/test/integration/analysis/test_all.dart
@@ -4,9 +4,8 @@
library test.integration.analysis.all;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../utils.dart';
import 'analysis_options_test.dart' as analysis_options_test;
import 'error_test.dart' as error_test;
import 'get_errors_after_analysis_test.dart' as get_errors_after_analysis_test;
@@ -31,8 +30,7 @@
* Utility for manually running all integration tests.
*/
main() {
- initializeTestEnvironment();
- group('analysis', () {
+ defineReflectiveSuite(() {
analysis_options_test.main();
error_test.main();
get_errors_after_analysis_test.main();
@@ -51,5 +49,5 @@
reanalyze_test.main();
update_content_test.main();
update_content_list_test.main();
- });
+ }, name: 'analysis');
}
diff --git a/pkg/analysis_server/test/integration/analysis/update_content_list_test.dart b/pkg/analysis_server/test/integration/analysis/update_content_list_test.dart
index 3eb72ff..b235a39 100644
--- a/pkg/analysis_server/test/integration/analysis/update_content_list_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/update_content_list_test.dart
@@ -5,15 +5,15 @@
library test.integration.analysis.update.content.list;
import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../utils.dart';
import '../integration_tests.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(Test);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(Test);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/integration/analysis/update_content_test.dart b/pkg/analysis_server/test/integration/analysis/update_content_test.dart
index b451396..c9d5400 100644
--- a/pkg/analysis_server/test/integration/analysis/update_content_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/update_content_test.dart
@@ -5,15 +5,15 @@
library test.integration.analysis.update.content;
import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../utils.dart';
import '../integration_tests.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(Test);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(Test);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/integration/completion/get_suggestions_test.dart b/pkg/analysis_server/test/integration/completion/get_suggestions_test.dart
index a318ea2..653711f 100644
--- a/pkg/analysis_server/test/integration/completion/get_suggestions_test.dart
+++ b/pkg/analysis_server/test/integration/completion/get_suggestions_test.dart
@@ -5,15 +5,15 @@
library test.integration.completion.get.suggestions;
import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../utils.dart';
import '../integration_tests.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(Test);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(Test);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/integration/completion/test_all.dart b/pkg/analysis_server/test/integration/completion/test_all.dart
index aae07f3..580ffca 100644
--- a/pkg/analysis_server/test/integration/completion/test_all.dart
+++ b/pkg/analysis_server/test/integration/completion/test_all.dart
@@ -4,17 +4,15 @@
library test.integration.completion.all;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../utils.dart';
import 'get_suggestions_test.dart' as get_suggestions_test;
/**
* Utility for manually running all integration tests.
*/
main() {
- initializeTestEnvironment();
- group('completion', () {
+ defineReflectiveSuite(() {
get_suggestions_test.main();
- });
+ }, name: 'completion');
}
diff --git a/pkg/analysis_server/test/integration/integration_test_methods.dart b/pkg/analysis_server/test/integration/integration_test_methods.dart
index 9e4a5ee..4bad372 100644
--- a/pkg/analysis_server/test/integration/integration_test_methods.dart
+++ b/pkg/analysis_server/test/integration/integration_test_methods.dart
@@ -15,7 +15,7 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/protocol/protocol_internal.dart';
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
import 'integration_tests.dart';
import 'protocol_matchers.dart';
@@ -51,7 +51,7 @@
*/
Future sendServerShutdown() async {
var result = await server.send("server.shutdown", null);
- expect(result, isNull);
+ outOfTestExpect(result, isNull);
return null;
}
@@ -72,7 +72,7 @@
Future sendServerSetSubscriptions(List<ServerService> subscriptions) async {
var params = new ServerSetSubscriptionsParams(subscriptions).toJson();
var result = await server.send("server.setSubscriptions", params);
- expect(result, isNull);
+ outOfTestExpect(result, isNull);
return null;
}
@@ -376,7 +376,7 @@
Future sendAnalysisReanalyze({List<String> roots}) async {
var params = new AnalysisReanalyzeParams(roots: roots).toJson();
var result = await server.send("analysis.reanalyze", params);
- expect(result, isNull);
+ outOfTestExpect(result, isNull);
return null;
}
@@ -442,7 +442,7 @@
Future sendAnalysisSetAnalysisRoots(List<String> included, List<String> excluded, {Map<String, String> packageRoots}) async {
var params = new AnalysisSetAnalysisRootsParams(included, excluded, packageRoots: packageRoots).toJson();
var result = await server.send("analysis.setAnalysisRoots", params);
- expect(result, isNull);
+ outOfTestExpect(result, isNull);
return null;
}
@@ -464,7 +464,7 @@
Future sendAnalysisSetGeneralSubscriptions(List<GeneralAnalysisService> subscriptions) async {
var params = new AnalysisSetGeneralSubscriptionsParams(subscriptions).toJson();
var result = await server.send("analysis.setGeneralSubscriptions", params);
- expect(result, isNull);
+ outOfTestExpect(result, isNull);
return null;
}
@@ -496,7 +496,7 @@
Future sendAnalysisSetPriorityFiles(List<String> files) async {
var params = new AnalysisSetPriorityFilesParams(files).toJson();
var result = await server.send("analysis.setPriorityFiles", params);
- expect(result, isNull);
+ outOfTestExpect(result, isNull);
return null;
}
@@ -535,7 +535,7 @@
Future sendAnalysisSetSubscriptions(Map<AnalysisService, List<String>> subscriptions) async {
var params = new AnalysisSetSubscriptionsParams(subscriptions).toJson();
var result = await server.send("analysis.setSubscriptions", params);
- expect(result, isNull);
+ outOfTestExpect(result, isNull);
return null;
}
@@ -579,7 +579,7 @@
Future sendAnalysisUpdateOptions(AnalysisOptions options) async {
var params = new AnalysisUpdateOptionsParams(options).toJson();
var result = await server.send("analysis.updateOptions", params);
- expect(result, isNull);
+ outOfTestExpect(result, isNull);
return null;
}
@@ -1503,7 +1503,7 @@
Future sendExecutionDeleteContext(String id) async {
var params = new ExecutionDeleteContextParams(id).toJson();
var result = await server.send("execution.deleteContext", params);
- expect(result, isNull);
+ outOfTestExpect(result, isNull);
return null;
}
@@ -1579,7 +1579,7 @@
Future sendExecutionSetSubscriptions(List<ExecutionService> subscriptions) async {
var params = new ExecutionSetSubscriptionsParams(subscriptions).toJson();
var result = await server.send("execution.setSubscriptions", params);
- expect(result, isNull);
+ outOfTestExpect(result, isNull);
return null;
}
@@ -1678,71 +1678,71 @@
ResponseDecoder decoder = new ResponseDecoder(null);
switch (event) {
case "server.connected":
- expect(params, isServerConnectedParams);
+ outOfTestExpect(params, isServerConnectedParams);
_onServerConnected.add(new ServerConnectedParams.fromJson(decoder, 'params', params));
break;
case "server.error":
- expect(params, isServerErrorParams);
+ outOfTestExpect(params, isServerErrorParams);
_onServerError.add(new ServerErrorParams.fromJson(decoder, 'params', params));
break;
case "server.status":
- expect(params, isServerStatusParams);
+ outOfTestExpect(params, isServerStatusParams);
_onServerStatus.add(new ServerStatusParams.fromJson(decoder, 'params', params));
break;
case "analysis.analyzedFiles":
- expect(params, isAnalysisAnalyzedFilesParams);
+ outOfTestExpect(params, isAnalysisAnalyzedFilesParams);
_onAnalysisAnalyzedFiles.add(new AnalysisAnalyzedFilesParams.fromJson(decoder, 'params', params));
break;
case "analysis.errors":
- expect(params, isAnalysisErrorsParams);
+ outOfTestExpect(params, isAnalysisErrorsParams);
_onAnalysisErrors.add(new AnalysisErrorsParams.fromJson(decoder, 'params', params));
break;
case "analysis.flushResults":
- expect(params, isAnalysisFlushResultsParams);
+ outOfTestExpect(params, isAnalysisFlushResultsParams);
_onAnalysisFlushResults.add(new AnalysisFlushResultsParams.fromJson(decoder, 'params', params));
break;
case "analysis.folding":
- expect(params, isAnalysisFoldingParams);
+ outOfTestExpect(params, isAnalysisFoldingParams);
_onAnalysisFolding.add(new AnalysisFoldingParams.fromJson(decoder, 'params', params));
break;
case "analysis.highlights":
- expect(params, isAnalysisHighlightsParams);
+ outOfTestExpect(params, isAnalysisHighlightsParams);
_onAnalysisHighlights.add(new AnalysisHighlightsParams.fromJson(decoder, 'params', params));
break;
case "analysis.implemented":
- expect(params, isAnalysisImplementedParams);
+ outOfTestExpect(params, isAnalysisImplementedParams);
_onAnalysisImplemented.add(new AnalysisImplementedParams.fromJson(decoder, 'params', params));
break;
case "analysis.invalidate":
- expect(params, isAnalysisInvalidateParams);
+ outOfTestExpect(params, isAnalysisInvalidateParams);
_onAnalysisInvalidate.add(new AnalysisInvalidateParams.fromJson(decoder, 'params', params));
break;
case "analysis.navigation":
- expect(params, isAnalysisNavigationParams);
+ outOfTestExpect(params, isAnalysisNavigationParams);
_onAnalysisNavigation.add(new AnalysisNavigationParams.fromJson(decoder, 'params', params));
break;
case "analysis.occurrences":
- expect(params, isAnalysisOccurrencesParams);
+ outOfTestExpect(params, isAnalysisOccurrencesParams);
_onAnalysisOccurrences.add(new AnalysisOccurrencesParams.fromJson(decoder, 'params', params));
break;
case "analysis.outline":
- expect(params, isAnalysisOutlineParams);
+ outOfTestExpect(params, isAnalysisOutlineParams);
_onAnalysisOutline.add(new AnalysisOutlineParams.fromJson(decoder, 'params', params));
break;
case "analysis.overrides":
- expect(params, isAnalysisOverridesParams);
+ outOfTestExpect(params, isAnalysisOverridesParams);
_onAnalysisOverrides.add(new AnalysisOverridesParams.fromJson(decoder, 'params', params));
break;
case "completion.results":
- expect(params, isCompletionResultsParams);
+ outOfTestExpect(params, isCompletionResultsParams);
_onCompletionResults.add(new CompletionResultsParams.fromJson(decoder, 'params', params));
break;
case "search.results":
- expect(params, isSearchResultsParams);
+ outOfTestExpect(params, isSearchResultsParams);
_onSearchResults.add(new SearchResultsParams.fromJson(decoder, 'params', params));
break;
case "execution.launchData":
- expect(params, isExecutionLaunchDataParams);
+ outOfTestExpect(params, isExecutionLaunchDataParams);
_onExecutionLaunchData.add(new ExecutionLaunchDataParams.fromJson(decoder, 'params', params));
break;
default:
diff --git a/pkg/analysis_server/test/integration/integration_tests.dart b/pkg/analysis_server/test/integration/integration_tests.dart
index f6748ed..71b5378 100644
--- a/pkg/analysis_server/test/integration/integration_tests.dart
+++ b/pkg/analysis_server/test/integration/integration_tests.dart
@@ -12,7 +12,7 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/constants.dart';
import 'package:path/path.dart';
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
import 'integration_test_methods.dart';
import 'protocol_matchers.dart';
@@ -40,6 +40,38 @@
Matcher isOneOf(List<Matcher> choiceMatchers) => new _OneOf(choiceMatchers);
/**
+ * Assert that [actual] matches [matcher].
+ */
+void outOfTestExpect(actual, matcher,
+ {String reason, skip, bool verbose: false}) {
+ var matchState = {};
+ try {
+ if (matcher.matches(actual, matchState)) return;
+ } catch (e, trace) {
+ if (reason == null) {
+ reason = '${(e is String) ? e : e.toString()} at $trace';
+ }
+ }
+ fail(_defaultFailFormatter(actual, matcher, reason, matchState, verbose));
+}
+
+String _defaultFailFormatter(
+ actual, Matcher matcher, String reason, Map matchState, bool verbose) {
+ var description = new StringDescription();
+ description.add('Expected: ').addDescriptionOf(matcher).add('\n');
+ description.add(' Actual: ').addDescriptionOf(actual).add('\n');
+
+ var mismatchDescription = new StringDescription();
+ matcher.describeMismatch(actual, mismatchDescription, matchState, verbose);
+
+ if (mismatchDescription.length > 0) {
+ description.add(' Which: $mismatchDescription\n');
+ }
+ if (reason != null) description.add(reason).add('\n');
+ return description.toString();
+}
+
+/**
* Type of closures used by LazyMatcher.
*/
typedef Matcher MatcherCreator();
@@ -111,7 +143,7 @@
StreamSubscription subscription;
// This will only work if the caller has already subscribed to
// SERVER_STATUS (e.g. using sendServerSetSubscriptions(['STATUS']))
- expect(_subscribedToServerStatus, isTrue);
+ outOfTestExpect(_subscribedToServerStatus, isTrue);
subscription = onServerStatus.listen((ServerStatusParams params) {
if (params.analysis != null && !params.analysis.isAnalyzing) {
completer.complete(params);
@@ -147,7 +179,7 @@
});
Completer serverConnected = new Completer();
onServerConnected.listen((_) {
- expect(serverConnected.isCompleted, isFalse);
+ outOfTestExpect(serverConnected.isCompleted, isFalse);
serverConnected.complete();
});
onServerError.listen((ServerErrorParams params) {
@@ -525,10 +557,10 @@
_badDataFromServer('JSON decode failure: $exception');
return;
}
- expect(message, isMap);
+ outOfTestExpect(message, isMap);
Map messageAsMap = message;
if (messageAsMap.containsKey('id')) {
- expect(messageAsMap['id'], isString);
+ outOfTestExpect(messageAsMap['id'], isString);
String id = message['id'];
Completer completer = _pendingCommands[id];
if (completer == null) {
@@ -546,17 +578,17 @@
// Check that the message is well-formed. We do this after calling
// completer.complete() or completer.completeError() so that we don't
// stall the test in the event of an error.
- expect(message, isResponse);
+ outOfTestExpect(message, isResponse);
} else {
// Message is a notification. It should have an event and possibly
// params.
- expect(messageAsMap, contains('event'));
- expect(messageAsMap['event'], isString);
+ outOfTestExpect(messageAsMap, contains('event'));
+ outOfTestExpect(messageAsMap['event'], isString);
notificationProcessor(messageAsMap['event'], messageAsMap['params']);
// Check that the message is well-formed. We do this after calling
// notificationController.add() so that we don't stall the test in the
// event of an error.
- expect(message, isNotification);
+ outOfTestExpect(message, isNotification);
}
});
_process.stderr
diff --git a/pkg/analysis_server/test/integration/protocol_matchers.dart b/pkg/analysis_server/test/integration/protocol_matchers.dart
index fef9ef3..7f2f3ab 100644
--- a/pkg/analysis_server/test/integration/protocol_matchers.dart
+++ b/pkg/analysis_server/test/integration/protocol_matchers.dart
@@ -11,7 +11,7 @@
*/
library test.integration.protocol.matchers;
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
import 'integration_tests.dart';
diff --git a/pkg/analysis_server/test/integration/search/get_type_hierarchy_test.dart b/pkg/analysis_server/test/integration/search/get_type_hierarchy_test.dart
index 5cd0820..bcfa73e 100644
--- a/pkg/analysis_server/test/integration/search/get_type_hierarchy_test.dart
+++ b/pkg/analysis_server/test/integration/search/get_type_hierarchy_test.dart
@@ -7,15 +7,15 @@
import 'dart:async';
import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../utils.dart';
import '../integration_tests.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(Test);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(Test);
+ });
}
/**
diff --git a/pkg/analysis_server/test/integration/search/test_all.dart b/pkg/analysis_server/test/integration/search/test_all.dart
index 7c58783..daeb6a4 100644
--- a/pkg/analysis_server/test/integration/search/test_all.dart
+++ b/pkg/analysis_server/test/integration/search/test_all.dart
@@ -4,17 +4,15 @@
library test.integration.search.all;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../utils.dart';
import 'get_type_hierarchy_test.dart' as get_type_hierarchy_test;
/**
* Utility for manually running all integration tests.
*/
main() {
- initializeTestEnvironment();
- group('search', () {
+ defineReflectiveSuite(() {
get_type_hierarchy_test.main();
- });
+ }, name: 'search');
}
diff --git a/pkg/analysis_server/test/integration/server/get_version_test.dart b/pkg/analysis_server/test/integration/server/get_version_test.dart
index d1ba458..223957b 100644
--- a/pkg/analysis_server/test/integration/server/get_version_test.dart
+++ b/pkg/analysis_server/test/integration/server/get_version_test.dart
@@ -6,12 +6,12 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../utils.dart';
import '../integration_tests.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(Test);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(Test);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/integration/server/set_subscriptions_invalid_service_test.dart b/pkg/analysis_server/test/integration/server/set_subscriptions_invalid_service_test.dart
index af778cf..2460ad9 100644
--- a/pkg/analysis_server/test/integration/server/set_subscriptions_invalid_service_test.dart
+++ b/pkg/analysis_server/test/integration/server/set_subscriptions_invalid_service_test.dart
@@ -4,15 +4,15 @@
library test.integration.server.set.subscriptions.invalid.service;
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../utils.dart';
import '../integration_tests.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(Test);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(Test);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/integration/server/set_subscriptions_test.dart b/pkg/analysis_server/test/integration/server/set_subscriptions_test.dart
index e649594..b88618c 100644
--- a/pkg/analysis_server/test/integration/server/set_subscriptions_test.dart
+++ b/pkg/analysis_server/test/integration/server/set_subscriptions_test.dart
@@ -7,15 +7,15 @@
import 'dart:async';
import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../utils.dart';
import '../integration_tests.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(Test);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(Test);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/integration/server/shutdown_test.dart b/pkg/analysis_server/test/integration/server/shutdown_test.dart
index 7ba89c7..c919d4e 100644
--- a/pkg/analysis_server/test/integration/server/shutdown_test.dart
+++ b/pkg/analysis_server/test/integration/server/shutdown_test.dart
@@ -6,15 +6,15 @@
import 'dart:async';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../utils.dart';
import '../integration_tests.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(Test);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(Test);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/integration/server/status_test.dart b/pkg/analysis_server/test/integration/server/status_test.dart
index 340a4b5..9222934 100644
--- a/pkg/analysis_server/test/integration/server/status_test.dart
+++ b/pkg/analysis_server/test/integration/server/status_test.dart
@@ -7,15 +7,15 @@
import 'dart:async';
import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../utils.dart';
import '../integration_tests.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(Test);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(Test);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/integration/server/test_all.dart b/pkg/analysis_server/test/integration/server/test_all.dart
index 2b81672..b2a8af0 100644
--- a/pkg/analysis_server/test/integration/server/test_all.dart
+++ b/pkg/analysis_server/test/integration/server/test_all.dart
@@ -4,9 +4,8 @@
library test.integration.server.all;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../utils.dart';
import 'get_version_test.dart' as get_version_test;
import 'set_subscriptions_invalid_service_test.dart'
as set_subscriptions_invalid_service_test;
@@ -18,12 +17,11 @@
* Utility for manually running all integration tests.
*/
main() {
- initializeTestEnvironment();
- group('server', () {
+ defineReflectiveSuite(() {
get_version_test.main();
set_subscriptions_test.main();
set_subscriptions_invalid_service_test.main();
shutdown_test.main();
status_test.main();
- });
+ }, name: 'server');
}
diff --git a/pkg/analysis_server/test/integration/test_all.dart b/pkg/analysis_server/test/integration/test_all.dart
index e217c92..3eda5bdf 100644
--- a/pkg/analysis_server/test/integration/test_all.dart
+++ b/pkg/analysis_server/test/integration/test_all.dart
@@ -4,9 +4,8 @@
library test.integration.all;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../utils.dart';
import 'analysis/test_all.dart' as analysis_test_all;
import 'completion/test_all.dart' as completion_test_all;
import 'search/test_all.dart' as search_test_all;
@@ -16,11 +15,10 @@
* Utility for manually running all integration tests.
*/
main() {
- initializeTestEnvironment();
- group('analysis_server_integration', () {
+ defineReflectiveSuite(() {
analysis_test_all.main();
completion_test_all.main();
search_test_all.main();
server_test_all.main();
- });
+ }, name: 'analysis_server_integration');
}
diff --git a/pkg/analysis_server/test/mock_sdk.dart b/pkg/analysis_server/test/mock_sdk.dart
index 94d1208..d3f44e0 100644
--- a/pkg/analysis_server/test/mock_sdk.dart
+++ b/pkg/analysis_server/test/mock_sdk.dart
@@ -397,4 +397,7 @@
bool get isVmLibrary => throw unimplemented;
UnimplementedError get unimplemented => new UnimplementedError();
+
+ @override
+ List<String> getPatches(int platform) => const <String>[];
}
diff --git a/pkg/analysis_server/test/mocks.dart b/pkg/analysis_server/test/mocks.dart
index 3d719e3..fa683a3 100644
--- a/pkg/analysis_server/test/mocks.dart
+++ b/pkg/analysis_server/test/mocks.dart
@@ -20,8 +20,8 @@
import 'package:analyzer/source/pub_package_map_provider.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:test/test.dart';
import 'package:typed_mock/typed_mock.dart';
-import 'package:unittest/unittest.dart';
/**
* Answer the absolute path the SDK relative to the currently running
diff --git a/pkg/analysis_server/test/operation/operation_queue_test.dart b/pkg/analysis_server/test/operation/operation_queue_test.dart
index e6926c9..e2f8484 100644
--- a/pkg/analysis_server/test/operation/operation_queue_test.dart
+++ b/pkg/analysis_server/test/operation/operation_queue_test.dart
@@ -13,16 +13,16 @@
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:typed_mock/typed_mock.dart';
-import 'package:unittest/unittest.dart';
import '../mocks.dart';
-import '../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(ServerOperationQueueTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ServerOperationQueueTest);
+ });
}
/**
diff --git a/pkg/analysis_server/test/operation/operation_test.dart b/pkg/analysis_server/test/operation/operation_test.dart
index 1972129..5161c16 100644
--- a/pkg/analysis_server/test/operation/operation_test.dart
+++ b/pkg/analysis_server/test/operation/operation_test.dart
@@ -5,13 +5,9 @@
library test.operation;
import 'package:analysis_server/src/operation/operation.dart';
-import 'package:unittest/unittest.dart';
-
-import '../utils.dart';
+import 'package:test/test.dart';
main() {
- initializeTestEnvironment();
-
group('ServerOperationPriority', () {
test('toString', () {
expect(ServerOperationPriority.ANALYSIS.toString(), 'ANALYSIS');
diff --git a/pkg/analysis_server/test/operation/test_all.dart b/pkg/analysis_server/test/operation/test_all.dart
index 4296f39..1b6f659 100644
--- a/pkg/analysis_server/test/operation/test_all.dart
+++ b/pkg/analysis_server/test/operation/test_all.dart
@@ -4,9 +4,8 @@
library test.operation.all;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../utils.dart';
import 'operation_queue_test.dart' as operation_queue_test;
import 'operation_test.dart' as operation_test;
@@ -14,9 +13,8 @@
* Utility for manually running all tests.
*/
main() {
- initializeTestEnvironment();
- group('operation', () {
+ defineReflectiveSuite(() {
operation_queue_test.main();
operation_test.main();
- });
+ }, name: 'operation');
}
diff --git a/pkg/analysis_server/test/plugin/protocol_dart_test.dart b/pkg/analysis_server/test/plugin/protocol_dart_test.dart
index ef2cd50..5f45220 100644
--- a/pkg/analysis_server/test/plugin/protocol_dart_test.dart
+++ b/pkg/analysis_server/test/plugin/protocol_dart_test.dart
@@ -15,16 +15,16 @@
import 'package:analyzer/src/dart/element/element.dart' as engine;
import 'package:analyzer/src/error/codes.dart' as engine;
import 'package:analyzer/src/generated/source.dart' as engine;
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../abstract_context.dart';
-import '../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(ElementTest);
- defineReflectiveTests(ElementKindTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ElementTest);
+ defineReflectiveTests(ElementKindTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/plugin/set_analysis_domain_test.dart b/pkg/analysis_server/test/plugin/set_analysis_domain_test.dart
index 36e1522..dc5c356 100644
--- a/pkg/analysis_server/test/plugin/set_analysis_domain_test.dart
+++ b/pkg/analysis_server/test/plugin/set_analysis_domain_test.dart
@@ -17,15 +17,15 @@
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/task/dart.dart';
import 'package:plugin/plugin.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../analysis_abstract.dart';
-import '../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(SetAnalysisDomainTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(SetAnalysisDomainTest);
+ });
}
/**
diff --git a/pkg/analysis_server/test/plugin/test_all.dart b/pkg/analysis_server/test/plugin/test_all.dart
index 5ad008b..385a8c7 100644
--- a/pkg/analysis_server/test/plugin/test_all.dart
+++ b/pkg/analysis_server/test/plugin/test_all.dart
@@ -3,9 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library test.plugin.analysis_contributor;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../utils.dart';
import 'protocol_dart_test.dart' as protocol_dart_test;
import 'set_analysis_domain_test.dart' as set_analysis_domain_test;
@@ -13,9 +12,8 @@
* Utility for manually running all tests.
*/
main() {
- initializeTestEnvironment();
- group('plugin', () {
+ defineReflectiveSuite(() {
protocol_dart_test.main();
set_analysis_domain_test.main();
- });
+ }, name: 'plugin');
}
diff --git a/pkg/analysis_server/test/protocol_server_test.dart b/pkg/analysis_server/test/protocol_server_test.dart
index bcbe18e..ba2b314 100644
--- a/pkg/analysis_server/test/protocol_server_test.dart
+++ b/pkg/analysis_server/test/protocol_server_test.dart
@@ -15,17 +15,17 @@
import 'package:analyzer/error/error.dart' as engine;
import 'package:analyzer/src/error/codes.dart' as engine;
import 'package:analyzer/src/generated/source.dart' as engine;
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:typed_mock/typed_mock.dart';
-import 'package:unittest/unittest.dart';
import 'mocks.dart';
-import 'utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(AnalysisErrorTest);
- defineReflectiveTests(EnumTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AnalysisErrorTest);
+ defineReflectiveTests(EnumTest);
+ });
}
class AnalysisErrorMock extends TypedMock implements engine.AnalysisError {}
diff --git a/pkg/analysis_server/test/protocol_test.dart b/pkg/analysis_server/test/protocol_test.dart
index 6428c62..ed3284a 100644
--- a/pkg/analysis_server/test/protocol_test.dart
+++ b/pkg/analysis_server/test/protocol_test.dart
@@ -9,17 +9,16 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/constants.dart';
import 'package:analysis_server/src/protocol/protocol_internal.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import 'utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(NotificationTest);
- defineReflectiveTests(RequestTest);
- defineReflectiveTests(RequestErrorTest);
- defineReflectiveTests(ResponseTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(NotificationTest);
+ defineReflectiveTests(RequestTest);
+ defineReflectiveTests(RequestErrorTest);
+ defineReflectiveTests(ResponseTest);
+ });
}
Matcher _throwsRequestFailure = throwsA(new isInstanceOf<RequestFailure>());
diff --git a/pkg/analysis_server/test/search/abstract_search_domain.dart b/pkg/analysis_server/test/search/abstract_search_domain.dart
index 9851d92..b59ac7d 100644
--- a/pkg/analysis_server/test/search/abstract_search_domain.dart
+++ b/pkg/analysis_server/test/search/abstract_search_domain.dart
@@ -11,7 +11,7 @@
import 'package:analysis_server/src/search/search_domain.dart';
import 'package:analysis_server/src/services/index/index.dart'
show Index, createMemoryIndex;
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
import '../analysis_abstract.dart';
diff --git a/pkg/analysis_server/test/search/element_references_test.dart b/pkg/analysis_server/test/search/element_references_test.dart
index cdd7e13..76aace1 100644
--- a/pkg/analysis_server/test/search/element_references_test.dart
+++ b/pkg/analysis_server/test/search/element_references_test.dart
@@ -8,16 +8,16 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/services/index/index.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../utils.dart';
import 'abstract_search_domain.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(ElementReferencesTest);
- defineReflectiveTests(_NoSearchEngine);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ElementReferencesTest);
+ defineReflectiveTests(_NoSearchEngine);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/search/member_declarations_test.dart b/pkg/analysis_server/test/search/member_declarations_test.dart
index 607e058..994f975 100644
--- a/pkg/analysis_server/test/search/member_declarations_test.dart
+++ b/pkg/analysis_server/test/search/member_declarations_test.dart
@@ -7,15 +7,15 @@
import 'dart:async';
import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../utils.dart';
import 'abstract_search_domain.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(MemberDeclarationsTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(MemberDeclarationsTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/search/member_references_test.dart b/pkg/analysis_server/test/search/member_references_test.dart
index 23ea1c7..cdc953f 100644
--- a/pkg/analysis_server/test/search/member_references_test.dart
+++ b/pkg/analysis_server/test/search/member_references_test.dart
@@ -7,15 +7,15 @@
import 'dart:async';
import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../utils.dart';
import 'abstract_search_domain.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(MemberReferencesTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(MemberReferencesTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/search/search_result_test.dart b/pkg/analysis_server/test/search/search_result_test.dart
index 2f3ef07..faa1dd1 100644
--- a/pkg/analysis_server/test/search/search_result_test.dart
+++ b/pkg/analysis_server/test/search/search_result_test.dart
@@ -6,14 +6,13 @@
import 'package:analysis_server/src/protocol_server.dart';
import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(SearchResultKindTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(SearchResultKindTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/search/test_all.dart b/pkg/analysis_server/test/search/test_all.dart
index fc5de31..e385ca6 100644
--- a/pkg/analysis_server/test/search/test_all.dart
+++ b/pkg/analysis_server/test/search/test_all.dart
@@ -3,9 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
library test.search;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../utils.dart';
import 'element_references_test.dart' as element_references_test;
import 'member_declarations_test.dart' as member_declarations;
import 'member_references_test.dart' as member_references_test;
@@ -17,13 +16,12 @@
* Utility for manually running all tests.
*/
main() {
- initializeTestEnvironment();
- group('search', () {
+ defineReflectiveSuite(() {
element_references_test.main();
member_declarations.main();
member_references_test.main();
search_result_test.main();
top_level_declarations_test.main();
type_hierarchy_test.main();
- });
+ }, name: 'search');
}
diff --git a/pkg/analysis_server/test/search/top_level_declarations_test.dart b/pkg/analysis_server/test/search/top_level_declarations_test.dart
index 8b1829c..16be988 100644
--- a/pkg/analysis_server/test/search/top_level_declarations_test.dart
+++ b/pkg/analysis_server/test/search/top_level_declarations_test.dart
@@ -7,15 +7,15 @@
import 'dart:async';
import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../utils.dart';
import 'abstract_search_domain.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(TopLevelDeclarationsTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(TopLevelDeclarationsTest);
+ });
}
@reflectiveTest
@@ -57,6 +57,11 @@
return null;
}
+ test_invalidRegex() async {
+ var result = await findTopLevelDeclarations('[A');
+ expect(result, new isInstanceOf<RequestError>());
+ }
+
test_startEndPattern() async {
addTestFile('''
class A {} // A
@@ -74,9 +79,4 @@
assertHasDeclaration(ElementKind.TOP_LEVEL_VARIABLE, 'E');
assertNoDeclaration(ElementKind.CLASS, 'ABC');
}
-
- test_invalidRegex() async {
- var result = await findTopLevelDeclarations('[A');
- expect(result, new isInstanceOf<RequestError>());
- }
}
diff --git a/pkg/analysis_server/test/search/type_hierarchy_test.dart b/pkg/analysis_server/test/search/type_hierarchy_test.dart
index c3efbbf..62402c8 100644
--- a/pkg/analysis_server/test/search/type_hierarchy_test.dart
+++ b/pkg/analysis_server/test/search/type_hierarchy_test.dart
@@ -9,15 +9,15 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/search/search_domain.dart';
import 'package:analysis_server/src/services/index/index.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../analysis_abstract.dart';
-import '../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(GetTypeHierarchyTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(GetTypeHierarchyTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/server_options_test.dart b/pkg/analysis_server/test/server_options_test.dart
index 4a32152..8561a23 100644
--- a/pkg/analysis_server/test/server_options_test.dart
+++ b/pkg/analysis_server/test/server_options_test.dart
@@ -8,18 +8,14 @@
library analysis_server.test.server_options;
import 'package:analysis_server/src/server_options.dart';
-import 'package:unittest/unittest.dart';
-
-import 'utils.dart';
+import 'package:test/test.dart';
void main() {
- initializeTestEnvironment();
-
group('server_options', () {
test('basic - []', () {
var options = new ServerOptions.fromContents('''# ignored
foo: bar
-baz: padded
+baz: ${"padded "}
''');
expect(options['foo'], equals('bar'));
expect(options['baz'], equals('padded'));
diff --git a/pkg/analysis_server/test/services/completion/completion_target_test.dart b/pkg/analysis_server/test/services/completion/completion_target_test.dart
index ce02343..e796abb 100644
--- a/pkg/analysis_server/test/services/completion/completion_target_test.dart
+++ b/pkg/analysis_server/test/services/completion/completion_target_test.dart
@@ -7,15 +7,15 @@
import 'package:analysis_server/src/provisional/completion/dart/completion_target.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../../abstract_context.dart';
-import '../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(CompletionTargetTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(CompletionTargetTest);
+ });
}
@reflectiveTest
@@ -45,6 +45,7 @@
reason: 'containingNode');
expect(target.argIndex, argIndex, reason: 'argIndex');
}
+
// Assert with parsed unit
assertCommon();
CompilationUnit unit =
diff --git a/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
index 44ddc2a..78a6f4e 100644
--- a/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/arglist_contributor_test.dart
@@ -7,15 +7,15 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/arglist_contributor.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../../utils.dart';
import 'completion_contributor_util.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(ArgListContributorTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ArgListContributorTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart
index 90856f7..7b4774c 100644
--- a/pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/combinator_contributor_test.dart
@@ -10,12 +10,12 @@
import 'package:analyzer/src/generated/source.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../../utils.dart';
import 'completion_contributor_util.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(CombinatorContributorTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(CombinatorContributorTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart b/pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart
index 498b3d1..8b5b681 100644
--- a/pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart
@@ -10,15 +10,15 @@
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/common_usage_sorter.dart';
import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../../../domain_completion_util.dart';
-import '../../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(CommonUsageSorterTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(CommonUsageSorterTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
index 0bf8a6d..c6982f3 100644
--- a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
+++ b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
@@ -20,7 +20,7 @@
import 'package:analysis_server/src/services/search/search_engine_internal.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/task/dart.dart';
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
import '../../../abstract_context.dart';
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart b/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart
index b678bd1..4d624b7 100644
--- a/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/completion_manager_test.dart
@@ -13,15 +13,15 @@
import 'package:analysis_server/src/services/completion/dart/imported_reference_contributor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/task/dart.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../../utils.dart';
import 'completion_contributor_util.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(CompletionManagerTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(CompletionManagerTest);
+ });
}
@reflectiveTest
@@ -91,6 +91,7 @@
fail('Failed to find $expectedUri in $importedNames');
});
}
+
void assertImportedLib(String expectedUri) {
ImportElement importElem = importNamed(expectedUri);
expect(importElem.importedLibrary.exportNamespace, isNotNull);
diff --git a/pkg/analysis_server/test/services/completion/dart/field_formal_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/field_formal_contributor_test.dart
index cc4d6f8..18da62c 100644
--- a/pkg/analysis_server/test/services/completion/dart/field_formal_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/field_formal_contributor_test.dart
@@ -6,15 +6,15 @@
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/field_formal_contributor.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../../utils.dart';
import 'completion_contributor_util.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(FieldFormalContributorTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(FieldFormalContributorTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
index 84b1781..7d3acd8 100644
--- a/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
@@ -12,16 +12,16 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../../../abstract_context.dart';
-import '../../../utils.dart';
import 'completion_contributor_util.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(ImportedReferenceContributorTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ImportedReferenceContributorTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/completion/dart/inherited_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/inherited_reference_contributor_test.dart
index 568d796..afed832 100644
--- a/pkg/analysis_server/test/services/completion/dart/inherited_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/inherited_reference_contributor_test.dart
@@ -7,15 +7,15 @@
import 'package:analysis_server/src/protocol_server.dart';
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/inherited_reference_contributor.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../../utils.dart';
import 'completion_contributor_util.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(InheritedContributorTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(InheritedContributorTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
index 2081aab..1667140 100644
--- a/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
@@ -8,15 +8,15 @@
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/keyword_contributor.dart';
import 'package:analyzer/dart/ast/token.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../../utils.dart';
import 'completion_contributor_util.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(KeywordContributorTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(KeywordContributorTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/completion/dart/label_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/label_contributor_test.dart
index 850389c..3968e24 100644
--- a/pkg/analysis_server/test/services/completion/dart/label_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/label_contributor_test.dart
@@ -11,15 +11,15 @@
import 'package:analysis_server/src/protocol_server.dart';
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/label_contributor.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../../utils.dart';
import 'completion_contributor_util.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(LabelContributorTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(LabelContributorTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart
index ddb0211..be8318e 100644
--- a/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/library_member_contributor_test.dart
@@ -6,15 +6,15 @@
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/library_member_contributor.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../../utils.dart';
import 'completion_contributor_util.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(LibraryMemberContributorTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(LibraryMemberContributorTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/completion/dart/library_prefix_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/library_prefix_contributor_test.dart
index 2de1f23..45d26da 100644
--- a/pkg/analysis_server/test/services/completion/dart/library_prefix_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/library_prefix_contributor_test.dart
@@ -7,15 +7,15 @@
import 'package:analysis_server/src/protocol_server.dart';
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/library_prefix_contributor.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../../utils.dart';
import 'completion_contributor_util.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(LibraryPrefixContributorTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(LibraryPrefixContributorTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/completion/dart/local_constructor_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_constructor_contributor_test.dart
index 0d1b13d..4977151 100644
--- a/pkg/analysis_server/test/services/completion/dart/local_constructor_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/local_constructor_contributor_test.dart
@@ -11,15 +11,15 @@
import 'package:analysis_server/src/protocol_server.dart';
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/local_constructor_contributor.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../../utils.dart';
import 'completion_contributor_util.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(LocalConstructorContributorTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(LocalConstructorContributorTest);
+ });
}
@reflectiveTest
@@ -2404,6 +2404,44 @@
expect(suggestion.hasNamedParameters, true);
}
+ test_InstanceCreationExpression_assignment_expression_filter() async {
+ addTestSource('''
+class A {} class B extends A {} class C implements A {} class D {}
+main() {
+ A a;
+ a = new ^
+}''');
+ await computeSuggestions();
+
+ assertSuggestConstructor('A',
+ elemOffset: -1,
+ relevance: DART_RELEVANCE_DEFAULT + DART_RELEVANCE_INCREMENT);
+ assertSuggestConstructor('B',
+ elemOffset: -1, relevance: DART_RELEVANCE_DEFAULT);
+ assertSuggestConstructor('C',
+ elemOffset: -1, relevance: DART_RELEVANCE_DEFAULT);
+ assertNotSuggested('D');
+ }
+
+ test_InstanceCreationExpression_assignment_expression_filter2() async {
+ addTestSource('''
+class A {} class B extends A {} class C implements A {} class D {}
+main() {
+ A a;
+ a = new ^;
+}''');
+ await computeSuggestions();
+
+ assertSuggestConstructor('A',
+ elemOffset: -1,
+ relevance: DART_RELEVANCE_DEFAULT + DART_RELEVANCE_INCREMENT);
+ assertSuggestConstructor('B',
+ elemOffset: -1, relevance: DART_RELEVANCE_DEFAULT);
+ assertSuggestConstructor('C',
+ elemOffset: -1, relevance: DART_RELEVANCE_DEFAULT);
+ assertNotSuggested('D');
+ }
+
test_InstanceCreationExpression_imported() async {
// SimpleIdentifier TypeName ConstructorName InstanceCreationExpression
addSource(
@@ -2485,44 +2523,6 @@
assertNotSuggested('D');
}
- test_InstanceCreationExpression_assignment_expression_filter() async {
- addTestSource('''
-class A {} class B extends A {} class C implements A {} class D {}
-main() {
- A a;
- a = new ^
-}''');
- await computeSuggestions();
-
- assertSuggestConstructor('A',
- elemOffset: -1,
- relevance: DART_RELEVANCE_DEFAULT + DART_RELEVANCE_INCREMENT);
- assertSuggestConstructor('B',
- elemOffset: -1, relevance: DART_RELEVANCE_DEFAULT);
- assertSuggestConstructor('C',
- elemOffset: -1, relevance: DART_RELEVANCE_DEFAULT);
- assertNotSuggested('D');
- }
-
- test_InstanceCreationExpression_assignment_expression_filter2() async {
- addTestSource('''
-class A {} class B extends A {} class C implements A {} class D {}
-main() {
- A a;
- a = new ^;
-}''');
- await computeSuggestions();
-
- assertSuggestConstructor('A',
- elemOffset: -1,
- relevance: DART_RELEVANCE_DEFAULT + DART_RELEVANCE_INCREMENT);
- assertSuggestConstructor('B',
- elemOffset: -1, relevance: DART_RELEVANCE_DEFAULT);
- assertSuggestConstructor('C',
- elemOffset: -1, relevance: DART_RELEVANCE_DEFAULT);
- assertNotSuggested('D');
- }
-
test_InterpolationExpression() async {
// SimpleIdentifier InterpolationExpression StringInterpolation
addSource(
diff --git a/pkg/analysis_server/test/services/completion/dart/local_declaration_visitor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_declaration_visitor_test.dart
index eff6ab6..fe3456d 100644
--- a/pkg/analysis_server/test/services/completion/dart/local_declaration_visitor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/local_declaration_visitor_test.dart
@@ -11,14 +11,13 @@
import 'package:analyzer/src/dart/scanner/reader.dart';
import 'package:analyzer/src/dart/scanner/scanner.dart';
import 'package:analyzer/src/generated/parser.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(LocalDeclarationVisitorTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(LocalDeclarationVisitorTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart
index 7851d49..b5758fd 100644
--- a/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart
@@ -6,15 +6,15 @@
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/local_library_contributor.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../../utils.dart';
import 'completion_contributor_util.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(LocalLibraryContributorTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(LocalLibraryContributorTest);
+ });
}
@reflectiveTest
@@ -102,7 +102,7 @@
assertNotSuggested('m');
}
- test_partFile_InstanceCreationExpression_variable_declaration_filter() async {
+ test_partFile_InstanceCreationExpression_assignment_filter() async {
// ConstructorName InstanceCreationExpression VariableDeclarationList
addSource(
'/testB.dart',
@@ -123,7 +123,9 @@
part "/testA.dart";
class Local { }
main() {
- A a = new ^
+ A a;
+ // FAIL:
+ a = new ^
}
var m;''');
await computeLibrariesContaining();
@@ -155,7 +157,7 @@
assertNotSuggested('m');
}
- test_partFile_InstanceCreationExpression_assignment_filter() async {
+ test_partFile_InstanceCreationExpression_variable_declaration_filter() async {
// ConstructorName InstanceCreationExpression VariableDeclarationList
addSource(
'/testB.dart',
@@ -176,9 +178,7 @@
part "/testA.dart";
class Local { }
main() {
- A a;
- // FAIL:
- a = new ^
+ A a = new ^
}
var m;''');
await computeLibrariesContaining();
diff --git a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
index 004e262..7e1cb94 100644
--- a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
@@ -11,15 +11,15 @@
import 'package:analysis_server/src/protocol_server.dart';
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/local_reference_contributor.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../../utils.dart';
import 'completion_contributor_util.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(LocalReferenceContributorTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(LocalReferenceContributorTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/completion/dart/named_constructor_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/named_constructor_contributor_test.dart
index b633efd..fd14593 100644
--- a/pkg/analysis_server/test/services/completion/dart/named_constructor_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/named_constructor_contributor_test.dart
@@ -8,15 +8,15 @@
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/named_constructor_contributor.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../../utils.dart';
import 'completion_contributor_util.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(NamedConstructorContributorTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(NamedConstructorContributorTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/completion/dart/optype_test.dart b/pkg/analysis_server/test/services/completion/dart/optype_test.dart
index 2fe206b..f285173 100644
--- a/pkg/analysis_server/test/services/completion/dart/optype_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/optype_test.dart
@@ -11,15 +11,15 @@
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:plugin/manager.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../../../abstract_context.dart';
-import '../../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(OpTypeTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(OpTypeTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart
index e219259..aa8fe6f 100644
--- a/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/override_contributor_test.dart
@@ -9,7 +9,7 @@
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/override_contributor.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
import 'completion_contributor_util.dart';
diff --git a/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart
index 878fbdb7..342dcc3 100644
--- a/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/static_member_contributor_test.dart
@@ -6,15 +6,15 @@
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/static_member_contributor.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../../utils.dart';
import 'completion_contributor_util.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(StaticMemberContributorTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(StaticMemberContributorTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/completion/dart/test_all.dart b/pkg/analysis_server/test/services/completion/dart/test_all.dart
index e9fb6c5..8fa0c51 100644
--- a/pkg/analysis_server/test/services/completion/dart/test_all.dart
+++ b/pkg/analysis_server/test/services/completion/dart/test_all.dart
@@ -4,9 +4,8 @@
library test.services.completion.dart;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../../utils.dart';
import 'arglist_contributor_test.dart' as arglist_test;
import 'combinator_contributor_test.dart' as combinator_test;
import 'common_usage_sorter_test.dart' as common_usage_test;
@@ -32,8 +31,7 @@
/// Utility for manually running all tests.
main() {
- initializeTestEnvironment();
- group('dart/completion', () {
+ defineReflectiveSuite(() {
arglist_test.main();
combinator_test.main();
common_usage_test.main();
@@ -56,5 +54,5 @@
type_member_contributor_test.main();
uri_contributor_test.main();
variable_name_contributor_test.main();
- });
+ }, name: 'dart');
}
diff --git a/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart
index b3dfba3..1915011 100644
--- a/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/type_member_contributor_test.dart
@@ -9,15 +9,15 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/type_member_contributor.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../../utils.dart';
import 'completion_contributor_util.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(TypeMemberContributorTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(TypeMemberContributorTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart
index 99cfd29..705b0e3 100644
--- a/pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/uri_contributor_test.dart
@@ -9,16 +9,16 @@
import 'package:analysis_server/src/services/completion/dart/uri_contributor.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:path/path.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../../utils.dart';
import 'completion_contributor_util.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(UriContributorTest);
- defineReflectiveTests(UriContributorWindowsTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(UriContributorTest);
+ defineReflectiveTests(UriContributorWindowsTest);
+ });
}
@reflectiveTest
@@ -267,6 +267,16 @@
csKind: CompletionSuggestionKind.IMPORT);
}
+ test_import_package2_raw() async {
+ addPackageSource('foo', 'foo.dart', 'library foo;');
+ addPackageSource('foo', 'baz/too.dart', 'library too;');
+ addPackageSource('bar', 'bar.dart', 'library bar;');
+ addTestSource('import r"package:foo/baz/^" import');
+ await computeSuggestions();
+ assertSuggest('package:foo/baz/too.dart',
+ csKind: CompletionSuggestionKind.IMPORT);
+ }
+
test_import_package2_with_trailing() async {
addPackageSource('foo', 'foo.dart', 'library foo;');
addPackageSource('foo', 'baz/too.dart', 'library too;');
@@ -279,16 +289,6 @@
expect(replacementLength, 5 + 16);
}
- test_import_package2_raw() async {
- addPackageSource('foo', 'foo.dart', 'library foo;');
- addPackageSource('foo', 'baz/too.dart', 'library too;');
- addPackageSource('bar', 'bar.dart', 'library bar;');
- addTestSource('import r"package:foo/baz/^" import');
- await computeSuggestions();
- assertSuggest('package:foo/baz/too.dart',
- csKind: CompletionSuggestionKind.IMPORT);
- }
-
test_import_package_missing_lib() async {
var pkgSrc = addPackageSource('bar', 'bar.dart', 'library bar;');
provider.deleteFolder(dirname(pkgSrc.fullName));
diff --git a/pkg/analysis_server/test/services/completion/dart/variable_name_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/variable_name_contributor_test.dart
index 6896850..a5c4446 100644
--- a/pkg/analysis_server/test/services/completion/dart/variable_name_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/variable_name_contributor_test.dart
@@ -6,15 +6,15 @@
import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
import 'package:analysis_server/src/services/completion/dart/variable_name_contributor.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../../utils.dart';
import 'completion_contributor_util.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(VariableNameContributorTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(VariableNameContributorTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/completion/test_all.dart b/pkg/analysis_server/test/services/completion/test_all.dart
index f219dda..fed3fef 100644
--- a/pkg/analysis_server/test/services/completion/test_all.dart
+++ b/pkg/analysis_server/test/services/completion/test_all.dart
@@ -4,17 +4,15 @@
library test.services.completion;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../utils.dart';
import 'completion_target_test.dart' as completion_target_test;
import 'dart/test_all.dart' as dart_contributor_tests;
/// Utility for manually running all tests.
main() {
- initializeTestEnvironment();
- group('completion', () {
+ defineReflectiveSuite(() {
completion_target_test.main();
dart_contributor_tests.main();
- });
+ }, name: 'completion');
}
diff --git a/pkg/analysis_server/test/services/correction/assist_test.dart b/pkg/analysis_server/test/services/correction/assist_test.dart
index 4188664..a2abeee 100644
--- a/pkg/analysis_server/test/services/correction/assist_test.dart
+++ b/pkg/analysis_server/test/services/correction/assist_test.dart
@@ -14,15 +14,15 @@
import 'package:analyzer/src/generated/source.dart';
import 'package:plugin/manager.dart';
import 'package:plugin/plugin.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../../abstract_single_unit.dart';
-import '../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(AssistProcessorTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AssistProcessorTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/correction/change_test.dart b/pkg/analysis_server/test/services/correction/change_test.dart
index 0cc92b4..67b7d51 100644
--- a/pkg/analysis_server/test/services/correction/change_test.dart
+++ b/pkg/analysis_server/test/services/correction/change_test.dart
@@ -7,19 +7,18 @@
import 'package:analysis_server/src/constants.dart';
import 'package:analysis_server/src/protocol_server.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(ChangeTest);
- defineReflectiveTests(EditTest);
- defineReflectiveTests(FileEditTest);
- defineReflectiveTests(LinkedEditGroupTest);
- defineReflectiveTests(LinkedEditSuggestionTest);
- defineReflectiveTests(PositionTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ChangeTest);
+ defineReflectiveTests(EditTest);
+ defineReflectiveTests(FileEditTest);
+ defineReflectiveTests(LinkedEditGroupTest);
+ defineReflectiveTests(LinkedEditSuggestionTest);
+ defineReflectiveTests(PositionTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/correction/fix_test.dart b/pkg/analysis_server/test/services/correction/fix_test.dart
index c7ed0bb..dbfb129 100644
--- a/pkg/analysis_server/test/services/correction/fix_test.dart
+++ b/pkg/analysis_server/test/services/correction/fix_test.dart
@@ -18,17 +18,17 @@
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/parser.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../../abstract_context.dart';
import '../../abstract_single_unit.dart';
-import '../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(FixProcessorTest);
- defineReflectiveTests(LintFixTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(FixProcessorTest);
+ defineReflectiveTests(LintFixTest);
+ });
}
typedef bool AnalysisErrorFilter(AnalysisError error);
@@ -5273,10 +5273,10 @@
resultCode = SourceEdit.applySequence(testCode, change.edits[0].edits);
}
- void findLint(String src, String lintCode) {
+ void findLint(String src, String lintCode, {int length: 1}) {
int errorOffset = src.indexOf('/*LINT*/');
resolveTestUnit(src.replaceAll('/*LINT*/', ''));
- error = new AnalysisError(testUnit.element.source, errorOffset, 1,
+ error = new AnalysisError(testUnit.element.source, errorOffset, length,
new LintCode(lintCode, '<ignored>'));
}
@@ -5462,6 +5462,23 @@
''');
}
+ test_lint_removeInterpolationBraces() async {
+ String src = r'''
+main() {
+ var v = 42;
+ print('v: /*LINT*/${ v}');
+}
+''';
+ findLint(src, LintNames.unnecessary_brace_in_string_interp, length: 4);
+ await applyFix(DartFixKind.LINT_REMOVE_INTERPOLATION_BRACES);
+ verifyResult(r'''
+main() {
+ var v = 42;
+ print('v: $v');
+}
+''');
+ }
+
void verifyResult(String expectedResult) {
expect(resultCode, expectedResult);
}
diff --git a/pkg/analysis_server/test/services/correction/levenshtein_test.dart b/pkg/analysis_server/test/services/correction/levenshtein_test.dart
index a1b0a92..956199a 100644
--- a/pkg/analysis_server/test/services/correction/levenshtein_test.dart
+++ b/pkg/analysis_server/test/services/correction/levenshtein_test.dart
@@ -5,14 +5,13 @@
library test.services.correction.levenshtein;
import 'package:analysis_server/src/services/correction/levenshtein.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(LevenshteinTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(LevenshteinTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/correction/name_suggestion_test.dart b/pkg/analysis_server/test/services/correction/name_suggestion_test.dart
index 76b7409..fdd914e 100644
--- a/pkg/analysis_server/test/services/correction/name_suggestion_test.dart
+++ b/pkg/analysis_server/test/services/correction/name_suggestion_test.dart
@@ -8,15 +8,15 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../../abstract_single_unit.dart';
-import '../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(VariableNameSuggestionTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(VariableNameSuggestionTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/correction/organize_directives_test.dart b/pkg/analysis_server/test/services/correction/organize_directives_test.dart
index dc03bce..503ad05 100644
--- a/pkg/analysis_server/test/services/correction/organize_directives_test.dart
+++ b/pkg/analysis_server/test/services/correction/organize_directives_test.dart
@@ -8,15 +8,15 @@
hide AnalysisError;
import 'package:analysis_server/src/services/correction/organize_directives.dart';
import 'package:analyzer/error/error.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../../abstract_single_unit.dart';
-import '../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(OrganizeDirectivesTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(OrganizeDirectivesTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/correction/sort_members_test.dart b/pkg/analysis_server/test/services/correction/sort_members_test.dart
index d3f6950..b60164f 100644
--- a/pkg/analysis_server/test/services/correction/sort_members_test.dart
+++ b/pkg/analysis_server/test/services/correction/sort_members_test.dart
@@ -6,15 +6,15 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/services/correction/sort_members.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../../abstract_single_unit.dart';
-import '../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(SortMembersTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(SortMembersTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/correction/source_range_test.dart b/pkg/analysis_server/test/services/correction/source_range_test.dart
index 6824519..28779ac 100644
--- a/pkg/analysis_server/test/services/correction/source_range_test.dart
+++ b/pkg/analysis_server/test/services/correction/source_range_test.dart
@@ -10,15 +10,15 @@
import 'package:analyzer/error/error.dart';
import 'package:analyzer/src/generated/parser.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../../abstract_single_unit.dart';
-import '../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(SourceRangesTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(SourceRangesTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/correction/status_test.dart b/pkg/analysis_server/test/services/correction/status_test.dart
index 0de1517..9e60de9 100644
--- a/pkg/analysis_server/test/services/correction/status_test.dart
+++ b/pkg/analysis_server/test/services/correction/status_test.dart
@@ -11,16 +11,16 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../../abstract_single_unit.dart';
-import '../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(RefactoringLocationTest);
- defineReflectiveTests(RefactoringStatusTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(RefactoringLocationTest);
+ defineReflectiveTests(RefactoringStatusTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/correction/strings_test.dart b/pkg/analysis_server/test/services/correction/strings_test.dart
index a5b4779..3f44c7c 100644
--- a/pkg/analysis_server/test/services/correction/strings_test.dart
+++ b/pkg/analysis_server/test/services/correction/strings_test.dart
@@ -5,14 +5,13 @@
library test.services.correction.strings;
import 'package:analysis_server/src/services/correction/strings.dart';
+import 'package:test/test.dart' hide isEmpty;
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart' hide isEmpty;
-
-import '../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(StringsTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(StringsTest);
+ });
}
@reflectiveTest
@@ -43,6 +42,7 @@
oldStr.substring(diff.offset + diff.length);
expect(applied, newStr);
}
+
assertDiff('', '');
assertDiff('', 'a');
assertDiff('abc', '');
diff --git a/pkg/analysis_server/test/services/correction/test_all.dart b/pkg/analysis_server/test/services/correction/test_all.dart
index f00f310..09eee7b 100644
--- a/pkg/analysis_server/test/services/correction/test_all.dart
+++ b/pkg/analysis_server/test/services/correction/test_all.dart
@@ -4,9 +4,8 @@
library test.services.correction;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../utils.dart';
import 'assist_test.dart' as assist_test;
import 'change_test.dart' as change_test;
import 'fix_test.dart' as fix_test;
@@ -21,8 +20,7 @@
/// Utility for manually running all tests.
main() {
- initializeTestEnvironment();
- group('correction', () {
+ defineReflectiveSuite(() {
assist_test.main();
change_test.main();
fix_test.main();
@@ -34,5 +32,5 @@
status_test.main();
strings_test.main();
util_test.main();
- });
+ }, name: 'correction');
}
diff --git a/pkg/analysis_server/test/services/correction/util_test.dart b/pkg/analysis_server/test/services/correction/util_test.dart
index a435b1c..2eb68bb 100644
--- a/pkg/analysis_server/test/services/correction/util_test.dart
+++ b/pkg/analysis_server/test/services/correction/util_test.dart
@@ -9,15 +9,15 @@
import 'package:analysis_server/src/services/correction/util.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../../abstract_single_unit.dart';
-import '../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(UtilTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(UtilTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/dependencies/library_dependencies_test.dart b/pkg/analysis_server/test/services/dependencies/library_dependencies_test.dart
index 2c1b7b9..5a58a4e 100644
--- a/pkg/analysis_server/test/services/dependencies/library_dependencies_test.dart
+++ b/pkg/analysis_server/test/services/dependencies/library_dependencies_test.dart
@@ -5,15 +5,15 @@
library test.services.dependencies.library;
import 'package:analysis_server/src/services/dependencies/library_dependencies.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../../abstract_context.dart';
-import '../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(LibraryDependenciesTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(LibraryDependenciesTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/dependencies/reachable_source_collector_test.dart b/pkg/analysis_server/test/services/dependencies/reachable_source_collector_test.dart
index 89369cd..23eaf32 100644
--- a/pkg/analysis_server/test/services/dependencies/reachable_source_collector_test.dart
+++ b/pkg/analysis_server/test/services/dependencies/reachable_source_collector_test.dart
@@ -7,15 +7,15 @@
import 'package:analysis_server/src/services/dependencies/reachable_source_collector.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../../abstract_context.dart';
-import '../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(ReachableSourceCollectorTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ReachableSourceCollectorTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/dependencies/test_all.dart b/pkg/analysis_server/test/services/dependencies/test_all.dart
index b26ac82..fe5c16f 100644
--- a/pkg/analysis_server/test/services/dependencies/test_all.dart
+++ b/pkg/analysis_server/test/services/dependencies/test_all.dart
@@ -4,17 +4,15 @@
library test.services.dependencies;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../utils.dart';
import 'library_dependencies_test.dart' as library_dependencies;
import 'reachable_source_collector_test.dart' as reachable_source_collector;
/// Utility for manually running all tests.
main() {
- initializeTestEnvironment();
- group('dependencies', () {
+ defineReflectiveSuite(() {
library_dependencies.main();
reachable_source_collector.main();
- });
+ }, name: 'dependencies');
}
diff --git a/pkg/analysis_server/test/services/index/index_test.dart b/pkg/analysis_server/test/services/index/index_test.dart
index 5a1f093..2d78865 100644
--- a/pkg/analysis_server/test/services/index/index_test.dart
+++ b/pkg/analysis_server/test/services/index/index_test.dart
@@ -7,16 +7,16 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/summary/idl.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:typed_mock/typed_mock.dart';
-import 'package:unittest/unittest.dart';
import '../../abstract_single_unit.dart';
-import '../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(IndexTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(IndexTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/index/index_unit_test.dart b/pkg/analysis_server/test/services/index/index_unit_test.dart
index 87388fd..046bdfa 100644
--- a/pkg/analysis_server/test/services/index/index_unit_test.dart
+++ b/pkg/analysis_server/test/services/index/index_unit_test.dart
@@ -9,14 +9,15 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../../abstract_single_unit.dart';
main() {
- groupSep = ' | ';
- defineReflectiveTests(PackageIndexAssemblerTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(PackageIndexAssemblerTest);
+ });
}
class ExpectedLocation {
diff --git a/pkg/analysis_server/test/services/index/test_all.dart b/pkg/analysis_server/test/services/index/test_all.dart
index 5c45ec5..18799f5 100644
--- a/pkg/analysis_server/test/services/index/test_all.dart
+++ b/pkg/analysis_server/test/services/index/test_all.dart
@@ -2,9 +2,8 @@
// 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:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../utils.dart';
import 'index_test.dart' as index_test;
import 'index_unit_test.dart' as index_unit_test;
@@ -12,9 +11,8 @@
* Utility for manually running all tests.
*/
main() {
- initializeTestEnvironment();
- group('index', () {
+ defineReflectiveSuite(() {
index_test.main();
index_unit_test.main();
- });
+ }, name: 'index');
}
diff --git a/pkg/analysis_server/test/services/linter/linter_test.dart b/pkg/analysis_server/test/services/linter/linter_test.dart
index 1017bd6..5ac13392 100644
--- a/pkg/analysis_server/test/services/linter/linter_test.dart
+++ b/pkg/analysis_server/test/services/linter/linter_test.dart
@@ -9,14 +9,13 @@
import 'package:analyzer/source/analysis_options_provider.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(LinterRuleOptionsValidatorTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(LinterRuleOptionsValidatorTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/refactoring/abstract_refactoring.dart b/pkg/analysis_server/test/services/refactoring/abstract_refactoring.dart
index a565c87..2ee99d1 100644
--- a/pkg/analysis_server/test/services/refactoring/abstract_refactoring.dart
+++ b/pkg/analysis_server/test/services/refactoring/abstract_refactoring.dart
@@ -14,7 +14,7 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/generated/source.dart';
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
import '../../abstract_single_unit.dart';
diff --git a/pkg/analysis_server/test/services/refactoring/abstract_rename.dart b/pkg/analysis_server/test/services/refactoring/abstract_rename.dart
index e6238e3..0c89003 100644
--- a/pkg/analysis_server/test/services/refactoring/abstract_rename.dart
+++ b/pkg/analysis_server/test/services/refactoring/abstract_rename.dart
@@ -9,7 +9,7 @@
import 'package:analysis_server/src/services/refactoring/refactoring.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
import 'abstract_refactoring.dart';
diff --git a/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart b/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart
index 4a62450..9b74f44 100644
--- a/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/convert_getter_to_method_test.dart
@@ -12,12 +12,12 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../utils.dart';
import 'abstract_refactoring.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(ConvertGetterToMethodTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConvertGetterToMethodTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/refactoring/convert_method_to_getter_test.dart b/pkg/analysis_server/test/services/refactoring/convert_method_to_getter_test.dart
index 5dca20d..accf182 100644
--- a/pkg/analysis_server/test/services/refactoring/convert_method_to_getter_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/convert_method_to_getter_test.dart
@@ -12,12 +12,12 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../utils.dart';
import 'abstract_refactoring.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(ConvertMethodToGetterTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConvertMethodToGetterTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/refactoring/extract_local_test.dart b/pkg/analysis_server/test/services/refactoring/extract_local_test.dart
index c35969f..976e77d 100644
--- a/pkg/analysis_server/test/services/refactoring/extract_local_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/extract_local_test.dart
@@ -11,15 +11,15 @@
import 'package:analysis_server/src/services/correction/status.dart';
import 'package:analysis_server/src/services/refactoring/extract_local.dart';
import 'package:analysis_server/src/services/refactoring/refactoring.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../utils.dart';
import 'abstract_refactoring.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(ExtractLocalTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ExtractLocalTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/refactoring/extract_method_test.dart b/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
index 2a5e7e4..6154170 100644
--- a/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
@@ -10,15 +10,15 @@
import 'package:analysis_server/src/services/correction/status.dart';
import 'package:analysis_server/src/services/refactoring/extract_method.dart';
import 'package:analysis_server/src/services/refactoring/refactoring.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../utils.dart';
import 'abstract_refactoring.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(ExtractMethodTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ExtractMethodTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/refactoring/inline_local_test.dart b/pkg/analysis_server/test/services/refactoring/inline_local_test.dart
index 37f46cd..e3ccaa1 100644
--- a/pkg/analysis_server/test/services/refactoring/inline_local_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/inline_local_test.dart
@@ -8,15 +8,15 @@
import 'package:analysis_server/src/services/correction/status.dart';
import 'package:analysis_server/src/services/refactoring/inline_local.dart';
import 'package:analysis_server/src/services/refactoring/refactoring.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../utils.dart';
import 'abstract_refactoring.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(InlineLocalTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(InlineLocalTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/refactoring/inline_method_test.dart b/pkg/analysis_server/test/services/refactoring/inline_method_test.dart
index 3433f1e..7c35f5e 100644
--- a/pkg/analysis_server/test/services/refactoring/inline_method_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/inline_method_test.dart
@@ -11,15 +11,15 @@
import 'package:analysis_server/src/services/refactoring/inline_method.dart';
import 'package:analysis_server/src/services/refactoring/refactoring.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../utils.dart';
import 'abstract_refactoring.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(InlineMethodTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(InlineMethodTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/refactoring/move_file_test.dart b/pkg/analysis_server/test/services/refactoring/move_file_test.dart
index df2e422..c0cecec 100644
--- a/pkg/analysis_server/test/services/refactoring/move_file_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/move_file_test.dart
@@ -14,12 +14,12 @@
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../../abstract_context.dart';
-import '../../utils.dart';
import 'abstract_refactoring.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(MoveFileTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(MoveFileTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/refactoring/naming_conventions_test.dart b/pkg/analysis_server/test/services/refactoring/naming_conventions_test.dart
index 7b9ead8..04afda2 100644
--- a/pkg/analysis_server/test/services/refactoring/naming_conventions_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/naming_conventions_test.dart
@@ -10,12 +10,12 @@
import 'package:analysis_server/src/services/refactoring/refactoring.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../utils.dart';
import 'abstract_refactoring.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(NamingConventionsTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(NamingConventionsTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart b/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart
index d35c631..e65a6e0 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_class_member_test.dart
@@ -7,15 +7,15 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/services/correction/status.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../utils.dart';
import 'abstract_rename.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(RenameClassMemberTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(RenameClassMemberTest);
+ });
}
@reflectiveTest
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 f10a11d..afc7782 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_constructor_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_constructor_test.dart
@@ -9,53 +9,19 @@
import 'package:analysis_server/src/services/refactoring/refactoring.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../utils.dart';
import 'abstract_rename.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(RenameConstructorTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(RenameConstructorTest);
+ });
}
@reflectiveTest
class RenameConstructorTest extends RenameRefactoringTest {
- test_checkFinalConditions_hasMember_constructor() async {
- indexTestUnit('''
-class A {
- A.test() {}
- A.newName() {} // existing
-}
-''');
- _createConstructorDeclarationRefactoring('test() {}');
- // check status
- refactoring.newName = 'newName';
- RefactoringStatus status = await refactoring.checkFinalConditions();
- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR,
- expectedMessage:
- "Class 'A' already declares constructor with name 'newName'.",
- expectedContextSearch: 'newName() {} // existing');
- }
-
- test_checkFinalConditions_hasMember_method() async {
- indexTestUnit('''
-class A {
- A.test() {}
- newName() {} // existing
-}
-''');
- _createConstructorDeclarationRefactoring('test() {}');
- // check status
- refactoring.newName = 'newName';
- RefactoringStatus status = await refactoring.checkFinalConditions();
- assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR,
- expectedMessage:
- "Class 'A' already declares method with name 'newName'.",
- expectedContextSearch: 'newName() {} // existing');
- }
-
test_checkInitialConditions_inSDK() async {
indexTestUnit('''
main() {
@@ -98,6 +64,40 @@
assertRefactoringStatusOK(refactoring.checkNewName());
}
+ test_checkNewName_hasMember_constructor() async {
+ indexTestUnit('''
+class A {
+ A.test() {}
+ A.newName() {} // existing
+}
+''');
+ _createConstructorDeclarationRefactoring('test() {}');
+ // check status
+ refactoring.newName = 'newName';
+ RefactoringStatus status = refactoring.checkNewName();
+ assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR,
+ expectedMessage:
+ "Class 'A' already declares constructor with name 'newName'.",
+ expectedContextSearch: 'newName() {} // existing');
+ }
+
+ test_checkNewName_hasMember_method() async {
+ indexTestUnit('''
+class A {
+ A.test() {}
+ newName() {} // existing
+}
+''');
+ _createConstructorDeclarationRefactoring('test() {}');
+ // check status
+ refactoring.newName = 'newName';
+ RefactoringStatus status = refactoring.checkNewName();
+ assertRefactoringStatus(status, RefactoringProblemSeverity.ERROR,
+ expectedMessage:
+ "Class 'A' already declares method with name 'newName'.",
+ expectedContextSearch: 'newName() {} // existing');
+ }
+
test_createChange_add() {
indexTestUnit('''
class A {
diff --git a/pkg/analysis_server/test/services/refactoring/rename_import_test.dart b/pkg/analysis_server/test/services/refactoring/rename_import_test.dart
index 8d061ed..f2df10b 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_import_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_import_test.dart
@@ -6,15 +6,15 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analyzer/dart/ast/ast.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../utils.dart';
import 'abstract_rename.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(RenameImportTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(RenameImportTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/refactoring/rename_label_test.dart b/pkg/analysis_server/test/services/refactoring/rename_label_test.dart
index 613a0d6..c1e995f 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_label_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_label_test.dart
@@ -5,15 +5,15 @@
library test.services.refactoring.rename_label;
import 'package:analysis_server/plugin/protocol/protocol.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../utils.dart';
import 'abstract_rename.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(RenameLabelTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(RenameLabelTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/refactoring/rename_library_test.dart b/pkg/analysis_server/test/services/refactoring/rename_library_test.dart
index 597df6e..fd58cc2 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_library_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_library_test.dart
@@ -6,15 +6,15 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../utils.dart';
import 'abstract_rename.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(RenameLibraryTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(RenameLibraryTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/refactoring/rename_local_test.dart b/pkg/analysis_server/test/services/refactoring/rename_local_test.dart
index e454ece..7cc5811 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_local_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_local_test.dart
@@ -6,15 +6,15 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/services/correction/status.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../utils.dart';
import 'abstract_rename.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(RenameLocalTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(RenameLocalTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/refactoring/rename_unit_member_test.dart b/pkg/analysis_server/test/services/refactoring/rename_unit_member_test.dart
index 3715ced..1ce560d 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_unit_member_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_unit_member_test.dart
@@ -6,15 +6,15 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/services/correction/status.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../utils.dart';
import 'abstract_rename.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(RenameUnitMemberTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(RenameUnitMemberTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/refactoring/test_all.dart b/pkg/analysis_server/test/services/refactoring/test_all.dart
index 1dcb857..903c2f4 100644
--- a/pkg/analysis_server/test/services/refactoring/test_all.dart
+++ b/pkg/analysis_server/test/services/refactoring/test_all.dart
@@ -4,9 +4,8 @@
library test.services.refactoring;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../utils.dart';
import 'convert_getter_to_method_test.dart' as convert_getter_to_method_test;
import 'convert_method_to_getter_test.dart' as convert_method_to_getter_test;
import 'extract_local_test.dart' as extract_local_test;
@@ -25,8 +24,7 @@
/// Utility for manually running all tests.
main() {
- initializeTestEnvironment();
- group('refactoring', () {
+ defineReflectiveSuite(() {
convert_getter_to_method_test.main();
convert_method_to_getter_test.main();
extract_local_test.main();
@@ -42,5 +40,5 @@
rename_library_test.main();
rename_local_test.main();
rename_unit_member_test.main();
- });
+ }, name: 'refactoring');
}
diff --git a/pkg/analysis_server/test/services/search/hierarchy_test.dart b/pkg/analysis_server/test/services/search/hierarchy_test.dart
index 802f351..618b868 100644
--- a/pkg/analysis_server/test/services/search/hierarchy_test.dart
+++ b/pkg/analysis_server/test/services/search/hierarchy_test.dart
@@ -10,15 +10,15 @@
import 'package:analysis_server/src/services/search/hierarchy.dart';
import 'package:analysis_server/src/services/search/search_engine_internal.dart';
import 'package:analyzer/dart/element/element.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../../abstract_single_unit.dart';
-import '../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(HierarchyTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(HierarchyTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/services/search/search_engine_test.dart b/pkg/analysis_server/test/services/search/search_engine_test.dart
index 7a9db13..8072301 100644
--- a/pkg/analysis_server/test/services/search/search_engine_test.dart
+++ b/pkg/analysis_server/test/services/search/search_engine_test.dart
@@ -13,15 +13,15 @@
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/member.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../../abstract_single_unit.dart';
-import '../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(SearchEngineImplTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(SearchEngineImplTest);
+ });
}
class ExpectedMatch {
@@ -617,6 +617,23 @@
await _verifyReferences(method, expected);
}
+ test_searchReferences_null_noUnitElement() async {
+ _indexTestUnit('''
+class A {
+ m() {}
+}
+main(A a) {
+ a.m();
+}
+''');
+ MethodElement method = findElement('m');
+ List<SearchMatch> matches = await searchEngine.searchReferences(method);
+ expect(matches, hasLength(1));
+ // Set the source contents, so the element is invalidated.
+ context.setContents(testSource, '');
+ expect(matches.single.element, isNull);
+ }
+
test_searchReferences_ParameterElement_ofConstructor() async {
_indexTestUnit('''
class C {
diff --git a/pkg/analysis_server/test/services/search/test_all.dart b/pkg/analysis_server/test/services/search/test_all.dart
index 187d3f3..39251a5 100644
--- a/pkg/analysis_server/test/services/search/test_all.dart
+++ b/pkg/analysis_server/test/services/search/test_all.dart
@@ -4,9 +4,8 @@
library test.services.src.search.all;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../utils.dart';
import 'hierarchy_test.dart' as hierarchy_test;
import 'search_engine_test.dart' as search_engine_test;
@@ -14,9 +13,8 @@
* Utility for manually running all tests.
*/
main() {
- initializeTestEnvironment();
- group('search', () {
+ defineReflectiveSuite(() {
hierarchy_test.main();
search_engine_test.main();
- });
+ }, name: 'search');
}
diff --git a/pkg/analysis_server/test/services/test_all.dart b/pkg/analysis_server/test/services/test_all.dart
index e0c2086..5ee80ac 100644
--- a/pkg/analysis_server/test/services/test_all.dart
+++ b/pkg/analysis_server/test/services/test_all.dart
@@ -4,7 +4,8 @@
library test.services;
-import '../utils.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
import 'completion/test_all.dart' as completion_all;
import 'correction/test_all.dart' as correction_all;
import 'dependencies/test_all.dart' as dependencies_all;
@@ -15,12 +16,13 @@
/// Utility for manually running all tests.
main() {
- initializeTestEnvironment();
- completion_all.main();
- correction_all.main();
- dependencies_all.main();
- index_all.main();
- linter_all.main();
- refactoring_all.main();
- search_all.main();
+ defineReflectiveSuite(() {
+ completion_all.main();
+ correction_all.main();
+ dependencies_all.main();
+ index_all.main();
+ linter_all.main();
+ refactoring_all.main();
+ search_all.main();
+ });
}
diff --git a/pkg/analysis_server/test/single_context_manager_test.dart b/pkg/analysis_server/test/single_context_manager_test.dart
index 62376bf..97b4ec6 100644
--- a/pkg/analysis_server/test/single_context_manager_test.dart
+++ b/pkg/analysis_server/test/single_context_manager_test.dart
@@ -17,17 +17,16 @@
import 'package:path/path.dart';
import 'package:plugin/manager.dart';
import 'package:plugin/plugin.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import 'context_manager_test.dart' show TestContextManagerCallbacks;
-import 'mock_sdk.dart';
import 'mocks.dart';
-import 'utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(SingleContextManagerTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(SingleContextManagerTest);
+ });
}
@reflectiveTest
@@ -64,8 +63,7 @@
packageResolver = new TestUriResolver();
_processRequiredPlugins();
- DartSdkManager sdkManager =
- new DartSdkManager('', false, (_) => new MockSdk());
+ DartSdkManager sdkManager = new DartSdkManager('', false);
manager = new SingleContextManager(resourceProvider, sdkManager,
(_) => packageResolver, analysisFilesGlobs, new AnalysisOptionsImpl());
callbacks = new TestContextManagerCallbacks(resourceProvider);
@@ -74,12 +72,14 @@
void test_isIgnored_false() {
String project = '/project';
+ resourceProvider.newFolder(project);
manager.setRoots(<String>[project], <String>[], <String, String>{});
expect(manager.isIgnored('$project/file.dart'), isFalse);
}
void test_isIgnored_true_inDotFolder() {
String project = '/project';
+ resourceProvider.newFolder(project);
manager.setRoots(<String>[project], <String>[], <String, String>{});
expect(manager.isIgnored('$project/foo/.bar/file.dart'), isTrue);
}
@@ -87,6 +87,7 @@
void test_isIgnored_true_inExcludedPath() {
String project = '/project';
String excludedPath = '/project/excluded';
+ resourceProvider.newFolder(project);
manager.setRoots(
<String>[project], <String>[excludedPath], <String, String>{});
expect(manager.isIgnored('$excludedPath/file.dart'), isTrue);
@@ -95,6 +96,8 @@
void test_isIgnored_true_notInRoot() {
String root1 = '/context/root1';
String root2 = '/context/root2';
+ resourceProvider.newFolder(root1);
+ resourceProvider.newFolder(root2);
manager.setRoots(<String>[root1, root2], <String>[], <String, String>{});
expect(manager.isIgnored('$context/root3/file.dart'), isTrue);
}
@@ -102,6 +105,7 @@
void test_isInAnalysisRoot_false_inExcludedPath() {
String project = '/project';
String excludedPath = '/project/excluded';
+ resourceProvider.newFolder(project);
manager.setRoots(
<String>[project], <String>[excludedPath], <String, String>{});
expect(manager.isInAnalysisRoot('$excludedPath/file.dart'), isFalse);
@@ -110,12 +114,15 @@
void test_isInAnalysisRoot_false_notInRoot() {
String root1 = '/context/root1';
String root2 = '/context/root2';
+ resourceProvider.newFolder(root1);
+ resourceProvider.newFolder(root2);
manager.setRoots(<String>[root1, root2], <String>[], <String, String>{});
expect(manager.isInAnalysisRoot('$context/root3/file.dart'), isFalse);
}
void test_isInAnalysisRoot_true() {
String project = '/project';
+ resourceProvider.newFolder(project);
manager.setRoots(<String>[project], <String>[], <String, String>{});
expect(manager.isInAnalysisRoot('$project/file.dart'), isTrue);
}
@@ -371,6 +378,7 @@
test_watch_addFile() async {
String project = '/project';
+ resourceProvider.newFolder(project);
manager.setRoots(<String>[project], <String>[], <String, String>{});
// empty folder initially
callbacks.assertContextFiles(project, []);
@@ -388,6 +396,8 @@
String root2 = '$contextPath/root2';
String file1 = '$root1/file1.dart';
String file2 = '$root2/file2.dart';
+ resourceProvider.newFolder(root1);
+ resourceProvider.newFolder(root2);
manager.setRoots(<String>[root1], <String>[], <String, String>{});
manager.setRoots(<String>[root2], <String>[], <String, String>{});
manager.setRoots(<String>[root1, root2], <String>[], <String, String>{});
@@ -459,8 +469,9 @@
callbacks.assertContextFiles(project, [fileA]);
}
- test_watch_addFileInSubfolder() async {
+ test_watch_addFileInSubFolder() async {
String project = '/project';
+ resourceProvider.newFolder(project);
manager.setRoots(<String>[project], <String>[], <String, String>{});
// empty folder initially
callbacks.assertContextFiles(project, []);
diff --git a/pkg/analysis_server/test/socket_server_test.dart b/pkg/analysis_server/test/socket_server_test.dart
index 948bf43..a6ea8b1 100644
--- a/pkg/analysis_server/test/socket_server_test.dart
+++ b/pkg/analysis_server/test/socket_server_test.dart
@@ -16,13 +16,11 @@
import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:plugin/manager.dart';
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
import 'mocks.dart';
-import 'utils.dart';
main() {
- initializeTestEnvironment();
group('SocketServer', () {
test('createAnalysisServer_successful',
SocketServerTest.createAnalysisServer_successful);
@@ -115,12 +113,11 @@
ServerPlugin serverPlugin = new ServerPlugin();
ExtensionManager manager = new ExtensionManager();
manager.processPlugins([serverPlugin]);
- SdkCreator sdkCreator = (_) => new FolderBasedDartSdk(resourceProvider,
- FolderBasedDartSdk.defaultSdkDirectory(resourceProvider));
return new SocketServer(
new AnalysisServerOptions(),
- new DartSdkManager('', false, sdkCreator),
- sdkCreator(null),
+ new DartSdkManager('', false),
+ new FolderBasedDartSdk(resourceProvider,
+ FolderBasedDartSdk.defaultSdkDirectory(resourceProvider)),
InstrumentationService.NULL_SERVICE,
serverPlugin,
null,
diff --git a/pkg/analysis_server/test/source/caching_put_package_map_provider_test.dart b/pkg/analysis_server/test/source/caching_put_package_map_provider_test.dart
index 4b78803..efc37e8 100644
--- a/pkg/analysis_server/test/source/caching_put_package_map_provider_test.dart
+++ b/pkg/analysis_server/test/source/caching_put_package_map_provider_test.dart
@@ -14,13 +14,9 @@
import 'package:analyzer/source/package_map_provider.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/generated/engine.dart';
-import 'package:unittest/unittest.dart';
-
-import '../utils.dart';
+import 'package:test/test.dart';
main() {
- initializeTestEnvironment();
-
group('CachingPubPackageMapProvider', () {
MemoryResourceProvider resProvider;
_MockPubListRunner mockRunner;
@@ -72,10 +68,11 @@
}
CachingPubPackageMapProvider newPkgProvider() {
+ Folder sdkFolder = resProvider
+ .newFolder(resProvider.convertPath('/Users/user/dart-sdk'));
return new CachingPubPackageMapProvider(
resProvider,
- new FolderBasedDartSdk(
- resProvider, FolderBasedDartSdk.defaultSdkDirectory(resProvider)),
+ new FolderBasedDartSdk(resProvider, sdkFolder),
mockRunner.runPubList,
mockWriteFile);
}
diff --git a/pkg/analysis_server/test/source/test_all.dart b/pkg/analysis_server/test/source/test_all.dart
index 1389dd3..317a910 100644
--- a/pkg/analysis_server/test/source/test_all.dart
+++ b/pkg/analysis_server/test/source/test_all.dart
@@ -4,11 +4,9 @@
library test.source;
-import '../utils.dart';
import 'caching_put_package_map_provider_test.dart' as caching_provider_test;
/// Utility for manually running all tests.
main() {
- initializeTestEnvironment();
caching_provider_test.main();
}
diff --git a/pkg/analysis_server/test/src/test_all.dart b/pkg/analysis_server/test/src/test_all.dart
index a3642f6..e7df8d3 100644
--- a/pkg/analysis_server/test/src/test_all.dart
+++ b/pkg/analysis_server/test/src/test_all.dart
@@ -4,17 +4,15 @@
library test.src;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../utils.dart';
import 'utilities/test_all.dart' as utilities_all;
/**
* Utility for manually running all tests.
*/
main() {
- initializeTestEnvironment();
- group('analysis_server', () {
+ defineReflectiveSuite(() {
utilities_all.main();
- });
+ }, name: 'analysis_server');
}
diff --git a/pkg/analysis_server/test/src/utilities/change_builder_core_test.dart b/pkg/analysis_server/test/src/utilities/change_builder_core_test.dart
index c36c700..118bdb8 100644
--- a/pkg/analysis_server/test/src/utilities/change_builder_core_test.dart
+++ b/pkg/analysis_server/test/src/utilities/change_builder_core_test.dart
@@ -7,18 +7,18 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/provisional/edit/utilities/change_builder_core.dart';
import 'package:analysis_server/src/utilities/change_builder_core.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../../domain_execution_test.dart';
-import '../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(ChangeBuilderImplTest);
- defineReflectiveTests(EditBuilderImplTest);
- defineReflectiveTests(FileEditBuilderImplTest);
- defineReflectiveTests(LinkedEditBuilderImplTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ChangeBuilderImplTest);
+ defineReflectiveTests(EditBuilderImplTest);
+ defineReflectiveTests(FileEditBuilderImplTest);
+ defineReflectiveTests(LinkedEditBuilderImplTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/src/utilities/change_builder_dart_test.dart b/pkg/analysis_server/test/src/utilities/change_builder_dart_test.dart
index 61f8328..a221d9b 100644
--- a/pkg/analysis_server/test/src/utilities/change_builder_dart_test.dart
+++ b/pkg/analysis_server/test/src/utilities/change_builder_dart_test.dart
@@ -11,17 +11,17 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../../abstract_context.dart';
-import '../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(DartChangeBuilderImplTest);
- defineReflectiveTests(DartEditBuilderImplTest);
- defineReflectiveTests(DartFileEditBuilderImplTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(DartChangeBuilderImplTest);
+ defineReflectiveTests(DartEditBuilderImplTest);
+ defineReflectiveTests(DartFileEditBuilderImplTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analysis_server/test/src/utilities/test_all.dart b/pkg/analysis_server/test/src/utilities/test_all.dart
index cdb4f83..b60e72d2 100644
--- a/pkg/analysis_server/test/src/utilities/test_all.dart
+++ b/pkg/analysis_server/test/src/utilities/test_all.dart
@@ -4,13 +4,15 @@
library test.services;
-import '../../utils.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
import 'change_builder_core_test.dart' as change_builder_core_test;
import 'change_builder_dart_test.dart' as change_builder_dart_test;
/// Utility for manually running all tests.
main() {
- initializeTestEnvironment();
- change_builder_core_test.main();
- change_builder_dart_test.main();
+ defineReflectiveSuite(() {
+ change_builder_core_test.main();
+ change_builder_dart_test.main();
+ });
}
diff --git a/pkg/analysis_server/test/src/watch_manager_test.dart b/pkg/analysis_server/test/src/watch_manager_test.dart
index 99b76fc..c3dc145 100644
--- a/pkg/analysis_server/test/src/watch_manager_test.dart
+++ b/pkg/analysis_server/test/src/watch_manager_test.dart
@@ -9,17 +9,17 @@
import 'package:analysis_server/src/watch_manager.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import 'package:watcher/watcher.dart';
import '../mocks.dart';
-import '../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(WatchManagerTest);
- defineReflectiveTests(WatchNodeTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(WatchManagerTest);
+ defineReflectiveTests(WatchNodeTest);
+ });
}
/**
diff --git a/pkg/analysis_server/test/test_all.dart b/pkg/analysis_server/test/test_all.dart
index e830864..50dbfaa 100644
--- a/pkg/analysis_server/test/test_all.dart
+++ b/pkg/analysis_server/test/test_all.dart
@@ -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.
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'analysis/test_all.dart' as analysis_all;
import 'analysis_server_test.dart' as analysis_server_test;
@@ -26,14 +26,12 @@
import 'socket_server_test.dart' as socket_server_test;
import 'source/test_all.dart' as source_all;
import 'src/test_all.dart' as src_all;
-import 'utils.dart';
/**
* Utility for manually running all tests.
*/
main() {
- initializeTestEnvironment();
- group('analysis_server', () {
+ defineReflectiveSuite(() {
analysis_all.main();
analysis_server_test.main();
channel_test.main();
@@ -56,5 +54,5 @@
socket_server_test.main();
source_all.main();
src_all.main();
- });
+ }, name: 'analisys_server');
}
diff --git a/pkg/analysis_server/test/utils.dart b/pkg/analysis_server/test/utils.dart
deleted file mode 100644
index e87a3c8..0000000
--- a/pkg/analysis_server/test/utils.dart
+++ /dev/null
@@ -1,11 +0,0 @@
-// 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 analysis_server.test.utils;
-
-import 'package:unittest/unittest.dart';
-
-void initializeTestEnvironment() {
- groupSep = ' | ';
-}
diff --git a/pkg/analysis_server/tool/instrumentation/log/log.dart b/pkg/analysis_server/tool/instrumentation/log/log.dart
index 7042fc4..2378c27 100644
--- a/pkg/analysis_server/tool/instrumentation/log/log.dart
+++ b/pkg/analysis_server/tool/instrumentation/log/log.dart
@@ -5,14 +5,83 @@
/**
* A representation of the contents of an instrumentation log.
*/
-library analysis_server.tool.instrumentation.log;
+library analysis_server.tool.instrumentation.log.log;
-import 'dart:collection';
import 'dart:convert';
import 'package:analyzer/instrumentation/instrumentation.dart';
/**
+ * A boolean-valued function of one argument.
+ */
+typedef bool Predicate<T>(T value);
+
+/**
+ * A description of a group of log entries.
+ */
+class EntryGroup {
+ /**
+ * A list of all of the instances of this class.
+ */
+ static final List<EntryGroup> groups = <EntryGroup>[
+ new EntryGroup._(
+ 'nonTask', 'Non-task', (LogEntry entry) => entry is! TaskEntry),
+ new EntryGroup._(
+ 'errors',
+ 'Errors',
+ (LogEntry entry) =>
+ entry is ErrorEntry ||
+ entry is ExceptionEntry ||
+ (entry is NotificationEntry && entry.isServerError)),
+ new EntryGroup._('malformed', 'Malformed',
+ (LogEntry entry) => entry is MalformedLogEntry),
+ new EntryGroup._('all', 'All', (LogEntry entry) => true),
+ ];
+
+ /**
+ * The unique id of the group.
+ */
+ final String id;
+
+ /**
+ * The human-readable name of the group.
+ */
+ final String name;
+
+ /**
+ * The filter used to determine which entries belong to the group. The filter
+ * should return `true` for members and `false` for non-members.
+ */
+ final Predicate<LogEntry> filter;
+
+ /**
+ * Initialize a newly created entry group with the given state.
+ */
+ EntryGroup._(this.id, this.name, this.filter);
+
+ /**
+ * Given a list of [entries], return all of the entries in the list that are
+ * members of this group.
+ */
+ List<LogEntry> computeMembers(List<LogEntry> entries) {
+ return entries.where(filter).toList();
+ }
+
+ /**
+ * Return the entry group with the given [id], or `null` if there is no group
+ * with the given id.
+ */
+ static EntryGroup withId(String id) {
+ for (EntryGroup group in groups) {
+ if (group.id == id) {
+ return group;
+ }
+ }
+ return null;
+ }
+}
+
+/**
* A range of log entries, represented by the index of the first and last
* entries in the range.
*/
@@ -107,34 +176,33 @@
List<LogEntry> logEntries;
/**
- * The entries in the instrumentation log that are not instances of
- * [TaskEntry].
+ * A table mapping the entry groups that have been computed to the list of
+ * entries in that group.
*/
- List<LogEntry> nonTaskEntries;
+ Map<EntryGroup, List<LogEntry>> entryGroups = <EntryGroup, List<LogEntry>>{};
/**
* A table mapping entries that are paired with another entry to the entry
* with which they are paired.
*/
- Map<LogEntry, LogEntry> _pairedEntries = new HashMap<LogEntry, LogEntry>();
+ Map<LogEntry, LogEntry> _pairedEntries = <LogEntry, LogEntry>{};
/**
* A table mapping the id's of requests to the entry representing the request.
*/
- Map<String, RequestEntry> _requestMap = new HashMap<String, RequestEntry>();
+ Map<String, RequestEntry> _requestMap = <String, RequestEntry>{};
/**
* A table mapping the id's of responses to the entry representing the
* response.
*/
- Map<String, ResponseEntry> _responseMap =
- new HashMap<String, ResponseEntry>();
+ Map<String, ResponseEntry> _responseMap = <String, ResponseEntry>{};
/**
* A table mapping the ids of completion events to the events with those ids.
*/
Map<String, List<NotificationEntry>> _completionMap =
- new HashMap<String, List<NotificationEntry>>();
+ <String, List<NotificationEntry>>{};
/**
* The ranges of entries that are between analysis start and analysis end
@@ -158,6 +226,12 @@
_completionMap[id];
/**
+ * Return the log entries that are contained in the given [group].
+ */
+ List<LogEntry> entriesInGroup(EntryGroup group) =>
+ entryGroups.putIfAbsent(group, () => group.computeMembers(logEntries));
+
+ /**
* Return the entry that is paired with the given [entry], or `null` if there
* is no entry paired with it.
*/
@@ -181,7 +255,7 @@
*/
List<TaskEntry> taskEntriesFor(int startIndex) {
List<TaskEntry> taskEntries = <TaskEntry>[];
- NotificationEntry startEntry = nonTaskEntries[startIndex];
+ NotificationEntry startEntry = logEntries[startIndex];
LogEntry endEntry = pairedEntry(startEntry);
int lastIndex = endEntry == null ? logEntries.length : endEntry.index;
for (int i = startEntry.index + 1; i < lastIndex; i++) {
@@ -194,6 +268,18 @@
}
/**
+ * Return `true` if the given [logContent] appears to be from session data.
+ */
+ bool _isSessionData(List<String> logContent) {
+ if (logContent.length < 2) {
+ return false;
+ }
+ String firstLine = logContent[0];
+ return firstLine.startsWith('-----') && logContent[1].startsWith('~') ||
+ firstLine.startsWith('~');
+ }
+
+ /**
* Merge any multi-line entries into a single line so that every element in
* the given [logContent] is a single entry.
*/
@@ -233,9 +319,18 @@
* Parse the given [logContent] into a list of log entries.
*/
void _parseLogContent(List<String> logContent) {
- _mergeEntries(logContent);
+ if (_isSessionData(logContent)) {
+ if (logContent[0].startsWith('-----')) {
+ logContent.removeAt(0);
+ }
+ int lastIndex = logContent.length - 1;
+ if (logContent[lastIndex].startsWith('extraction complete')) {
+ logContent.removeAt(lastIndex);
+ }
+ } else {
+ _mergeEntries(logContent);
+ }
logEntries = <LogEntry>[];
- nonTaskEntries = <LogEntry>[];
analysisRanges = <EntryRange>[];
NotificationEntry analysisStartEntry = null;
int analysisStartIndex = -1;
@@ -244,9 +339,6 @@
LogEntry entry = new LogEntry.from(logEntries.length, line);
if (entry != null) {
logEntries.add(entry);
- if (entry is! TaskEntry) {
- nonTaskEntries.add(entry);
- }
if (entry is RequestEntry) {
_requestMap[entry.id] = entry;
} else if (entry is ResponseEntry) {
@@ -439,6 +531,7 @@
'Err': 'Error',
'Ex': 'Exception',
'Log': 'Log message',
+ 'Mal': 'Malformed entry',
'Noti': 'Notification',
'Read': 'Read file',
'Req': 'Request',
@@ -479,47 +572,54 @@
if (entry.isEmpty) {
return null;
}
- List<String> components = _parseComponents(entry);
- int timeStamp;
try {
- timeStamp = int.parse(components[0]);
- } catch (exception) {
- print('Invalid time stamp in "${components[0]}"; entry = "$entry"');
- return null;
- }
- String entryKind = components[1];
- if (entryKind == InstrumentationService.TAG_ANALYSIS_TASK) {
- return new TaskEntry(index, timeStamp, components[2], components[3]);
- } else if (entryKind == InstrumentationService.TAG_ERROR) {
- return new ErrorEntry(index, timeStamp, entryKind, components.sublist(2));
- } else if (entryKind == InstrumentationService.TAG_EXCEPTION) {
- return new ExceptionEntry(
+ List<String> components = _parseComponents(entry);
+ int timeStamp;
+ String component = components[0];
+ if (component.startsWith('~')) {
+ component = component.substring(1);
+ }
+ timeStamp = int.parse(component);
+ String entryKind = components[1];
+ if (entryKind == InstrumentationService.TAG_ANALYSIS_TASK) {
+ return new TaskEntry(index, timeStamp, components[2], components[3]);
+ } else if (entryKind == InstrumentationService.TAG_ERROR) {
+ return new ErrorEntry(
+ index, timeStamp, entryKind, components.sublist(2));
+ } else if (entryKind == InstrumentationService.TAG_EXCEPTION) {
+ return new ExceptionEntry(
+ index, timeStamp, entryKind, components.sublist(2));
+ } else if (entryKind == InstrumentationService.TAG_FILE_READ) {
+ // Fall through
+ } else if (entryKind == InstrumentationService.TAG_LOG_ENTRY) {
+ // Fall through
+ } else if (entryKind == InstrumentationService.TAG_NOTIFICATION) {
+ Map requestData = JSON.decode(components[2]);
+ return new NotificationEntry(index, timeStamp, requestData);
+ } else if (entryKind == InstrumentationService.TAG_PERFORMANCE) {
+ // Fall through
+ } else if (entryKind == InstrumentationService.TAG_REQUEST) {
+ Map requestData = JSON.decode(components[2]);
+ return new RequestEntry(index, timeStamp, requestData);
+ } else if (entryKind == InstrumentationService.TAG_RESPONSE) {
+ Map responseData = JSON.decode(components[2]);
+ return new ResponseEntry(index, timeStamp, responseData);
+ } else if (entryKind == InstrumentationService.TAG_SUBPROCESS_START) {
+ // Fall through
+ } else if (entryKind == InstrumentationService.TAG_SUBPROCESS_RESULT) {
+ // Fall through
+ } else if (entryKind == InstrumentationService.TAG_VERSION) {
+ // Fall through
+ } else if (entryKind == InstrumentationService.TAG_WATCH_EVENT) {
+ // Fall through
+ }
+ return new GenericEntry(
index, timeStamp, entryKind, components.sublist(2));
- } else if (entryKind == InstrumentationService.TAG_FILE_READ) {
- // Fall through
- } else if (entryKind == InstrumentationService.TAG_LOG_ENTRY) {
- // Fall through
- } else if (entryKind == InstrumentationService.TAG_NOTIFICATION) {
- Map requestData = JSON.decode(components[2]);
- return new NotificationEntry(index, timeStamp, requestData);
- } else if (entryKind == InstrumentationService.TAG_PERFORMANCE) {
- // Fall through
- } else if (entryKind == InstrumentationService.TAG_REQUEST) {
- Map requestData = JSON.decode(components[2]);
- return new RequestEntry(index, timeStamp, requestData);
- } else if (entryKind == InstrumentationService.TAG_RESPONSE) {
- Map responseData = JSON.decode(components[2]);
- return new ResponseEntry(index, timeStamp, responseData);
- } else if (entryKind == InstrumentationService.TAG_SUBPROCESS_START) {
- // Fall through
- } else if (entryKind == InstrumentationService.TAG_SUBPROCESS_RESULT) {
- // Fall through
- } else if (entryKind == InstrumentationService.TAG_VERSION) {
- // Fall through
- } else if (entryKind == InstrumentationService.TAG_WATCH_EVENT) {
- // Fall through
+ } catch (exception) {
+ LogEntry logEntry = new MalformedLogEntry(index, entry);
+ logEntry.recordProblem(exception.toString());
+ return logEntry;
}
- return new GenericEntry(index, timeStamp, entryKind, components.sublist(2));
}
/**
@@ -608,6 +708,25 @@
}
/**
+ * A representation of a malformed log entry.
+ */
+class MalformedLogEntry extends LogEntry {
+ final String entry;
+
+ MalformedLogEntry(int index, this.entry) : super(index, -1);
+
+ @override
+ String get kind => 'Mal';
+
+ @override
+ void _appendDetails(StringBuffer buffer) {
+ super._appendDetails(buffer);
+ buffer.write(entry);
+ buffer.write('<br>');
+ }
+}
+
+/**
* A log entry representing a notification that was sent from the server to the
* client.
*/
@@ -625,6 +744,11 @@
String get event => data['event'];
/**
+ * Return `true` if this is a server error notification.
+ */
+ bool get isServerError => event == 'server.error';
+
+ /**
* Return `true` if this is a server status notification.
*/
bool get isServerStatus => event == 'server.status';
diff --git a/pkg/analysis_server/tool/instrumentation/log_viewer.dart b/pkg/analysis_server/tool/instrumentation/log_viewer.dart
index 1d59e3b..62d5722 100644
--- a/pkg/analysis_server/tool/instrumentation/log_viewer.dart
+++ b/pkg/analysis_server/tool/instrumentation/log_viewer.dart
@@ -118,6 +118,7 @@
stackTrace: stackTrace);
return;
}
+ print('Log file contains ${lines.length} lines');
InstrumentationLog log =
new InstrumentationLog(<String>[logFile.path], lines);
diff --git a/pkg/analysis_server/tool/instrumentation/page/log_page.dart b/pkg/analysis_server/tool/instrumentation/page/log_page.dart
index 83dd31d..ad1194d 100644
--- a/pkg/analysis_server/tool/instrumentation/page/log_page.dart
+++ b/pkg/analysis_server/tool/instrumentation/page/log_page.dart
@@ -2,7 +2,6 @@
// 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:collection';
import 'dart:math' as math;
import '../log/log.dart';
@@ -20,6 +19,16 @@
InstrumentationLog log;
/**
+ * The id of the entry groups to be displayed.
+ */
+ EntryGroup selectedGroup;
+
+ /**
+ * The entries in the selected group.
+ */
+ List<LogEntry> entries;
+
+ /**
* The index of the first entry to be written.
*/
int pageStart = 0;
@@ -36,26 +45,16 @@
int prefixLength;
/**
- * The number of each kind of log entry. Currently used only for debugging and
- * should be removed.
- */
- Map<String, int> counts = new HashMap<String, int>();
-
- /**
* Initialize a newly created writer to write the content of the given
* [instrumentationLog].
*/
- LogPage(this.log) {
- List<LogEntry> entries = log.logEntries;
- prefixLength = computePrefixLength(entries);
- for (LogEntry entry in entries) {
- int count = counts.putIfAbsent(entry.kind, () => 0);
- counts[entry.kind] = count + 1;
- }
- }
+ LogPage(this.log);
@override
void writeBody(StringSink sink) {
+ entries = log.entriesInGroup(selectedGroup);
+ prefixLength = computePrefixLength(entries);
+
writeMenu(sink);
writeTwoColumns(
sink, 'leftColumn', _writeLeftColumn, 'rightColumn', _writeRightColumn);
@@ -89,6 +88,11 @@
element.innerHTML = detailsContent;
}
}
+function selectEntryGroup(pageStart) {
+ var element = document.getElementById("entryGroup");
+ var url = "/log?group=" + element.value;
+ window.location.assign(url);
+}
''');
}
@@ -175,6 +179,8 @@
description = '<span class="error">$description</span>';
} else if (entry is ExceptionEntry) {
description = '<span class="error">$description</span>';
+ } else if (entry is MalformedLogEntry) {
+ description = '<span class="error">$description</span>';
}
id = id == null ? '' : 'id="$id" ';
clickHandler = '$clickHandler; setDetails(\'${escape(entry.details())}\')';
@@ -198,7 +204,6 @@
* Write the entries in the instrumentation log to the given [sink].
*/
void _writeLeftColumn(StringSink sink) {
- List<LogEntry> entries = log.nonTaskEntries;
int length = entries.length;
int pageEnd =
pageLength == null ? length : math.min(pageStart + pageLength, length);
@@ -207,6 +212,19 @@
//
sink.writeln('<div class="columnHeader">');
sink.writeln('<div style="float: left">');
+ sink.writeln('<select id="entryGroup" onchange="selectEntryGroup()">');
+ for (EntryGroup group in EntryGroup.groups) {
+ sink.write('<option value="');
+ sink.write(group.id);
+ sink.write('"');
+ if (group == selectedGroup) {
+ sink.write(' selected');
+ }
+ sink.write('>');
+ sink.write(group.name);
+ sink.writeln('</option>');
+ }
+ sink.writeln('</select>');
sink.writeln('Events $pageStart - ${pageEnd - 1} of ${length - 1}');
sink.writeln('</div>');
@@ -216,7 +234,7 @@
} else {
sink.write('<button type="button">');
sink.write(
- '<a href="${WebServer.logPath}?start=${pageStart - pageLength}">');
+ '<a href="${WebServer.logPath}?group=${selectedGroup.id}&start=${pageStart - pageLength}">');
sink.write('<b><</b>');
sink.writeln('</a></button>');
}
@@ -226,7 +244,7 @@
} else {
sink.write('<button type="button">');
sink.write(
- '<a href="${WebServer.logPath}?start=${pageStart + pageLength}">');
+ '<a href="${WebServer.logPath}?group=${selectedGroup.id}&start=${pageStart + pageLength}">');
sink.write('<b>></b>');
sink.writeln('</a></button>');
}
diff --git a/pkg/analysis_server/tool/instrumentation/page/page_writer.dart b/pkg/analysis_server/tool/instrumentation/page/page_writer.dart
index bd7e769..dca5673 100644
--- a/pkg/analysis_server/tool/instrumentation/page/page_writer.dart
+++ b/pkg/analysis_server/tool/instrumentation/page/page_writer.dart
@@ -48,7 +48,11 @@
* Return an escaped version of the given [unsafe] text.
*/
String escape(String unsafe) {
- return htmlEscape.convert(unsafe);
+ // We double escape single quotes because the escaped characters are
+ // processed as part of reading the HTML, which means that single quotes
+ // end up terminating string literals too early when they appear in event
+ // handlers (which in turn leads to JavaScript syntax errors).
+ return htmlEscape.convert(unsafe).replaceAll(''', '&#39;');
}
/**
@@ -273,8 +277,8 @@
*/
void writeTwoColumns(StringSink sink, String leftColumnId,
Writer writeLeftColumn, String rightColumnId, Writer writeRightColumn) {
- sink.writeln('<div>');
- sink.writeln(' <div>');
+ sink.writeln('<div id="container">');
+ sink.writeln(' <div id="content">');
sink.writeln(' <div id="$leftColumnId">');
sink.writeln(' <div class="inset">');
writeLeftColumn(sink);
diff --git a/pkg/analysis_server/tool/instrumentation/page/stats_page.dart b/pkg/analysis_server/tool/instrumentation/page/stats_page.dart
index 02ec025..42cd704 100644
--- a/pkg/analysis_server/tool/instrumentation/page/stats_page.dart
+++ b/pkg/analysis_server/tool/instrumentation/page/stats_page.dart
@@ -52,20 +52,8 @@
@override
void writeBody(StringSink sink) {
writeMenu(sink);
- sink.writeln('<div id="container">');
- sink.writeln(' <div id="content">');
- sink.writeln(' <div id="leftColumn">');
- sink.writeln(' <div class="inset">');
- _writeLeftColumn(sink);
- sink.writeln(' </div>');
- sink.writeln(' </div>');
- sink.writeln(' <div id="rightColumn">');
- sink.writeln(' <div class="inset">');
- _writeRightColumn(sink);
- sink.writeln(' </div>');
- sink.writeln(' </div>');
- sink.writeln(' </div>');
- sink.writeln('</div>');
+ writeTwoColumns(
+ sink, 'leftColumn', _writeLeftColumn, 'rightColumn', _writeRightColumn);
}
/**
@@ -74,20 +62,7 @@
*/
void writeStyleSheet(StringSink sink) {
super.writeStyleSheet(sink);
- sink.writeln(r'''
-#leftColumn {
- float: left;
- height: 100%;
- overflow: auto;
- width: 50%;
-}
-#rightColumn {
- float: right;
- height: 100%;
- overflow: auto;
- width: 50%;
-}
-''');
+ writeTwoColumnStyles(sink, 'leftColumn', 'rightColumn');
}
/**
diff --git a/pkg/analysis_server/tool/instrumentation/server.dart b/pkg/analysis_server/tool/instrumentation/server.dart
index 324244c..768c8b8 100644
--- a/pkg/analysis_server/tool/instrumentation/server.dart
+++ b/pkg/analysis_server/tool/instrumentation/server.dart
@@ -186,8 +186,10 @@
void _writeLogPage(HttpRequest request, StringBuffer buffer) {
Map<String, String> parameterMap = getParameterMap(request);
+ String groupId = parameterMap['group'];
String startIndex = parameterMap['start'];
LogPage page = new LogPage(log);
+ page.selectedGroup = EntryGroup.withId(groupId ?? 'nonTask');
if (startIndex != null) {
page.pageStart = int.parse(startIndex);
} else {
diff --git a/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart b/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart
index b34cca3..b734061 100644
--- a/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart
+++ b/pkg/analysis_server/tool/spec/codegen_inttest_methods.dart
@@ -104,7 +104,7 @@
writeln("import 'package:analysis_server/plugin/protocol/protocol.dart';");
writeln(
"import 'package:analysis_server/src/protocol/protocol_internal.dart';");
- writeln("import 'package:unittest/unittest.dart';");
+ writeln("import 'package:test/test.dart';");
writeln();
writeln("import 'integration_tests.dart';");
writeln("import 'protocol_matchers.dart';");
@@ -179,7 +179,7 @@
indent(() {
String paramsValidator = camelJoin(
['is', notification.domainName, notification.event, 'params']);
- writeln('expect(params, $paramsValidator);');
+ writeln('outOfTestExpect(params, $paramsValidator);');
String constructorCall;
if (notification.params == null) {
constructorCall = 'new $className()';
@@ -255,7 +255,7 @@
writeln('ResponseDecoder decoder = new ResponseDecoder($kind);');
writeln("return new $resultClass.fromJson(decoder, 'result', result);");
} else {
- writeln('expect(result, isNull);');
+ writeln('outOfTestExpect(result, isNull);');
writeln('return null;');
}
});
diff --git a/pkg/analysis_server/tool/spec/codegen_matchers.dart b/pkg/analysis_server/tool/spec/codegen_matchers.dart
index 10c5b85..a5bf0d1 100644
--- a/pkg/analysis_server/tool/spec/codegen_matchers.dart
+++ b/pkg/analysis_server/tool/spec/codegen_matchers.dart
@@ -105,7 +105,7 @@
writeln(' */');
writeln('library test.integration.protocol.matchers;');
writeln();
- writeln("import 'package:unittest/unittest.dart';");
+ writeln("import 'package:test/test.dart';");
writeln();
writeln("import 'integration_tests.dart';");
writeln();
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index 5290921..07a0577 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -148,6 +148,34 @@
<h4>Options</h4>
<blockquote>
<dl>
+ <dt>--client-id</dt>
+ <dd>
+ <p>
+ Specifies an identifier associated with the client. Used when
+ generating error reports.
+ </p>
+ <p>
+ Clients are strongly encouraged to provide this information in
+ order to improve the quality of information that can be provided
+ to them.
+ </p>
+ </dd>
+ </dl>
+ <dl>
+ <dt>--client-version</dt>
+ <dd>
+ <p>
+ Specifies the version of the client that is communicating with
+ the server. Used when generating error reports.
+ </p>
+ <p>
+ Clients are strongly encouraged to provide this information in
+ order to improve the quality of information that can be provided
+ to them.
+ </p>
+ </dd>
+ </dl>
+ <dl>
<dt>--no-error-notification</dt>
<dd>
Disable notifications about errors (see analysis.error). If this
@@ -156,29 +184,30 @@
</dd>
</dl>
<dl>
- <dt>--file-read-mode</dt>
- <dd>
- An enumeration of the ways files can be read from disk. Some clients
- normalize end of line characters which would make the file offset and
- range information incorrect. The default option is <tt>as-is</tt>, but
- can also be set to <tt>normalize-eol-always</tt>. The default option
- (<tt>as-is</tt>) reads files as they are on disk. The
- <tt>normalize-eol-always</tt> option does the following:
- <ul>
- <li>'\r\n' is converted to '\n';</li>
- <li>'\r' by itself is converted to '\n';</li>
- <li>this happens regardless of the OS editor is running on.</li>
- </ul>
- </dd>
- </dl>
- <dl>
<dt>--no-index</dt>
<dd>
Disable the server from generating an index. If this flag is passed and an
API is used that requires an index, then an error, <tt>NO_INDEX_GENERATED</tt>,
will be thrown. The set of API calls that require an index include:
refactoring calls, code completions and searching.
- <!-- TODO(jwren/scheglov): make sure that this of APIs that is complete. -->
+ <!-- TODO(jwren/scheglov): make sure that this list of APIs that is complete. -->
+ </dd>
+ </dl>
+ <dl>
+ <dt>--file-read-mode</dt>
+ <dd>
+ <p><b>Deprecated</b></p>
+ An enumeration of the ways files can be read from disk. Some clients
+ normalize end of line characters which would make the file offset and
+ range information incorrect. The default option is <tt>as-is</tt>, but
+ can also be set to <tt>normalize-eol-always</tt>. The default option
+ (<tt>as-is</tt>) reads files as they are on disk. The
+ <tt>normalize-eol-always</tt> option does the following:
+ <ul>
+ <li>'\r\n' is converted to '\n';</li>
+ <li>'\r' by itself is converted to '\n';</li>
+ <li>this happens regardless of the OS editor is running on.</li>
+ </ul>
</dd>
</dl>
</blockquote>
diff --git a/pkg/analyzer/BUILD.gn b/pkg/analyzer/BUILD.gn
new file mode 100644
index 0000000..1f39031
--- /dev/null
+++ b/pkg/analyzer/BUILD.gn
@@ -0,0 +1,26 @@
+# 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("//build/dart/dart_package.gni")
+
+dart_package("analyzer") {
+ package_name = "analyzer"
+
+ source_dir = "lib"
+
+ deps = [
+ "//third_party/dart-pkg/pub/args",
+ "//third_party/dart-pkg/pub/charcode",
+ "//third_party/dart-pkg/pub/crypto",
+ "//third_party/dart-pkg/pub/glob",
+ "//third_party/dart-pkg/pub/html",
+ "//third_party/dart-pkg/pub/isolate",
+ "//third_party/dart-pkg/pub/meta",
+ "//third_party/dart-pkg/pub/package_config",
+ "//third_party/dart-pkg/pub/path",
+ "//third_party/dart-pkg/pub/plugin",
+ "//third_party/dart-pkg/pub/watcher",
+ "//third_party/dart-pkg/pub/yaml",
+ ]
+}
diff --git a/pkg/analyzer/lib/dart/ast/visitor.dart b/pkg/analyzer/lib/dart/ast/visitor.dart
index 989e7c6..d3e55d3 100644
--- a/pkg/analyzer/lib/dart/ast/visitor.dart
+++ b/pkg/analyzer/lib/dart/ast/visitor.dart
@@ -108,787 +108,23 @@
*
* Clients may not extend, implement or mix-in this class.
*/
-class DelegatingAstVisitor<T> implements AstVisitor<T> {
+class DelegatingAstVisitor<T> extends UnifyingAstVisitor<T> {
/**
* The delegates whose visit methods will be invoked.
*/
- final Iterable<AstVisitor<T>> _delegates;
+ final Iterable<AstVisitor<T>> delegates;
/**
* Initialize a newly created visitor to use each of the given delegate
* visitors to visit the nodes of an AST structure.
*/
- DelegatingAstVisitor(this._delegates);
+ DelegatingAstVisitor(this.delegates);
@override
- T visitAdjacentStrings(AdjacentStrings node) {
- _delegates.forEach((delegate) => delegate.visitAdjacentStrings(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitAnnotation(Annotation node) {
- _delegates.forEach((delegate) => delegate.visitAnnotation(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitArgumentList(ArgumentList node) {
- _delegates.forEach((delegate) => delegate.visitArgumentList(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitAsExpression(AsExpression node) {
- _delegates.forEach((delegate) => delegate.visitAsExpression(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitAssertStatement(AssertStatement node) {
- _delegates.forEach((delegate) => delegate.visitAssertStatement(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitAssignmentExpression(AssignmentExpression node) {
- _delegates.forEach((delegate) => delegate.visitAssignmentExpression(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitAwaitExpression(AwaitExpression node) {
- _delegates.forEach((delegate) => delegate.visitAwaitExpression(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitBinaryExpression(BinaryExpression node) {
- _delegates.forEach((delegate) => delegate.visitBinaryExpression(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitBlock(Block node) {
- _delegates.forEach((delegate) => delegate.visitBlock(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitBlockFunctionBody(BlockFunctionBody node) {
- _delegates.forEach((delegate) => delegate.visitBlockFunctionBody(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitBooleanLiteral(BooleanLiteral node) {
- _delegates.forEach((delegate) => delegate.visitBooleanLiteral(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitBreakStatement(BreakStatement node) {
- _delegates.forEach((delegate) => delegate.visitBreakStatement(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitCascadeExpression(CascadeExpression node) {
- _delegates.forEach((delegate) => delegate.visitCascadeExpression(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitCatchClause(CatchClause node) {
- _delegates.forEach((delegate) => delegate.visitCatchClause(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitClassDeclaration(ClassDeclaration node) {
- _delegates.forEach((delegate) => delegate.visitClassDeclaration(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitClassTypeAlias(ClassTypeAlias node) {
- _delegates.forEach((delegate) => delegate.visitClassTypeAlias(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitComment(Comment node) {
- _delegates.forEach((delegate) => delegate.visitComment(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitCommentReference(CommentReference node) {
- _delegates.forEach((delegate) => delegate.visitCommentReference(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitCompilationUnit(CompilationUnit node) {
- _delegates.forEach((delegate) => delegate.visitCompilationUnit(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitConditionalExpression(ConditionalExpression node) {
- _delegates.forEach((delegate) => delegate.visitConditionalExpression(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitConfiguration(Configuration node) {
- _delegates.forEach((delegate) => delegate.visitConfiguration(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitConstructorDeclaration(ConstructorDeclaration node) {
- _delegates
- .forEach((delegate) => delegate.visitConstructorDeclaration(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitConstructorFieldInitializer(ConstructorFieldInitializer node) {
- _delegates
- .forEach((delegate) => delegate.visitConstructorFieldInitializer(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitConstructorName(ConstructorName node) {
- _delegates.forEach((delegate) => delegate.visitConstructorName(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitContinueStatement(ContinueStatement node) {
- _delegates.forEach((delegate) => delegate.visitContinueStatement(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitDeclaredIdentifier(DeclaredIdentifier node) {
- _delegates.forEach((delegate) => delegate.visitDeclaredIdentifier(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitDefaultFormalParameter(DefaultFormalParameter node) {
- _delegates
- .forEach((delegate) => delegate.visitDefaultFormalParameter(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitDoStatement(DoStatement node) {
- _delegates.forEach((delegate) => delegate.visitDoStatement(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitDottedName(DottedName node) {
- _delegates.forEach((delegate) => delegate.visitDottedName(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitDoubleLiteral(DoubleLiteral node) {
- _delegates.forEach((delegate) => delegate.visitDoubleLiteral(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitEmptyFunctionBody(EmptyFunctionBody node) {
- _delegates.forEach((delegate) => delegate.visitEmptyFunctionBody(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitEmptyStatement(EmptyStatement node) {
- _delegates.forEach((delegate) => delegate.visitEmptyStatement(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitEnumConstantDeclaration(EnumConstantDeclaration node) {
- _delegates
- .forEach((delegate) => delegate.visitEnumConstantDeclaration(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitEnumDeclaration(EnumDeclaration node) {
- _delegates.forEach((delegate) => delegate.visitEnumDeclaration(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitExportDirective(ExportDirective node) {
- _delegates.forEach((delegate) => delegate.visitExportDirective(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitExpressionFunctionBody(ExpressionFunctionBody node) {
- _delegates
- .forEach((delegate) => delegate.visitExpressionFunctionBody(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitExpressionStatement(ExpressionStatement node) {
- _delegates.forEach((delegate) => delegate.visitExpressionStatement(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitExtendsClause(ExtendsClause node) {
- _delegates.forEach((delegate) => delegate.visitExtendsClause(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitFieldDeclaration(FieldDeclaration node) {
- _delegates.forEach((delegate) => delegate.visitFieldDeclaration(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitFieldFormalParameter(FieldFormalParameter node) {
- _delegates.forEach((delegate) => delegate.visitFieldFormalParameter(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitForEachStatement(ForEachStatement node) {
- _delegates.forEach((delegate) => delegate.visitForEachStatement(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitFormalParameterList(FormalParameterList node) {
- _delegates.forEach((delegate) => delegate.visitFormalParameterList(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitForStatement(ForStatement node) {
- _delegates.forEach((delegate) => delegate.visitForStatement(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitFunctionDeclaration(FunctionDeclaration node) {
- _delegates.forEach((delegate) => delegate.visitFunctionDeclaration(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitFunctionDeclarationStatement(FunctionDeclarationStatement node) {
- _delegates.forEach(
- (delegate) => delegate.visitFunctionDeclarationStatement(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitFunctionExpression(FunctionExpression node) {
- _delegates.forEach((delegate) => delegate.visitFunctionExpression(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
- _delegates.forEach(
- (delegate) => delegate.visitFunctionExpressionInvocation(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitFunctionTypeAlias(FunctionTypeAlias node) {
- _delegates.forEach((delegate) => delegate.visitFunctionTypeAlias(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
- _delegates.forEach(
- (delegate) => delegate.visitFunctionTypedFormalParameter(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitHideCombinator(HideCombinator node) {
- _delegates.forEach((delegate) => delegate.visitHideCombinator(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitIfStatement(IfStatement node) {
- _delegates.forEach((delegate) => delegate.visitIfStatement(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitImplementsClause(ImplementsClause node) {
- _delegates.forEach((delegate) => delegate.visitImplementsClause(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitImportDirective(ImportDirective node) {
- _delegates.forEach((delegate) => delegate.visitImportDirective(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitIndexExpression(IndexExpression node) {
- _delegates.forEach((delegate) => delegate.visitIndexExpression(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitInstanceCreationExpression(InstanceCreationExpression node) {
- _delegates
- .forEach((delegate) => delegate.visitInstanceCreationExpression(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitIntegerLiteral(IntegerLiteral node) {
- _delegates.forEach((delegate) => delegate.visitIntegerLiteral(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitInterpolationExpression(InterpolationExpression node) {
- _delegates
- .forEach((delegate) => delegate.visitInterpolationExpression(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitInterpolationString(InterpolationString node) {
- _delegates.forEach((delegate) => delegate.visitInterpolationString(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitIsExpression(IsExpression node) {
- _delegates.forEach((delegate) => delegate.visitIsExpression(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitLabel(Label node) {
- _delegates.forEach((delegate) => delegate.visitLabel(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitLabeledStatement(LabeledStatement node) {
- _delegates.forEach((delegate) => delegate.visitLabeledStatement(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitLibraryDirective(LibraryDirective node) {
- _delegates.forEach((delegate) => delegate.visitLibraryDirective(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitLibraryIdentifier(LibraryIdentifier node) {
- _delegates.forEach((delegate) => delegate.visitLibraryIdentifier(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitListLiteral(ListLiteral node) {
- _delegates.forEach((delegate) => delegate.visitListLiteral(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitMapLiteral(MapLiteral node) {
- _delegates.forEach((delegate) => delegate.visitMapLiteral(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitMapLiteralEntry(MapLiteralEntry node) {
- _delegates.forEach((delegate) => delegate.visitMapLiteralEntry(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitMethodDeclaration(MethodDeclaration node) {
- _delegates.forEach((delegate) => delegate.visitMethodDeclaration(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitMethodInvocation(MethodInvocation node) {
- _delegates.forEach((delegate) => delegate.visitMethodInvocation(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitNamedExpression(NamedExpression node) {
- _delegates.forEach((delegate) => delegate.visitNamedExpression(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitNativeClause(NativeClause node) {
- _delegates.forEach((delegate) => delegate.visitNativeClause(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitNativeFunctionBody(NativeFunctionBody node) {
- _delegates.forEach((delegate) => delegate.visitNativeFunctionBody(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitNullLiteral(NullLiteral node) {
- _delegates.forEach((delegate) => delegate.visitNullLiteral(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitParenthesizedExpression(ParenthesizedExpression node) {
- _delegates
- .forEach((delegate) => delegate.visitParenthesizedExpression(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitPartDirective(PartDirective node) {
- _delegates.forEach((delegate) => delegate.visitPartDirective(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitPartOfDirective(PartOfDirective node) {
- _delegates.forEach((delegate) => delegate.visitPartOfDirective(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitPostfixExpression(PostfixExpression node) {
- _delegates.forEach((delegate) => delegate.visitPostfixExpression(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitPrefixedIdentifier(PrefixedIdentifier node) {
- _delegates.forEach((delegate) => delegate.visitPrefixedIdentifier(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitPrefixExpression(PrefixExpression node) {
- _delegates.forEach((delegate) => delegate.visitPrefixExpression(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitPropertyAccess(PropertyAccess node) {
- _delegates.forEach((delegate) => delegate.visitPropertyAccess(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitRedirectingConstructorInvocation(
- RedirectingConstructorInvocation node) {
- _delegates.forEach(
- (delegate) => delegate.visitRedirectingConstructorInvocation(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitRethrowExpression(RethrowExpression node) {
- _delegates.forEach((delegate) => delegate.visitRethrowExpression(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitReturnStatement(ReturnStatement node) {
- _delegates.forEach((delegate) => delegate.visitReturnStatement(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitScriptTag(ScriptTag node) {
- _delegates.forEach((delegate) => delegate.visitScriptTag(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitShowCombinator(ShowCombinator node) {
- _delegates.forEach((delegate) => delegate.visitShowCombinator(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitSimpleFormalParameter(SimpleFormalParameter node) {
- _delegates.forEach((delegate) => delegate.visitSimpleFormalParameter(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitSimpleIdentifier(SimpleIdentifier node) {
- _delegates.forEach((delegate) => delegate.visitSimpleIdentifier(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitSimpleStringLiteral(SimpleStringLiteral node) {
- _delegates.forEach((delegate) => delegate.visitSimpleStringLiteral(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitStringInterpolation(StringInterpolation node) {
- _delegates.forEach((delegate) => delegate.visitStringInterpolation(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitSuperConstructorInvocation(SuperConstructorInvocation node) {
- _delegates
- .forEach((delegate) => delegate.visitSuperConstructorInvocation(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitSuperExpression(SuperExpression node) {
- _delegates.forEach((delegate) => delegate.visitSuperExpression(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitSwitchCase(SwitchCase node) {
- _delegates.forEach((delegate) => delegate.visitSwitchCase(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitSwitchDefault(SwitchDefault node) {
- _delegates.forEach((delegate) => delegate.visitSwitchDefault(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitSwitchStatement(SwitchStatement node) {
- _delegates.forEach((delegate) => delegate.visitSwitchStatement(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitSymbolLiteral(SymbolLiteral node) {
- _delegates.forEach((delegate) => delegate.visitSymbolLiteral(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitThisExpression(ThisExpression node) {
- _delegates.forEach((delegate) => delegate.visitThisExpression(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitThrowExpression(ThrowExpression node) {
- _delegates.forEach((delegate) => delegate.visitThrowExpression(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
- _delegates
- .forEach((delegate) => delegate.visitTopLevelVariableDeclaration(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitTryStatement(TryStatement node) {
- _delegates.forEach((delegate) => delegate.visitTryStatement(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitTypeArgumentList(TypeArgumentList node) {
- _delegates.forEach((delegate) => delegate.visitTypeArgumentList(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitTypeName(TypeName node) {
- _delegates.forEach((delegate) => delegate.visitTypeName(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitTypeParameter(TypeParameter node) {
- _delegates.forEach((delegate) => delegate.visitTypeParameter(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitTypeParameterList(TypeParameterList node) {
- _delegates.forEach((delegate) => delegate.visitTypeParameterList(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitVariableDeclaration(VariableDeclaration node) {
- _delegates.forEach((delegate) => delegate.visitVariableDeclaration(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitVariableDeclarationList(VariableDeclarationList node) {
- _delegates
- .forEach((delegate) => delegate.visitVariableDeclarationList(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitVariableDeclarationStatement(VariableDeclarationStatement node) {
- _delegates.forEach(
- (delegate) => delegate.visitVariableDeclarationStatement(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitWhileStatement(WhileStatement node) {
- _delegates.forEach((delegate) => delegate.visitWhileStatement(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitWithClause(WithClause node) {
- _delegates.forEach((delegate) => delegate.visitWithClause(node));
- node.visitChildren(this);
- return null;
- }
-
- @override
- T visitYieldStatement(YieldStatement node) {
- _delegates.forEach((delegate) => delegate.visitYieldStatement(node));
+ T visitNode(AstNode node) {
+ delegates.forEach((delegate) {
+ node.accept(delegate);
+ });
node.visitChildren(this);
return null;
}
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 712e6ae..648a447 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -798,7 +798,6 @@
ParserErrorCode.UNEXPECTED_TOKEN,
ParserErrorCode.WITH_BEFORE_EXTENDS,
ParserErrorCode.WITH_WITHOUT_EXTENDS,
- ParserErrorCode.WRONG_SEPARATOR_FOR_NAMED_PARAMETER,
ParserErrorCode.WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER,
ParserErrorCode.WRONG_TERMINATOR_FOR_PARAMETER_GROUP,
ParserErrorCode.VAR_AND_TYPE,
diff --git a/pkg/analyzer/lib/file_system/file_system.dart b/pkg/analyzer/lib/file_system/file_system.dart
index f005eef..ac8c0db 100644
--- a/pkg/analyzer/lib/file_system/file_system.dart
+++ b/pkg/analyzer/lib/file_system/file_system.dart
@@ -260,8 +260,8 @@
if (!isFileUri(uri)) {
return null;
}
- Resource resource =
- _provider.getResource(_provider.pathContext.fromUri(uri));
+ String path = _provider.pathContext.fromUri(uri);
+ Resource resource = _provider.getResource(path);
if (resource is File) {
return resource.createSource(actualUri ?? uri);
}
diff --git a/pkg/analyzer/lib/file_system/memory_file_system.dart b/pkg/analyzer/lib/file_system/memory_file_system.dart
index 7dd097c..44f8a06 100644
--- a/pkg/analyzer/lib/file_system/memory_file_system.dart
+++ b/pkg/analyzer/lib/file_system/memory_file_system.dart
@@ -13,7 +13,7 @@
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/source/source_resource.dart';
import 'package:analyzer/src/util/absolute_path.dart';
-import 'package:path/path.dart';
+import 'package:path/path.dart' as pathos;
import 'package:watcher/watcher.dart';
/**
@@ -29,17 +29,34 @@
new HashMap<String, List<StreamController<WatchEvent>>>();
int nextStamp = 0;
- final Context _pathContext;
+ final pathos.Context _pathContext;
@override
final AbsolutePathContext absolutePathContext;
- MemoryResourceProvider({bool isWindows: false})
- : _pathContext = isWindows ? windows : posix,
- absolutePathContext = new AbsolutePathContext(isWindows);
+ MemoryResourceProvider(
+ {pathos.Context context, @deprecated bool isWindows: false})
+ : _pathContext = (context ??= pathos.context),
+ absolutePathContext =
+ new AbsolutePathContext(context.style == pathos.Style.windows);
@override
- Context get pathContext => _pathContext;
+ pathos.Context get pathContext => _pathContext;
+
+ /**
+ * Convert the given posix [path] to conform to this provider's path context.
+ *
+ * This is a utility method for testing; paths passed in to other methods in
+ * this class are never converted automatically.
+ */
+ String convertPath(String path) {
+ if (pathContext.style == pathos.windows.style &&
+ path.startsWith(pathos.posix.separator)) {
+ path = r'C:' +
+ path.replaceAll(pathos.posix.separator, pathos.windows.separator);
+ }
+ return path;
+ }
/**
* Delete the file with the given path.
@@ -78,7 +95,13 @@
File getFile(String path) => new _MemoryFile(this, path);
@override
- Folder getFolder(String path) => newFolder(path);
+ Folder getFolder(String path) {
+ path = pathContext.normalize(path);
+ if (!pathContext.isAbsolute(path)) {
+ throw new ArgumentError("Path must be absolute : $path");
+ }
+ return new _MemoryFolder(this, path);
+ }
@override
Future<List<int>> getModificationTimes(List<Source> sources) async {
@@ -213,6 +236,9 @@
void _checkFileAtPath(String path) {
_MemoryResource resource = _pathToResource[path];
if (resource is! _MemoryFile) {
+ if (resource == null) {
+ throw new ArgumentError('File expected at "$path" but does not exist');
+ }
throw new ArgumentError(
'File expected at "$path" but ${resource.runtimeType} found');
}
@@ -324,9 +350,6 @@
}
@override
- Uri toUri() => new Uri.file(path, windows: _provider.pathContext == windows);
-
- @override
void writeAsBytesSync(List<int> bytes) {
throw new FileSystemException(path, 'File could not be written');
}
@@ -399,9 +422,6 @@
File resolveSymbolicLinksSync() => this;
@override
- Uri toUri() => new Uri.file(path, windows: _provider.pathContext == windows);
-
- @override
void writeAsBytesSync(List<int> bytes) {
_provider._setFileContent(this, bytes);
}
@@ -494,10 +514,6 @@
@override
Folder resolveSymbolicLinksSync() => this;
-
- @override
- Uri toUri() =>
- new Uri.directory(path, windows: _provider.pathContext == windows);
}
/**
@@ -535,7 +551,7 @@
if (parentPath == path) {
return null;
}
- return _provider.getResource(parentPath);
+ return _provider.getFolder(parentPath);
}
@override
@@ -551,4 +567,7 @@
@override
String toString() => path;
+
+ @override
+ Uri toUri() => _provider.pathContext.toUri(path);
}
diff --git a/pkg/analyzer/lib/src/context/builder.dart b/pkg/analyzer/lib/src/context/builder.dart
index e72f333..882094f 100644
--- a/pkg/analyzer/lib/src/context/builder.dart
+++ b/pkg/analyzer/lib/src/context/builder.dart
@@ -14,9 +14,13 @@
import 'package:analyzer/source/analysis_options_provider.dart';
import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart';
+import 'package:analyzer/src/generated/bazel.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/summary/package_bundle_reader.dart';
+import 'package:analyzer/src/summary/pub_summary.dart';
+import 'package:analyzer/src/summary/summary_sdk.dart';
import 'package:analyzer/src/task/options.dart';
import 'package:package_config/packages.dart';
import 'package:package_config/packages_file.dart';
@@ -68,12 +72,14 @@
* The resolver provider used to create a package: URI resolver, or `null` if
* the normal (Package Specification DEP) lookup mechanism is to be used.
*/
+ @deprecated
ResolverProvider packageResolverProvider;
/**
* The resolver provider used to create a file: URI resolver, or `null` if
* the normal file URI resolver is to be used.
*/
+ @deprecated
ResolverProvider fileResolverProvider;
/**
@@ -91,6 +97,13 @@
String defaultPackagesDirectoryPath;
/**
+ * The file path of the file containing the summary of the SDK that should be
+ * used to "analyze" the SDK. This option should only be specified by
+ * command-line tools such as 'dartanalyzer' or 'ddc'.
+ */
+ String dartSdkSummaryPath;
+
+ /**
* The file path of the analysis options file that should be used in place of
* any file in the root directory or a parent of the root directory, or `null`
* if the normal lookup mechanism should be used.
@@ -111,6 +124,11 @@
Map<String, String> declaredVariables;
/**
+ * The manager of pub package summaries.
+ */
+ PubSummaryManager pubSummaryManager;
+
+ /**
* Initialize a newly created builder to be ready to build a context rooted in
* the directory with the given [rootDirectoryPath].
*/
@@ -132,9 +150,29 @@
context.name = path;
//_processAnalysisOptions(context, optionMap);
declareVariables(context);
+ configureSummaries(context);
return context;
}
+ /**
+ * Configure the context to make use of summaries.
+ */
+ void configureSummaries(InternalAnalysisContext context) {
+ if (pubSummaryManager != null) {
+ List<LinkedPubPackage> linkedBundles =
+ pubSummaryManager.getLinkedBundles(context);
+ if (linkedBundles.isNotEmpty) {
+ SummaryDataStore store = new SummaryDataStore([]);
+ for (LinkedPubPackage package in linkedBundles) {
+ store.addBundle(null, package.unlinked);
+ store.addBundle(null, package.linked);
+ }
+ context.resultProvider =
+ new InputPackagesResultProvider(context, store);
+ }
+ }
+ }
+
Map<String, List<Folder>> convertPackagesToMap(Packages packages) {
Map<String, List<Folder>> folderMap = new HashMap<String, List<Folder>>();
if (packages != null && packages != Packages.noPackages) {
@@ -193,38 +231,24 @@
return findPackagesFromFile(rootDirectoryPath);
}
- SourceFactory createSourceFactory(
- String rootDirectoryPath, AnalysisOptions options) {
- Folder _folder = null;
- Folder folder() {
- return _folder ??= resourceProvider.getFolder(rootDirectoryPath);
+ SourceFactory createSourceFactory(String rootPath, AnalysisOptions options) {
+ BazelWorkspace bazelWorkspace =
+ BazelWorkspace.find(resourceProvider, rootPath);
+ if (bazelWorkspace != null) {
+ List<UriResolver> resolvers = <UriResolver>[
+ new DartUriResolver(findSdk(null, options)),
+ new BazelPackageUriResolver(bazelWorkspace),
+ new BazelFileUriResolver(bazelWorkspace)
+ ];
+ return new SourceFactory(resolvers, null, resourceProvider);
}
- UriResolver fileResolver;
- if (fileResolverProvider != null) {
- fileResolver = fileResolverProvider(folder());
- }
- fileResolver ??= new ResourceUriResolver(resourceProvider);
- if (packageResolverProvider != null) {
- UriResolver packageResolver = packageResolverProvider(folder());
- if (packageResolver != null) {
- // TODO(brianwilkerson) This doesn't support either embedder files or
- // sdk extensions because we don't have a way to get the package map
- // from the resolver.
- List<UriResolver> resolvers = <UriResolver>[
- new DartUriResolver(findSdk(null, options)),
- packageResolver,
- fileResolver
- ];
- return new SourceFactory(resolvers, null, resourceProvider);
- }
- }
- Packages packages = createPackageMap(rootDirectoryPath);
+ Packages packages = createPackageMap(rootPath);
Map<String, List<Folder>> packageMap = convertPackagesToMap(packages);
List<UriResolver> resolvers = <UriResolver>[
new DartUriResolver(findSdk(packageMap, options)),
new PackageMapUriResolver(resourceProvider, packageMap),
- fileResolver
+ new ResourceUriResolver(resourceProvider)
];
return new SourceFactory(resolvers, packages, resourceProvider);
}
@@ -272,7 +296,9 @@
*/
DartSdk findSdk(
Map<String, List<Folder>> packageMap, AnalysisOptions options) {
- if (packageMap != null) {
+ if (dartSdkSummaryPath != null) {
+ return new SummaryBasedDartSdk(dartSdkSummaryPath, options.strongMode);
+ } else if (packageMap != null) {
SdkExtensionFinder extFinder = new SdkExtensionFinder(packageMap);
List<String> extFilePaths = extFinder.extensionFilePaths;
EmbedderYamlLocator locator = new EmbedderYamlLocator(packageMap);
@@ -324,8 +350,8 @@
String sdkPath = sdkManager.defaultSdkDirectory;
SdkDescription description = new SdkDescription(<String>[sdkPath], options);
return sdkManager.getSdk(description, () {
- FolderBasedDartSdk sdk = new FolderBasedDartSdk(
- resourceProvider, resourceProvider.getFolder(sdkPath));
+ FolderBasedDartSdk sdk = new FolderBasedDartSdk(resourceProvider,
+ resourceProvider.getFolder(sdkPath), options.strongMode);
sdk.analysisOptions = options;
sdk.useSummary = sdkManager.canUseSummaries;
return sdk;
diff --git a/pkg/analyzer/lib/src/context/cache.dart b/pkg/analyzer/lib/src/context/cache.dart
index bf981e5..ef78031 100644
--- a/pkg/analyzer/lib/src/context/cache.dart
+++ b/pkg/analyzer/lib/src/context/cache.dart
@@ -1229,7 +1229,8 @@
*/
CacheFlushManager _getFlushManager(ResultDescriptor descriptor) {
ResultCachingPolicy policy = descriptor.cachingPolicy;
- if (identical(policy, DEFAULT_CACHING_POLICY)) {
+ if (identical(policy, DEFAULT_CACHING_POLICY) ||
+ context.analysisOptions.disableCacheFlushing) {
return UnlimitedCacheFlushManager.INSTANCE;
}
CacheFlushManager manager = _flushManagerMap[policy];
diff --git a/pkg/analyzer/lib/src/context/context.dart b/pkg/analyzer/lib/src/context/context.dart
index f56c12c..d0a2104 100644
--- a/pkg/analyzer/lib/src/context/context.dart
+++ b/pkg/analyzer/lib/src/context/context.dart
@@ -290,6 +290,8 @@
this._options.enableAssertMessage != options.enableAssertMessage ||
this._options.enableInitializingFormalAccess !=
options.enableInitializingFormalAccess ||
+ this._options.enableLazyAssignmentOperators !=
+ options.enableLazyAssignmentOperators ||
((options is AnalysisOptionsImpl)
? this._options.strongModeHints != options.strongModeHints
: false) ||
@@ -306,10 +308,6 @@
options.enableStrictCallChecks ||
this._options.enableGenericMethods != options.enableGenericMethods ||
this._options.enableSuperMixins != options.enableSuperMixins;
- int cacheSize = options.cacheSize;
- if (this._options.cacheSize != cacheSize) {
- this._options.cacheSize = cacheSize;
- }
this._options.analyzeFunctionBodiesPredicate =
options.analyzeFunctionBodiesPredicate;
this._options.generateImplicitErrors = options.generateImplicitErrors;
@@ -321,6 +319,8 @@
this._options.enableStrictCallChecks = options.enableStrictCallChecks;
this._options.enableInitializingFormalAccess =
options.enableInitializingFormalAccess;
+ this._options.enableLazyAssignmentOperators =
+ options.enableLazyAssignmentOperators;
this._options.enableSuperMixins = options.enableSuperMixins;
this._options.enableTiming = options.enableTiming;
this._options.hint = options.hint;
@@ -334,6 +334,7 @@
}
this._options.strongMode = options.strongMode;
this._options.trackCacheDependencies = options.trackCacheDependencies;
+ this._options.disableCacheFlushing = options.disableCacheFlushing;
this._options.finerGrainedInvalidation = options.finerGrainedInvalidation;
if (options is AnalysisOptionsImpl) {
this._options.strongModeHints = options.strongModeHints;
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 4df003d..b260fa8 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -283,7 +283,7 @@
Element get element {
if (_element != null) {
return _element;
- } else if (_name != null) {
+ } else if (_constructorName == null && _name != null) {
return _name.staticElement;
}
return null;
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index f8ecce5..8cf5463 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -19,6 +19,13 @@
import 'package:analyzer/src/generated/utilities_dart.dart';
/**
+ * A function used to handle exceptions that are thrown by delegates while using
+ * an [ExceptionHandlingDelegatingAstVisitor].
+ */
+typedef void ExceptionInDelegateHandler(
+ AstNode node, AstVisitor visitor, dynamic exception, StackTrace stackTrace);
+
+/**
* An AST visitor that will clone any AST structure that it visits. The cloner
* will only clone the structure, it will not preserve any resolution results or
* properties associated with the nodes.
@@ -2631,6 +2638,69 @@
}
/**
+ * A [DelegatingAstVisitor] that will additionally catch all exceptions from the
+ * delegates without stopping the visiting. A function must be provided that
+ * will be invoked for each such exception.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+class ExceptionHandlingDelegatingAstVisitor<T> extends DelegatingAstVisitor<T> {
+ /**
+ * The function that will be executed for each exception that is thrown by one
+ * of the visit methods on the delegate.
+ */
+ final ExceptionInDelegateHandler handler;
+
+ /**
+ * Initialize a newly created visitor to use each of the given delegate
+ * visitors to visit the nodes of an AST structure.
+ */
+ ExceptionHandlingDelegatingAstVisitor(
+ Iterable<AstVisitor<T>> delegates, this.handler)
+ : super(delegates) {
+ if (handler == null) {
+ throw new ArgumentError('A handler must be provided');
+ }
+ }
+
+ @override
+ T visitNode(AstNode node) {
+ delegates.forEach((delegate) {
+ try {
+ node.accept(delegate);
+ } catch (exception, stackTrace) {
+ handler(node, delegate, exception, stackTrace);
+ }
+ });
+ node.visitChildren(this);
+ return null;
+ }
+
+ /**
+ * A function that can be used with instances of this class to log and then
+ * ignore any exceptions that are thrown by any of the delegates.
+ */
+ static void logException(AstNode node, AstVisitor visitor, dynamic exception,
+ StackTrace stackTrace) {
+ StringBuffer buffer = new StringBuffer();
+ buffer.write('Exception while using a ${visitor.runtimeType} to visit a ');
+ AstNode currentNode = node;
+ bool first = true;
+ while (currentNode != null) {
+ if (first) {
+ first = false;
+ } else {
+ buffer.write('in ');
+ }
+ buffer.write(currentNode.runtimeType);
+ currentNode = currentNode.parent;
+ }
+ AnalysisEngine.instance.logger.logError(
+ buffer.toString(), new CaughtException(exception, stackTrace));
+ }
+}
+
+/**
* An object that will clone any AST structure that it visits. The cloner will
* clone the structure, replacing the specified ASTNode with a new ASTNode,
* mapping the old token stream to a new token stream, and preserving resolution
diff --git a/pkg/analyzer/lib/src/dart/constant/utilities.dart b/pkg/analyzer/lib/src/dart/constant/utilities.dart
index 90c8a38..d9ef263 100644
--- a/pkg/analyzer/lib/src/dart/constant/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/constant/utilities.dart
@@ -46,6 +46,13 @@
}
@override
+ Annotation visitAnnotation(Annotation node) {
+ Annotation annotation = super.visitAnnotation(node);
+ annotation.element = node.element;
+ return annotation;
+ }
+
+ @override
FunctionExpression visitFunctionExpression(FunctionExpression node) {
FunctionExpression expression = super.visitFunctionExpression(node);
expression.element = node.element;
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 9cb2c7b..6c18785 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -6837,12 +6837,7 @@
*/
int _visibleRangeLength = -1;
- /**
- * True if this parameter inherits from a covariant parameter. This happens
- * when it overrides a method in a supertype that has a corresponding
- * covariant parameter.
- */
- bool inheritsCovariant = false;
+ bool _inheritsCovariant = false;
/**
* Initialize a newly created parameter element to have the given [name] and
@@ -6967,6 +6962,28 @@
super.hasImplicitType = hasImplicitType;
}
+ /**
+ * True if this parameter inherits from a covariant parameter. This happens
+ * when it overrides a method in a supertype that has a corresponding
+ * covariant parameter.
+ */
+ bool get inheritsCovariant {
+ if (_unlinkedParam != null) {
+ return enclosingUnit.resynthesizerContext
+ .inheritsCovariant(_unlinkedParam.inheritsCovariantSlot);
+ } else {
+ return _inheritsCovariant;
+ }
+ }
+
+ /**
+ * Record whether or not this parameter inherits from a covariant parameter.
+ */
+ void set inheritsCovariant(bool value) {
+ assert(_unlinkedParam == null);
+ _inheritsCovariant = value;
+ }
+
@override
FunctionElement get initializer {
if (_unlinkedParam != null && _initializer == null) {
@@ -7738,6 +7755,11 @@
UnitExplicitTopLevelVariables buildTopLevelVariables();
/**
+ * Return `true` if the given parameter [slot] inherits `@covariant` behavior.
+ */
+ bool inheritsCovariant(int slot);
+
+ /**
* Return `true` if the given const constructor [slot] is a part of a cycle.
*/
bool isInConstCycle(int slot);
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
index 29b347f..d498728 100644
--- a/pkg/analyzer/lib/src/dart/element/member.dart
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -742,34 +742,6 @@
super.visitChildren(visitor);
safelyVisitChildren(parameters, visitor);
}
-
- /**
- * If the given [parameter]'s type is different when any type parameters from
- * the defining type's declaration are replaced with the actual type
- * arguments from the [definingType], create a parameter member representing
- * the given parameter. Return the member that was created, or the base
- * parameter if no member was created.
- */
- static ParameterElement from(
- ParameterElement parameter, ParameterizedType definingType) {
- if (parameter == null || definingType.typeArguments.length == 0) {
- return parameter;
- }
- // Check if parameter type depends on defining type type arguments.
- // It is possible that we did not resolve field formal parameter yet,
- // so skip this check for it.
- if (parameter is FieldFormalParameterElement) {
- return new FieldFormalParameterMember(parameter, definingType);
- } else {
- DartType baseType = parameter.type;
- List<DartType> argumentTypes = definingType.typeArguments;
- List<DartType> parameterTypes =
- TypeParameterTypeImpl.getTypes(definingType.typeParameters);
- DartType substitutedType =
- baseType.substitute2(argumentTypes, parameterTypes);
- return new ParameterMember(parameter, definingType, substitutedType);
- }
- }
}
/**
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 4c2e971..4bc84b6 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -515,13 +515,41 @@
if (parameterCount == 0) {
return baseParameters;
}
+
// create specialized parameters
- List<ParameterElement> specializedParameters =
- new List<ParameterElement>(parameterCount);
+ var specializedParams = new List<ParameterElement>(parameterCount);
+
+ var parameterTypes = TypeParameterTypeImpl.getTypes(typeParameters);
for (int i = 0; i < parameterCount; i++) {
- specializedParameters[i] = ParameterMember.from(baseParameters[i], this);
+ var parameter = baseParameters[i];
+ if (parameter?.type == null) {
+ specializedParams[i] = parameter;
+ continue;
+ }
+
+ // Check if parameter type depends on defining type type arguments, or
+ // if it needs to be pruned.
+
+ if (parameter is FieldFormalParameterElement) {
+ // TODO(jmesserly): this seems like it won't handle pruning correctly.
+ specializedParams[i] = new FieldFormalParameterMember(parameter, this);
+ continue;
+ }
+
+ var baseType = parameter.type as TypeImpl;
+ TypeImpl type;
+ if (typeArguments.isEmpty ||
+ typeArguments.length != typeParameters.length) {
+ type = baseType.pruned(newPrune);
+ } else {
+ type = baseType.substitute2(typeArguments, parameterTypes, newPrune);
+ }
+
+ specializedParams[i] = identical(type, baseType)
+ ? parameter
+ : new ParameterMember(parameter, this, type);
}
- return specializedParameters;
+ return specializedParams;
}
@override
@@ -634,6 +662,7 @@
return instantiate(freshVariables) ==
object.instantiate(freshVariables);
}
+
return returnType == object.returnType &&
TypeImpl.equalArrays(
normalParameterTypes, object.normalParameterTypes) &&
diff --git a/pkg/analyzer/lib/src/dart/element/utilities.dart b/pkg/analyzer/lib/src/dart/element/utilities.dart
deleted file mode 100644
index 7c5aa4c..0000000
--- a/pkg/analyzer/lib/src/dart/element/utilities.dart
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2014, 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 analyzer.src.dart.element.utilities;
-
-import 'dart:collection';
-
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/visitor.dart';
-
-/**
- * A visitor that can be used to collect all of the non-synthetic elements in an
- * element model.
- */
-class ElementGatherer extends GeneralizingElementVisitor {
- /**
- * The set in which the elements are collected.
- */
- final Set<Element> elements = new HashSet<Element>();
-
- /**
- * Initialize the visitor.
- */
- ElementGatherer();
-
- @override
- void visitElement(Element element) {
- if (!element.isSynthetic) {
- elements.add(element);
- }
- super.visitElement(element);
- }
-}
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
index 31ee726..706abd1 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
@@ -614,10 +614,6 @@
'WITH_WITHOUT_EXTENDS',
"The with clause cannot be used without an extends clause");
- static const ParserErrorCode WRONG_SEPARATOR_FOR_NAMED_PARAMETER =
- const ParserErrorCode('WRONG_SEPARATOR_FOR_NAMED_PARAMETER',
- "The default value of a named parameter should be preceeded by ':'");
-
static const ParserErrorCode WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER =
const ParserErrorCode('WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER',
"The default value of a positional parameter should be preceeded by '='");
diff --git a/pkg/analyzer/lib/src/dart/sdk/patch.dart b/pkg/analyzer/lib/src/dart/sdk/patch.dart
new file mode 100644
index 0000000..88a122e
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/sdk/patch.dart
@@ -0,0 +1,371 @@
+// 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.
+
+library analyzer.src.dart.sdk.patch;
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/dart/scanner/reader.dart';
+import 'package:analyzer/src/dart/scanner/scanner.dart';
+import 'package:analyzer/src/dart/sdk/sdk.dart';
+import 'package:analyzer/src/generated/parser.dart';
+import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:meta/meta.dart';
+import 'package:path/src/context.dart';
+
+/**
+ * [SdkPatcher] applies patches to SDK [CompilationUnit].
+ */
+class SdkPatcher {
+ bool _allowNewPublicNames;
+ String _baseDesc;
+ String _patchDesc;
+ CompilationUnit _patchUnit;
+
+ /**
+ * Patch the given [unit] of a SDK [source] with the patches defined in
+ * the [sdk] for the given [platform]. Throw [ArgumentError] if a patch
+ * file cannot be read, or the contents violates rules for patch files.
+ */
+ void patch(
+ FolderBasedDartSdk sdk,
+ int platform,
+ AnalysisErrorListener errorListener,
+ Source source,
+ CompilationUnit unit) {
+ // Process URI.
+ String libraryUriStr;
+ bool isLibraryDefiningUnit;
+ {
+ Uri uri = source.uri;
+ if (uri.scheme != 'dart') {
+ throw new ArgumentError(
+ 'The URI of the unit to patch must have the "dart" scheme: $uri');
+ }
+ List<String> uriSegments = uri.pathSegments;
+ String libraryName = uriSegments.first;
+ libraryUriStr = 'dart:$libraryName';
+ isLibraryDefiningUnit = uriSegments.length == 1;
+ _allowNewPublicNames = libraryName == '_internal';
+ }
+ // Prepare the patch files to apply.
+ List<String> patchPaths;
+ {
+ SdkLibrary sdkLibrary = sdk.getSdkLibrary(libraryUriStr);
+ if (sdkLibrary == null) {
+ throw new ArgumentError(
+ 'The library $libraryUriStr is not defined in the SDK.');
+ }
+ patchPaths = sdkLibrary.getPatches(platform);
+ }
+
+ bool strongMode = sdk.analysisOptions.strongMode;
+ Context pathContext = sdk.resourceProvider.pathContext;
+ for (String path in patchPaths) {
+ String pathInLib = pathContext.joinAll(path.split('/'));
+ File patchFile = sdk.libraryDirectory.getChildAssumingFile(pathInLib);
+ if (!patchFile.exists) {
+ throw new ArgumentError(
+ 'The patch file ${patchFile.path} for $source does not exist.');
+ }
+ Source patchSource = patchFile.createSource();
+ CompilationUnit patchUnit = parse(patchSource, strongMode, errorListener);
+
+ // Prepare for reporting errors.
+ _baseDesc = source.toString();
+ _patchDesc = patchFile.path;
+ _patchUnit = patchUnit;
+
+ if (isLibraryDefiningUnit) {
+ _patchDirectives(source, unit, patchSource, patchUnit);
+ }
+ _patchTopLevelDeclarations(unit, patchUnit, isLibraryDefiningUnit);
+ }
+ }
+
+ void _failExternalKeyword(String name, int offset) {
+ throw new ArgumentError(
+ 'The keyword "external" was expected for "$name" in $_baseDesc @ $offset.');
+ }
+
+ void _failIfPublicName(AstNode node, String name) {
+ if (_allowNewPublicNames) {
+ return;
+ }
+ if (!Identifier.isPrivateName(name)) {
+ _failInPatch('contains a public declaration "$name"', node.offset);
+ }
+ }
+
+ void _failInPatch(String message, int offset) {
+ String loc = _getLocationDesc3(_patchUnit, offset);
+ throw new ArgumentError(
+ 'The patch file $_patchDesc for $_baseDesc $message at $loc.');
+ }
+
+ String _getLocationDesc3(CompilationUnit unit, int offset) {
+ LineInfo_Location location = unit.lineInfo.getLocation(offset);
+ return 'the line ${location.lineNumber}';
+ }
+
+ void _patchClassMembers(
+ ClassDeclaration baseClass, ClassDeclaration patchClass) {
+ String className = baseClass.name.name;
+ List<ClassMember> membersToAppend = [];
+ for (ClassMember patchMember in patchClass.members) {
+ if (patchMember is FieldDeclaration) {
+ if (_hasPatchAnnotation(patchMember.metadata)) {
+ _failInPatch('attempts to patch a field', patchMember.offset);
+ }
+ List<VariableDeclaration> fields = patchMember.fields.variables;
+ if (fields.length != 1) {
+ _failInPatch('contains a field declaration with more than one field',
+ patchMember.offset);
+ }
+ String name = fields[0].name.name;
+ if (!_allowNewPublicNames &&
+ !Identifier.isPrivateName(className) &&
+ !Identifier.isPrivateName(name)) {
+ _failInPatch('contains a public field', patchMember.offset);
+ }
+ membersToAppend.add(patchMember);
+ } else if (patchMember is MethodDeclaration) {
+ String name = patchMember.name.name;
+ if (_hasPatchAnnotation(patchMember.metadata)) {
+ for (ClassMember baseMember in baseClass.members) {
+ if (baseMember is MethodDeclaration &&
+ baseMember.name.name == name) {
+ // Remove the "external" keyword.
+ Token externalKeyword = baseMember.externalKeyword;
+ if (externalKeyword != null) {
+ baseMember.externalKeyword = null;
+ _removeToken(externalKeyword);
+ } else {
+ _failExternalKeyword(name, baseMember.offset);
+ }
+ // Replace the body.
+ FunctionBody oldBody = baseMember.body;
+ FunctionBody newBody = patchMember.body;
+ _replaceNodeTokens(oldBody, newBody);
+ baseMember.body = newBody;
+ }
+ }
+ } else {
+ _failIfPublicName(patchMember, name);
+ membersToAppend.add(patchMember);
+ }
+ } else if (patchMember is ConstructorDeclaration) {
+ String name = patchMember.name?.name;
+ if (_hasPatchAnnotation(patchMember.metadata)) {
+ for (ClassMember baseMember in baseClass.members) {
+ if (baseMember is ConstructorDeclaration &&
+ baseMember.name?.name == name) {
+ // Remove the "external" keyword.
+ Token externalKeyword = baseMember.externalKeyword;
+ if (externalKeyword != null) {
+ baseMember.externalKeyword = null;
+ _removeToken(externalKeyword);
+ } else {
+ _failExternalKeyword(name, baseMember.offset);
+ }
+ // Factory vs. generative.
+ if (baseMember.factoryKeyword == null &&
+ patchMember.factoryKeyword != null) {
+ _failInPatch(
+ 'attempts to replace generative constructor with a factory one',
+ patchMember.offset);
+ } else if (baseMember.factoryKeyword != null &&
+ patchMember.factoryKeyword == null) {
+ _failInPatch(
+ 'attempts to replace factory constructor with a generative one',
+ patchMember.offset);
+ }
+ // The base constructor should not have initializers.
+ if (baseMember.initializers.isNotEmpty) {
+ throw new ArgumentError(
+ 'Cannot patch external constructors with initializers '
+ 'in $_baseDesc.');
+ }
+ // Prepare nodes.
+ FunctionBody baseBody = baseMember.body;
+ FunctionBody patchBody = patchMember.body;
+ NodeList<ConstructorInitializer> baseInitializers =
+ baseMember.initializers;
+ NodeList<ConstructorInitializer> patchInitializers =
+ patchMember.initializers;
+ // Replace initializers and link tokens.
+ if (patchInitializers.isNotEmpty) {
+ baseMember.parameters.endToken
+ .setNext(patchInitializers.beginToken.previous);
+ baseInitializers.addAll(patchInitializers);
+ patchBody.endToken.setNext(baseBody.endToken.next);
+ } else {
+ _replaceNodeTokens(baseBody, patchBody);
+ }
+ // Replace the body.
+ baseMember.body = patchBody;
+ }
+ }
+ } else {
+ if (name == null) {
+ if (!_allowNewPublicNames && !Identifier.isPrivateName(className)) {
+ _failInPatch(
+ 'contains an unnamed public constructor', patchMember.offset);
+ }
+ } else {
+ _failIfPublicName(patchMember, name);
+ }
+ membersToAppend.add(patchMember);
+ }
+ } else {
+ String className = patchClass.name.name;
+ _failInPatch('contains an unsupported class member in $className',
+ patchMember.offset);
+ }
+ }
+ // Append new class members.
+ _appendToNodeList(
+ baseClass.members, membersToAppend, baseClass.leftBracket);
+ }
+
+ void _patchDirectives(Source baseSource, CompilationUnit baseUnit,
+ Source patchSource, CompilationUnit patchUnit) {
+ for (Directive patchDirective in patchUnit.directives) {
+ if (patchDirective is ImportDirective) {
+ baseUnit.directives.add(patchDirective);
+ } else {
+ _failInPatch('contains an unsupported "$patchDirective" directive',
+ patchDirective.offset);
+ }
+ }
+ }
+
+ void _patchTopLevelDeclarations(CompilationUnit baseUnit,
+ CompilationUnit patchUnit, bool appendNewTopLevelDeclarations) {
+ List<CompilationUnitMember> declarationsToAppend = [];
+ for (CompilationUnitMember patchDeclaration in patchUnit.declarations) {
+ if (patchDeclaration is FunctionDeclaration) {
+ String name = patchDeclaration.name.name;
+ if (_hasPatchAnnotation(patchDeclaration.metadata)) {
+ for (CompilationUnitMember baseDeclaration in baseUnit.declarations) {
+ if (patchDeclaration is FunctionDeclaration &&
+ baseDeclaration is FunctionDeclaration &&
+ baseDeclaration.name.name == name) {
+ // Remove the "external" keyword.
+ Token externalKeyword = baseDeclaration.externalKeyword;
+ if (externalKeyword != null) {
+ baseDeclaration.externalKeyword = null;
+ _removeToken(externalKeyword);
+ } else {
+ _failExternalKeyword(name, baseDeclaration.offset);
+ }
+ // Replace the body.
+ FunctionExpression oldExpr = baseDeclaration.functionExpression;
+ FunctionBody newBody = patchDeclaration.functionExpression.body;
+ _replaceNodeTokens(oldExpr.body, newBody);
+ oldExpr.body = newBody;
+ }
+ }
+ } else if (appendNewTopLevelDeclarations) {
+ _failIfPublicName(patchDeclaration, name);
+ declarationsToAppend.add(patchDeclaration);
+ }
+ } else if (patchDeclaration is FunctionTypeAlias) {
+ if (patchDeclaration.metadata.isNotEmpty) {
+ _failInPatch('contains a function type alias with an annotation',
+ patchDeclaration.offset);
+ }
+ _failIfPublicName(patchDeclaration, patchDeclaration.name.name);
+ declarationsToAppend.add(patchDeclaration);
+ } else if (patchDeclaration is ClassDeclaration) {
+ if (_hasPatchAnnotation(patchDeclaration.metadata)) {
+ String name = patchDeclaration.name.name;
+ for (CompilationUnitMember baseDeclaration in baseUnit.declarations) {
+ if (baseDeclaration is ClassDeclaration &&
+ baseDeclaration.name.name == name) {
+ _patchClassMembers(baseDeclaration, patchDeclaration);
+ }
+ }
+ } else {
+ _failIfPublicName(patchDeclaration, patchDeclaration.name.name);
+ declarationsToAppend.add(patchDeclaration);
+ }
+ } else {
+ _failInPatch('contains an unsupported top-level declaration',
+ patchDeclaration.offset);
+ }
+ }
+ // Append new top-level declarations.
+ if (appendNewTopLevelDeclarations) {
+ _appendToNodeList(baseUnit.declarations, declarationsToAppend,
+ baseUnit.endToken.previous);
+ }
+ }
+
+ /**
+ * Parse the given [source] into AST.
+ */
+ @visibleForTesting
+ static CompilationUnit parse(
+ Source source, bool strong, AnalysisErrorListener errorListener) {
+ String code = source.contents.data;
+
+ CharSequenceReader reader = new CharSequenceReader(code);
+ Scanner scanner = new Scanner(source, reader, errorListener);
+ scanner.scanGenericMethodComments = strong;
+ Token token = scanner.tokenize();
+ LineInfo lineInfo = new LineInfo(scanner.lineStarts);
+
+ Parser parser = new Parser(source, errorListener);
+ parser.parseGenericMethodComments = strong;
+ CompilationUnit unit = parser.parseCompilationUnit(token);
+ unit.lineInfo = lineInfo;
+ return unit;
+ }
+
+ /**
+ * Append [newNodes] to the given [nodes] and attach new tokens to the end
+ * token of the last [nodes] items, or, if it is empty, to [defaultPrevToken].
+ */
+ static void _appendToNodeList(
+ NodeList<AstNode> nodes, List<AstNode> newNodes, Token defaultPrevToken) {
+ Token prevToken = nodes.endToken ?? defaultPrevToken;
+ for (AstNode newNode in newNodes) {
+ newNode.endToken.setNext(prevToken.next);
+ prevToken.setNext(newNode.beginToken);
+ nodes.add(newNode);
+ prevToken = newNode.endToken;
+ }
+ }
+
+ /**
+ * Return `true` if [metadata] has the `@patch` annotation.
+ */
+ static bool _hasPatchAnnotation(List<Annotation> metadata) {
+ return metadata.any((annotation) {
+ Identifier name = annotation.name;
+ return annotation.constructorName == null &&
+ name is SimpleIdentifier &&
+ name.name == 'patch';
+ });
+ }
+
+ /**
+ * Remove the [token] from the stream.
+ */
+ static void _removeToken(Token token) {
+ token.previous.setNext(token.next);
+ }
+
+ /**
+ * Replace tokens of the [oldNode] with tokens of the [newNode].
+ */
+ static void _replaceNodeTokens(AstNode oldNode, AstNode newNode) {
+ oldNode.beginToken.previous.setNext(newNode.beginToken);
+ newNode.endToken.setNext(oldNode.endToken.next);
+ }
+}
diff --git a/pkg/analyzer/lib/src/dart/sdk/sdk.dart b/pkg/analyzer/lib/src/dart/sdk/sdk.dart
index 7ab8272..303e6a4 100644
--- a/pkg/analyzer/lib/src/dart/sdk/sdk.dart
+++ b/pkg/analyzer/lib/src/dart/sdk/sdk.dart
@@ -66,6 +66,11 @@
PackageBundle _sdkBundle;
/**
+ * Return the analysis options for this SDK analysis context.
+ */
+ AnalysisOptions get analysisOptions => _analysisOptions;
+
+ /**
* Set the [options] for this SDK analysis context. Throw [StateError] if the
* context has been already created.
*/
@@ -680,6 +685,15 @@
return null;
}
pathos.Context pathContext = resourceProvider.pathContext;
+ if (pathContext.style != pathos.context.style) {
+ // This will only happen when running tests.
+ if (exec.startsWith(new RegExp('[a-zA-Z]:'))) {
+ exec = exec.substring(2);
+ } else if (resourceProvider is MemoryResourceProvider) {
+ exec = resourceProvider.convertPath(exec);
+ }
+ exec = pathContext.fromUri(pathos.context.toUri(exec));
+ }
// Might be "xcodebuild/ReleaseIA32/dart" with "sdk" sibling
String outDir = pathContext.dirname(pathContext.dirname(exec));
String sdkPath = pathContext.join(pathContext.dirname(outDir), "sdk");
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index 06d6ae3..7d9eec5 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -752,6 +752,17 @@
'DUPLICATE_DEFINITION', "The name '{0}' is already defined");
/**
+ * 18.3 Parts: It's a compile-time error if the same library contains two part
+ * directives with the same URI.
+ *
+ * Parameters:
+ * 0: the URI of the duplicate part
+ */
+ static const CompileTimeErrorCode DUPLICATE_PART = const CompileTimeErrorCode(
+ 'DUPLICATE_PART',
+ "The library already contains a part with the uri '{0}'.");
+
+ /**
* 7. Classes: It is a compile-time error if a class has an instance member
* and a static member with the same name.
*
diff --git a/pkg/analyzer/lib/src/generated/bazel.dart b/pkg/analyzer/lib/src/generated/bazel.dart
index debd300..b81a0c8 100644
--- a/pkg/analyzer/lib/src/generated/bazel.dart
+++ b/pkg/analyzer/lib/src/generated/bazel.dart
@@ -4,11 +4,14 @@
library analyzer.src.generated.bazel;
+import 'dart:collection';
import 'dart:core';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/util/fast_uri.dart';
+import 'package:path/path.dart';
/**
* Instances of the class `BazelFileUriResolver` resolve `file` URI's by first
@@ -16,54 +19,279 @@
* corresponding generated directories.
*/
class BazelFileUriResolver extends ResourceUriResolver {
- /**
- * The Bazel workspace directory.
- */
- final Folder _workspaceDir;
+ final BazelWorkspace workspace;
- /**
- * The build directories that relative `file` URI's should use to resolve
- * relative URIs.
- */
- final List<Folder> _buildDirectories;
-
- BazelFileUriResolver(
- ResourceProvider provider, this._workspaceDir, this._buildDirectories)
- : super(provider);
+ BazelFileUriResolver(BazelWorkspace workspace)
+ : workspace = workspace,
+ super(workspace.provider);
@override
Source resolveAbsolute(Uri uri, [Uri actualUri]) {
if (!ResourceUriResolver.isFileUri(uri)) {
return null;
}
-
- File uriFile = provider.getFile(provider.pathContext.fromUri(uri));
- if (uriFile.exists) {
- return uriFile.createSource(actualUri ?? uri);
- }
-
- String relativeFromWorkspaceDir = _getPathFromWorkspaceDir(uri);
- if (_buildDirectories.isEmpty || relativeFromWorkspaceDir.isEmpty) {
- return null;
- }
-
- for (Folder buildDir in _buildDirectories) {
- File file = buildDir.getChildAssumingFile(relativeFromWorkspaceDir);
- if (file.exists) {
- return file.createSource(actualUri ?? uri);
- }
+ String path = provider.pathContext.fromUri(uri);
+ File file = workspace.findFile(path);
+ if (file != null) {
+ return file.createSource(actualUri ?? uri);
}
return null;
}
+}
- String _getPathFromWorkspaceDir(Uri uri) {
- String uriPath = uri.path;
- String workspacePath = _workspaceDir.path;
+/**
+ * The [UriResolver] that can resolve `package` URIs in [BazelWorkspace].
+ */
+class BazelPackageUriResolver extends UriResolver {
+ final BazelWorkspace _workspace;
+ final Context _context;
- if (uriPath.startsWith(workspacePath) &&
- workspacePath.length < uriPath.length) {
- return uriPath.substring(workspacePath.length + 1);
+ /**
+ * The cache of absolute [Uri]s to [Source]s mappings.
+ */
+ final Map<Uri, Source> _sourceCache = new HashMap<Uri, Source>();
+
+ BazelPackageUriResolver(BazelWorkspace workspace)
+ : _workspace = workspace,
+ _context = workspace.provider.pathContext;
+
+ @override
+ Source resolveAbsolute(Uri uri, [Uri actualUri]) {
+ return _sourceCache.putIfAbsent(uri, () {
+ if (uri.scheme != 'package') {
+ return null;
+ }
+ String uriPath = uri.path;
+ int slash = uriPath.indexOf('/');
+
+ // If the path either starts with a slash or has no slash, it is invalid.
+ if (slash < 1) {
+ return null;
+ }
+
+ String packageName = uriPath.substring(0, slash);
+ String fileUriPart = uriPath.substring(slash + 1);
+ String filePath = fileUriPart.replaceAll('/', _context.separator);
+
+ if (packageName.indexOf('.') == -1) {
+ String path = _context.join(_workspace.root, 'third_party', 'dart',
+ packageName, 'lib', filePath);
+ File file = _workspace.findFile(path);
+ return file?.createSource(uri);
+ } else {
+ String packagePath = packageName.replaceAll('.', _context.separator);
+ String path =
+ _context.join(_workspace.root, packagePath, 'lib', filePath);
+ File file = _workspace.findFile(path);
+ return file?.createSource(uri);
+ }
+ });
+ }
+
+ @override
+ Uri restoreAbsolute(Source source) {
+ Context context = _workspace.provider.pathContext;
+ String path = source.fullName;
+
+ Uri restore(String root, String path) {
+ if (root != null && context.isWithin(root, path)) {
+ String relative = context.relative(path, from: root);
+ List<String> components = context.split(relative);
+ if (components.length >= 1 && components[0] == 'third_party') {
+ if (components.length > 4 &&
+ components[1] == 'dart' &&
+ components[3] == 'lib') {
+ String packageName = components[2];
+ String pathInLib = components.skip(4).join('/');
+ return FastUri.parse('package:$packageName/$pathInLib');
+ }
+ } else {
+ for (int i = 2; i < components.length - 1; i++) {
+ String component = components[i];
+ if (component == 'lib') {
+ String packageName = components.getRange(0, i).join('.');
+ String pathInLib = components.skip(i + 1).join('/');
+ return FastUri.parse('package:$packageName/$pathInLib');
+ }
+ }
+ }
+ }
+ return null;
}
- return '';
+
+ // Search in each root.
+ for (String root in [
+ _workspace.bin,
+ _workspace.genfiles,
+ _workspace.readonly,
+ _workspace.root
+ ]) {
+ Uri uri = restore(root, path);
+ if (uri != null) {
+ return uri;
+ }
+ }
+
+ return null;
+ }
+}
+
+/**
+ * Information about a Bazel workspace.
+ */
+class BazelWorkspace {
+ static const String _WORKSPACE = 'WORKSPACE';
+ static const String _READONLY = 'READONLY';
+
+ final ResourceProvider provider;
+
+ /**
+ * The absolute workspace root path.
+ *
+ * It contains the `WORKSPACE` file or its parent contains the `READONLY`
+ * folder.
+ */
+ final String root;
+
+ /**
+ * The absolute path to the optional read only workspace root, in the
+ * `READONLY` folder if a git-based workspace, or `null`.
+ */
+ final String readonly;
+
+ /**
+ * The absolute path to the `bazel-bin` folder.
+ */
+ final String bin;
+
+ /**
+ * The absolute path to the `bazel-genfiles` folder.
+ */
+ final String genfiles;
+
+ BazelWorkspace._(
+ this.provider, this.root, this.readonly, this.bin, this.genfiles);
+
+ /**
+ * Return the file with the given [absolutePath], looking first into
+ * directories for generated files: `bazel-bin` and `bazel-genfiles`, and
+ * then into the workspace root. The file in the workspace root is returned
+ * even if it does not exist. Return `null` if the given [absolutePath] is
+ * not in the workspace [root].
+ */
+ File findFile(String absolutePath) {
+ Context context = provider.pathContext;
+ try {
+ String relative = context.relative(absolutePath, from: root);
+ // genfiles
+ if (genfiles != null) {
+ File file = provider.getFile(context.join(genfiles, relative));
+ if (file.exists) {
+ return file;
+ }
+ }
+ // bin
+ if (bin != null) {
+ File file = provider.getFile(context.join(bin, relative));
+ if (file.exists) {
+ return file;
+ }
+ }
+ // READONLY
+ if (readonly != null) {
+ File file = provider.getFile(context.join(readonly, relative));
+ if (file.exists) {
+ return file;
+ }
+ }
+ // Not generated, return the default one.
+ return provider.getFile(absolutePath);
+ } catch (_) {
+ return null;
+ }
+ }
+
+ /**
+ * Find the Bazel workspace that contains the given [path].
+ *
+ * Return `null` if a workspace markers, such as the `WORKSPACE` file, or
+ * the sibling `READONLY` folder cannot be found.
+ *
+ * Return `null` if the workspace does not have `bazel-genfiles` or
+ * `blaze-genfiles` folders, so we don't know where to search generated files.
+ *
+ * Return `null` if there is a folder 'foo' with the sibling `READONLY`
+ * folder, but there is corresponding folder 'foo' in `READONLY`, i.e. the
+ * corresponding readonly workspace root.
+ */
+ static BazelWorkspace find(ResourceProvider provider, String path) {
+ Context context = provider.pathContext;
+
+ // Ensure that the path is absolute and normalized.
+ if (!context.isAbsolute(path)) {
+ throw new ArgumentError('not absolute: $path');
+ }
+ path = context.normalize(path);
+
+ Folder folder = provider.getFolder(path);
+ while (true) {
+ Folder parent = folder.parent;
+ if (parent == null) {
+ return null;
+ }
+
+ // Found the READONLY folder, might be a git-based workspace.
+ Folder readonlyFolder = parent.getChildAssumingFolder(_READONLY);
+ if (readonlyFolder.exists) {
+ String root = folder.path;
+ String readonlyRoot =
+ context.join(readonlyFolder.path, folder.shortName);
+ if (provider.getFolder(readonlyRoot).exists) {
+ String symlinkPrefix = _findSymlinkPrefix(provider, root);
+ if (symlinkPrefix != null) {
+ return new BazelWorkspace._(
+ provider,
+ root,
+ readonlyRoot,
+ context.join(root, '$symlinkPrefix-bin'),
+ context.join(root, '$symlinkPrefix-genfiles'));
+ }
+ }
+ }
+
+ // Found the WORKSPACE file, must be a non-git workspace.
+ if (folder.getChildAssumingFile(_WORKSPACE).exists) {
+ String root = folder.path;
+ String symlinkPrefix = _findSymlinkPrefix(provider, root);
+ if (symlinkPrefix == null) {
+ return null;
+ }
+ return new BazelWorkspace._(
+ provider,
+ root,
+ null,
+ context.join(root, '$symlinkPrefix-bin'),
+ context.join(root, '$symlinkPrefix-genfiles'));
+ }
+
+ // Go up the folder.
+ folder = parent;
+ }
+ }
+
+ /**
+ * Return the symlink prefix for folders `X-bin` or `X-genfiles` by probing
+ * the internal `blaze-genfiles` and `bazel-genfiles`. Return `null` if
+ * neither of the folders exists.
+ */
+ static String _findSymlinkPrefix(ResourceProvider provider, String root) {
+ Context context = provider.pathContext;
+ if (provider.getFolder(context.join(root, 'blaze-genfiles')).exists) {
+ return 'blaze';
+ }
+ if (provider.getFolder(context.join(root, 'bazel-genfiles')).exists) {
+ return 'bazel';
+ }
+ return null;
}
}
diff --git a/pkg/analyzer/lib/src/generated/declaration_resolver.dart b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
new file mode 100644
index 0000000..d67bc4c
--- /dev/null
+++ b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
@@ -0,0 +1,628 @@
+// 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.
+
+library analyzer.src.generated.declaration_resolver;
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/exception/exception.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+
+/**
+ * A visitor that resolves declarations in an AST structure to already built
+ * elements.
+ *
+ * The resulting AST must have everything resolved that would have been resolved
+ * by a [CompilationUnitBuilder] (that is, must be a valid [RESOLVED_UNIT1]).
+ * This class must not assume that the [CompilationUnitElement] passed to it is
+ * any more complete than a [COMPILATION_UNIT_ELEMENT].
+ */
+class DeclarationResolver extends RecursiveAstVisitor<Object> {
+ /**
+ * The compilation unit containing the AST nodes being visited.
+ */
+ CompilationUnitElementImpl _enclosingUnit;
+
+ /**
+ * The [ElementWalker] we are using to keep track of progress through the
+ * element model.
+ */
+ ElementWalker _walker;
+
+ /**
+ * Resolve the declarations within the given compilation [unit] to the
+ * elements rooted at the given [element]. Throw an [ElementMismatchException]
+ * if the element model and compilation unit do not match each other.
+ */
+ void resolve(CompilationUnit unit, CompilationUnitElement element) {
+ _enclosingUnit = element;
+ _walker = new ElementWalker.forCompilationUnit(element);
+ unit.element = element;
+ try {
+ unit.accept(this);
+ _walker.validate();
+ } on Error catch (e, st) {
+ throw new _ElementMismatchException(
+ element, _walker.element, new CaughtException(e, st));
+ }
+ }
+
+ @override
+ Object visitCatchClause(CatchClause node) {
+ SimpleIdentifier exceptionParameter = node.exceptionParameter;
+ if (exceptionParameter != null) {
+ _match(exceptionParameter, _walker.getVariable());
+ SimpleIdentifier stackTraceParameter = node.stackTraceParameter;
+ if (stackTraceParameter != null) {
+ _match(stackTraceParameter, _walker.getVariable());
+ }
+ }
+ return super.visitCatchClause(node);
+ }
+
+ @override
+ Object visitClassDeclaration(ClassDeclaration node) {
+ ClassElement element = _match(node.name, _walker.getClass());
+ _walk(new ElementWalker.forClass(element), () {
+ super.visitClassDeclaration(node);
+ });
+ _resolveMetadata(node, node.metadata, element);
+ return null;
+ }
+
+ @override
+ Object visitClassTypeAlias(ClassTypeAlias node) {
+ ClassElement element = _match(node.name, _walker.getClass());
+ _walk(new ElementWalker.forClass(element), () {
+ super.visitClassTypeAlias(node);
+ });
+ _resolveMetadata(node, node.metadata, element);
+ return null;
+ }
+
+ @override
+ Object visitConstructorDeclaration(ConstructorDeclaration node) {
+ ConstructorElement element = _match(node.name, _walker.getConstructor());
+ _walk(new ElementWalker.forExecutable(element), () {
+ node.element = element;
+ super.visitConstructorDeclaration(node);
+ });
+ _resolveMetadata(node, node.metadata, element);
+ return null;
+ }
+
+ @override
+ Object visitDeclaredIdentifier(DeclaredIdentifier node) {
+ VariableElement element = _match(node.identifier, _walker.getVariable());
+ super.visitDeclaredIdentifier(node);
+ _resolveMetadata(node, node.metadata, element);
+ return null;
+ }
+
+ @override
+ Object visitDefaultFormalParameter(DefaultFormalParameter node) {
+ ParameterElement element =
+ _match(node.parameter.identifier, _walker.getParameter());
+ Expression defaultValue = node.defaultValue;
+ if (defaultValue != null) {
+ _walk(new ElementWalker.forExecutable(element.initializer), () {
+ defaultValue.accept(this);
+ });
+ }
+ _walk(new ElementWalker.forParameter(element), () {
+ super.visitDefaultFormalParameter(node);
+ });
+ _resolveMetadata(node, node.metadata, element);
+ return null;
+ }
+
+ @override
+ Object visitEnumDeclaration(EnumDeclaration node) {
+ ClassElement element = _match(node.name, _walker.getEnum());
+ _walk(new ElementWalker.forClass(element), () {
+ for (EnumConstantDeclaration constant in node.constants) {
+ _match(constant.name, _walker.getVariable());
+ }
+ super.visitEnumDeclaration(node);
+ });
+ _resolveMetadata(node, node.metadata, element);
+ return null;
+ }
+
+ @override
+ Object visitExportDirective(ExportDirective node) {
+ super.visitExportDirective(node);
+ _resolveAnnotations(
+ node, node.metadata, _enclosingUnit.getAnnotations(node.offset));
+ return null;
+ }
+
+ @override
+ Object visitFieldDeclaration(FieldDeclaration node) {
+ super.visitFieldDeclaration(node);
+ _resolveMetadata(node, node.metadata, node.fields.variables[0].element);
+ return null;
+ }
+
+ @override
+ Object visitFieldFormalParameter(FieldFormalParameter node) {
+ if (node.parent is! DefaultFormalParameter) {
+ ParameterElement element =
+ _match(node.identifier, _walker.getParameter());
+ _walk(new ElementWalker.forParameter(element), () {
+ super.visitFieldFormalParameter(node);
+ });
+ _resolveMetadata(node, node.metadata, element);
+ return null;
+ } else {
+ return super.visitFieldFormalParameter(node);
+ }
+ }
+
+ @override
+ Object visitFunctionDeclaration(FunctionDeclaration node) {
+ SimpleIdentifier functionName = node.name;
+ Token property = node.propertyKeyword;
+ ExecutableElement element;
+ if (property == null) {
+ element = _match(functionName, _walker.getFunction());
+ } else {
+ if (_walker.element is ExecutableElement) {
+ element = _match(functionName, _walker.getFunction());
+ } else if (property.keyword == Keyword.GET) {
+ element = _match(functionName, _walker.getAccessor());
+ } else {
+ assert(property.keyword == Keyword.SET);
+ element = _match(functionName, _walker.getAccessor(),
+ elementName: functionName.name + '=');
+ }
+ }
+ node.functionExpression.element = element;
+ _walk(new ElementWalker.forExecutable(element), () {
+ super.visitFunctionDeclaration(node);
+ });
+ _resolveMetadata(node, node.metadata, element);
+ return null;
+ }
+
+ @override
+ Object visitFunctionExpression(FunctionExpression node) {
+ if (node.parent is! FunctionDeclaration) {
+ FunctionElement element = _walker.getFunction();
+ node.element = element;
+ _walk(new ElementWalker.forExecutable(element), () {
+ super.visitFunctionExpression(node);
+ });
+ return null;
+ } else {
+ return super.visitFunctionExpression(node);
+ }
+ }
+
+ @override
+ Object visitFunctionTypeAlias(FunctionTypeAlias node) {
+ FunctionTypeAliasElement element = _match(node.name, _walker.getTypedef());
+ _walk(new ElementWalker.forTypedef(element), () {
+ super.visitFunctionTypeAlias(node);
+ });
+ _resolveMetadata(node, node.metadata, element);
+ return null;
+ }
+
+ @override
+ Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
+ if (node.parent is! DefaultFormalParameter) {
+ ParameterElement element =
+ _match(node.identifier, _walker.getParameter());
+ _walk(new ElementWalker.forParameter(element), () {
+ super.visitFunctionTypedFormalParameter(node);
+ });
+ _resolveMetadata(node, node.metadata, element);
+ return null;
+ } else {
+ return super.visitFunctionTypedFormalParameter(node);
+ }
+ }
+
+ @override
+ Object visitImportDirective(ImportDirective node) {
+ super.visitImportDirective(node);
+ _resolveAnnotations(
+ node, node.metadata, _enclosingUnit.getAnnotations(node.offset));
+ return null;
+ }
+
+ @override
+ Object visitLabeledStatement(LabeledStatement node) {
+ for (Label label in node.labels) {
+ _match(label.label, _walker.getLabel());
+ }
+ return super.visitLabeledStatement(node);
+ }
+
+ @override
+ Object visitLibraryDirective(LibraryDirective node) {
+ super.visitLibraryDirective(node);
+ _resolveAnnotations(
+ node, node.metadata, _enclosingUnit.getAnnotations(node.offset));
+ return null;
+ }
+
+ @override
+ Object visitMethodDeclaration(MethodDeclaration node) {
+ Token property = node.propertyKeyword;
+ SimpleIdentifier methodName = node.name;
+ String nameOfMethod = methodName.name;
+ ExecutableElement element;
+ if (property == null) {
+ String elementName = nameOfMethod == '-' &&
+ node.parameters != null &&
+ node.parameters.parameters.isEmpty
+ ? 'unary-'
+ : nameOfMethod;
+ element =
+ _match(methodName, _walker.getFunction(), elementName: elementName);
+ } else {
+ if (property.keyword == Keyword.GET) {
+ element = _match(methodName, _walker.getAccessor());
+ } else {
+ assert(property.keyword == Keyword.SET);
+ element = _match(methodName, _walker.getAccessor(),
+ elementName: nameOfMethod + '=');
+ }
+ }
+ _walk(new ElementWalker.forExecutable(element), () {
+ super.visitMethodDeclaration(node);
+ });
+ _resolveMetadata(node, node.metadata, element);
+ return null;
+ }
+
+ @override
+ Object visitPartDirective(PartDirective node) {
+ super.visitPartDirective(node);
+ _resolveAnnotations(
+ node, node.metadata, _enclosingUnit.getAnnotations(node.offset));
+ return null;
+ }
+
+ @override
+ Object visitPartOfDirective(PartOfDirective node) {
+ node.element = _enclosingUnit.library;
+ return super.visitPartOfDirective(node);
+ }
+
+ @override
+ Object visitSimpleFormalParameter(SimpleFormalParameter node) {
+ if (node.parent is! DefaultFormalParameter) {
+ ParameterElement element =
+ _match(node.identifier, _walker.getParameter());
+ _walk(new ElementWalker.forParameter(element), () {
+ super.visitSimpleFormalParameter(node);
+ });
+ _resolveMetadata(node, node.metadata, element);
+ return null;
+ } else {
+ return super.visitSimpleFormalParameter(node);
+ }
+ }
+
+ @override
+ Object visitSwitchCase(SwitchCase node) {
+ for (Label label in node.labels) {
+ _match(label.label, _walker.getLabel());
+ }
+ return super.visitSwitchCase(node);
+ }
+
+ @override
+ Object visitSwitchDefault(SwitchDefault node) {
+ for (Label label in node.labels) {
+ _match(label.label, _walker.getLabel());
+ }
+ return super.visitSwitchDefault(node);
+ }
+
+ @override
+ Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+ super.visitTopLevelVariableDeclaration(node);
+ _resolveMetadata(node, node.metadata, node.variables.variables[0].element);
+ return null;
+ }
+
+ @override
+ Object visitTypeParameter(TypeParameter node) {
+ Element element = _match(node.name, _walker.getTypeParameter());
+ super.visitTypeParameter(node);
+ _resolveMetadata(node, node.metadata, element);
+ return null;
+ }
+
+ @override
+ Object visitVariableDeclaration(VariableDeclaration node) {
+ VariableElement element = _match(node.name, _walker.getVariable());
+ Expression initializer = node.initializer;
+ if (initializer != null) {
+ _walk(new ElementWalker.forExecutable(element.initializer), () {
+ super.visitVariableDeclaration(node);
+ });
+ return null;
+ } else {
+ return super.visitVariableDeclaration(node);
+ }
+ }
+
+ @override
+ Object visitVariableDeclarationList(VariableDeclarationList node) {
+ super.visitVariableDeclarationList(node);
+ if (node.parent is! FieldDeclaration &&
+ node.parent is! TopLevelVariableDeclaration) {
+ _resolveMetadata(node, node.metadata, node.variables[0].element);
+ }
+ return null;
+ }
+
+ /**
+ * Updates [identifier] to point to [element], after ensuring that the
+ * element has the expected name.
+ *
+ * If no [elementName] is given, it defaults to the name of the [identifier]
+ * (or the empty string if [identifier] is `null`).
+ *
+ * If [identifier] is `null`, nothing is updated, but the element name is
+ * still checked.
+ */
+ Element/*=E*/ _match/*<E extends Element>*/(
+ SimpleIdentifier identifier, Element/*=E*/ element,
+ {String elementName}) {
+ elementName ??= identifier?.name ?? '';
+ if (element.name != elementName) {
+ throw new StateError(
+ 'Expected an element matching `$elementName`, got `${element.name}`');
+ }
+ identifier?.staticElement = element;
+ return element;
+ }
+
+ /**
+ * Associate each of the annotation [nodes] with the corresponding
+ * [ElementAnnotation] in [annotations]. If there is a problem, report it
+ * against the given [parent] node.
+ */
+ void _resolveAnnotations(AstNode parent, NodeList<Annotation> nodes,
+ List<ElementAnnotation> annotations) {
+ int nodeCount = nodes.length;
+ if (nodeCount != annotations.length) {
+ throw new StateError('Found $nodeCount annotation nodes and '
+ '${annotations.length} element annotations');
+ }
+ for (int i = 0; i < nodeCount; i++) {
+ nodes[i].elementAnnotation = annotations[i];
+ }
+ }
+
+ /**
+ * If [element] is not `null`, associate each of the annotation [nodes] with
+ * the corresponding [ElementAnnotation] in [element.metadata]. If there is a
+ * problem, report it against the given [parent] node.
+ *
+ * If [element] is `null`, do nothing--this allows us to be robust in the
+ * case where we are operating on an element model that hasn't been fully
+ * built.
+ */
+ void _resolveMetadata(
+ AstNode parent, NodeList<Annotation> nodes, Element element) {
+ if (element != null) {
+ _resolveAnnotations(parent, nodes, element.metadata);
+ }
+ }
+
+ /**
+ * Recurses through the element model and AST, verifying that all elements are
+ * matched.
+ *
+ * Executes [callback] with [_walker] pointing to the given [walker] (which
+ * should be a new instance of [ElementWalker]). Once [callback] returns,
+ * uses [ElementWalker.validate] to verify that all expected elements have
+ * been matched.
+ */
+ void _walk(ElementWalker walker, void callback()) {
+ ElementWalker outerWalker = _walker;
+ _walker = walker;
+ callback();
+ walker.validate();
+ _walker = outerWalker;
+ }
+}
+
+/**
+ * Keeps track of the set of non-synthetic child elements of an element,
+ * yielding them one at a time in response to "get" method calls.
+ */
+class ElementWalker {
+ /**
+ * The element whose child elements are being walked.
+ */
+ final Element element;
+
+ List<PropertyAccessorElement> _accessors;
+ int _accessorIndex = 0;
+ List<ClassElement> _classes;
+ int _classIndex = 0;
+ List<ConstructorElement> _constructors;
+ int _constructorIndex = 0;
+ List<ClassElement> _enums;
+ int _enumIndex = 0;
+ List<ExecutableElement> _functions;
+ int _functionIndex = 0;
+ List<LabelElement> _labels;
+ int _labelIndex = 0;
+ List<ParameterElement> _parameters;
+ int _parameterIndex = 0;
+ List<FunctionTypeAliasElement> _typedefs;
+ int _typedefIndex = 0;
+ List<TypeParameterElement> _typeParameters;
+ int _typeParameterIndex = 0;
+ List<VariableElement> _variables;
+ int _variableIndex = 0;
+
+ /**
+ * Creates an [ElementWalker] which walks the child elements of a class
+ * element.
+ */
+ ElementWalker.forClass(ClassElement element)
+ : element = element,
+ _accessors = element.accessors.where(_isNotSynthetic).toList(),
+ _constructors = element.isMixinApplication
+ ? null
+ : element.constructors.where(_isNotSynthetic).toList(),
+ _functions = element.methods,
+ _typeParameters = element.typeParameters,
+ _variables = element.fields.where(_isNotSynthetic).toList();
+
+ /**
+ * Creates an [ElementWalker] which walks the child elements of a compilation
+ * unit element.
+ */
+ ElementWalker.forCompilationUnit(CompilationUnitElement compilationUnit)
+ : element = compilationUnit,
+ _accessors = compilationUnit.accessors.where(_isNotSynthetic).toList(),
+ _classes = compilationUnit.types,
+ _enums = compilationUnit.enums,
+ _functions = compilationUnit.functions,
+ _typedefs = compilationUnit.functionTypeAliases,
+ _variables =
+ compilationUnit.topLevelVariables.where(_isNotSynthetic).toList();
+
+ /**
+ * Creates an [ElementWalker] which walks the child elements of a compilation
+ * unit element.
+ */
+ ElementWalker.forExecutable(ExecutableElement element)
+ : element = element,
+ _functions = element.functions,
+ _labels = element.labels,
+ _parameters = element.parameters,
+ _typeParameters = element.typeParameters,
+ _variables = element.localVariables;
+
+ /**
+ * Creates an [ElementWalker] which walks the child elements of a parameter
+ * element.
+ */
+ ElementWalker.forParameter(ParameterElement element)
+ : element = element,
+ _parameters = element.parameters;
+
+ /**
+ * Creates an [ElementWalker] which walks the child elements of a typedef
+ * element.
+ */
+ ElementWalker.forTypedef(FunctionTypeAliasElement element)
+ : element = element,
+ _parameters = element.parameters,
+ _typeParameters = element.typeParameters;
+
+ /**
+ * Returns the next non-synthetic child of [element] which is an accessor;
+ * throws an [IndexError] if there are no more.
+ */
+ PropertyAccessorElement getAccessor() => _accessors[_accessorIndex++];
+
+ /**
+ * Returns the next non-synthetic child of [element] which is a class; throws
+ * an [IndexError] if there are no more.
+ */
+ ClassElement getClass() => _classes[_classIndex++];
+
+ /**
+ * Returns the next non-synthetic child of [element] which is a constructor;
+ * throws an [IndexError] if there are no more.
+ */
+ ConstructorElement getConstructor() => _constructors[_constructorIndex++];
+
+ /**
+ * Returns the next non-synthetic child of [element] which is an enum; throws
+ * an [IndexError] if there are no more.
+ */
+ ClassElement getEnum() => _enums[_enumIndex++];
+
+ /**
+ * Returns the next non-synthetic child of [element] which is a top level
+ * function, method, or local function; throws an [IndexError] if there are no
+ * more.
+ */
+ ExecutableElement getFunction() => _functions[_functionIndex++];
+
+ /**
+ * Returns the next non-synthetic child of [element] which is a label; throws
+ * an [IndexError] if there are no more.
+ */
+ LabelElement getLabel() => _labels[_labelIndex++];
+
+ /**
+ * Returns the next non-synthetic child of [element] which is a parameter;
+ * throws an [IndexError] if there are no more.
+ */
+ ParameterElement getParameter() => _parameters[_parameterIndex++];
+
+ /**
+ * Returns the next non-synthetic child of [element] which is a typedef;
+ * throws an [IndexError] if there are no more.
+ */
+ FunctionTypeAliasElement getTypedef() => _typedefs[_typedefIndex++];
+
+ /**
+ * Returns the next non-synthetic child of [element] which is a type
+ * parameter; throws an [IndexError] if there are no more.
+ */
+ TypeParameterElement getTypeParameter() =>
+ _typeParameters[_typeParameterIndex++];
+
+ /**
+ * Returns the next non-synthetic child of [element] which is a top level
+ * variable, field, or local variable; throws an [IndexError] if there are no
+ * more.
+ */
+ VariableElement getVariable() => _variables[_variableIndex++];
+
+ /**
+ * Verifies that all non-synthetic children of [element] have been obtained
+ * from their corresponding "get" method calls; if not, throws a [StateError].
+ */
+ void validate() {
+ void check(List<Element> elements, int index) {
+ if (elements != null && elements.length != index) {
+ throw new StateError(
+ 'Unmatched ${elements[index].runtimeType} ${elements[index]}');
+ }
+ }
+
+ check(_accessors, _accessorIndex);
+ check(_classes, _classIndex);
+ check(_constructors, _constructorIndex);
+ check(_enums, _enumIndex);
+ check(_functions, _functionIndex);
+ check(_labels, _labelIndex);
+ check(_parameters, _parameterIndex);
+ check(_typedefs, _typedefIndex);
+ check(_typeParameters, _typeParameterIndex);
+ check(_variables, _variableIndex);
+ }
+
+ static bool _isNotSynthetic(Element e) => !e.isSynthetic;
+}
+
+class _ElementMismatchException extends AnalysisException {
+ /**
+ * Creates an exception to refer to the given [compilationUnit], [element],
+ * and [cause].
+ */
+ _ElementMismatchException(
+ CompilationUnitElement compilationUnit, Element element,
+ [CaughtException cause = null])
+ : super('Element mismatch in $compilationUnit at $element', cause);
+}
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index 01b2ced..fedd2e4 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -1061,9 +1061,12 @@
AnalyzeFunctionBodiesPredicate get analyzeFunctionBodiesPredicate;
/**
- * Return the maximum number of sources for which AST structures should be
+ * DEPRECATED: Return the maximum number of sources for which AST structures should be
* kept in the cache.
+ *
+ * This setting no longer has any effect.
*/
+ @deprecated
int get cacheSize;
/**
@@ -1072,6 +1075,17 @@
bool get dart2jsHint;
/**
+ * Return `true` if cache flushing should be disabled. Setting this option to
+ * `true` can improve analysis speed at the expense of memory usage. It may
+ * also be useful for working around bugs.
+ *
+ * This option should not be used when the analyzer is part of a long running
+ * process (such as the analysis server) because it has the potential to
+ * prevent memory from being reclaimed.
+ */
+ bool get disableCacheFlushing;
+
+ /**
* Return `true` if the parser is to parse asserts in the initializer list of
* a constructor.
*/
@@ -1214,16 +1228,20 @@
*/
class AnalysisOptionsImpl implements AnalysisOptions {
/**
- * The maximum number of sources for which data should be kept in the cache.
+ * DEPRECATED: The maximum number of sources for which data should be kept in the cache.
+ *
+ * This constant no longer has any effect.
*/
+ @deprecated
static const int DEFAULT_CACHE_SIZE = 64;
static const int ENABLE_ASSERT_FLAG = 0x01;
static const int ENABLE_GENERIC_METHODS_FLAG = 0x02;
- static const int ENABLE_STRICT_CALL_CHECKS_FLAG = 0x04;
- static const int ENABLE_STRONG_MODE_FLAG = 0x08;
- static const int ENABLE_STRONG_MODE_HINTS_FLAG = 0x10;
- static const int ENABLE_SUPER_MIXINS_FLAG = 0x20;
+ static const int ENABLE_LAZY_ASSIGNMENT_OPERATORS = 0x04;
+ static const int ENABLE_STRICT_CALL_CHECKS_FLAG = 0x08;
+ static const int ENABLE_STRONG_MODE_FLAG = 0x10;
+ static const int ENABLE_STRONG_MODE_HINTS_FLAG = 0x20;
+ static const int ENABLE_SUPER_MIXINS_FLAG = 0x40;
/**
* The default list of non-nullable type names.
@@ -1238,6 +1256,7 @@
_analyzeAllFunctionBodies;
@override
+ @deprecated
int cacheSize = DEFAULT_CACHE_SIZE;
@override
@@ -1305,6 +1324,9 @@
@override
bool trackCacheDependencies = true;
+ @override
+ bool disableCacheFlushing = false;
+
/**
* A flag indicating whether implicit casts are allowed in [strongMode]
* (they are always allowed in Dart 1.0 mode).
@@ -1346,13 +1368,13 @@
*/
AnalysisOptionsImpl.from(AnalysisOptions options) {
analyzeFunctionBodiesPredicate = options.analyzeFunctionBodiesPredicate;
- cacheSize = options.cacheSize;
dart2jsHint = options.dart2jsHint;
enableAssertInitializer = options.enableAssertInitializer;
enableAssertMessage = options.enableAssertMessage;
enableStrictCallChecks = options.enableStrictCallChecks;
enableGenericMethods = options.enableGenericMethods;
enableInitializingFormalAccess = options.enableInitializingFormalAccess;
+ enableLazyAssignmentOperators = options.enableLazyAssignmentOperators;
enableSuperMixins = options.enableSuperMixins;
enableTiming = options.enableTiming;
generateImplicitErrors = options.generateImplicitErrors;
@@ -1371,6 +1393,7 @@
implicitDynamic = options.implicitDynamic;
}
trackCacheDependencies = options.trackCacheDependencies;
+ disableCacheFlushing = options.disableCacheFlushing;
finerGrainedInvalidation = options.finerGrainedInvalidation;
}
@@ -1423,15 +1446,17 @@
int encodeCrossContextOptions() =>
(enableAssertMessage ? ENABLE_ASSERT_FLAG : 0) |
(enableGenericMethods ? ENABLE_GENERIC_METHODS_FLAG : 0) |
+ (enableLazyAssignmentOperators ? ENABLE_LAZY_ASSIGNMENT_OPERATORS : 0) |
(enableStrictCallChecks ? ENABLE_STRICT_CALL_CHECKS_FLAG : 0) |
+ (enableSuperMixins ? ENABLE_SUPER_MIXINS_FLAG : 0) |
(strongMode ? ENABLE_STRONG_MODE_FLAG : 0) |
- (strongModeHints ? ENABLE_STRONG_MODE_HINTS_FLAG : 0) |
- (enableSuperMixins ? ENABLE_SUPER_MIXINS_FLAG : 0);
+ (strongModeHints ? ENABLE_STRONG_MODE_HINTS_FLAG : 0);
@override
void setCrossContextOptionsFrom(AnalysisOptions options) {
enableAssertMessage = options.enableAssertMessage;
enableGenericMethods = options.enableGenericMethods;
+ enableLazyAssignmentOperators = options.enableLazyAssignmentOperators;
enableStrictCallChecks = options.enableStrictCallChecks;
enableSuperMixins = options.enableSuperMixins;
strongMode = options.strongMode;
@@ -1465,18 +1490,21 @@
if (encoding & ENABLE_GENERIC_METHODS_FLAG > 0) {
add('genericMethods');
}
+ if (encoding & ENABLE_LAZY_ASSIGNMENT_OPERATORS > 0) {
+ add('lazyAssignmentOperators');
+ }
if (encoding & ENABLE_STRICT_CALL_CHECKS_FLAG > 0) {
add('strictCallChecks');
}
+ if (encoding & ENABLE_SUPER_MIXINS_FLAG > 0) {
+ add('superMixins');
+ }
if (encoding & ENABLE_STRONG_MODE_FLAG > 0) {
add('strongMode');
}
if (encoding & ENABLE_STRONG_MODE_HINTS_FLAG > 0) {
add('strongModeHints');
}
- if (encoding & ENABLE_SUPER_MIXINS_FLAG > 0) {
- add('superMixins');
- }
return buffer.toString();
}
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 13964ba..792e5db 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -2355,7 +2355,7 @@
libraryNames.sort();
_errorReporter.reportErrorForNode(StaticWarningCode.AMBIGUOUS_IMPORT,
node, [name, StringUtilities.printListOfQuotedNames(libraryNames)]);
- } else {
+ } else if (element != null) {
List<Element> sdkElements =
node.getProperty(LibraryImportScope.conflictingSdkElements);
if (sdkElements != null) {
@@ -6372,7 +6372,9 @@
String name = member.name;
ClassElement superclass = classElement.supertype?.element;
while (superclass != null) {
- ExecutableElement member = superclass.getMethod(name) ?? superclass.getGetter(name) ?? superclass.getSetter(name);
+ ExecutableElement member = superclass.getMethod(name) ??
+ superclass.getGetter(name) ??
+ superclass.getSetter(name);
if (member != null) {
return member;
}
diff --git a/pkg/analyzer/lib/src/generated/java_io.dart b/pkg/analyzer/lib/src/generated/java_io.dart
index 9b07d6d..3c147bf 100644
--- a/pkg/analyzer/lib/src/generated/java_io.dart
+++ b/pkg/analyzer/lib/src/generated/java_io.dart
@@ -9,6 +9,7 @@
import 'package:path/path.dart' as path;
class JavaFile {
+ @deprecated
static path.Context pathContext = path.context;
static final String separator = Platform.pathSeparator;
static final int separatorChar = Platform.pathSeparator.codeUnitAt(0);
@@ -16,12 +17,12 @@
JavaFile(String path) {
_path = path;
}
- JavaFile.fromUri(Uri uri) : this(pathContext.fromUri(uri));
+ JavaFile.fromUri(Uri uri) : this(path.context.fromUri(uri));
JavaFile.relative(JavaFile base, String child) {
if (child.isEmpty) {
this._path = base._path;
} else {
- this._path = pathContext.join(base._path, child);
+ this._path = path.context.join(base._path, child);
}
}
@override
@@ -43,9 +44,9 @@
JavaFile getAbsoluteFile() => new JavaFile(getAbsolutePath());
String getAbsolutePath() {
- String path = pathContext.absolute(_path);
- path = pathContext.normalize(path);
- return path;
+ String abolutePath = path.context.absolute(_path);
+ abolutePath = path.context.normalize(abolutePath);
+ return abolutePath;
}
JavaFile getCanonicalFile() => new JavaFile(getCanonicalPath());
@@ -53,9 +54,9 @@
return _newFile().resolveSymbolicLinksSync();
}
- String getName() => pathContext.basename(_path);
+ String getName() => path.context.basename(_path);
String getParent() {
- var result = pathContext.dirname(_path);
+ var result = path.context.dirname(_path);
// "." or "/" or "C:\"
if (result.length < 4) return null;
return result;
@@ -101,8 +102,8 @@
@override
String toString() => _path.toString();
Uri toURI() {
- String path = getAbsolutePath();
- return pathContext.toUri(path);
+ String absolutePath = getAbsolutePath();
+ return path.context.toUri(absolutePath);
}
Directory _newDirectory() => new Directory(_path);
@@ -134,18 +135,15 @@
String sdkPath;
// may be "xcodebuild/ReleaseIA32/dart" with "sdk" sibling
{
- var outDir =
- JavaFile.pathContext.dirname(JavaFile.pathContext.dirname(exec));
- sdkPath = JavaFile.pathContext
- .join(JavaFile.pathContext.dirname(outDir), "sdk");
+ var outDir = path.context.dirname(path.context.dirname(exec));
+ sdkPath = path.context.join(path.context.dirname(outDir), "sdk");
if (new Directory(sdkPath).existsSync()) {
_properties[name] = sdkPath;
return sdkPath;
}
}
// probably be "dart-sdk/bin/dart"
- sdkPath =
- JavaFile.pathContext.dirname(JavaFile.pathContext.dirname(exec));
+ sdkPath = path.context.dirname(path.context.dirname(exec));
_properties[name] = sdkPath;
return sdkPath;
}
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index fb111ff..1f51d66 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -2780,6 +2780,7 @@
* normalFormalParameter ('=' expression)?
*
* defaultNamedParameter ::=
+ * normalFormalParameter ('=' expression)?
* normalFormalParameter (':' expression)?
*/
FormalParameter parseFormalParameter(ParameterKind kind) {
@@ -2788,10 +2789,7 @@
if (type == TokenType.EQ) {
Token separator = getAndAdvance();
Expression defaultValue = parseExpression2();
- if (kind == ParameterKind.NAMED) {
- _reportErrorForToken(
- ParserErrorCode.WRONG_SEPARATOR_FOR_NAMED_PARAMETER, separator);
- } else if (kind == ParameterKind.REQUIRED) {
+ if (kind == ParameterKind.REQUIRED) {
_reportErrorForNode(
ParserErrorCode.POSITIONAL_PARAMETER_OUTSIDE_GROUP, parameter);
}
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 3e1dc6b..d9dd238 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -19,7 +19,6 @@
import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
-import 'package:analyzer/src/dart/element/utilities.dart';
import 'package:analyzer/src/dart/resolver/inheritance_manager.dart';
import 'package:analyzer/src/dart/resolver/scope.dart';
import 'package:analyzer/src/error/codes.dart';
@@ -2267,658 +2266,6 @@
}
/**
- * A visitor that resolves declarations in an AST structure to already built
- * elements.
- *
- * The resulting AST must have everything resolved that would have been resolved
- * by a [CompilationUnitBuilder] (that is, must be a valid [RESOLVED_UNIT1]).
- * This class must not assume that the [CompilationUnitElement] passed to it is
- * any more complete than a [COMPILATION_UNIT_ELEMENT].
- */
-class DeclarationResolver extends RecursiveAstVisitor<Object>
- with ExistingElementResolver {
- /**
- * The analysis context containing the sources to be analyzed.
- */
- AnalysisContext _context;
-
- /**
- * The elements that are reachable from the compilation unit element. When a
- * compilation unit has been resolved, this set should be empty.
- */
- Set<Element> _expectedElements;
-
- /**
- * The function type alias containing the AST nodes being visited, or `null`
- * if we are not in the scope of a function type alias.
- */
- FunctionTypeAliasElement _enclosingAlias;
-
- /**
- * The class containing the AST nodes being visited, or `null` if we are not
- * in the scope of a class.
- */
- ClassElement _enclosingClass;
-
- /**
- * The method or function containing the AST nodes being visited, or `null` if
- * we are not in the scope of a method or function.
- */
- ExecutableElement _enclosingExecutable;
-
- /**
- * The parameter containing the AST nodes being visited, or `null` if we are
- * not in the scope of a parameter.
- */
- ParameterElement _enclosingParameter;
-
- /**
- * Resolve the declarations within the given compilation [unit] to the
- * elements rooted at the given [element]. Throw an [ElementMismatchException]
- * if the element model and compilation unit do not match each other.
- */
- void resolve(CompilationUnit unit, CompilationUnitElement element) {
- _context = element.context;
- ElementGatherer gatherer = new ElementGatherer();
- element.accept(gatherer);
- _expectedElements = gatherer.elements;
- _enclosingUnit = element;
- _expectedElements.remove(element);
- unit.element = element;
- unit.accept(this);
- _validateResolution();
- }
-
- @override
- Object visitCatchClause(CatchClause node) {
- SimpleIdentifier exceptionParameter = node.exceptionParameter;
- if (exceptionParameter != null) {
- List<LocalVariableElement> localVariables =
- _enclosingExecutable.localVariables;
- _findIdentifier(localVariables, exceptionParameter);
- SimpleIdentifier stackTraceParameter = node.stackTraceParameter;
- if (stackTraceParameter != null) {
- _findIdentifier(localVariables, stackTraceParameter);
- }
- }
- return super.visitCatchClause(node);
- }
-
- @override
- Object visitClassDeclaration(ClassDeclaration node) {
- ClassElement outerClass = _enclosingClass;
- try {
- SimpleIdentifier className = node.name;
- _enclosingClass = _findIdentifier(_enclosingUnit.types, className);
- super.visitClassDeclaration(node);
- _resolveMetadata(node, node.metadata, _enclosingClass);
- return null;
- } finally {
- _enclosingClass = outerClass;
- }
- }
-
- @override
- Object visitClassTypeAlias(ClassTypeAlias node) {
- ClassElement outerClass = _enclosingClass;
- try {
- SimpleIdentifier className = node.name;
- _enclosingClass = _findIdentifier(_enclosingUnit.types, className);
- super.visitClassTypeAlias(node);
- _resolveMetadata(node, node.metadata, _enclosingClass);
- return null;
- } finally {
- _enclosingClass = outerClass;
- }
- }
-
- @override
- Object visitConstructorDeclaration(ConstructorDeclaration node) {
- ExecutableElement outerExecutable = _enclosingExecutable;
- try {
- SimpleIdentifier constructorName = node.name;
- if (constructorName == null) {
- _enclosingExecutable = _enclosingClass.unnamedConstructor;
- if (_enclosingExecutable == null) {
- _mismatch('Could not find default constructor', node);
- }
- } else {
- _enclosingExecutable =
- _enclosingClass.getNamedConstructor(constructorName.name);
- if (_enclosingExecutable == null) {
- _mismatch(
- 'Could not find constructor element with name "${constructorName.name}',
- node);
- }
- constructorName.staticElement = _enclosingExecutable;
- }
- _expectedElements.remove(_enclosingExecutable);
- node.element = _enclosingExecutable as ConstructorElement;
- super.visitConstructorDeclaration(node);
- _resolveMetadata(node, node.metadata, _enclosingExecutable);
- return null;
- } finally {
- _enclosingExecutable = outerExecutable;
- }
- }
-
- @override
- Object visitDeclaredIdentifier(DeclaredIdentifier node) {
- SimpleIdentifier variableName = node.identifier;
- Element element =
- _findIdentifier(_enclosingExecutable.localVariables, variableName);
- super.visitDeclaredIdentifier(node);
- _resolveMetadata(node, node.metadata, element);
- return null;
- }
-
- @override
- Object visitDefaultFormalParameter(DefaultFormalParameter node) {
- SimpleIdentifier parameterName = node.parameter.identifier;
- ParameterElement element = _getElementForParameter(node, parameterName);
- Expression defaultValue = node.defaultValue;
- if (defaultValue != null) {
- ExecutableElement outerExecutable = _enclosingExecutable;
- try {
- _enclosingExecutable = element.initializer;
- defaultValue.accept(this);
- } finally {
- _enclosingExecutable = outerExecutable;
- }
- }
- ParameterElement outerParameter = _enclosingParameter;
- try {
- _enclosingParameter = element;
- super.visitDefaultFormalParameter(node);
- _resolveMetadata(node, node.metadata, element);
- return null;
- } finally {
- _enclosingParameter = outerParameter;
- }
- }
-
- @override
- Object visitEnumDeclaration(EnumDeclaration node) {
- ClassElement enclosingEnum =
- _findIdentifier(_enclosingUnit.enums, node.name);
- List<FieldElement> constants = enclosingEnum.fields;
- for (EnumConstantDeclaration constant in node.constants) {
- _findIdentifier(constants, constant.name);
- }
- super.visitEnumDeclaration(node);
- _resolveMetadata(node, node.metadata, enclosingEnum);
- return null;
- }
-
- @override
- Object visitExportDirective(ExportDirective node) {
- super.visitExportDirective(node);
- _resolveAnnotations(
- node, node.metadata, _enclosingUnit.getAnnotations(node.offset));
- return null;
- }
-
- @override
- Object visitFieldDeclaration(FieldDeclaration node) {
- super.visitFieldDeclaration(node);
- _resolveMetadata(node, node.metadata, node.fields.variables[0].element);
- return null;
- }
-
- @override
- Object visitFieldFormalParameter(FieldFormalParameter node) {
- if (node.parent is! DefaultFormalParameter) {
- SimpleIdentifier parameterName = node.identifier;
- ParameterElement element = _getElementForParameter(node, parameterName);
- ParameterElement outerParameter = _enclosingParameter;
- try {
- _enclosingParameter = element;
- super.visitFieldFormalParameter(node);
- _resolveMetadata(node, node.metadata, element);
- return null;
- } finally {
- _enclosingParameter = outerParameter;
- }
- } else {
- return super.visitFieldFormalParameter(node);
- }
- }
-
- @override
- Object visitFunctionDeclaration(FunctionDeclaration node) {
- ExecutableElement outerExecutable = _enclosingExecutable;
- try {
- SimpleIdentifier functionName = node.name;
- Token property = node.propertyKeyword;
- if (property == null) {
- if (_enclosingExecutable != null) {
- _enclosingExecutable =
- _findIdentifier(_enclosingExecutable.functions, functionName);
- } else {
- _enclosingExecutable =
- _findIdentifier(_enclosingUnit.functions, functionName);
- }
- } else {
- if (_enclosingExecutable != null) {
- _enclosingExecutable =
- _findIdentifier(_enclosingExecutable.functions, functionName);
- } else {
- List<PropertyAccessorElement> accessors;
- if (_enclosingClass != null) {
- accessors = _enclosingClass.accessors;
- } else {
- accessors = _enclosingUnit.accessors;
- }
- PropertyAccessorElement accessor;
- if (property.keyword == Keyword.GET) {
- accessor = _findIdentifier(accessors, functionName);
- } else if (property.keyword == Keyword.SET) {
- accessor = _findWithNameAndOffset(accessors, functionName,
- functionName.name + '=', functionName.offset);
- _expectedElements.remove(accessor);
- functionName.staticElement = accessor;
- }
- _enclosingExecutable = accessor;
- }
- }
- node.functionExpression.element = _enclosingExecutable;
- super.visitFunctionDeclaration(node);
- _resolveMetadata(node, node.metadata, _enclosingExecutable);
- return null;
- } finally {
- _enclosingExecutable = outerExecutable;
- }
- }
-
- @override
- Object visitFunctionExpression(FunctionExpression node) {
- if (node.parent is! FunctionDeclaration) {
- FunctionElement element = _findAtOffset(
- _enclosingExecutable.functions, node, node.beginToken.offset);
- _expectedElements.remove(element);
- node.element = element;
- }
- ExecutableElement outerExecutable = _enclosingExecutable;
- try {
- _enclosingExecutable = node.element;
- return super.visitFunctionExpression(node);
- } finally {
- _enclosingExecutable = outerExecutable;
- }
- }
-
- @override
- Object visitFunctionTypeAlias(FunctionTypeAlias node) {
- FunctionTypeAliasElement outerAlias = _enclosingAlias;
- try {
- SimpleIdentifier aliasName = node.name;
- _enclosingAlias =
- _findIdentifier(_enclosingUnit.functionTypeAliases, aliasName);
- super.visitFunctionTypeAlias(node);
- _resolveMetadata(node, node.metadata, _enclosingAlias);
- return null;
- } finally {
- _enclosingAlias = outerAlias;
- }
- }
-
- @override
- Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
- if (node.parent is! DefaultFormalParameter) {
- SimpleIdentifier parameterName = node.identifier;
- ParameterElement element = _getElementForParameter(node, parameterName);
- ParameterElement outerParameter = _enclosingParameter;
- try {
- _enclosingParameter = element;
- super.visitFunctionTypedFormalParameter(node);
- _resolveMetadata(node, node.metadata, _enclosingParameter);
- return null;
- } finally {
- _enclosingParameter = outerParameter;
- }
- } else {
- return super.visitFunctionTypedFormalParameter(node);
- }
- }
-
- @override
- Object visitImportDirective(ImportDirective node) {
- super.visitImportDirective(node);
- _resolveAnnotations(
- node, node.metadata, _enclosingUnit.getAnnotations(node.offset));
- return null;
- }
-
- @override
- Object visitLabeledStatement(LabeledStatement node) {
- for (Label label in node.labels) {
- SimpleIdentifier labelName = label.label;
- _findIdentifier(_enclosingExecutable.labels, labelName);
- }
- return super.visitLabeledStatement(node);
- }
-
- @override
- Object visitLibraryDirective(LibraryDirective node) {
- super.visitLibraryDirective(node);
- _resolveAnnotations(
- node, node.metadata, _enclosingUnit.getAnnotations(node.offset));
- return null;
- }
-
- @override
- Object visitMethodDeclaration(MethodDeclaration node) {
- ExecutableElement outerExecutable = _enclosingExecutable;
- try {
- Token property = node.propertyKeyword;
- SimpleIdentifier methodName = node.name;
- String nameOfMethod = methodName.name;
- if (property == null) {
- String elementName = nameOfMethod == '-' &&
- node.parameters != null &&
- node.parameters.parameters.isEmpty
- ? 'unary-'
- : nameOfMethod;
- _enclosingExecutable = _findWithNameAndOffset(_enclosingClass.methods,
- methodName, elementName, methodName.offset);
- _expectedElements.remove(_enclosingExecutable);
- methodName.staticElement = _enclosingExecutable;
- } else {
- PropertyAccessorElement accessor;
- if (property.keyword == Keyword.GET) {
- accessor = _findIdentifier(_enclosingClass.accessors, methodName);
- } else if (property.keyword == Keyword.SET) {
- accessor = _findWithNameAndOffset(_enclosingClass.accessors,
- methodName, nameOfMethod + '=', methodName.offset);
- _expectedElements.remove(accessor);
- methodName.staticElement = accessor;
- }
- _enclosingExecutable = accessor;
- }
- super.visitMethodDeclaration(node);
- _resolveMetadata(node, node.metadata, _enclosingExecutable);
- return null;
- } finally {
- _enclosingExecutable = outerExecutable;
- }
- }
-
- @override
- Object visitPartDirective(PartDirective node) {
- super.visitPartDirective(node);
- _resolveAnnotations(
- node, node.metadata, _enclosingUnit.getAnnotations(node.offset));
- return null;
- }
-
- @override
- Object visitPartOfDirective(PartOfDirective node) {
- node.element = _enclosingUnit.library;
- return super.visitPartOfDirective(node);
- }
-
- @override
- Object visitSimpleFormalParameter(SimpleFormalParameter node) {
- if (node.parent is! DefaultFormalParameter) {
- SimpleIdentifier parameterName = node.identifier;
- ParameterElement element = _getElementForParameter(node, parameterName);
- ParameterElement outerParameter = _enclosingParameter;
- try {
- _enclosingParameter = element;
- super.visitSimpleFormalParameter(node);
- _resolveMetadata(node, node.metadata, element);
- return null;
- } finally {
- _enclosingParameter = outerParameter;
- }
- } else {}
- return super.visitSimpleFormalParameter(node);
- }
-
- @override
- Object visitSwitchCase(SwitchCase node) {
- for (Label label in node.labels) {
- SimpleIdentifier labelName = label.label;
- _findIdentifier(_enclosingExecutable.labels, labelName);
- }
- return super.visitSwitchCase(node);
- }
-
- @override
- Object visitSwitchDefault(SwitchDefault node) {
- for (Label label in node.labels) {
- SimpleIdentifier labelName = label.label;
- _findIdentifier(_enclosingExecutable.labels, labelName);
- }
- return super.visitSwitchDefault(node);
- }
-
- @override
- Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
- super.visitTopLevelVariableDeclaration(node);
- _resolveMetadata(node, node.metadata, node.variables.variables[0].element);
- return null;
- }
-
- @override
- Object visitTypeParameter(TypeParameter node) {
- SimpleIdentifier parameterName = node.name;
- Element element = null;
- if (_enclosingExecutable != null) {
- element = _findIdentifier(
- _enclosingExecutable.typeParameters, parameterName,
- required: false);
- }
- if (element == null) {
- if (_enclosingClass != null) {
- element =
- _findIdentifier(_enclosingClass.typeParameters, parameterName);
- } else if (_enclosingAlias != null) {
- element =
- _findIdentifier(_enclosingAlias.typeParameters, parameterName);
- }
- }
- if (element == null) {
- String name = parameterName.name;
- int offset = parameterName.offset;
- _mismatch(
- 'Could not find type parameter with name "$name" at $offset', node);
- }
- super.visitTypeParameter(node);
- _resolveMetadata(node, node.metadata, element);
- return null;
- }
-
- @override
- Object visitVariableDeclaration(VariableDeclaration node) {
- VariableElement element = null;
- SimpleIdentifier variableName = node.name;
- if (_enclosingExecutable != null) {
- element = _findIdentifier(
- _enclosingExecutable.localVariables, variableName,
- required: false);
- }
- if (element == null && _enclosingClass != null) {
- element = _findIdentifier(_enclosingClass.fields, variableName,
- required: false);
- }
- if (element == null && _enclosingUnit != null) {
- element = _findIdentifier(_enclosingUnit.topLevelVariables, variableName);
- }
- Expression initializer = node.initializer;
- if (initializer != null) {
- ExecutableElement outerExecutable = _enclosingExecutable;
- try {
- _enclosingExecutable = element.initializer;
- return super.visitVariableDeclaration(node);
- } finally {
- _enclosingExecutable = outerExecutable;
- }
- }
- return super.visitVariableDeclaration(node);
- }
-
- @override
- Object visitVariableDeclarationList(VariableDeclarationList node) {
- super.visitVariableDeclarationList(node);
- if (node.parent is! FieldDeclaration &&
- node.parent is! TopLevelVariableDeclaration) {
- _resolveMetadata(node, node.metadata, node.variables[0].element);
- }
- return null;
- }
-
- /**
- * Return the element in the given list of [elements] that was created for the
- * declaration at the given [offset]. Throw an [ElementMismatchException] if
- * an element at that offset cannot be found.
- *
- * This method should only be used when there is no name associated with the
- * node.
- */
- Element _findAtOffset(List<Element> elements, AstNode node, int offset) =>
- _findWithNameAndOffset(elements, node, '', offset);
-
- /**
- * Return the element in the given list of [elements] that was created for the
- * declaration with the given [identifier]. As a side-effect, associate the
- * returned element with the identifier. Throw an [ElementMismatchException]
- * if an element corresponding to the identifier cannot be found unless
- * [required] is `false`, in which case return `null`.
- */
- Element _findIdentifier(List<Element> elements, SimpleIdentifier identifier,
- {bool required: true}) {
- Element element = _findWithNameAndOffset(
- elements, identifier, identifier.name, identifier.offset,
- required: required);
- _expectedElements.remove(element);
- identifier.staticElement = element;
- return element;
- }
-
- /**
- * Return the element in the given list of [elements] that was created for the
- * declaration with the given [name] at the given [offset]. Throw an
- * [ElementMismatchException] if an element corresponding to the identifier
- * cannot be found unless [required] is `false`, in which case return `null`.
- */
- Element _findWithNameAndOffset(
- List<Element> elements, AstNode node, String name, int offset,
- {bool required: true}) {
- int length = elements.length;
- for (int i = 0; i < length; i++) {
- Element element = elements[i];
- if (element.nameOffset == offset && element.name == name) {
- return element;
- }
- }
- if (!required) {
- return null;
- }
- for (int i = 0; i < length; i++) {
- Element element = elements[i];
- if (element.name == name) {
- _mismatch(
- 'Found element with name "$name" at ${element.nameOffset}, '
- 'but expected offset of $offset',
- node);
- }
- if (element.nameOffset == offset) {
- _mismatch(
- 'Found element with name "${element.name}" at $offset, '
- 'but expected element with name "$name"',
- node);
- }
- }
- _mismatch('Could not find element with name "$name" at $offset', node);
- return null; // Never reached
- }
-
- /**
- * Search the most closely enclosing list of parameter elements for a
- * parameter, defined by the given [node], with the given [parameterName].
- * Return the element that was found, or throw an [ElementMismatchException]
- * if an element corresponding to the identifier cannot be found.
- */
- ParameterElement _getElementForParameter(
- FormalParameter node, SimpleIdentifier parameterName) {
- List<ParameterElement> parameters = null;
- if (_enclosingParameter != null) {
- parameters = _enclosingParameter.parameters;
- }
- if (parameters == null && _enclosingExecutable != null) {
- parameters = _enclosingExecutable.parameters;
- }
- if (parameters == null && _enclosingAlias != null) {
- parameters = _enclosingAlias.parameters;
- }
- if (parameters == null) {
- StringBuffer buffer = new StringBuffer();
- buffer.writeln('Could not find parameter in enclosing scope');
- buffer.writeln(
- '(_enclosingParameter == null) == ${_enclosingParameter == null}');
- buffer.writeln(
- '(_enclosingExecutable == null) == ${_enclosingExecutable == null}');
- buffer.writeln('(_enclosingAlias == null) == ${_enclosingAlias == null}');
- _mismatch(buffer.toString(), parameterName);
- }
- return _findIdentifier(parameters, parameterName);
- }
-
- /**
- * Associate each of the annotation [nodes] with the corresponding
- * [ElementAnnotation] in [annotations]. If there is a problem, report it
- * against the given [parent] node.
- */
- void _resolveAnnotations(AstNode parent, NodeList<Annotation> nodes,
- List<ElementAnnotation> annotations) {
- int nodeCount = nodes.length;
- if (nodeCount != annotations.length) {
- _mismatch(
- 'Found $nodeCount annotation nodes and '
- '${annotations.length} element annotations',
- parent);
- }
- for (int i = 0; i < nodeCount; i++) {
- nodes[i].elementAnnotation = annotations[i];
- }
- }
-
- /**
- * If [element] is not `null`, associate each of the annotation [nodes] with
- * the corresponding [ElementAnnotation] in [element.metadata]. If there is a
- * problem, report it against the given [parent] node.
- *
- * If [element] is `null`, do nothing--this allows us to be robust in the
- * case where we are operating on an element model that hasn't been fully
- * built.
- */
- void _resolveMetadata(
- AstNode parent, NodeList<Annotation> nodes, Element element) {
- if (element != null) {
- _resolveAnnotations(parent, nodes, element.metadata);
- }
- }
-
- /**
- * Throw an exception if there are non-synthetic elements in the element model
- * that were not associated with an AST node.
- */
- void _validateResolution() {
- if (_expectedElements.isNotEmpty) {
- StringBuffer buffer = new StringBuffer();
- buffer.write(_expectedElements.length);
- buffer.writeln(' unmatched elements found:');
- for (Element element in _expectedElements) {
- buffer.write(' ');
- buffer.writeln(element);
- }
- throw new ElementMismatchException(buffer.toString());
- }
- }
-}
-
-/**
* A visitor that resolves directives in an AST structure to already built
* elements.
*
@@ -3331,15 +2678,6 @@
}
}
-class ElementMismatchException extends AnalysisException {
- /**
- * Initialize a newly created exception to have the given [message] and
- * [cause].
- */
- ElementMismatchException(String message, [CaughtException cause = null])
- : super(message, cause);
-}
-
/**
* Instances of the class `EnumMemberBuilder` build the members in enum declarations.
*/
@@ -3431,41 +2769,6 @@
}
/**
- * A mixin for classes that use an existing element model to resolve a portion
- * of an AST structure.
- */
-class ExistingElementResolver {
- /**
- * The compilation unit containing the AST nodes being visited.
- */
- CompilationUnitElementImpl _enclosingUnit;
-
- /**
- * Throw an [ElementMismatchException] to report that the element model and the
- * AST do not match. The [message] will have the path to the given [node]
- * appended to it.
- */
- void _mismatch(String message, AstNode node) {
- StringBuffer buffer = new StringBuffer();
- buffer.write('Mismatch in ');
- buffer.write(runtimeType);
- buffer.write(' while resolving ');
- buffer.writeln(_enclosingUnit?.source?.fullName);
- buffer.writeln(message);
- buffer.write('Path to root:');
- String separator = ' ';
- AstNode parent = node;
- while (parent != null) {
- buffer.write(separator);
- buffer.write(parent.runtimeType.toString());
- separator = ', ';
- parent = parent.parent;
- }
- throw new ElementMismatchException(buffer.toString());
- }
-}
-
-/**
* Instances of the class `ExitDetector` determine whether the visited AST node is guaranteed
* to terminate by executing a `return` statement, `throw` expression, `rethrow`
* expression, or simple infinite loop such as `while(true)`.
diff --git a/pkg/analyzer/lib/src/generated/sdk.dart b/pkg/analyzer/lib/src/generated/sdk.dart
index 7e86d8d..c3e8e65 100644
--- a/pkg/analyzer/lib/src/generated/sdk.dart
+++ b/pkg/analyzer/lib/src/generated/sdk.dart
@@ -7,6 +7,7 @@
import 'dart:collection';
import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/src/generated/engine.dart'
show AnalysisContext, AnalysisOptions, AnalysisOptionsImpl;
@@ -15,12 +16,6 @@
import 'package:analyzer/src/summary/idl.dart' show PackageBundle;
/**
- * A function used to create a new DartSdk with the given [options]. If the
- * passed [options] are `null`, then default options are used.
- */
-typedef DartSdk SdkCreator(AnalysisOptions options);
-
-/**
* A Dart SDK installed in a specified location.
*/
abstract class DartSdk {
@@ -117,11 +112,6 @@
final bool canUseSummaries;
/**
- * The function used to create new SDK's.
- */
- final SdkCreator sdkCreator;
-
- /**
* A table mapping (an encoding of) analysis options and SDK locations to the
* DartSdk from that location that has been configured with those options.
*/
@@ -130,8 +120,7 @@
/**
* Initialize a newly created manager.
*/
- DartSdkManager(
- this.defaultSdkDirectory, this.canUseSummaries, this.sdkCreator);
+ DartSdkManager(this.defaultSdkDirectory, this.canUseSummaries);
/**
* Return any SDK that has been created, or `null` if no SDKs have been
@@ -151,25 +140,13 @@
List<SdkDescription> get sdkDescriptors => sdkMap.keys.toList();
/**
- * Return the Dart SDK that is appropriate for the given analysis [options].
- * If such an SDK has not yet been created, then the [sdkCreator] will be
- * invoked to create it.
+ * Return the Dart SDK that is appropriate for the given SDK [description].
+ * If such an SDK has not yet been created, then the [ifAbsent] function will
+ * be invoked to create it.
*/
DartSdk getSdk(SdkDescription description, DartSdk ifAbsent()) {
return sdkMap.putIfAbsent(description, ifAbsent);
}
-
- /**
- * Return the Dart SDK that is appropriate for the given analysis [options].
- * If such an SDK has not yet been created, then the [sdkCreator] will be
- * invoked to create it.
- */
- DartSdk getSdkForOptions(AnalysisOptions options) {
- // TODO(brianwilkerson) Remove this method and the field sdkCreator.
- SdkDescription description =
- new SdkDescription(<String>[defaultSdkDirectory], options);
- return getSdk(description, () => sdkCreator(options));
- }
}
/**
@@ -274,6 +251,7 @@
buffer.write(optionName);
needsSeparator = true;
}
+
for (String path in paths) {
add(path);
}
@@ -308,6 +286,11 @@
static String _DART2JS_PATH = "dart2jsPath";
/**
+ * The name of the `dart2js` platform.
+ */
+ static String _DART2JS_PLATFORM = 'DART2JS_PLATFORM';
+
+ /**
* The name of the optional parameter used to indicate whether the library is
* documented.
*/
@@ -320,6 +303,12 @@
static String _CATEGORIES = "categories";
/**
+ * The name of the optional parameter used to specify the patches for
+ * the library.
+ */
+ static String _PATCHES = "patches";
+
+ /**
* The name of the optional parameter used to specify the platforms on which
* the library can be used.
*/
@@ -397,6 +386,30 @@
library._implementation = (expression as BooleanLiteral).value;
} else if (name == _DOCUMENTED) {
library.documented = (expression as BooleanLiteral).value;
+ } else if (name == _PATCHES) {
+ if (expression is MapLiteral) {
+ expression.entries.forEach((MapLiteralEntry entry) {
+ int platforms = _convertPlatforms(entry.key);
+ Expression pathsListLiteral = entry.value;
+ if (pathsListLiteral is ListLiteral) {
+ List<String> paths = <String>[];
+ pathsListLiteral.elements.forEach((Expression pathExpr) {
+ if (pathExpr is SimpleStringLiteral) {
+ String path = pathExpr.value;
+ _validatePatchPath(path);
+ paths.add(path);
+ } else {
+ throw new ArgumentError(
+ 'The "patch" argument items must be simple strings.');
+ }
+ });
+ library.setPatchPaths(platforms, paths);
+ } else {
+ throw new ArgumentError(
+ 'The "patch" argument values must be list literals.');
+ }
+ });
+ }
} else if (name == _PLATFORMS) {
if (expression is SimpleIdentifier) {
String identifier = expression.name;
@@ -417,6 +430,61 @@
}
return null;
}
+
+ /**
+ * Validate the given [path] to a patch file. Throw [ArgumentError] if not a
+ * valid path: is absolute, or contains `..`.
+ */
+ void _validatePatchPath(String path) {
+ if (path.contains(r'\')) {
+ throw new ArgumentError('The path to a patch file must be posix: $path');
+ }
+ if (path.contains('..')) {
+ throw new ArgumentError(
+ 'The path to a patch file cannot contain "..": $path');
+ }
+ if (path.startsWith('/')) {
+ throw new ArgumentError(
+ 'The path to a patch file cannot be absolute: $path');
+ }
+ }
+
+ /**
+ * Return the platform constant value for the given [expr].
+ * Throw [ArgumentError] if not a valid platform name given.
+ */
+ static int _convertPlatform(Expression expr) {
+ if (expr is SimpleIdentifier) {
+ String name = expr.name;
+ if (name == _DART2JS_PLATFORM) {
+ return SdkLibraryImpl.DART2JS_PLATFORM;
+ }
+ if (name == _VM_PLATFORM) {
+ return SdkLibraryImpl.VM_PLATFORM;
+ }
+ throw new ArgumentError('Invalid platform name: $name');
+ }
+ throw new ArgumentError('Invalid platform type: ${expr.runtimeType}');
+ }
+
+ /**
+ * Return the platforms combination value for the [expr], which should be
+ * either `name1 | name2` or `name`. Throw [ArgumentError] if any of the
+ * names is not a valid platform name.
+ */
+ static int _convertPlatforms(Expression expr) {
+ if (expr is BinaryExpression) {
+ TokenType operator = expr.operator?.type;
+ if (operator == TokenType.BAR) {
+ return _convertPlatforms(expr.leftOperand) |
+ _convertPlatforms(expr.rightOperand);
+ } else {
+ throw new ArgumentError('Invalid platforms combination: $operator');
+ }
+ } else {
+ return _convertPlatform(expr);
+ }
+ }
}
/**
@@ -469,6 +537,12 @@
* including `dart:`.
*/
String get shortName;
+
+ /**
+ * Return the list of paths to the patch files that should be applied
+ * to this library for the given [platform], not `null`.
+ */
+ List<String> getPatches(int platform);
}
/**
@@ -521,6 +595,14 @@
int _platforms = 0;
/**
+ * The mapping from the platform combination to the list of paths (relative
+ * to the `sdk/lib` folder) of patches that should be applied to this library
+ * on every platform in the combination.
+ */
+ final Map<int, List<String>> _platformsToPatchPaths =
+ new HashMap<int, List<String>>();
+
+ /**
* Initialize a newly created library to represent the library with the given
* [name].
*/
@@ -551,6 +633,17 @@
@override
bool get isVmLibrary => (_platforms & VM_PLATFORM) != 0;
+ @override
+ List<String> getPatches(int platform) {
+ List<String> paths = <String>[];
+ _platformsToPatchPaths.forEach((int platforms, List<String> value) {
+ if ((platforms & platform) != 0) {
+ paths.addAll(value);
+ }
+ });
+ return paths;
+ }
+
/**
* Record that this library can be compiled to JavaScript by dart2js.
*/
@@ -559,6 +652,14 @@
}
/**
+ * Add a new patch with the given [path] that should be applied for the
+ * given [platforms].
+ */
+ void setPatchPaths(int platforms, List<String> paths) {
+ _platformsToPatchPaths[platforms] = paths;
+ }
+
+ /**
* Record that this library can be run on the VM.
*/
void setVmLibrary() {
diff --git a/pkg/analyzer/lib/src/generated/source_io.dart b/pkg/analyzer/lib/src/generated/source_io.dart
index 025e209..43dfb42 100644
--- a/pkg/analyzer/lib/src/generated/source_io.dart
+++ b/pkg/analyzer/lib/src/generated/source_io.dart
@@ -10,6 +10,7 @@
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/java_io.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:path/path.dart' as path;
export 'package:analyzer/src/generated/source.dart';
@@ -508,8 +509,7 @@
* Convert the given file path to a "file:" URI. On Windows, this transforms
* backslashes to forward slashes.
*/
- String _toFileUri(String filePath) =>
- JavaFile.pathContext.toUri(filePath).toString();
+ String _toFileUri(String filePath) => path.context.toUri(filePath).toString();
/**
* Return `true` if the given URI is a `package` URI.
diff --git a/pkg/analyzer/lib/src/summary/bazel_summary.dart b/pkg/analyzer/lib/src/summary/bazel_summary.dart
index f307395..a7b9b88 100644
--- a/pkg/analyzer/lib/src/summary/bazel_summary.dart
+++ b/pkg/analyzer/lib/src/summary/bazel_summary.dart
@@ -8,79 +8,143 @@
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_collection.dart';
+import 'package:analyzer/src/summary/api_signature.dart';
+import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary/link.dart';
+import 'package:analyzer/src/summary/package_bundle_reader.dart';
+import 'package:analyzer/src/summary/summarize_elements.dart';
+import 'package:analyzer/src/util/fast_uri.dart';
import 'package:convert/convert.dart';
import 'package:crypto/crypto.dart';
import 'package:meta/meta.dart';
/**
- * Return the path of the directory where bundles for the given [uri] should be
- * looked for. This directory should contain corresponding pairs of `*.api.ds`
- * and `*.full.ds` files, possibly more than one pair. Return `null` if the
- * given [uri] does not have the expected structure, so the output path cannot
- * be computed.
+ * Return the [Folder] where bundles for the given [absoluteUri] should be
+ * looked for. This folder should contain corresponding `*.full.ds` files,
+ * possibly more than one one. Return `null` if the given [absoluteUri]
+ * does not have the expected structure, so the output path cannot be computed.
*/
-typedef String GetOutputPath(ResourceProvider provider, Uri uri);
+typedef Folder GetOutputFolder(Uri absoluteUri);
+
+/**
+ * Load linked packages on demand from [SummaryProvider].
+ */
+class BazelResultProvider extends ResynthesizerResultProvider {
+ final SummaryDataStore dataStore;
+ final SummaryProvider summaryProvider;
+
+ final Map<Source, bool> sourceToSuccessMap = <Source, bool>{};
+ final Set<Package> addedPackages = new Set<Package>();
+
+ factory BazelResultProvider(SummaryProvider summaryProvider) {
+ SummaryDataStore dataStore = new SummaryDataStore(const <String>[]);
+ return new BazelResultProvider._(dataStore, summaryProvider);
+ }
+
+ BazelResultProvider._(
+ SummaryDataStore dataStore, SummaryProvider summaryProvider)
+ : dataStore = dataStore,
+ summaryProvider = summaryProvider,
+ super(summaryProvider.context, dataStore) {
+ AnalysisContext sdkContext = context.sourceFactory.dartSdk.context;
+ createResynthesizer(sdkContext, sdkContext.typeProvider);
+ }
+
+ @override
+ bool hasResultsForSource(Source source) {
+ return sourceToSuccessMap.putIfAbsent(source, () {
+ List<Package> packages = summaryProvider.getLinkedPackages(source);
+ if (packages == null) {
+ return false;
+ }
+ for (Package package in packages) {
+ if (addedPackages.add(package)) {
+ dataStore.addBundle(null, package.unlinked);
+ dataStore.addBundle(null, package.linked);
+ }
+ }
+ String uriString = source.uri.toString();
+ return resynthesizer.hasLibrarySummary(uriString);
+ });
+ }
+}
/**
* Information about a Dart package in Bazel.
*/
class Package {
- final String bundlePath;
- final PackageBundle bundle;
+ final File unlinkedFile;
+ final PackageBundle unlinked;
final Set<String> _unitUris = new Set<String>();
- Package(this.bundlePath, this.bundle) {
- _unitUris.addAll(bundle.unlinkedUnitUris);
+ PackageBundle _linked;
+
+ Package(this.unlinkedFile, this.unlinked) {
+ _unitUris.addAll(unlinked.unlinkedUnitUris);
}
+
+ PackageBundle get linked => _linked;
+
+ @override
+ String toString() => '$unlinkedFile';
}
/**
* Class that reads summaries of Bazel packages.
*
* When the client needs to produce a resolution result for a new [Source], it
- * should call [getPackages] to checked whether there is the set of packages
- * to resynthesize resolution results.
+ * should call [getLinkedPackages] to check whether there is the set of
+ * packages to resynthesize resolution results.
*/
class SummaryProvider {
final ResourceProvider provider;
- final GetOutputPath getOutputPath;
+ final String tempFileName;
+ final GetOutputFolder getOutputFolder;
+ final Folder linkedCacheFolder;
final AnalysisContext context;
+ final PackageBundle sdkBundle;
+
+ /**
+ * If `true` (by default), then linking new bundles is allowed.
+ * Otherwise only using existing cached bundles can be used.
+ */
+ final bool allowLinking;
+
+ /**
+ * See [PackageBundleAssembler.currentMajorVersion].
+ */
+ final int majorVersion;
/**
* Mapping from bundle paths to corresponding [Package]s. The packages in
* the map were consistent with their constituent sources at the moment when
* they were put into the map.
*/
- final Map<String, Package> bundlePathToPackageMap = <String, Package>{};
+ final Map<Folder, List<Package>> folderToPackagesMap = {};
/**
- * When we detected than some bundle is not consistent with its constituent
- * sources (i.e. even its unlinked state is not consistent), we remember
- * this fact to avoid loading and checking consistency next time.
+ * Mapping from [Uri]s to corresponding [Package]s.
*/
- final Set<String> knownInconsistentBundlePaths = new Set<String>();
-
- SummaryProvider(this.provider, this.getOutputPath, this.context);
+ final Map<Uri, Package> uriToPackageMap = {};
/**
- * Return the [Package] that contains information about the source with
- * the given [uri], or `null` if such package does not exist.
+ * Mapping from [Package]s to corresponding [_LinkNode]s.
*/
- @visibleForTesting
- Package getPackageForUri(Uri uri) {
- String outputPath = getOutputPath(provider, uri);
- if (outputPath != null) {
- List<Package> packages = _getPackages(outputPath);
- for (Package package in packages) {
- String uriStr = uri.toString();
- if (package._unitUris.contains(uriStr)) {
- return package;
- }
- }
- }
- return null;
- }
+ final Map<Package, _LinkNode> packageToNodeMap = {};
+
+ SummaryProvider(
+ this.provider,
+ this.tempFileName,
+ this.getOutputFolder,
+ this.linkedCacheFolder,
+ AnalysisContext context,
+ {@visibleForTesting
+ this.allowLinking: true,
+ @visibleForTesting
+ this.majorVersion: PackageBundleAssembler.currentMajorVersion})
+ : context = context,
+ sdkBundle = context.sourceFactory.dartSdk?.getLinkedBundle();
/**
* Return the complete list of [Package]s that are required to provide all
@@ -94,13 +158,64 @@
* If the full set of packages cannot be produced, for example because some
* bundles are not built, or out of date, etc, then `null` is returned.
*/
- List<PackageBundle> getPackages(Source source) {
- // TODO(scheglov) implement
- return null;
+ List<Package> getLinkedPackages(Source source) {
+ // Find the node that contains the source.
+ _LinkNode node = _getLinkNodeForUri(source.uri);
+ if (node == null) {
+ return null;
+ }
+
+ // Compute all transitive dependencies.
+ node.computeTransitiveDependencies();
+ List<_LinkNode> nodes = node.transitiveDependencies.toList();
+ nodes.forEach((dependency) => dependency.computeTransitiveDependencies());
+
+ // Fail if any dependency cannot be resolved.
+ if (node.failed) {
+ return null;
+ }
+
+ // Read existing cached linked bundles.
+ for (_LinkNode node in nodes) {
+ _readLinked(node);
+ }
+
+ // Link new packages, if allowed.
+ if (allowLinking) {
+ _link(nodes);
+ }
+
+ // Create successfully linked packages.
+ return nodes
+ .map((node) => node.package)
+ .where((package) => package.linked != null)
+ .toList();
}
/**
- * Return the hexadecimal string for the given [source] contents.
+ * Return the [Package] that contains information about the source with
+ * the given [uri], or `null` if such package does not exist.
+ */
+ @visibleForTesting
+ Package getUnlinkedForUri(Uri uri) {
+ return uriToPackageMap.putIfAbsent(uri, () {
+ Folder outputFolder = getOutputFolder(uri);
+ if (outputFolder != null) {
+ String uriStr = uri.toString();
+ List<Package> packages = _getUnlinkedPackages(outputFolder);
+ for (Package package in packages) {
+ if (package._unitUris.contains(uriStr)) {
+ return package;
+ }
+ }
+ }
+ return null;
+ });
+ }
+
+ /**
+ * Return the hexadecimal string of the MD5 hash of the contents of the
+ * given [source] in [context].
*/
String _computeSourceHashHex(Source source) {
String text = context.getContents(source).data;
@@ -110,63 +225,60 @@
}
/**
- * Return the [Package] from the file with the given [path], or `null` if the
- * file does not exist, or it cannot be read, or is not consistent with the
- * sources it contains, etc.
+ * Return the name of the file for a linked bundle, in strong or spec mode.
*/
- Package _getPackage(String path) {
- // Check if the bundle know to be inconsistent, missing, etc.
- if (knownInconsistentBundlePaths.contains(path)) {
- return null;
- }
- // Attempt to get from the cache or read from the file system.
- try {
- Package package = bundlePathToPackageMap[path];
- if (package == null) {
- File file = provider.getFile(path);
- List<int> bytes = file.readAsBytesSync();
- PackageBundle bundle = new PackageBundle.fromBuffer(bytes);
- // Check for consistency, and fail if it's not.
- if (!_isUnlinkedBundleConsistent(bundle)) {
- knownInconsistentBundlePaths.add(path);
- return null;
- }
- // OK, put the package into the cache.
- package = new Package(path, bundle);
- bundlePathToPackageMap[path] = package;
- }
- return package;
- } catch (_) {
- return null;
+ String _getLinkedName(String hash) {
+ if (context.analysisOptions.strongMode) {
+ return 'linked_$hash.ds';
+ } else {
+ return 'linked_spec_$hash.ds';
}
}
/**
- * Return all consistent [Package]s in the given [folderPath].
+ * Return the node for the given [uri], or `null` if there is no unlinked
+ * bundle that contains [uri].
*/
- List<Package> _getPackages(String folderPath) {
- List<Package> packages = <Package>[];
- try {
- Folder folder = provider.getFolder(folderPath);
- List<Resource> children = folder.getChildren();
- for (Resource child in children) {
- if (child is File) {
- String packagePath = child.path;
- if (packagePath.toLowerCase().endsWith('.full.ds')) {
- Package package = _getPackage(packagePath);
- if (package != null) {
- packages.add(package);
+ _LinkNode _getLinkNodeForUri(Uri uri) {
+ Package package = getUnlinkedForUri(uri);
+ return packageToNodeMap.putIfAbsent(package, () {
+ if (package == null) {
+ return null;
+ }
+ return new _LinkNode(this, package);
+ });
+ }
+
+ /**
+ * Return all consistent unlinked [Package]s in the given [folder]. Some of
+ * the returned packages might be already linked.
+ */
+ List<Package> _getUnlinkedPackages(Folder folder) {
+ List<Package> packages = folderToPackagesMap[folder];
+ if (packages == null) {
+ packages = <Package>[];
+ try {
+ List<Resource> children = folder.getChildren();
+ for (Resource child in children) {
+ if (child is File) {
+ String packagePath = child.path;
+ if (packagePath.toLowerCase().endsWith('.full.ds')) {
+ Package package = _readUnlinkedPackage(child);
+ if (package != null) {
+ packages.add(package);
+ }
}
}
}
- }
- } on FileSystemException {}
+ } on FileSystemException {}
+ folderToPackagesMap[folder] = packages;
+ }
return packages;
}
/**
* Return `true` if the unlinked information of the [bundle] is consistent
- * with its constituent sources.
+ * with its constituent sources in [context].
*/
bool _isUnlinkedBundleConsistent(PackageBundle bundle) {
try {
@@ -184,8 +296,266 @@
List<String> bundleHashes = bundle.unlinkedUnitHashes.toList()..sort();
actualHashes.sort();
return listsEqual(actualHashes, bundleHashes);
- } catch (_) {
- return false;
+ } on FileSystemException {}
+ return false;
+ }
+
+ /**
+ * Link the given [nodes].
+ */
+ void _link(List<_LinkNode> nodes) {
+ // Fill the store with bundles.
+ // Append the linked SDK bundle.
+ // Append unlinked and (if read from a cache) linked package bundles.
+ SummaryDataStore store = new SummaryDataStore(const <String>[]);
+ store.addBundle(null, sdkBundle);
+ for (_LinkNode node in nodes) {
+ store.addBundle(null, node.package.unlinked);
+ if (node.package.linked != null) {
+ store.addBundle(null, node.package.linked);
+ }
+ }
+
+ // Prepare URIs to link.
+ Map<String, _LinkNode> uriToNode = <String, _LinkNode>{};
+ for (_LinkNode node in nodes) {
+ if (!node.isReady) {
+ for (String uri in node.package.unlinked.unlinkedUnitUris) {
+ uriToNode[uri] = node;
+ }
+ }
+ }
+ Set<String> libraryUris = uriToNode.keys.toSet();
+
+ // Perform linking.
+ Map<String, LinkedLibraryBuilder> linkedLibraries =
+ link(libraryUris, (String uri) {
+ return store.linkedMap[uri];
+ }, (String uri) {
+ return store.unlinkedMap[uri];
+ }, context.declaredVariables.get, context.analysisOptions.strongMode);
+
+ // Assemble newly linked bundles.
+ for (_LinkNode node in nodes) {
+ if (!node.isReady) {
+ PackageBundleAssembler assembler = new PackageBundleAssembler();
+ linkedLibraries.forEach((uri, linkedLibrary) {
+ if (identical(uriToNode[uri], node)) {
+ assembler.addLinkedLibrary(uri, linkedLibrary);
+ }
+ });
+ List<int> bytes = assembler.assemble().toBuffer();
+ node.package._linked = new PackageBundle.fromBuffer(bytes);
+ _writeLinked(node, bytes);
+ }
}
}
+
+ /**
+ * Attempt to read the linked bundle that corresponds to the given [node]
+ * with all its transitive dependencies.
+ */
+ void _readLinked(_LinkNode node) {
+ String hash = node.linkedHash;
+ if (!node.isReady && hash != null) {
+ String fileName = _getLinkedName(hash);
+ File file = linkedCacheFolder.getChildAssumingFile(fileName);
+ // Try to read from the file system.
+ if (file.exists) {
+ try {
+ List<int> bytes = file.readAsBytesSync();
+ node.package._linked = new PackageBundle.fromBuffer(bytes);
+ } on FileSystemException {
+ // Ignore file system exceptions.
+ }
+ }
+ }
+ }
+
+ /**
+ * Read the unlinked [Package] from the given [file], or return `null` if the
+ * file does not exist, or it cannot be read, or is not consistent with the
+ * constituent sources on the file system.
+ */
+ Package _readUnlinkedPackage(File file) {
+ try {
+ List<int> bytes = file.readAsBytesSync();
+ PackageBundle bundle = new PackageBundle.fromBuffer(bytes);
+ // Check the major version.
+ if (bundle.majorVersion != majorVersion) {
+ return null;
+ }
+ // Check for consistency, and fail if it's not.
+ if (!_isUnlinkedBundleConsistent(bundle)) {
+ return null;
+ }
+ // OK, use the bundle.
+ return new Package(file, bundle);
+ } on FileSystemException {}
+ return null;
+ }
+
+ /**
+ * Atomically write the given [bytes] into the file in the [folder].
+ */
+ void _writeAtomic(Folder folder, String fileName, List<int> bytes) {
+ String filePath = folder.getChildAssumingFile(fileName).path;
+ File tempFile = folder.getChildAssumingFile(tempFileName);
+ tempFile.writeAsBytesSync(bytes);
+ tempFile.renameSync(filePath);
+ }
+
+ /**
+ * If a new linked bundle was linked for the given [node], write the bundle
+ * into the memory cache and the file system.
+ */
+ void _writeLinked(_LinkNode node, List<int> bytes) {
+ String hash = node.linkedHash;
+ if (hash != null) {
+ String fileName = _getLinkedName(hash);
+ _writeAtomic(linkedCacheFolder, fileName, bytes);
+ }
+ }
+}
+
+/**
+ * Information about a single [Package].
+ */
+class _LinkNode {
+ final SummaryProvider linker;
+ final Package package;
+
+ bool failed = false;
+ Set<_LinkNode> transitiveDependencies;
+
+ List<_LinkNode> _dependencies;
+ String _linkedHash;
+
+ _LinkNode(this.linker, this.package);
+
+ /**
+ * Retrieve the dependencies of this node.
+ */
+ List<_LinkNode> get dependencies {
+ if (_dependencies == null) {
+ Set<_LinkNode> dependencies = new Set<_LinkNode>();
+
+ void appendDependency(String uriStr) {
+ Uri uri = FastUri.parse(uriStr);
+ if (!uri.hasScheme) {
+ // A relative path in this package, skip it.
+ } else if (uri.scheme == 'dart') {
+ // Dependency on the SDK is implicit and always added.
+ // The SDK linked bundle is precomputed before linking packages.
+ } else if (uri.scheme == 'package') {
+ _LinkNode packageNode = linker._getLinkNodeForUri(uri);
+ if (packageNode == null) {
+ failed = true;
+ }
+ if (packageNode != null) {
+ dependencies.add(packageNode);
+ }
+ } else {
+ failed = true;
+ }
+ }
+
+ for (UnlinkedUnit unit in package.unlinked.unlinkedUnits) {
+ for (UnlinkedImport import in unit.imports) {
+ if (!import.isImplicit) {
+ appendDependency(import.uri);
+ }
+ }
+ for (UnlinkedExportPublic export in unit.publicNamespace.exports) {
+ appendDependency(export.uri);
+ }
+ }
+
+ _dependencies = dependencies.toList();
+ }
+ return _dependencies;
+ }
+
+ /**
+ * Return `true` is the node is ready - has the linked bundle or failed (does
+ * not have all required dependencies).
+ */
+ bool get isReady => package.linked != null || failed;
+
+ /**
+ * Return the hash string that corresponds to this linked bundle in the
+ * context of its SDK bundle and transitive dependencies. Return `null` if
+ * the hash computation fails, because for example the full transitive
+ * dependencies cannot computed.
+ */
+ String get linkedHash {
+ if (_linkedHash == null && transitiveDependencies != null && !failed) {
+ ApiSignature signature = new ApiSignature();
+ // Add all unlinked API signatures.
+ List<String> signatures = <String>[];
+ signatures.add(linker.sdkBundle.apiSignature);
+ transitiveDependencies
+ .map((node) => node.package.unlinked.apiSignature)
+ .forEach(signatures.add);
+ signatures.sort();
+ signatures.forEach(signature.addString);
+ // Combine into a single hash.
+ appendDeclaredVariables(signature);
+ _linkedHash = signature.toHex();
+ }
+ return _linkedHash;
+ }
+
+ /**
+ * Append names and values of all referenced declared variables (even the
+ * ones without actually declared values) to the given [signature].
+ */
+ void appendDeclaredVariables(ApiSignature signature) {
+ Set<String> nameSet = new Set<String>();
+ for (_LinkNode node in transitiveDependencies) {
+ for (UnlinkedUnit unit in node.package.unlinked.unlinkedUnits) {
+ for (UnlinkedImport import in unit.imports) {
+ for (UnlinkedConfiguration configuration in import.configurations) {
+ nameSet.add(configuration.name);
+ }
+ }
+ for (UnlinkedExportPublic export in unit.publicNamespace.exports) {
+ for (UnlinkedConfiguration configuration in export.configurations) {
+ nameSet.add(configuration.name);
+ }
+ }
+ }
+ }
+ List<String> sortedNameList = nameSet.toList()..sort();
+ signature.addInt(sortedNameList.length);
+ for (String name in sortedNameList) {
+ signature.addString(name);
+ signature.addString(linker.context.declaredVariables.get(name) ?? '');
+ }
+ }
+
+ /**
+ * Compute the set of existing transitive dependencies for this node.
+ * If any dependency cannot be resolved, then set [failed] to `true`.
+ * Only unlinked bundle is used, so this method can be called before linking.
+ */
+ void computeTransitiveDependencies() {
+ if (transitiveDependencies == null) {
+ transitiveDependencies = new Set<_LinkNode>();
+
+ void appendDependencies(_LinkNode node) {
+ if (transitiveDependencies.add(node)) {
+ node.dependencies.forEach(appendDependencies);
+ }
+ }
+
+ appendDependencies(this);
+ if (transitiveDependencies.any((node) => node.failed)) {
+ failed = true;
+ }
+ }
+ }
+
+ @override
+ String toString() => package.toString();
}
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index 2f7fc97..a515954 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -1425,6 +1425,7 @@
class LinkedUnitBuilder extends Object with _LinkedUnitMixin implements idl.LinkedUnit {
List<int> _constCycles;
+ List<int> _parametersInheritingCovariant;
List<LinkedReferenceBuilder> _references;
List<EntityRefBuilder> _types;
@@ -1441,6 +1442,19 @@
}
@override
+ List<int> get parametersInheritingCovariant => _parametersInheritingCovariant ??= <int>[];
+
+ /**
+ * List of slot ids (referring to [UnlinkedParam.inheritsCovariantSlot])
+ * corresponding to parameters that inherit `@covariant` behavior from a base
+ * class.
+ */
+ void set parametersInheritingCovariant(List<int> value) {
+ assert(value == null || value.every((e) => e >= 0));
+ this._parametersInheritingCovariant = value;
+ }
+
+ @override
List<LinkedReferenceBuilder> get references => _references ??= <LinkedReferenceBuilder>[];
/**
@@ -1466,8 +1480,9 @@
this._types = value;
}
- LinkedUnitBuilder({List<int> constCycles, List<LinkedReferenceBuilder> references, List<EntityRefBuilder> types})
+ LinkedUnitBuilder({List<int> constCycles, List<int> parametersInheritingCovariant, List<LinkedReferenceBuilder> references, List<EntityRefBuilder> types})
: _constCycles = constCycles,
+ _parametersInheritingCovariant = parametersInheritingCovariant,
_references = references,
_types = types;
@@ -1507,15 +1522,27 @@
signature.addInt(x);
}
}
+ if (this._parametersInheritingCovariant == null) {
+ signature.addInt(0);
+ } else {
+ signature.addInt(this._parametersInheritingCovariant.length);
+ for (var x in this._parametersInheritingCovariant) {
+ signature.addInt(x);
+ }
+ }
}
fb.Offset finish(fb.Builder fbBuilder) {
fb.Offset offset_constCycles;
+ fb.Offset offset_parametersInheritingCovariant;
fb.Offset offset_references;
fb.Offset offset_types;
if (!(_constCycles == null || _constCycles.isEmpty)) {
offset_constCycles = fbBuilder.writeListUint32(_constCycles);
}
+ if (!(_parametersInheritingCovariant == null || _parametersInheritingCovariant.isEmpty)) {
+ offset_parametersInheritingCovariant = fbBuilder.writeListUint32(_parametersInheritingCovariant);
+ }
if (!(_references == null || _references.isEmpty)) {
offset_references = fbBuilder.writeList(_references.map((b) => b.finish(fbBuilder)).toList());
}
@@ -1526,6 +1553,9 @@
if (offset_constCycles != null) {
fbBuilder.addOffset(2, offset_constCycles);
}
+ if (offset_parametersInheritingCovariant != null) {
+ fbBuilder.addOffset(3, offset_parametersInheritingCovariant);
+ }
if (offset_references != null) {
fbBuilder.addOffset(0, offset_references);
}
@@ -1550,6 +1580,7 @@
_LinkedUnitImpl(this._bc, this._bcOffset);
List<int> _constCycles;
+ List<int> _parametersInheritingCovariant;
List<idl.LinkedReference> _references;
List<idl.EntityRef> _types;
@@ -1560,6 +1591,12 @@
}
@override
+ List<int> get parametersInheritingCovariant {
+ _parametersInheritingCovariant ??= const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 3, const <int>[]);
+ return _parametersInheritingCovariant;
+ }
+
+ @override
List<idl.LinkedReference> get references {
_references ??= const fb.ListReader<idl.LinkedReference>(const _LinkedReferenceReader()).vTableGet(_bc, _bcOffset, 0, const <idl.LinkedReference>[]);
return _references;
@@ -1577,6 +1614,7 @@
Map<String, Object> toJson() {
Map<String, Object> _result = <String, Object>{};
if (constCycles.isNotEmpty) _result["constCycles"] = constCycles;
+ if (parametersInheritingCovariant.isNotEmpty) _result["parametersInheritingCovariant"] = parametersInheritingCovariant;
if (references.isNotEmpty) _result["references"] = references.map((_value) => _value.toJson()).toList();
if (types.isNotEmpty) _result["types"] = types.map((_value) => _value.toJson()).toList();
return _result;
@@ -1585,6 +1623,7 @@
@override
Map<String, Object> toMap() => {
"constCycles": constCycles,
+ "parametersInheritingCovariant": parametersInheritingCovariant,
"references": references,
"types": types,
};
@@ -6718,6 +6757,7 @@
CodeRangeBuilder _codeRange;
String _defaultValueCode;
int _inferredTypeSlot;
+ int _inheritsCovariantSlot;
UnlinkedExecutableBuilder _initializer;
bool _isFunctionTyped;
bool _isInitializingFormal;
@@ -6780,6 +6820,22 @@
}
@override
+ int get inheritsCovariantSlot => _inheritsCovariantSlot ??= 0;
+
+ /**
+ * If this is a parameter of an instance method, a nonzero slot id which is
+ * unique within this compilation unit. If this id is found in
+ * [LinkedUnit.parametersInheritingCovariant], then this parameter inherits
+ * `@covariant` behavior from a base class.
+ *
+ * Otherwise, zero.
+ */
+ void set inheritsCovariantSlot(int value) {
+ assert(value == null || value >= 0);
+ this._inheritsCovariantSlot = value;
+ }
+
+ @override
UnlinkedExecutableBuilder get initializer => _initializer;
/**
@@ -6886,11 +6942,12 @@
this._visibleOffset = value;
}
- UnlinkedParamBuilder({List<UnlinkedConstBuilder> annotations, CodeRangeBuilder codeRange, String defaultValueCode, int inferredTypeSlot, UnlinkedExecutableBuilder initializer, bool isFunctionTyped, bool isInitializingFormal, idl.UnlinkedParamKind kind, String name, int nameOffset, List<UnlinkedParamBuilder> parameters, EntityRefBuilder type, int visibleLength, int visibleOffset})
+ UnlinkedParamBuilder({List<UnlinkedConstBuilder> annotations, CodeRangeBuilder codeRange, String defaultValueCode, int inferredTypeSlot, int inheritsCovariantSlot, UnlinkedExecutableBuilder initializer, bool isFunctionTyped, bool isInitializingFormal, idl.UnlinkedParamKind kind, String name, int nameOffset, List<UnlinkedParamBuilder> parameters, EntityRefBuilder type, int visibleLength, int visibleOffset})
: _annotations = annotations,
_codeRange = codeRange,
_defaultValueCode = defaultValueCode,
_inferredTypeSlot = inferredTypeSlot,
+ _inheritsCovariantSlot = inheritsCovariantSlot,
_initializer = initializer,
_isFunctionTyped = isFunctionTyped,
_isInitializingFormal = isInitializingFormal,
@@ -6946,6 +7003,7 @@
signature.addInt(this._visibleOffset ?? 0);
signature.addBool(this._initializer != null);
this._initializer?.collectApiSignature(signature);
+ signature.addInt(this._inheritsCovariantSlot ?? 0);
}
fb.Offset finish(fb.Builder fbBuilder) {
@@ -6990,6 +7048,9 @@
if (_inferredTypeSlot != null && _inferredTypeSlot != 0) {
fbBuilder.addUint32(2, _inferredTypeSlot);
}
+ if (_inheritsCovariantSlot != null && _inheritsCovariantSlot != 0) {
+ fbBuilder.addUint32(14, _inheritsCovariantSlot);
+ }
if (offset_initializer != null) {
fbBuilder.addOffset(12, offset_initializer);
}
@@ -7041,6 +7102,7 @@
idl.CodeRange _codeRange;
String _defaultValueCode;
int _inferredTypeSlot;
+ int _inheritsCovariantSlot;
idl.UnlinkedExecutable _initializer;
bool _isFunctionTyped;
bool _isInitializingFormal;
@@ -7077,6 +7139,12 @@
}
@override
+ int get inheritsCovariantSlot {
+ _inheritsCovariantSlot ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 14, 0);
+ return _inheritsCovariantSlot;
+ }
+
+ @override
idl.UnlinkedExecutable get initializer {
_initializer ??= const _UnlinkedExecutableReader().vTableGet(_bc, _bcOffset, 12, null);
return _initializer;
@@ -7145,6 +7213,7 @@
if (codeRange != null) _result["codeRange"] = codeRange.toJson();
if (defaultValueCode != '') _result["defaultValueCode"] = defaultValueCode;
if (inferredTypeSlot != 0) _result["inferredTypeSlot"] = inferredTypeSlot;
+ if (inheritsCovariantSlot != 0) _result["inheritsCovariantSlot"] = inheritsCovariantSlot;
if (initializer != null) _result["initializer"] = initializer.toJson();
if (isFunctionTyped != false) _result["isFunctionTyped"] = isFunctionTyped;
if (isInitializingFormal != false) _result["isInitializingFormal"] = isInitializingFormal;
@@ -7164,6 +7233,7 @@
"codeRange": codeRange,
"defaultValueCode": defaultValueCode,
"inferredTypeSlot": inferredTypeSlot,
+ "inheritsCovariantSlot": inheritsCovariantSlot,
"initializer": initializer,
"isFunctionTyped": isFunctionTyped,
"isInitializingFormal": isInitializingFormal,
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs
index c7afabc..3da4512 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -1079,6 +1079,13 @@
constCycles:[uint] (id: 2);
/**
+ * List of slot ids (referring to [UnlinkedParam.inheritsCovariantSlot])
+ * corresponding to parameters that inherit `@covariant` behavior from a base
+ * class.
+ */
+ parametersInheritingCovariant:[uint] (id: 3);
+
+ /**
* Information about the resolution of references within the compilation
* unit. Each element of [UnlinkedUnit.references] has a corresponding
* element in this list (at the same index). If this list has additional
@@ -2016,6 +2023,16 @@
inferredTypeSlot:uint (id: 2);
/**
+ * If this is a parameter of an instance method, a nonzero slot id which is
+ * unique within this compilation unit. If this id is found in
+ * [LinkedUnit.parametersInheritingCovariant], then this parameter inherits
+ * `@covariant` behavior from a base class.
+ *
+ * Otherwise, zero.
+ */
+ inheritsCovariantSlot:uint (id: 14);
+
+ /**
* The synthetic initializer function of the parameter. Absent if the variable
* does not have an initializer.
*/
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index 4eff005..ba024af 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -529,6 +529,14 @@
List<int> get constCycles;
/**
+ * List of slot ids (referring to [UnlinkedParam.inheritsCovariantSlot])
+ * corresponding to parameters that inherit `@covariant` behavior from a base
+ * class.
+ */
+ @Id(3)
+ List<int> get parametersInheritingCovariant;
+
+ /**
* Information about the resolution of references within the compilation
* unit. Each element of [UnlinkedUnit.references] has a corresponding
* element in this list (at the same index). If this list has additional
@@ -2261,6 +2269,17 @@
int get inferredTypeSlot;
/**
+ * If this is a parameter of an instance method, a nonzero slot id which is
+ * unique within this compilation unit. If this id is found in
+ * [LinkedUnit.parametersInheritingCovariant], then this parameter inherits
+ * `@covariant` behavior from a base class.
+ *
+ * Otherwise, zero.
+ */
+ @Id(14)
+ int get inheritsCovariantSlot;
+
+ /**
* The synthetic initializer function of the parameter. Absent if the variable
* does not have an initializer.
*/
diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/analyzer/lib/src/summary/link.dart
index 42f2994..ea25920 100644
--- a/pkg/analyzer/lib/src/summary/link.dart
+++ b/pkg/analyzer/lib/src/summary/link.dart
@@ -1216,14 +1216,19 @@
// TODO(paulberry): implement other cases as necessary
throw new UnimplementedError('${element._unlinkedExecutable.kind}');
}
- return addRawReference(element.name,
- numTypeParameters: element.typeParameters.length,
- containingReference:
- enclosingClass != null ? addReference(enclosingClass) : null,
- dependency: enclosingClass != null
- ? null
- : library.addDependency(element.library as LibraryElementForLink),
- kind: kind);
+ if (enclosingClass == null) {
+ return addRawReference(element.name,
+ numTypeParameters: element.typeParameters.length,
+ dependency:
+ library.addDependency(element.library as LibraryElementForLink),
+ unitNum: element.compilationUnit.unitNum,
+ kind: kind);
+ } else {
+ return addRawReference(element.name,
+ numTypeParameters: element.typeParameters.length,
+ containingReference: addReference(enclosingClass),
+ kind: kind);
+ }
} else if (element is FunctionElementForLink_Initializer) {
return addRawReference('',
containingReference: addReference(element.enclosingElement),
@@ -1231,6 +1236,7 @@
} else if (element is TopLevelVariableElementForLink) {
return addRawReference(element.name,
dependency: library.addDependency(element.library),
+ unitNum: element.compilationUnit.unitNum,
kind: ReferenceKind.topLevelPropertyAccessor);
} else if (element is FieldElementForLink_ClassField) {
ClassElementForLink_Class enclosingClass = element.enclosingElement;
@@ -1280,6 +1286,7 @@
*/
void unlink() {
_linkedUnit.constCycles.clear();
+ _linkedUnit.parametersInheritingCovariant.clear();
_linkedUnit.references.length = _unlinkedUnit.references.length;
_linkedUnit.types.clear();
}
@@ -1293,6 +1300,14 @@
}
/**
+ * Store the fact that the given [slot] represents a parameter that inherits
+ * `@covariant` behavior.
+ */
+ void _storeInheritsCovariant(int slot) {
+ _linkedUnit.parametersInheritingCovariant.add(slot);
+ }
+
+ /**
* Store the given [linkedType] in the given [slot] of the this compilation
* unit's linked type list.
*/
@@ -3382,6 +3397,11 @@
LibraryCycleForLink get libraryCycleForLink;
@override
+ String get name {
+ return _definingUnlinkedUnit.libraryName;
+ }
+
+ @override
List<UnitElement> get units {
if (_units == null) {
UnlinkedUnit definingUnit = definingUnlinkedUnit;
@@ -3937,9 +3957,7 @@
DartType _inferredType;
DartType _declaredType;
-
- @override
- bool inheritsCovariant = false;
+ bool _inheritsCovariant = false;
ParameterElementForLink(this.enclosingElement, this._unlinkedParam,
this._typeParameterContext, this.compilationUnit, this._parameterIndex) {
@@ -3956,7 +3974,32 @@
!_unlinkedParam.isFunctionTyped && _unlinkedParam.type == null;
@override
- bool get isCovariant => false;
+ bool get inheritsCovariant => _inheritsCovariant;
+
+ @override
+ void set inheritsCovariant(bool value) {
+ _inheritsCovariant = value;
+ }
+
+ @override
+ bool get isCovariant {
+ if (inheritsCovariant) {
+ return true;
+ }
+ for (UnlinkedConst annotation in _unlinkedParam.annotations) {
+ if (annotation.operations.length == 1 &&
+ annotation.operations[0] == UnlinkedConstOperation.pushReference) {
+ ReferenceableElementForLink element =
+ this.compilationUnit.resolveRef(annotation.references[0].reference);
+ if (element is PropertyAccessorElementForLink &&
+ element.name == 'checked' &&
+ element.library.name == 'meta') {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
@override
String get name => _unlinkedParam.name;
@@ -4012,6 +4055,10 @@
void link(CompilationUnitElementInBuildUnit compilationUnit) {
compilationUnit._storeLinkedType(
_unlinkedParam.inferredTypeSlot, _inferredType, _typeParameterContext);
+ if (inheritsCovariant) {
+ compilationUnit
+ ._storeInheritsCovariant(_unlinkedParam.inheritsCovariantSlot);
+ }
}
@override
diff --git a/pkg/analyzer/lib/src/summary/pub_summary.dart b/pkg/analyzer/lib/src/summary/pub_summary.dart
index 0113564..171c2ff 100644
--- a/pkg/analyzer/lib/src/summary/pub_summary.dart
+++ b/pkg/analyzer/lib/src/summary/pub_summary.dart
@@ -33,12 +33,6 @@
import 'package:path/path.dart' as pathos;
/**
- * Return the raw string value of the variable with the given [name],
- * or `null` of the variable is not defined.
- */
-typedef String _GetDeclaredVariable(String name);
-
-/**
* Unlinked and linked information about a [PubPackage].
*/
class LinkedPubPackage {
@@ -180,94 +174,7 @@
* referencing the same packages.
*/
List<LinkedPubPackage> getLinkedBundles(AnalysisContext context) {
-// Stopwatch timer = new Stopwatch()..start();
-
- _GetDeclaredVariable getDeclaredVariable = context.declaredVariables.get;
- SourceFactory sourceFactory = context.sourceFactory;
- _ListedPackages listedPackages = new _ListedPackages(sourceFactory);
-
- PackageBundle sdkBundle = sourceFactory.dartSdk.getLinkedBundle();
- if (sdkBundle == null) {
- return const <LinkedPubPackage>[];
- }
-
- bool strong = context.analysisOptions.strongMode;
- Map<PubPackage, PackageBundle> unlinkedBundles =
- getUnlinkedBundles(context);
-
- // TODO(scheglov) remove debug output after optimizing
-// print('LOADED ${unlinkedBundles.length} unlinked bundles'
-// ' in ${timer.elapsedMilliseconds} ms');
-// timer..reset();
-
- // If no unlinked bundles, there is nothing we can try to link.
- if (unlinkedBundles.isEmpty) {
- return const <LinkedPubPackage>[];
- }
-
- // Create graph nodes for packages.
- List<_LinkNode> nodes = <_LinkNode>[];
- Map<String, _LinkNode> packageToNode = <String, _LinkNode>{};
- unlinkedBundles.forEach((package, unlinked) {
- _LinkNode node = new _LinkNode(sdkBundle, getDeclaredVariable,
- listedPackages, package, unlinked, packageToNode);
- nodes.add(node);
- packageToNode[package.name] = node;
- });
-
- // Compute transitive dependencies, mark some nodes as failed.
- for (_LinkNode node in nodes) {
- node.computeTransitiveDependencies();
- }
-
- // Attempt to read existing linked bundles.
- for (_LinkNode node in nodes) {
- _readLinked(node, strong);
- }
-
- // Link new bundles, if allowed.
- if (allowLinking) {
- // Fill the store with bundles.
- // Append the linked SDK bundle.
- // Append unlinked and (if read from a cache) linked package bundles.
- SummaryDataStore store = new SummaryDataStore(const <String>[]);
- store.addBundle(null, sdkBundle);
- for (_LinkNode node in nodes) {
- store.addBundle(null, node.unlinked);
- if (node.linked != null) {
- store.addBundle(null, node.linked);
- }
- }
-
- // Link each package node.
- for (_LinkNode node in nodes) {
- if (!node.isEvaluated) {
- new _LinkWalker(getDeclaredVariable, listedPackages, store, strong)
- .walk(node);
- }
- }
-
- // Write newly linked bundles.
- for (_LinkNode node in nodes) {
- _writeLinked(node, strong);
- }
- }
-
- // Create successfully linked packages.
- List<LinkedPubPackage> linkedPackages = <LinkedPubPackage>[];
- for (_LinkNode node in nodes) {
- if (node.linked != null) {
- linkedPackages.add(new LinkedPubPackage(
- node.package, node.unlinked, node.linked, node.linkedHash));
- }
- }
-
- // TODO(scheglov) remove debug output after optimizing
-// print('LINKED ${linkedPackages.length} bundles'
-// ' in ${timer.elapsedMilliseconds} ms');
-
- // Done.
- return linkedPackages;
+ return new _ContextLinker(this, context).getLinkedBundles();
}
/**
@@ -381,17 +288,6 @@
}
/**
- * Return the name of the file for a linked bundle, in strong or spec mode.
- */
- String _getLinkedName(String hash, bool strong) {
- if (strong) {
- return 'linked_$hash.ds';
- } else {
- return 'linked_spec_$hash.ds';
- }
- }
-
- /**
* Return the name of the file for an unlinked bundle, in strong or spec mode.
*/
String _getUnlinkedName(bool strong) {
@@ -511,35 +407,6 @@
}
/**
- * Attempt to find the linked bundle that corresponds to the given [node]
- * with all its transitive dependencies and put it into [_LinkNode.linked].
- */
- void _readLinked(_LinkNode node, bool strong) {
- String hash = node.linkedHash;
- if (hash != null) {
- String fileName = _getLinkedName(hash, strong);
- File file = node.package.folder.getChildAssumingFile(fileName);
- // Try to find in the cache.
- PackageBundle linked = linkedBundleMap[file.path];
- if (linked != null) {
- node.linked = linked;
- return;
- }
- // Try to read from the file system.
- if (file.exists) {
- try {
- List<int> bytes = file.readAsBytesSync();
- linked = new PackageBundle.fromBuffer(bytes);
- linkedBundleMap[file.path] = linked;
- node.linked = linked;
- } on FileSystemException {
- // Ignore file system exceptions.
- }
- }
- }
- }
-
- /**
* Schedule delayed computation of the next package unlinked bundle from the
* set of [packagesToComputeUnlinked]. We delay each computation because we
* want operations in analysis server to proceed, and computing bundles of
@@ -570,20 +437,6 @@
}
/**
- * If a new linked bundle was linked for the given [node], write the bundle
- * into the memory cache and the file system.
- */
- void _writeLinked(_LinkNode node, bool strong) {
- String hash = node.linkedHash;
- if (hash != null && node.linkedNewBytes != null) {
- String fileName = _getLinkedName(hash, strong);
- File file = node.package.folder.getChildAssumingFile(fileName);
- linkedBundleMap[file.path] = node.linked;
- _writeAtomic(node.package.folder, fileName, node.linkedNewBytes);
- }
- }
-
- /**
* If the given [uri] has the `package` scheme, return the name of the
* package that contains the referenced resource. Otherwise return `null`.
*
@@ -617,33 +470,270 @@
}
}
-/**
- * Specialization of [Node] for linking packages in proper dependency order.
- */
-class _LinkNode extends Node<_LinkNode> {
- final PackageBundle sdkBundle;
- final _GetDeclaredVariable getDeclaredVariable;
+class _ContextLinker {
+ final PubSummaryManager manager;
+ final AnalysisContext context;
+
+ final strong;
final _ListedPackages listedPackages;
+ final PackageBundle sdkBundle;
+
+ final List<_LinkNode> nodes = <_LinkNode>[];
+ final Map<String, _LinkNode> packageToNode = <String, _LinkNode>{};
+
+ _ContextLinker(this.manager, AnalysisContext context)
+ : context = context,
+ strong = context.analysisOptions.strongMode,
+ listedPackages = new _ListedPackages(context.sourceFactory),
+ sdkBundle = context.sourceFactory.dartSdk.getLinkedBundle();
+
+ /**
+ * Return the list of linked [LinkedPubPackage]s that can be provided at this
+ * time for a subset of the packages used by the [context].
+ */
+ List<LinkedPubPackage> getLinkedBundles() {
+// Stopwatch timer = new Stopwatch()..start();
+
+ if (sdkBundle == null) {
+ return const <LinkedPubPackage>[];
+ }
+
+ Map<PubPackage, PackageBundle> unlinkedBundles =
+ manager.getUnlinkedBundles(context);
+
+ // TODO(scheglov) remove debug output after optimizing
+// print('LOADED ${unlinkedBundles.length} unlinked bundles'
+// ' in ${timer.elapsedMilliseconds} ms');
+// timer..reset();
+
+ // If no unlinked bundles, there is nothing we can try to link.
+ if (unlinkedBundles.isEmpty) {
+ return const <LinkedPubPackage>[];
+ }
+
+ // Create nodes for packages.
+ unlinkedBundles.forEach((package, unlinked) {
+ _LinkNode node = new _LinkNode(this, package, unlinked);
+ nodes.add(node);
+ packageToNode[package.name] = node;
+ });
+
+ // Compute transitive dependencies, mark some nodes as failed.
+ for (_LinkNode node in nodes) {
+ node.computeTransitiveDependencies();
+ }
+
+ // Attempt to read existing linked bundles.
+ for (_LinkNode node in nodes) {
+ _readLinked(node);
+ }
+
+ // Link new packages, if allowed.
+ if (manager.allowLinking) {
+ _link();
+ }
+
+ // Create successfully linked packages.
+ List<LinkedPubPackage> linkedPackages = <LinkedPubPackage>[];
+ for (_LinkNode node in nodes) {
+ if (node.linked != null) {
+ linkedPackages.add(new LinkedPubPackage(
+ node.package, node.unlinked, node.linked, node.linkedHash));
+ }
+ }
+
+ // TODO(scheglov) remove debug output after optimizing
+// print('LINKED ${linkedPackages.length} bundles'
+// ' in ${timer.elapsedMilliseconds} ms');
+
+ // Done.
+ return linkedPackages;
+ }
+
+ String _getDeclaredVariable(String name) {
+ return context.declaredVariables.get(name);
+ }
+
+ /**
+ * Return the name of the file for a linked bundle, in strong or spec mode.
+ */
+ String _getLinkedName(String hash) {
+ if (strong) {
+ return 'linked_$hash.ds';
+ } else {
+ return 'linked_spec_$hash.ds';
+ }
+ }
+
+ void _link() {
+ // Fill the store with bundles.
+ // Append the linked SDK bundle.
+ // Append unlinked and (if read from a cache) linked package bundles.
+ SummaryDataStore store = new SummaryDataStore(const <String>[]);
+ store.addBundle(null, sdkBundle);
+ for (_LinkNode node in nodes) {
+ store.addBundle(null, node.unlinked);
+ if (node.linked != null) {
+ store.addBundle(null, node.linked);
+ }
+ }
+
+ // Prepare URIs to link.
+ Map<String, _LinkNode> uriToNode = <String, _LinkNode>{};
+ for (_LinkNode node in nodes) {
+ if (!node.isReady) {
+ for (String uri in node.unlinked.unlinkedUnitUris) {
+ uriToNode[uri] = node;
+ }
+ }
+ }
+ Set<String> libraryUris = uriToNode.keys.toSet();
+
+ // Perform linking.
+ Map<String, LinkedLibraryBuilder> linkedLibraries =
+ link(libraryUris, (String uri) {
+ return store.linkedMap[uri];
+ }, (String uri) {
+ return store.unlinkedMap[uri];
+ }, _getDeclaredVariable, strong);
+
+ // Assemble newly linked bundles.
+ for (_LinkNode node in nodes) {
+ if (!node.isReady) {
+ PackageBundleAssembler assembler = new PackageBundleAssembler();
+ linkedLibraries.forEach((uri, linkedLibrary) {
+ if (identical(uriToNode[uri], node)) {
+ assembler.addLinkedLibrary(uri, linkedLibrary);
+ }
+ });
+ List<int> bytes = assembler.assemble().toBuffer();
+ node.linkedNewBytes = bytes;
+ node.linked = new PackageBundle.fromBuffer(bytes);
+ }
+ }
+
+ // Write newly linked bundles.
+ for (_LinkNode node in nodes) {
+ _writeLinked(node);
+ }
+ }
+
+ /**
+ * Attempt to find the linked bundle that corresponds to the given [node]
+ * with all its transitive dependencies and put it into [_LinkNode.linked].
+ */
+ void _readLinked(_LinkNode node) {
+ String hash = node.linkedHash;
+ if (hash != null) {
+ String fileName = _getLinkedName(hash);
+ File file = node.package.folder.getChildAssumingFile(fileName);
+ // Try to find in the cache.
+ PackageBundle linked = manager.linkedBundleMap[file.path];
+ if (linked != null) {
+ node.linked = linked;
+ return;
+ }
+ // Try to read from the file system.
+ if (file.exists) {
+ try {
+ List<int> bytes = file.readAsBytesSync();
+ linked = new PackageBundle.fromBuffer(bytes);
+ manager.linkedBundleMap[file.path] = linked;
+ node.linked = linked;
+ } on FileSystemException {
+ // Ignore file system exceptions.
+ }
+ }
+ }
+ }
+
+ /**
+ * If a new linked bundle was linked for the given [node], write the bundle
+ * into the memory cache and the file system.
+ */
+ void _writeLinked(_LinkNode node) {
+ String hash = node.linkedHash;
+ if (hash != null && node.linkedNewBytes != null) {
+ String fileName = _getLinkedName(hash);
+ File file = node.package.folder.getChildAssumingFile(fileName);
+ manager.linkedBundleMap[file.path] = node.linked;
+ manager._writeAtomic(node.package.folder, fileName, node.linkedNewBytes);
+ }
+ }
+}
+
+/**
+ * Information about a package to link.
+ */
+class _LinkNode {
+ final _ContextLinker linker;
final PubPackage package;
final PackageBundle unlinked;
- final Map<String, _LinkNode> packageToNode;
bool failed = false;
Set<_LinkNode> transitiveDependencies;
+
+ List<_LinkNode> _dependencies;
String _linkedHash;
List<int> linkedNewBytes;
PackageBundle linked;
- _LinkNode(this.sdkBundle, this.getDeclaredVariable, this.listedPackages,
- this.package, this.unlinked, this.packageToNode);
+ _LinkNode(this.linker, this.package, this.unlinked);
- @override
- bool get isEvaluated => linked != null || failed;
+ /**
+ * Retrieve the dependencies of this node.
+ */
+ List<_LinkNode> get dependencies {
+ if (_dependencies == null) {
+ Set<_LinkNode> dependencies = new Set<_LinkNode>();
+
+ void appendDependency(String uriStr) {
+ Uri uri = FastUri.parse(uriStr);
+ if (!uri.hasScheme) {
+ // A relative path in this package, skip it.
+ } else if (uri.scheme == 'dart') {
+ // Dependency on the SDK is implicit and always added.
+ // The SDK linked bundle is precomputed before linking packages.
+ } else if (uriStr.startsWith('package:')) {
+ String package = PubSummaryManager.getPackageName(uriStr);
+ _LinkNode packageNode = linker.packageToNode[package];
+ if (packageNode == null && linker.listedPackages.isListed(uriStr)) {
+ failed = true;
+ }
+ if (packageNode != null) {
+ dependencies.add(packageNode);
+ }
+ } else {
+ failed = true;
+ }
+ }
+
+ for (UnlinkedUnit unit in unlinked.unlinkedUnits) {
+ for (UnlinkedImport import in unit.imports) {
+ if (!import.isImplicit) {
+ appendDependency(import.uri);
+ }
+ }
+ for (UnlinkedExportPublic export in unit.publicNamespace.exports) {
+ appendDependency(export.uri);
+ }
+ }
+
+ _dependencies = dependencies.toList();
+ }
+ return _dependencies;
+ }
+
+ /**
+ * Return `true` is the node is ready - has the linked bundle or failed (does
+ * not have all required dependencies).
+ */
+ bool get isReady => linked != null || failed;
/**
* Return the hash string that corresponds to this linked bundle in the
- * context of its [sdkBundle] and transitive dependencies. Return `null` if
+ * context of its SDK bundle and transitive dependencies. Return `null` if
* the hash computation fails, because for example the full transitive
* dependencies cannot computed.
*/
@@ -652,56 +742,45 @@
ApiSignature signature = new ApiSignature();
// Add all unlinked API signatures.
List<String> signatures = <String>[];
- signatures.add(sdkBundle.apiSignature);
+ signatures.add(linker.sdkBundle.apiSignature);
transitiveDependencies
.map((node) => node.unlinked.apiSignature)
.forEach(signatures.add);
signatures.sort();
signatures.forEach(signature.addString);
// Combine into a single hash.
- _appendDeclaredVariables(signature);
+ appendDeclaredVariables(signature);
_linkedHash = signature.toHex();
}
return _linkedHash;
}
- @override
- List<_LinkNode> computeDependencies() {
- Set<_LinkNode> dependencies = new Set<_LinkNode>();
-
- void appendDependency(String uriStr) {
- Uri uri = FastUri.parse(uriStr);
- if (!uri.hasScheme) {
- // A relative path in this package, skip it.
- } else if (uri.scheme == 'dart') {
- // Dependency on the SDK is implicit and always added.
- // The SDK linked bundle is precomputed before linking packages.
- } else if (uriStr.startsWith('package:')) {
- String package = PubSummaryManager.getPackageName(uriStr);
- _LinkNode packageNode = packageToNode[package];
- if (packageNode == null && listedPackages.isListed(uriStr)) {
- failed = true;
+ /**
+ * Append names and values of all referenced declared variables (even the
+ * ones without actually declared values) to the given [signature].
+ */
+ void appendDeclaredVariables(ApiSignature signature) {
+ Set<String> nameSet = new Set<String>();
+ for (_LinkNode node in transitiveDependencies) {
+ for (UnlinkedUnit unit in node.unlinked.unlinkedUnits) {
+ for (UnlinkedImport import in unit.imports) {
+ for (UnlinkedConfiguration configuration in import.configurations) {
+ nameSet.add(configuration.name);
+ }
}
- if (packageNode != null) {
- dependencies.add(packageNode);
+ for (UnlinkedExportPublic export in unit.publicNamespace.exports) {
+ for (UnlinkedConfiguration configuration in export.configurations) {
+ nameSet.add(configuration.name);
+ }
}
- } else {
- failed = true;
}
}
-
- for (UnlinkedUnit unit in unlinked.unlinkedUnits) {
- for (UnlinkedImport import in unit.imports) {
- if (!import.isImplicit) {
- appendDependency(import.uri);
- }
- }
- for (UnlinkedExportPublic export in unit.publicNamespace.exports) {
- appendDependency(export.uri);
- }
+ List<String> sortedNameList = nameSet.toList()..sort();
+ signature.addInt(sortedNameList.length);
+ for (String name in sortedNameList) {
+ signature.addString(name);
+ signature.addString(linker._getDeclaredVariable(name) ?? '');
}
-
- return dependencies.toList();
}
/**
@@ -729,83 +808,6 @@
@override
String toString() => package.toString();
-
- /**
- * Append names and values of all referenced declared variables (even the
- * ones without actually declared values) to the given [signature].
- */
- void _appendDeclaredVariables(ApiSignature signature) {
- Set<String> nameSet = new Set<String>();
- for (_LinkNode node in transitiveDependencies) {
- for (UnlinkedUnit unit in node.unlinked.unlinkedUnits) {
- for (UnlinkedImport import in unit.imports) {
- for (UnlinkedConfiguration configuration in import.configurations) {
- nameSet.add(configuration.name);
- }
- }
- for (UnlinkedExportPublic export in unit.publicNamespace.exports) {
- for (UnlinkedConfiguration configuration in export.configurations) {
- nameSet.add(configuration.name);
- }
- }
- }
- }
- List<String> sortedNameList = nameSet.toList()..sort();
- signature.addInt(sortedNameList.length);
- for (String name in sortedNameList) {
- signature.addString(name);
- signature.addString(getDeclaredVariable(name) ?? '');
- }
- }
-}
-
-/**
- * Specialization of [DependencyWalker] for linking packages.
- */
-class _LinkWalker extends DependencyWalker<_LinkNode> {
- final _GetDeclaredVariable getDeclaredVariable;
- final _ListedPackages listedPackages;
- final SummaryDataStore store;
- final bool strong;
-
- _LinkWalker(
- this.getDeclaredVariable, this.listedPackages, this.store, this.strong);
-
- @override
- void evaluate(_LinkNode node) {
- evaluateScc([node]);
- }
-
- @override
- void evaluateScc(List<_LinkNode> scc) {
- Map<String, _LinkNode> uriToNode = <String, _LinkNode>{};
- for (_LinkNode node in scc) {
- for (String uri in node.unlinked.unlinkedUnitUris) {
- uriToNode[uri] = node;
- }
- }
- Set<String> libraryUris = uriToNode.keys.toSet();
- // Perform linking.
- Map<String, LinkedLibraryBuilder> linkedLibraries =
- link(libraryUris, (String uri) {
- return store.linkedMap[uri];
- }, (String uri) {
- return store.unlinkedMap[uri];
- }, getDeclaredVariable, strong);
- // Assemble linked bundles and put them into the store.
- for (_LinkNode node in scc) {
- PackageBundleAssembler assembler = new PackageBundleAssembler();
- linkedLibraries.forEach((uri, linkedLibrary) {
- if (identical(uriToNode[uri], node)) {
- assembler.addLinkedLibrary(uri, linkedLibrary);
- }
- });
- List<int> bytes = assembler.assemble().toBuffer();
- node.linkedNewBytes = bytes;
- node.linked = new PackageBundle.fromBuffer(bytes);
- store.addBundle(null, node.linked);
- }
- }
}
/**
diff --git a/pkg/analyzer/lib/src/summary/resynthesize.dart b/pkg/analyzer/lib/src/summary/resynthesize.dart
index 2df51d4..d8f0ce2 100644
--- a/pkg/analyzer/lib/src/summary/resynthesize.dart
+++ b/pkg/analyzer/lib/src/summary/resynthesize.dart
@@ -19,8 +19,10 @@
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/generated/testing/ast_factory.dart';
import 'package:analyzer/src/generated/testing/token_factory.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/util/fast_uri.dart';
/**
* Implementation of [ElementResynthesizer] used when resynthesizing an element
@@ -1160,9 +1162,8 @@
}
LibraryElementHandle _getLibraryByRelativeUri(String depUri) {
- String absoluteUri = resynthesizer.summaryResynthesizer.sourceFactory
- .resolveUri(resynthesizer.librarySource, depUri)
- .uri
+ String absoluteUri = resolveRelativeUri(
+ resynthesizer.librarySource.uri, FastUri.parse(depUri))
.toString();
return new LibraryElementHandle(resynthesizer.summaryResynthesizer,
new ElementLocationImpl.con3(<String>[absoluteUri]));
@@ -1388,6 +1389,11 @@
}
@override
+ bool inheritsCovariant(int slot) {
+ return _unitResynthesizer.parametersInheritingCovariant.contains(slot);
+ }
+
+ @override
bool isInConstCycle(int slot) {
return _unitResynthesizer.constCycles.contains(slot);
}
@@ -1453,6 +1459,12 @@
*/
Set<int> constCycles;
+ /**
+ * Set of slot ids corresponding to parameters that inherit `@covariant`
+ * behavior.
+ */
+ Set<int> parametersInheritingCovariant;
+
int numLinkedReferences;
int numUnlinkedReferences;
@@ -1481,6 +1493,8 @@
linkedTypeMap[t.slot] = t;
}
constCycles = linkedUnit.constCycles.toSet();
+ parametersInheritingCovariant =
+ linkedUnit.parametersInheritingCovariant.toSet();
numLinkedReferences = linkedUnit.references.length;
numUnlinkedReferences = unlinkedUnit.references.length;
referenceInfos = new List<_ReferenceInfo>(numLinkedReferences);
@@ -1511,7 +1525,8 @@
constructorName = null;
}
elementAnnotation.annotationAst = AstFactory.annotation2(
- typeName, constructorName, constExpr.argumentList);
+ typeName, constructorName, constExpr.argumentList)
+ ..element = constExpr.staticElement;
} else {
throw new StateError(
'Unexpected annotation type: ${constExpr.runtimeType}');
diff --git a/pkg/analyzer/lib/src/summary/summarize_ast.dart b/pkg/analyzer/lib/src/summary/summarize_ast.dart
index 87bf1d1..82d596e 100644
--- a/pkg/analyzer/lib/src/summary/summarize_ast.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_ast.dart
@@ -359,6 +359,12 @@
Set<String> _parameterNames;
/**
+ * Indicates whether parameters found during visitors might inherit
+ * covariance.
+ */
+ bool _parametersMayInheritCovariance = false;
+
+ /**
* Create a slot id for storing a propagated or inferred type or const cycle
* info.
*/
@@ -638,9 +644,12 @@
b.returnType = serializeTypeName(returnType);
bool isSemanticallyStatic = isTopLevel || isDeclaredStatic;
if (formalParameters != null) {
+ bool oldMayInheritCovariance = _parametersMayInheritCovariance;
+ _parametersMayInheritCovariance = !isTopLevel && !isDeclaredStatic;
b.parameters = formalParameters.parameters
.map((FormalParameter p) => p.accept(this) as UnlinkedParamBuilder)
.toList();
+ _parametersMayInheritCovariance = oldMayInheritCovariance;
if (!isSemanticallyStatic) {
for (int i = 0; i < formalParameters.parameters.length; i++) {
if (!b.parameters[i].isFunctionTyped &&
@@ -748,9 +757,12 @@
if (serializedReturnType != null) {
b.type = serializedReturnType;
}
+ bool oldMayInheritCovariance = _parametersMayInheritCovariance;
+ _parametersMayInheritCovariance = false;
b.parameters = parameters.parameters
.map((FormalParameter p) => p.accept(this) as UnlinkedParamBuilder)
.toList();
+ _parametersMayInheritCovariance = oldMayInheritCovariance;
}
/**
@@ -782,6 +794,9 @@
b.nameOffset = node.identifier.offset;
b.annotations = serializeAnnotations(node.metadata);
b.codeRange = serializeCodeRange(node);
+ if (_parametersMayInheritCovariance) {
+ b.inheritsCovariantSlot = assignSlot();
+ }
switch (node.kind) {
case ParameterKind.REQUIRED:
b.kind = UnlinkedParamKind.required;
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index 01f9495..59ffdd8 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -26,6 +26,7 @@
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/error/pending_error.dart';
import 'package:analyzer/src/generated/constant.dart';
+import 'package:analyzer/src/generated/declaration_resolver.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/error_verifier.dart';
import 'package:analyzer/src/generated/incremental_resolver.dart';
@@ -1510,6 +1511,7 @@
LibraryIdentifier libraryNameNode = null;
String partsLibraryName = _UNKNOWN_LIBRARY_NAME;
bool hasPartDirective = false;
+ Set<Source> seenPartSources = new Set<Source>();
FunctionElement entryPoint =
_findEntryPoint(definingCompilationUnitElement);
List<Directive> directivesToResolve = <Directive>[];
@@ -1533,6 +1535,17 @@
partElement.uriEnd = partUri.end;
partElement.uri = directive.uriContent;
//
+ // Validate that the part source is unique in the library.
+ //
+ if (!seenPartSources.add(partSource)) {
+ errors.add(new AnalysisError(
+ librarySource,
+ partUri.offset,
+ partUri.length,
+ CompileTimeErrorCode.DUPLICATE_PART,
+ [partSource.uri]));
+ }
+ //
// Validate that the part contains a part-of directive with the same
// name as the library.
//
@@ -3237,12 +3250,10 @@
// Prepare inputs.
//
CompilationUnit unit = getRequiredInput(RESOLVED_UNIT_INPUT);
-
//
// Generate lints.
//
List<AstVisitor> visitors = <AstVisitor>[];
-
bool timeVisits = analysisOptions.enableTiming;
List<Linter> linters = getLints(context);
int length = linters.length;
@@ -3257,10 +3268,9 @@
visitors.add(visitor);
}
}
-
- DelegatingAstVisitor dv = new DelegatingAstVisitor(visitors);
- unit.accept(dv);
-
+ AstVisitor visitor = new ExceptionHandlingDelegatingAstVisitor(
+ visitors, ExceptionHandlingDelegatingAstVisitor.logException);
+ unit.accept(visitor);
//
// Record outputs.
//
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 6521345..a17b516 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
name: analyzer
-version: 0.29.0-alpha.1
+version: 0.29.0
author: Dart Team <misc@dartlang.org>
description: Static analyzer for Dart.
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
@@ -19,6 +19,6 @@
watcher: '>=0.9.6 <0.10.0'
yaml: ^2.1.2
dev_dependencies:
- test_reflective_loader: '>=0.0.4 <0.1.0'
+ test_reflective_loader: ^0.1.0
typed_mock: '>=0.0.4 <1.0.0'
- unittest: '>=0.9.0 <0.12.0'
+ test: ^0.12.0
diff --git a/pkg/analyzer/test/cancelable_future_test.dart b/pkg/analyzer/test/cancelable_future_test.dart
index d22ca56..8f38b6a 100644
--- a/pkg/analyzer/test/cancelable_future_test.dart
+++ b/pkg/analyzer/test/cancelable_future_test.dart
@@ -7,16 +7,15 @@
import 'dart:async';
import 'package:analyzer/src/cancelable_future.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import 'package:watcher/src/utils.dart';
-import 'utils.dart';
-
void main() {
- initializeTestEnvironment();
- defineReflectiveTests(CancelableCompleterTests);
- defineReflectiveTests(CancelableFutureTests);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(CancelableCompleterTests);
+ defineReflectiveTests(CancelableFutureTests);
+ });
}
@reflectiveTest
diff --git a/pkg/analyzer/test/context/declared_variables_test.dart b/pkg/analyzer/test/context/declared_variables_test.dart
index 9007855..1d131c6 100644
--- a/pkg/analyzer/test/context/declared_variables_test.dart
+++ b/pkg/analyzer/test/context/declared_variables_test.dart
@@ -8,15 +8,15 @@
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/generated/constant.dart';
import 'package:analyzer/src/generated/testing/test_type_provider.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../generated/test_support.dart';
-import '../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(DeclaredVariablesTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(DeclaredVariablesTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analyzer/test/context/test_all.dart b/pkg/analyzer/test/context/test_all.dart
index b5387ba..af0e8b8 100644
--- a/pkg/analyzer/test/context/test_all.dart
+++ b/pkg/analyzer/test/context/test_all.dart
@@ -4,15 +4,13 @@
library analyzer.test.context.test_all;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../utils.dart';
import 'declared_variables_test.dart' as declared_variables;
/// Utility for manually running all tests.
main() {
- initializeTestEnvironment();
- group('context tests', () {
+ defineReflectiveSuite(() {
declared_variables.main();
- });
+ }, name: 'context');
}
diff --git a/pkg/analyzer/test/dart/ast/ast_test.dart b/pkg/analyzer/test/dart/ast/ast_test.dart
index cfc85bd..ffc0d21 100644
--- a/pkg/analyzer/test/dart/ast/ast_test.dart
+++ b/pkg/analyzer/test/dart/ast/ast_test.dart
@@ -9,26 +9,26 @@
import 'package:analyzer/src/dart/ast/token.dart';
import 'package:analyzer/src/generated/testing/ast_factory.dart';
import 'package:analyzer/src/generated/testing/token_factory.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../../generated/parser_test.dart' show ParserTestCase;
import '../../generated/test_support.dart';
-import '../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(ClassDeclarationTest);
- defineReflectiveTests(ClassTypeAliasTest);
- defineReflectiveTests(ConstructorDeclarationTest);
- defineReflectiveTests(FieldFormalParameterTest);
- defineReflectiveTests(IndexExpressionTest);
- defineReflectiveTests(MethodDeclarationTest);
- defineReflectiveTests(NodeListTest);
- defineReflectiveTests(SimpleIdentifierTest);
- defineReflectiveTests(SimpleStringLiteralTest);
- defineReflectiveTests(StringInterpolationTest);
- defineReflectiveTests(VariableDeclarationTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ClassDeclarationTest);
+ defineReflectiveTests(ClassTypeAliasTest);
+ defineReflectiveTests(ConstructorDeclarationTest);
+ defineReflectiveTests(FieldFormalParameterTest);
+ defineReflectiveTests(IndexExpressionTest);
+ defineReflectiveTests(MethodDeclarationTest);
+ defineReflectiveTests(NodeListTest);
+ defineReflectiveTests(SimpleIdentifierTest);
+ defineReflectiveTests(SimpleStringLiteralTest);
+ defineReflectiveTests(StringInterpolationTest);
+ defineReflectiveTests(VariableDeclarationTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analyzer/test/dart/ast/test_all.dart b/pkg/analyzer/test/dart/ast/test_all.dart
index 64f8170..4babcdf 100644
--- a/pkg/analyzer/test/dart/ast/test_all.dart
+++ b/pkg/analyzer/test/dart/ast/test_all.dart
@@ -4,17 +4,15 @@
library analyzer.test.dart.ast.test_all;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../utils.dart';
import 'ast_test.dart' as ast;
import 'visitor_test.dart' as visitor;
/// Utility for manually running all tests.
main() {
- initializeTestEnvironment();
- group('ast tests', () {
+ defineReflectiveSuite(() {
ast.main();
visitor.main();
- });
+ }, name: 'ast');
}
diff --git a/pkg/analyzer/test/dart/ast/visitor_test.dart b/pkg/analyzer/test/dart/ast/visitor_test.dart
index 45ba196..5c7d14f 100644
--- a/pkg/analyzer/test/dart/ast/visitor_test.dart
+++ b/pkg/analyzer/test/dart/ast/visitor_test.dart
@@ -6,16 +6,16 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../../generated/parser_test.dart' show ParserTestCase;
import '../../generated/test_support.dart';
-import '../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(BreadthFirstVisitorTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(BreadthFirstVisitorTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analyzer/test/dart/element/element_test.dart b/pkg/analyzer/test/dart/element/element_test.dart
index 615d7b2..c4490fc 100644
--- a/pkg/analyzer/test/dart/element/element_test.dart
+++ b/pkg/analyzer/test/dart/element/element_test.dart
@@ -6,15 +6,15 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/generated/testing/element_factory.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../../generated/test_support.dart';
-import '../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(ElementKindTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ElementKindTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analyzer/test/dart/element/test_all.dart b/pkg/analyzer/test/dart/element/test_all.dart
index 5dac037..bb4c779 100644
--- a/pkg/analyzer/test/dart/element/test_all.dart
+++ b/pkg/analyzer/test/dart/element/test_all.dart
@@ -4,15 +4,13 @@
library analyzer.test.dart.element.test_all;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../utils.dart';
import 'element_test.dart' as element;
/// Utility for manually running all tests.
main() {
- initializeTestEnvironment();
- group('element tests', () {
+ defineReflectiveSuite(() {
element.main();
- });
+ }, name: 'element');
}
diff --git a/pkg/analyzer/test/dart/test_all.dart b/pkg/analyzer/test/dart/test_all.dart
index df7ff55..7827a63 100644
--- a/pkg/analyzer/test/dart/test_all.dart
+++ b/pkg/analyzer/test/dart/test_all.dart
@@ -4,17 +4,15 @@
library analyzer.test.generated.test_all;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../utils.dart';
import 'ast/test_all.dart' as ast;
import 'element/test_all.dart' as element;
/// Utility for manually running all tests.
main() {
- initializeTestEnvironment();
- group('dart tests', () {
+ defineReflectiveSuite(() {
ast.main();
element.main();
- });
+ }, name: 'dart');
}
diff --git a/pkg/analyzer/test/embedder_tests.dart b/pkg/analyzer/test/embedder_tests.dart
index f10606f..18083dd 100644
--- a/pkg/analyzer/test/embedder_tests.dart
+++ b/pkg/analyzer/test/embedder_tests.dart
@@ -8,10 +8,8 @@
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:path/path.dart' as path;
import 'resource_utils.dart';
-import 'utils.dart';
abstract class EmbedderRelatedTest {
final String emptyPath = '/home/.pub-cache/empty';
@@ -22,8 +20,7 @@
ResourceProvider resourceProvider;
buildResourceProvider() {
- MemoryResourceProvider rawProvider =
- new MemoryResourceProvider(isWindows: isWindows);
+ MemoryResourceProvider rawProvider = new MemoryResourceProvider();
resourceProvider = new TestResourceProvider(rawProvider);
pathTranslator = new TestPathTranslator(rawProvider)
..newFolder('/home/.pub-cache/empty')
@@ -47,12 +44,10 @@
}
void setUp() {
- initializeTestEnvironment(path.context);
buildResourceProvider();
}
void tearDown() {
- initializeTestEnvironment();
clearResourceProvider();
}
}
diff --git a/pkg/analyzer/test/file_system/memory_file_system_test.dart b/pkg/analyzer/test/file_system/memory_file_system_test.dart
index 0878963..abc373f 100644
--- a/pkg/analyzer/test/file_system/memory_file_system_test.dart
+++ b/pkg/analyzer/test/file_system/memory_file_system_test.dart
@@ -12,21 +12,20 @@
import 'package:analyzer/src/generated/engine.dart' show TimestampedData;
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:path/path.dart';
+import 'package:path/path.dart' as pathos;
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import 'package:watcher/watcher.dart';
-import '../utils.dart';
-
main() {
- initializeTestEnvironment();
- defineReflectiveTests(FileSystemExceptionTest);
- defineReflectiveTests(FileTest);
- defineReflectiveTests(FolderTest);
- defineReflectiveTests(MemoryFileSourceExistingTest);
- defineReflectiveTests(MemoryFileSourceNotExistingTest);
- defineReflectiveTests(MemoryResourceProviderTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(FileSystemExceptionTest);
+ defineReflectiveTests(FileTest);
+ defineReflectiveTests(FolderTest);
+ defineReflectiveTests(MemoryFileSourceExistingTest);
+ defineReflectiveTests(MemoryFileSourceNotExistingTest);
+ defineReflectiveTests(MemoryResourceProviderTest);
+ });
}
var _isFile = new isInstanceOf<File>();
@@ -49,7 +48,8 @@
MemoryResourceProvider provider = new MemoryResourceProvider();
void test_delete() {
- File file = provider.newFile('/foo/file.txt', 'content');
+ File file =
+ provider.newFile(provider.convertPath('/foo/file.txt'), 'content');
expect(file.exists, isTrue);
// delete
file.delete();
@@ -57,7 +57,7 @@
}
void test_equals_beforeAndAfterCreate() {
- String path = '/file.txt';
+ String path = provider.convertPath('/file.txt');
File file1 = provider.getResource(path);
provider.newFile(path, 'contents');
File file2 = provider.getResource(path);
@@ -65,37 +65,39 @@
}
void test_equals_false() {
- File fileA = provider.getResource('/fileA.txt');
- File fileB = provider.getResource('/fileB.txt');
+ File fileA = provider.getResource(provider.convertPath('/fileA.txt'));
+ File fileB = provider.getResource(provider.convertPath('/fileB.txt'));
expect(fileA == new Object(), isFalse);
expect(fileA == fileB, isFalse);
}
void test_equals_true() {
- File file = provider.getResource('/file.txt');
+ File file = provider.getResource(provider.convertPath('/file.txt'));
expect(file == file, isTrue);
}
void test_exists_false() {
- File file = provider.getResource('/file.txt');
+ File file = provider.getResource(provider.convertPath('/file.txt'));
expect(file, isNotNull);
expect(file.exists, isFalse);
}
void test_exists_true() {
- provider.newFile('/foo/file.txt', 'qwerty');
- File file = provider.getResource('/foo/file.txt');
+ String path = provider.convertPath('/foo/file.txt');
+ provider.newFile(path, 'qwerty');
+ File file = provider.getResource(path);
expect(file, isNotNull);
expect(file.exists, isTrue);
}
void test_fullName() {
- File file = provider.getResource('/foo/bar/file.txt');
- expect(file.path, '/foo/bar/file.txt');
+ String path = provider.convertPath('/foo/bar/file.txt');
+ File file = provider.getResource(path);
+ expect(file.path, path);
}
void test_hashCode() {
- String path = '/foo/bar/file.txt';
+ String path = provider.convertPath('/foo/bar/file.txt');
File file1 = provider.getResource(path);
provider.newFile(path, 'contents');
File file2 = provider.getResource(path);
@@ -103,14 +105,14 @@
}
void test_isOrContains() {
- String path = '/foo/bar/file.txt';
+ String path = provider.convertPath('/foo/bar/file.txt');
File file = provider.getResource(path);
expect(file.isOrContains(path), isTrue);
- expect(file.isOrContains('/foo/bar'), isFalse);
+ expect(file.isOrContains(provider.convertPath('/foo/bar')), isFalse);
}
void test_modificationStamp_doesNotExist() {
- String path = '/foo/bar/file.txt';
+ String path = provider.convertPath('/foo/bar/file.txt');
File file = provider.newFile(path, 'qwerty');
provider.deleteFile(path);
expect(() {
@@ -119,21 +121,22 @@
}
void test_modificationStamp_exists() {
- String path = '/foo/bar/file.txt';
+ String path = provider.convertPath('/foo/bar/file.txt');
File file = provider.newFile(path, 'qwerty');
expect(file.modificationStamp, isNonNegative);
}
void test_parent() {
- provider.newFile('/foo/bar/file.txt', 'content');
- File file = provider.getResource('/foo/bar/file.txt');
+ String path = provider.convertPath('/foo/bar/file.txt');
+ provider.newFile(path, 'content');
+ File file = provider.getResource(path);
Resource parent = file.parent;
expect(parent, new isInstanceOf<Folder>());
- expect(parent.path, equals('/foo/bar'));
+ expect(parent.path, equals(provider.convertPath('/foo/bar')));
}
void test_readAsBytesSync_doesNotExist() {
- File file = provider.getResource('/test.bin');
+ File file = provider.getResource(provider.convertPath('/test.bin'));
expect(() {
file.readAsBytesSync();
}, throwsA(_isFileSystemException));
@@ -141,25 +144,26 @@
void test_readAsBytesSync_exists() {
List<int> bytes = <int>[1, 2, 3, 4, 5];
- File file = provider.newFileWithBytes('/file.bin', bytes);
+ File file =
+ provider.newFileWithBytes(provider.convertPath('/file.bin'), bytes);
expect(file.readAsBytesSync(), bytes);
}
void test_readAsStringSync_doesNotExist() {
- File file = provider.getResource('/test.txt');
+ File file = provider.getResource(provider.convertPath('/test.txt'));
expect(() {
file.readAsStringSync();
}, throwsA(_isFileSystemException));
}
void test_readAsStringSync_exists() {
- File file = provider.newFile('/file.txt', 'abc');
+ File file = provider.newFile(provider.convertPath('/file.txt'), 'abc');
expect(file.readAsStringSync(), 'abc');
}
void test_renameSync_newDoesNotExist() {
- String oldPath = '/foo/bar/file.txt';
- String newPath = '/foo/bar/new-file.txt';
+ String oldPath = provider.convertPath('/foo/bar/file.txt');
+ String newPath = provider.convertPath('/foo/bar/new-file.txt');
File file = provider.newFile(oldPath, 'text');
File newFile = file.renameSync(newPath);
expect(file.path, oldPath);
@@ -170,8 +174,8 @@
}
void test_renameSync_newExists_file() {
- String oldPath = '/foo/bar/file.txt';
- String newPath = '/foo/bar/new-file.txt';
+ String oldPath = provider.convertPath('/foo/bar/file.txt');
+ String newPath = provider.convertPath('/foo/bar/new-file.txt');
File file = provider.newFile(oldPath, 'text');
provider.newFile(newPath, 'new text');
File newFile = file.renameSync(newPath);
@@ -183,8 +187,8 @@
}
void test_renameSync_newExists_folder() {
- String oldPath = '/foo/bar/file.txt';
- String newPath = '/foo/bar/baz';
+ String oldPath = provider.convertPath('/foo/bar/file.txt');
+ String newPath = provider.convertPath('/foo/bar/baz');
File file = provider.newFile(oldPath, 'text');
provider.newFolder(newPath);
expect(() {
@@ -195,29 +199,31 @@
}
void test_resolveSymbolicLinksSync() {
- File file = provider.newFile('/test.txt', 'text');
+ File file = provider.newFile(provider.convertPath('/test.txt'), 'text');
expect(file.resolveSymbolicLinksSync(), file);
}
void test_shortName() {
- File file = provider.getResource('/foo/bar/file.txt');
+ File file = provider.getResource(provider.convertPath('/foo/bar/file.txt'));
expect(file.shortName, 'file.txt');
}
void test_toString() {
- File file = provider.getResource('/foo/bar/file.txt');
- expect(file.toString(), '/foo/bar/file.txt');
+ String path = provider.convertPath('/foo/bar/file.txt');
+ File file = provider.getResource(path);
+ expect(file.toString(), path);
}
void test_toUri() {
- String path = '/foo/file.txt';
+ String path = provider.convertPath('/foo/file.txt');
File file = provider.newFile(path, '');
- expect(file.toUri(), new Uri.file(path, windows: false));
+ expect(file.toUri(), provider.pathContext.toUri(path));
}
void test_writeAsBytesSync_existing() {
List<int> content = <int>[1, 2];
- File file = provider.newFileWithBytes('/foo/file.bin', content);
+ File file = provider.newFileWithBytes(
+ provider.convertPath('/foo/file.bin'), content);
expect(file.readAsBytesSync(), content);
// write new bytes
content = <int>[10, 20];
@@ -226,7 +232,7 @@
}
void test_writeAsBytesSync_new() {
- File file = provider.getFile('/foo/file.bin');
+ File file = provider.getFile(provider.convertPath('/foo/file.bin'));
expect(file.exists, false);
// write new bytes
List<int> content = <int>[10, 20];
@@ -237,7 +243,8 @@
void test_writeAsStringSync_existing() {
String content = 'ab';
- File file = provider.newFile('/foo/file.txt', content);
+ File file =
+ provider.newFile(provider.convertPath('/foo/file.txt'), content);
expect(file.readAsStringSync(), content);
// write new bytes
content = 'CD';
@@ -246,7 +253,7 @@
}
void test_writeAsStringSync_new() {
- File file = provider.getFile('/foo/file.txt');
+ File file = provider.getFile(provider.convertPath('/foo/file.txt'));
expect(file.exists, false);
// write new bytes
String content = 'ef';
@@ -258,36 +265,43 @@
@reflectiveTest
class FolderTest {
- static const String path = '/foo/bar';
-
MemoryResourceProvider provider = new MemoryResourceProvider();
+ String path;
Folder folder;
void setUp() {
+ path = provider.convertPath('/foo/bar');
folder = provider.newFolder(path);
}
void test_canonicalizePath() {
- expect(folder.canonicalizePath('baz'), equals('/foo/bar/baz'));
- expect(folder.canonicalizePath('/baz'), equals('/baz'));
- expect(folder.canonicalizePath('../baz'), equals('/foo/baz'));
- expect(folder.canonicalizePath('/a/b/../c'), equals('/a/c'));
- expect(folder.canonicalizePath('./baz'), equals('/foo/bar/baz'));
- expect(folder.canonicalizePath('/a/b/./c'), equals('/a/b/c'));
+ expect(folder.canonicalizePath(provider.convertPath('baz')),
+ equals(provider.convertPath('/foo/bar/baz')));
+ expect(folder.canonicalizePath(provider.convertPath('/baz')),
+ equals(provider.convertPath('/baz')));
+ expect(folder.canonicalizePath(provider.convertPath('../baz')),
+ equals(provider.convertPath('/foo/baz')));
+ expect(folder.canonicalizePath(provider.convertPath('/a/b/../c')),
+ equals(provider.convertPath('/a/c')));
+ expect(folder.canonicalizePath(provider.convertPath('./baz')),
+ equals(provider.convertPath('/foo/bar/baz')));
+ expect(folder.canonicalizePath(provider.convertPath('/a/b/./c')),
+ equals(provider.convertPath('/a/b/c')));
}
void test_contains() {
- expect(folder.contains('/foo/bar/aaa.txt'), isTrue);
- expect(folder.contains('/foo/bar/aaa/bbb.txt'), isTrue);
- expect(folder.contains('/baz.txt'), isFalse);
- expect(folder.contains('/foo/bar'), isFalse);
+ expect(folder.contains(provider.convertPath('/foo/bar/aaa.txt')), isTrue);
+ expect(
+ folder.contains(provider.convertPath('/foo/bar/aaa/bbb.txt')), isTrue);
+ expect(folder.contains(provider.convertPath('/baz.txt')), isFalse);
+ expect(folder.contains(provider.convertPath('/foo/bar')), isFalse);
}
void test_delete() {
- Folder folder = provider.newFolder('/foo');
- Folder barFolder = provider.newFolder('/foo/bar');
- File aFile = provider.newFile('/foo/bar/a.txt', '');
- File bFile = provider.newFile('/foo/b.txt', '');
+ Folder folder = provider.newFolder(provider.convertPath('/foo'));
+ Folder barFolder = provider.newFolder(provider.convertPath('/foo/bar'));
+ File aFile = provider.newFile(provider.convertPath('/foo/bar/a.txt'), '');
+ File bFile = provider.newFile(provider.convertPath('/foo/b.txt'), '');
expect(folder.exists, isTrue);
expect(barFolder.exists, isTrue);
expect(aFile.exists, isTrue);
@@ -301,7 +315,7 @@
}
void test_equal_false() {
- String path2 = '/foo/baz';
+ String path2 = provider.convertPath('/foo/baz');
Folder folder2 = provider.newFolder(path2);
expect(folder == folder2, isFalse);
}
@@ -318,14 +332,14 @@
}
void test_getChild_file() {
- provider.newFile('/foo/bar/file.txt', 'content');
+ provider.newFile(provider.convertPath('/foo/bar/file.txt'), 'content');
File child = folder.getChild('file.txt');
expect(child, isNotNull);
expect(child.exists, isTrue);
}
void test_getChild_folder() {
- provider.newFolder('/foo/bar/baz');
+ provider.newFolder(provider.convertPath('/foo/bar/baz'));
Folder child = folder.getChild('baz');
expect(child, isNotNull);
expect(child.exists, isTrue);
@@ -338,14 +352,14 @@
}
void test_getChildAssumingFile_file() {
- provider.newFile('/foo/bar/name', 'content');
+ provider.newFile(provider.convertPath('/foo/bar/name'), 'content');
File child = folder.getChildAssumingFile('name');
expect(child, isNotNull);
expect(child.exists, isTrue);
}
void test_getChildAssumingFile_folder() {
- provider.newFolder('/foo/bar/name');
+ provider.newFolder(provider.convertPath('/foo/bar/name'));
File child = folder.getChildAssumingFile('name');
expect(child, isNotNull);
expect(child.exists, isFalse);
@@ -358,14 +372,14 @@
}
void test_getChildAssumingFolder_file() {
- provider.newFile('/foo/bar/foldername', 'content');
+ provider.newFile(provider.convertPath('/foo/bar/foldername'), 'content');
Folder child = folder.getChildAssumingFolder('foldername');
expect(child, isNotNull);
expect(child.exists, isFalse);
}
void test_getChildAssumingFolder_folder() {
- provider.newFolder('/foo/bar/foldername');
+ provider.newFolder(provider.convertPath('/foo/bar/foldername'));
Folder child = folder.getChildAssumingFolder('foldername');
expect(child, isNotNull);
expect(child.exists, isTrue);
@@ -379,9 +393,9 @@
}
void test_getChildren_exists() {
- provider.newFile('/foo/bar/a.txt', 'aaa');
- provider.newFolder('/foo/bar/bFolder');
- provider.newFile('/foo/bar/c.txt', 'ccc');
+ provider.newFile(provider.convertPath('/foo/bar/a.txt'), 'aaa');
+ provider.newFolder(provider.convertPath('/foo/bar/bFolder'));
+ provider.newFile(provider.convertPath('/foo/bar/c.txt'), 'ccc');
// prepare 3 children
List<Resource> children = folder.getChildren();
expect(children, hasLength(3));
@@ -406,36 +420,40 @@
}
void test_isOrContains() {
- expect(folder.isOrContains('/foo/bar'), isTrue);
- expect(folder.isOrContains('/foo/bar/aaa.txt'), isTrue);
- expect(folder.isOrContains('/foo/bar/aaa/bbb.txt'), isTrue);
- expect(folder.isOrContains('/baz.txt'), isFalse);
+ expect(folder.isOrContains(provider.convertPath('/foo/bar')), isTrue);
+ expect(
+ folder.isOrContains(provider.convertPath('/foo/bar/aaa.txt')), isTrue);
+ expect(folder.isOrContains(provider.convertPath('/foo/bar/aaa/bbb.txt')),
+ isTrue);
+ expect(folder.isOrContains(provider.convertPath('/baz.txt')), isFalse);
}
void test_parent() {
Resource parent1 = folder.parent;
expect(parent1, new isInstanceOf<Folder>());
- expect(parent1.path, equals('/foo'));
+ expect(parent1.path, equals(provider.convertPath('/foo')));
Resource parent2 = parent1.parent;
expect(parent2, new isInstanceOf<Folder>());
- expect(parent2.path, equals('/'));
+ expect(parent2.path, equals(provider.convertPath('/')));
expect(parent2.parent, isNull);
}
void test_toUri() {
- String path = '/foo/directory';
+ String path = provider.convertPath('/foo/directory');
Folder folder = provider.newFolder(path);
- expect(folder.toUri(), new Uri.directory(path, windows: false));
+ expect(folder.toUri(), provider.pathContext.toUri(path));
}
}
@reflectiveTest
class MemoryFileSourceExistingTest {
MemoryResourceProvider provider = new MemoryResourceProvider();
+ String path;
Source source;
setUp() {
- File file = provider.newFile('/foo/test.dart', 'library test;');
+ path = provider.convertPath('/foo/test.dart');
+ File file = provider.newFile(path, 'library test;');
source = file.createSource();
}
@@ -445,32 +463,36 @@
}
void test_encoding() {
- expect(source.encoding, 'file:///foo/test.dart');
+ String expected = 'file:///foo/test.dart';
+ if (provider.pathContext.style == pathos.windows.style) {
+ expected = 'file:///C:/foo/test.dart';
+ }
+ expect(source.encoding, expected);
}
void test_equals_false_differentFile() {
- File fileA = provider.newFile('/foo/a.dart', '');
- File fileB = provider.newFile('/foo/b.dart', '');
+ File fileA = provider.newFile(provider.convertPath('/foo/a.dart'), '');
+ File fileB = provider.newFile(provider.convertPath('/foo/b.dart'), '');
Source sourceA = fileA.createSource();
Source sourceB = fileB.createSource();
expect(sourceA == sourceB, isFalse);
}
void test_equals_false_notMemorySource() {
- File file = provider.newFile('/foo/test.dart', '');
+ File file = provider.newFile(path, '');
Source source = file.createSource();
expect(source == new Object(), isFalse);
}
void test_equals_true_sameFile() {
- File file = provider.newFile('/foo/test.dart', '');
+ File file = provider.newFile(path, '');
Source sourceA = file.createSource();
Source sourceB = file.createSource();
expect(sourceA == sourceB, isTrue);
}
void test_equals_true_self() {
- File file = provider.newFile('/foo/test.dart', '');
+ File file = provider.newFile(path, '');
Source source = file.createSource();
expect(source == source, isTrue);
}
@@ -480,7 +502,7 @@
}
void test_fullName() {
- expect(source.fullName, '/foo/test.dart');
+ expect(source.fullName, path);
}
void test_hashCode() {
@@ -488,12 +510,17 @@
}
void test_resolveRelative() {
- Uri relative = resolveRelativeUri(source.uri, new Uri.file('bar/baz.dart'));
- expect(relative.path, '/foo/bar/baz.dart');
+ Uri relative = resolveRelativeUri(
+ source.uri,
+ provider.pathContext
+ .toUri(provider.pathContext.join('bar', 'baz.dart')));
+ expect(relative,
+ provider.pathContext.toUri(provider.convertPath('/foo/bar/baz.dart')));
}
void test_resolveRelative_dart() {
- File file = provider.newFile('/sdk/lib/core/core.dart', '');
+ File file =
+ provider.newFile(provider.convertPath('/sdk/lib/core/core.dart'), '');
Source source = file.createSource(Uri.parse('dart:core'));
Uri resolved = resolveRelativeUri(source.uri, Uri.parse('int.dart'));
expect(resolved.toString(), 'dart:core/int.dart');
@@ -507,10 +534,12 @@
@reflectiveTest
class MemoryFileSourceNotExistingTest {
MemoryResourceProvider provider = new MemoryResourceProvider();
+ String path;
Source source;
setUp() {
- File file = provider.getResource('/foo/test.dart');
+ path = provider.convertPath('/foo/test.dart');
+ File file = provider.getResource(path);
source = file.createSource();
}
@@ -521,7 +550,11 @@
}
void test_encoding() {
- expect(source.encoding, 'file:///foo/test.dart');
+ String expected = 'file:///foo/test.dart';
+ if (provider.pathContext.style == pathos.windows.style) {
+ expected = 'file:///C:/foo/test.dart';
+ }
+ expect(source.encoding, expected);
}
void test_exists() {
@@ -529,7 +562,7 @@
}
void test_fullName() {
- expect(source.fullName, '/foo/test.dart');
+ expect(source.fullName, path);
}
void test_modificationStamp() {
@@ -537,8 +570,12 @@
}
void test_resolveRelative() {
- Uri relative = resolveRelativeUri(source.uri, new Uri.file('bar/baz.dart'));
- expect(relative.path, '/foo/bar/baz.dart');
+ Uri relative = resolveRelativeUri(
+ source.uri,
+ provider.pathContext
+ .toUri(provider.pathContext.join('bar', 'baz.dart')));
+ expect(relative,
+ provider.pathContext.toUri(provider.convertPath('/foo/bar/baz.dart')));
}
void test_shortName() {
@@ -551,7 +588,7 @@
MemoryResourceProvider provider = new MemoryResourceProvider();
void test_deleteFile_folder() {
- String path = '/my/file';
+ String path = provider.convertPath('/my/file');
provider.newFolder(path);
expect(() {
provider.deleteFile(path);
@@ -560,7 +597,7 @@
}
void test_deleteFile_notExistent() {
- String path = '/my/file';
+ String path = provider.convertPath('/my/file');
expect(() {
provider.deleteFile(path);
}, throwsA(new isInstanceOf<ArgumentError>()));
@@ -570,7 +607,7 @@
}
void test_deleteFile_success() {
- String path = '/my/file';
+ String path = provider.convertPath('/my/file');
provider.newFile(path, 'contents');
Resource file = provider.getResource(path);
expect(file, new isInstanceOf<File>());
@@ -579,8 +616,25 @@
expect(file.exists, isFalse);
}
+ test_getFolder_existing() async {
+ String path = provider.convertPath('/foo/bar');
+ provider.newFolder(path);
+ Folder folder = provider.getFolder(path);
+ expect(folder, isNotNull);
+ expect(folder.path, path);
+ expect(folder.exists, isTrue);
+ }
+
+ test_getFolder_notExisting() async {
+ String path = provider.convertPath('/foo/bar');
+ Folder folder = provider.getFolder(path);
+ expect(folder, isNotNull);
+ expect(folder.path, path);
+ expect(folder.exists, isFalse);
+ }
+
test_getModificationTimes() async {
- File file = provider.newFile('/test.dart', '');
+ File file = provider.newFile(provider.convertPath('/test.dart'), '');
Source source = file.createSource();
List<int> times = await provider.getModificationTimes([source]);
expect(times, [source.modificationStamp]);
@@ -598,7 +652,7 @@
}
void test_modifyFile_isFolder() {
- String path = '/my/file';
+ String path = provider.convertPath('/my/file');
provider.newFolder(path);
expect(() {
provider.modifyFile(path, 'contents');
@@ -607,7 +661,7 @@
}
void test_modifyFile_notExistent() {
- String path = '/my/file';
+ String path = provider.convertPath('/my/file');
expect(() {
provider.modifyFile(path, 'contents');
}, throwsA(new isInstanceOf<ArgumentError>()));
@@ -617,7 +671,7 @@
}
void test_modifyFile_success() {
- String path = '/my/file';
+ String path = provider.convertPath('/my/file');
provider.newFile(path, 'contents 1');
Resource file = provider.getResource(path);
expect(file, new isInstanceOf<File>());
@@ -628,7 +682,7 @@
}
void test_newFileWithBytes() {
- String path = '/my/file';
+ String path = provider.convertPath('/my/file');
List<int> bytes = <int>[1, 2, 3, 4, 5];
provider.newFileWithBytes(path, bytes);
File file = provider.getResource(path);
@@ -638,15 +692,16 @@
}
void test_newFolder_alreadyExists_asFile() {
- provider.newFile('/my/file', 'qwerty');
+ provider.newFile(provider.convertPath('/my/file'), 'qwerty');
expect(() {
- provider.newFolder('/my/file');
+ provider.newFolder(provider.convertPath('/my/file'));
}, throwsA(new isInstanceOf<ArgumentError>()));
}
void test_newFolder_alreadyExists_asFolder() {
- Folder folder = provider.newFolder('/my/folder');
- Folder newFolder = provider.newFolder('/my/folder');
+ String path = provider.convertPath('/my/folder');
+ Folder folder = provider.newFolder(path);
+ Folder newFolder = provider.newFolder(path);
expect(newFolder, folder);
}
@@ -663,11 +718,11 @@
}
test_watch_createFile() {
- String rootPath = '/my/path';
+ String rootPath = provider.convertPath('/my/path');
provider.newFolder(rootPath);
return _watchingFolder(rootPath, (changesReceived) {
expect(changesReceived, hasLength(0));
- String path = posix.join(rootPath, 'foo');
+ String path = provider.pathContext.join(rootPath, 'foo');
provider.newFile(path, 'contents');
return _delayed(() {
expect(changesReceived, hasLength(1));
@@ -678,9 +733,9 @@
}
test_watch_deleteFile() {
- String rootPath = '/my/path';
+ String rootPath = provider.convertPath('/my/path');
provider.newFolder(rootPath);
- String path = posix.join(rootPath, 'foo');
+ String path = provider.pathContext.join(rootPath, 'foo');
provider.newFile(path, 'contents 1');
return _watchingFolder(rootPath, (changesReceived) {
expect(changesReceived, hasLength(0));
@@ -694,9 +749,9 @@
}
test_watch_modifyFile() {
- String rootPath = '/my/path';
+ String rootPath = provider.convertPath('/my/path');
provider.newFolder(rootPath);
- String path = posix.join(rootPath, 'foo');
+ String path = provider.pathContext.join(rootPath, 'foo');
provider.newFile(path, 'contents 1');
return _watchingFolder(rootPath, (changesReceived) {
expect(changesReceived, hasLength(0));
@@ -710,11 +765,11 @@
}
test_watch_modifyFile_inSubDir() {
- String rootPath = '/my/path';
+ String rootPath = provider.convertPath('/my/path');
provider.newFolder(rootPath);
- String subdirPath = posix.join(rootPath, 'foo');
+ String subdirPath = provider.pathContext.join(rootPath, 'foo');
provider.newFolder(subdirPath);
- String path = posix.join(rootPath, 'bar');
+ String path = provider.pathContext.join(rootPath, 'bar');
provider.newFile(path, 'contents 1');
return _watchingFolder(rootPath, (changesReceived) {
expect(changesReceived, hasLength(0));
diff --git a/pkg/analyzer/test/file_system/physical_resource_provider_test.dart b/pkg/analyzer/test/file_system/physical_resource_provider_test.dart
index 6be1f2b..39ac5dc 100644
--- a/pkg/analyzer/test/file_system/physical_resource_provider_test.dart
+++ b/pkg/analyzer/test/file_system/physical_resource_provider_test.dart
@@ -11,19 +11,18 @@
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/src/generated/source_io.dart';
-import 'package:path/path.dart';
+import 'package:path/path.dart' as pathos;
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import 'package:watcher/watcher.dart';
-import '../utils.dart';
-
main() {
- initializeTestEnvironment();
if (!new bool.fromEnvironment('skipPhysicalResourceProviderTests')) {
- defineReflectiveTests(PhysicalResourceProviderTest);
- defineReflectiveTests(FileTest);
- defineReflectiveTests(FolderTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(PhysicalResourceProviderTest);
+ defineReflectiveTests(FileTest);
+ defineReflectiveTests(FolderTest);
+ });
}
}
@@ -31,6 +30,9 @@
var _isFileSystemException = new isInstanceOf<FileSystemException>();
var _isFolder = new isInstanceOf<Folder>();
+String join(String part1, [String part2, String part3]) =>
+ pathos.join(part1, part2, part3);
+
@reflectiveTest
class FileTest extends _BaseTest {
String path;
@@ -181,7 +183,7 @@
}
void test_resolveSymbolicLinksSync_links() {
- Context pathContext = PhysicalResourceProvider.INSTANCE.pathContext;
+ pathos.Context pathContext = PhysicalResourceProvider.INSTANCE.pathContext;
String pathA = pathContext.join(tempPath, 'a');
String pathB = pathContext.join(pathA, 'b');
new io.Directory(pathB).createSync(recursive: true);
@@ -441,7 +443,7 @@
test_getFolder_trailingSeparator() {
String path = tempPath;
PhysicalResourceProvider provider = PhysicalResourceProvider.INSTANCE;
- Folder folder = provider.getFolder('$path$separator');
+ Folder folder = provider.getFolder('$path${pathos.separator}');
expect(folder.path, path);
}
diff --git a/pkg/analyzer/test/file_system/resource_uri_resolver_test.dart b/pkg/analyzer/test/file_system/resource_uri_resolver_test.dart
index 92e1148..610048d 100644
--- a/pkg/analyzer/test/file_system/resource_uri_resolver_test.dart
+++ b/pkg/analyzer/test/file_system/resource_uri_resolver_test.dart
@@ -7,14 +7,13 @@
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(ResourceUriResolverTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ResourceUriResolverTest);
+ });
}
@reflectiveTest
@@ -25,8 +24,8 @@
void setUp() {
provider = new MemoryResourceProvider();
resolver = new ResourceUriResolver(provider);
- provider.newFile('/test.dart', '');
- provider.newFolder('/folder');
+ provider.newFile(provider.convertPath('/test.dart'), '');
+ provider.newFolder(provider.convertPath('/folder'));
}
void test_creation() {
@@ -35,15 +34,15 @@
}
void test_resolveAbsolute_file() {
- var uri = new Uri(scheme: 'file', path: '/test.dart');
+ var uri = provider.pathContext.toUri(provider.convertPath('/test.dart'));
Source source = resolver.resolveAbsolute(uri);
expect(source, isNotNull);
expect(source.exists(), isTrue);
- expect(source.fullName, '/test.dart');
+ expect(source.fullName, provider.convertPath('/test.dart'));
}
void test_resolveAbsolute_folder() {
- var uri = new Uri(scheme: 'file', path: '/folder');
+ var uri = provider.pathContext.toUri(provider.convertPath('/folder'));
Source source = resolver.resolveAbsolute(uri);
expect(source, isNull);
}
@@ -61,7 +60,7 @@
}
void test_restoreAbsolute() {
- var uri = new Uri(scheme: 'file', path: '/test.dart');
+ var uri = provider.pathContext.toUri(provider.convertPath('/test.dart'));
Source source = resolver.resolveAbsolute(uri);
expect(source, isNotNull);
expect(resolver.restoreAbsolute(source), uri);
diff --git a/pkg/analyzer/test/file_system/test_all.dart b/pkg/analyzer/test/file_system/test_all.dart
index 1714c0b..75a06d2 100644
--- a/pkg/analyzer/test/file_system/test_all.dart
+++ b/pkg/analyzer/test/file_system/test_all.dart
@@ -4,9 +4,8 @@
library analyzer.test.file_system.test_all;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../utils.dart';
import 'memory_file_system_test.dart' as memory_file_system_test;
import 'physical_resource_provider_test.dart'
as physical_resource_provider_test;
@@ -14,10 +13,9 @@
/// Utility for manually running all tests.
main() {
- initializeTestEnvironment();
- group('file_system', () {
+ defineReflectiveSuite(() {
memory_file_system_test.main();
physical_resource_provider_test.main();
resource_uri_resolver_test.main();
- });
+ }, name: 'file system');
}
diff --git a/pkg/analyzer/test/generated/all_the_rest_test.dart b/pkg/analyzer/test/generated/all_the_rest_test.dart
index a8411f4..7ba7573 100644
--- a/pkg/analyzer/test/generated/all_the_rest_test.dart
+++ b/pkg/analyzer/test/generated/all_the_rest_test.dart
@@ -33,38 +33,38 @@
import 'package:analyzer/src/generated/testing/token_factory.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/source/source_resource.dart';
-import 'package:path/path.dart';
+import 'package:path/path.dart' as path;
import 'package:source_span/source_span.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../utils.dart';
import 'parser_test.dart';
import 'resolver_test_case.dart';
import 'test_support.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(ContentCacheTest);
- // ignore: deprecated_member_use
- defineReflectiveTests(CustomUriResolverTest);
- defineReflectiveTests(DartUriResolverTest);
- // ignore: deprecated_member_use
- defineReflectiveTests(DirectoryBasedDartSdkTest);
- // ignore: deprecated_member_use
- defineReflectiveTests(DirectoryBasedSourceContainerTest);
- defineReflectiveTests(ElementBuilderTest);
- defineReflectiveTests(ElementLocatorTest);
- defineReflectiveTests(EnumMemberBuilderTest);
- defineReflectiveTests(ErrorReporterTest);
- defineReflectiveTests(ErrorSeverityTest);
- defineReflectiveTests(ExitDetectorTest);
- defineReflectiveTests(ExitDetectorTest2);
- defineReflectiveTests(FileBasedSourceTest);
- defineReflectiveTests(ResolveRelativeUriTest);
- // ignore: deprecated_member_use
- defineReflectiveTests(SDKLibrariesReaderTest);
- defineReflectiveTests(UriKindTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ContentCacheTest);
+ // ignore: deprecated_member_use
+ defineReflectiveTests(CustomUriResolverTest);
+ defineReflectiveTests(DartUriResolverTest);
+ // ignore: deprecated_member_use
+ defineReflectiveTests(DirectoryBasedDartSdkTest);
+ // ignore: deprecated_member_use
+ defineReflectiveTests(DirectoryBasedSourceContainerTest);
+ defineReflectiveTests(ElementBuilderTest);
+ defineReflectiveTests(ElementLocatorTest);
+ defineReflectiveTests(EnumMemberBuilderTest);
+ defineReflectiveTests(ErrorReporterTest);
+ defineReflectiveTests(ErrorSeverityTest);
+ defineReflectiveTests(ExitDetectorTest);
+ defineReflectiveTests(ExitDetectorTest2);
+ defineReflectiveTests(FileBasedSourceTest);
+ defineReflectiveTests(ResolveRelativeUriTest);
+ // ignore: deprecated_member_use
+ defineReflectiveTests(SDKLibrariesReaderTest);
+ defineReflectiveTests(UriKindTest);
+ });
}
/**
@@ -128,14 +128,14 @@
}
void test_resolve_uri() {
- String path =
+ String filePath =
FileUtilities2.createFile("/path/to/library.dart").getAbsolutePath();
UriResolver resolver = new CustomUriResolver({
- 'custom:library': path,
+ 'custom:library': filePath,
});
Source result = resolver.resolveAbsolute(Uri.parse("custom:library"));
expect(result, isNotNull);
- expect(result.fullName, path);
+ expect(result.fullName, filePath);
}
}
@@ -3183,7 +3183,7 @@
ErrorReporter reporter = new ErrorReporter(
listener,
new NonExistingSource(
- '/test.dart', toUri('/test.dart'), UriKind.FILE_URI));
+ '/test.dart', path.toUri('/test.dart'), UriKind.FILE_URI));
reporter.reportErrorForElement(
StaticWarningCode.CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER,
element,
diff --git a/pkg/analyzer/test/generated/analysis_context_factory.dart b/pkg/analyzer/test/generated/analysis_context_factory.dart
index 272e26e..b2c1975 100644
--- a/pkg/analyzer/test/generated/analysis_context_factory.dart
+++ b/pkg/analyzer/test/generated/analysis_context_factory.dart
@@ -25,9 +25,8 @@
import 'package:analyzer/src/generated/testing/element_factory.dart';
import 'package:analyzer/src/generated/testing/test_type_provider.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:analyzer/src/source/source_resource.dart';
import 'package:analyzer/src/string_source.dart';
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
/**
* The class `AnalysisContextFactory` defines utility methods used to create analysis contexts
@@ -489,25 +488,24 @@
* Helper for creating and managing single [AnalysisContext].
*/
class AnalysisContextHelper {
- ResourceProvider resourceProvider;
+ MemoryResourceProvider resourceProvider;
AnalysisContext context;
/**
* Creates new [AnalysisContext] using [AnalysisContextFactory].
*/
AnalysisContextHelper(
- [AnalysisOptionsImpl options, ResourceProvider provider]) {
+ [AnalysisOptionsImpl options, MemoryResourceProvider provider]) {
resourceProvider = provider ?? new MemoryResourceProvider();
- if (options == null) {
- options = new AnalysisOptionsImpl();
- }
- options.cacheSize = 256;
- context = AnalysisContextFactory.contextWithCoreAndOptions(options,
+ context = AnalysisContextFactory.contextWithCoreAndOptions(
+ options ?? new AnalysisOptionsImpl(),
resourceProvider: resourceProvider);
}
Source addSource(String path, String code) {
- Source source = new FileSource(resourceProvider.getFile(path));
+ Source source = resourceProvider
+ .getFile(resourceProvider.convertPath(path))
+ .createSource();
if (path.endsWith(".dart") || path.endsWith(".html")) {
ChangeSet changeSet = new ChangeSet();
changeSet.addedSource(source);
diff --git a/pkg/analyzer/test/generated/bazel_test.dart b/pkg/analyzer/test/generated/bazel_test.dart
index 227681c..cc1a75a 100644
--- a/pkg/analyzer/test/generated/bazel_test.dart
+++ b/pkg/analyzer/test/generated/bazel_test.dart
@@ -4,98 +4,85 @@
library analyzer.test.generated.bazel_test;
-import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/generated/bazel.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../utils.dart';
+import 'package:typed_mock/typed_mock.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(BazelFileUriResolverTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(BazelFileUriResolverTest);
+ defineReflectiveTests(BazelPackageUriResolverTest);
+ defineReflectiveTests(BazelWorkspaceTest);
+ });
}
@reflectiveTest
-class BazelFileUriResolverTest {
- MemoryResourceProvider provider;
- Folder workspace;
- List<Folder> buildDirs;
- ResourceUriResolver resolver;
+class BazelFileUriResolverTest extends _BaseTest {
+ BazelWorkspace workspace;
+ BazelFileUriResolver resolver;
void setUp() {
- provider = new MemoryResourceProvider();
- workspace = provider.newFolder('/workspace');
- buildDirs = [
- provider.newFolder('/workspace/one'),
- provider.newFolder('/workspace/two')
- ];
- resolver = new BazelFileUriResolver(provider, workspace, buildDirs);
- provider.newFile('/workspace/test.dart', '');
- provider.newFile('/workspace/one/gen1.dart', '');
- provider.newFile('/workspace/two/gen2.dart', '');
+ provider.newFile(_p('/workspace/WORKSPACE'), '');
+ provider.newFolder(_p('/workspace/bazel-genfiles'));
+ workspace = BazelWorkspace.find(provider, _p('/workspace'));
+ resolver = new BazelFileUriResolver(workspace);
+ provider.newFile(_p('/workspace/test.dart'), '');
+ provider.newFile(_p('/workspace/bazel-bin/gen1.dart'), '');
+ provider.newFile(_p('/workspace/bazel-genfiles/gen2.dart'), '');
}
- void test_creation() {
- expect(provider, isNotNull);
- expect(workspace, isNotNull);
- expect(buildDirs, isNotNull);
- expect(buildDirs.length, 2);
- expect(resolver, isNotNull);
+ void test_resolveAbsolute_doesNotExist() {
+ Source source = _resolvePath('/workspace/foo.dart');
+ expect(source, isNotNull);
+ expect(source.exists(), isFalse);
+ expect(source.fullName, _p('/workspace/foo.dart'));
}
void test_resolveAbsolute_file() {
- var uri = new Uri(scheme: 'file', path: '/workspace/test.dart');
- Source source = resolver.resolveAbsolute(uri);
+ Source source = _resolvePath('/workspace/test.dart');
expect(source, isNotNull);
expect(source.exists(), isTrue);
- expect(source.fullName, '/workspace/test.dart');
+ expect(source.fullName, _p('/workspace/test.dart'));
}
void test_resolveAbsolute_folder() {
- var uri = new Uri(scheme: 'file', path: '/workspace');
- Source source = resolver.resolveAbsolute(uri);
- expect(source, isNull);
- }
-
- void test_resolveAbsolute_generated_file_does_not_exist_three() {
- var uri = new Uri(scheme: 'file', path: '/workspace/gen3.dart');
- Source source = resolver.resolveAbsolute(uri);
- expect(source, isNull);
+ Source source = _resolvePath('/workspace');
+ expect(source, isNotNull);
+ expect(source.exists(), isFalse);
+ expect(source.fullName, _p('/workspace'));
}
void test_resolveAbsolute_generated_file_exists_one() {
- var uri = new Uri(scheme: 'file', path: '/workspace/gen1.dart');
- Source source = resolver.resolveAbsolute(uri);
+ Source source = _resolvePath('/workspace/gen1.dart');
expect(source, isNotNull);
expect(source.exists(), isTrue);
- expect(source.fullName, '/workspace/one/gen1.dart');
+ expect(source.fullName, _p('/workspace/bazel-bin/gen1.dart'));
}
void test_resolveAbsolute_generated_file_exists_two() {
- var uri = new Uri(scheme: 'file', path: '/workspace/gen2.dart');
- Source source = resolver.resolveAbsolute(uri);
+ Source source = _resolvePath('/workspace/gen2.dart');
expect(source, isNotNull);
expect(source.exists(), isTrue);
- expect(source.fullName, '/workspace/two/gen2.dart');
+ expect(source.fullName, _p('/workspace/bazel-genfiles/gen2.dart'));
}
void test_resolveAbsolute_notFile_dartUri() {
- var uri = new Uri(scheme: 'dart', path: 'core');
+ Uri uri = new Uri(scheme: 'dart', path: 'core');
Source source = resolver.resolveAbsolute(uri);
expect(source, isNull);
}
void test_resolveAbsolute_notFile_httpsUri() {
- var uri = new Uri(scheme: 'https', path: '127.0.0.1/test.dart');
+ Uri uri = new Uri(scheme: 'https', path: '127.0.0.1/test.dart');
Source source = resolver.resolveAbsolute(uri);
expect(source, isNull);
}
void test_restoreAbsolute() {
- var uri = new Uri(scheme: 'file', path: '/workspace/test.dart');
+ Uri uri = provider.pathContext.toUri(_p('/workspace/test.dart'));
Source source = resolver.resolveAbsolute(uri);
expect(source, isNotNull);
expect(resolver.restoreAbsolute(source), uri);
@@ -104,4 +91,555 @@
new NonExistingSource(source.fullName, null, null)),
uri);
}
+
+ Source _resolvePath(String absolutePosixPath) {
+ String absolutePath = provider.convertPath(absolutePosixPath);
+ Uri uri = provider.pathContext.toUri(absolutePath);
+ return resolver.resolveAbsolute(uri);
+ }
+}
+
+@reflectiveTest
+class BazelPackageUriResolverTest extends _BaseTest {
+ BazelWorkspace workspace;
+ BazelPackageUriResolver resolver;
+
+ void test_resolveAbsolute_bin() {
+ _addResources([
+ '/workspace/WORKSPACE',
+ '/workspace/bazel-genfiles/',
+ '/workspace/my/foo/lib/foo1.dart',
+ '/workspace/bazel-bin/my/foo/lib/foo1.dart'
+ ]);
+ _assertResolve(
+ 'package:my.foo/foo1.dart', '/workspace/bazel-bin/my/foo/lib/foo1.dart',
+ exists: true);
+ }
+
+ void test_resolveAbsolute_bin_notInWorkspace() {
+ _addResources([
+ '/workspace/WORKSPACE',
+ '/workspace/bazel-genfiles/',
+ '/workspace/bazel-bin/my/foo/lib/foo1.dart'
+ ]);
+ _assertResolve(
+ 'package:my.foo/foo1.dart', '/workspace/bazel-bin/my/foo/lib/foo1.dart',
+ exists: true);
+ }
+
+ void test_resolveAbsolute_genfiles() {
+ _addResources([
+ '/workspace/WORKSPACE',
+ '/workspace/bazel-genfiles/',
+ '/workspace/my/foo/lib/foo1.dart',
+ '/workspace/bazel-genfiles/my/foo/lib/foo1.dart'
+ ]);
+ _assertResolve('package:my.foo/foo1.dart',
+ '/workspace/bazel-genfiles/my/foo/lib/foo1.dart',
+ exists: true);
+ }
+
+ void test_resolveAbsolute_genfiles_notInWorkspace() {
+ _addResources([
+ '/workspace/WORKSPACE',
+ '/workspace/bazel-genfiles/',
+ '/workspace/bazel-genfiles/my/foo/lib/foo1.dart'
+ ]);
+ _assertResolve('package:my.foo/foo1.dart',
+ '/workspace/bazel-genfiles/my/foo/lib/foo1.dart',
+ exists: true);
+ }
+
+ void test_resolveAbsolute_null_noSlash() {
+ _addResources([
+ '/workspace/WORKSPACE',
+ '/workspace/bazel-genfiles/',
+ ]);
+ Source source = resolver.resolveAbsolute(Uri.parse('package:foo'));
+ expect(source, isNull);
+ }
+
+ void test_resolveAbsolute_null_notPackage() {
+ _addResources([
+ '/workspace/WORKSPACE',
+ '/workspace/bazel-genfiles/',
+ ]);
+ Source source = resolver.resolveAbsolute(Uri.parse('dart:async'));
+ expect(source, isNull);
+ }
+
+ void test_resolveAbsolute_null_startsWithSlash() {
+ _addResources([
+ '/workspace/WORKSPACE',
+ '/workspace/bazel-genfiles/',
+ '/workspace/my/foo/lib/bar.dart',
+ ]);
+ Source source =
+ resolver.resolveAbsolute(Uri.parse('package:/foo/bar.dart'));
+ expect(source, isNull);
+ }
+
+ void test_resolveAbsolute_readonly_bin() {
+ _addResources([
+ '/Users/user/test/READONLY/prime/',
+ '/Users/user/test/READONLY/prime/my/foo/lib/foo1.dart',
+ '/Users/user/test/prime/bazel-genfiles/',
+ '/Users/user/test/prime/my/module/',
+ '/Users/user/test/prime/bazel-bin/my/foo/lib/foo1.dart',
+ ], workspacePath: '/Users/user/test/prime/my/module');
+ _assertResolve('package:my.foo/foo1.dart',
+ '/Users/user/test/prime/bazel-bin/my/foo/lib/foo1.dart',
+ exists: true);
+ }
+
+ void test_resolveAbsolute_readonly_bin_notInWorkspace() {
+ _addResources([
+ '/Users/user/test/READONLY/prime/',
+ '/Users/user/test/prime/bazel-genfiles/',
+ '/Users/user/test/prime/my/module/',
+ '/Users/user/test/prime/bazel-bin/my/foo/lib/foo1.dart',
+ ], workspacePath: '/Users/user/test/prime/my/module');
+ _assertResolve('package:my.foo/foo1.dart',
+ '/Users/user/test/prime/bazel-bin/my/foo/lib/foo1.dart',
+ exists: true);
+ }
+
+ void test_resolveAbsolute_readonly_genfiles() {
+ _addResources([
+ '/Users/user/test/READONLY/prime/',
+ '/Users/user/test/READONLY/prime/my/foo/lib/foo1.dart',
+ '/Users/user/test/prime/bazel-genfiles/',
+ '/Users/user/test/prime/my/module/',
+ '/Users/user/test/prime/bazel-genfiles/my/foo/lib/foo1.dart',
+ ], workspacePath: '/Users/user/test/prime/my/module');
+ _assertResolve('package:my.foo/foo1.dart',
+ '/Users/user/test/prime/bazel-genfiles/my/foo/lib/foo1.dart',
+ exists: true);
+ }
+
+ void test_resolveAbsolute_readonly_genfiles_notInWorkspace() {
+ _addResources([
+ '/Users/user/test/READONLY/prime/',
+ '/Users/user/test/prime/bazel-genfiles/',
+ '/Users/user/test/prime/my/module/',
+ '/Users/user/test/prime/bazel-genfiles/my/foo/lib/foo1.dart',
+ ], workspacePath: '/Users/user/test/prime/my/module');
+ _assertResolve('package:my.foo/foo1.dart',
+ '/Users/user/test/prime/bazel-genfiles/my/foo/lib/foo1.dart',
+ exists: true);
+ }
+
+ void test_resolveAbsolute_readonly_thirdParty_bin() {
+ _addResources([
+ '/Users/user/test/READONLY/prime/',
+ '/Users/user/test/READONLY/prime/third_party/dart/foo/lib/foo1.dart',
+ '/Users/user/test/prime/bazel-genfiles/',
+ '/Users/user/test/prime/my/module/',
+ '/Users/user/test/prime/bazel-bin/third_party/dart/foo/lib/foo1.dart',
+ ], workspacePath: '/Users/user/test/prime/my/module');
+ _assertResolve('package:foo/foo1.dart',
+ '/Users/user/test/prime/bazel-bin/third_party/dart/foo/lib/foo1.dart',
+ exists: true);
+ }
+
+ void test_resolveAbsolute_readonly_thirdParty_genfiles() {
+ _addResources([
+ '/Users/user/test/READONLY/prime/',
+ '/Users/user/test/READONLY/prime/third_party/dart/foo/lib/foo1.dart',
+ '/Users/user/test/prime/bazel-genfiles/',
+ '/Users/user/test/prime/my/module/',
+ '/Users/user/test/prime/bazel-genfiles/third_party/dart/foo/lib/foo1.dart',
+ ], workspacePath: '/Users/user/test/prime/my/module');
+ _assertResolve('package:foo/foo1.dart',
+ '/Users/user/test/prime/bazel-genfiles/third_party/dart/foo/lib/foo1.dart',
+ exists: true);
+ }
+
+ void test_resolveAbsolute_readonly_thirdParty_workspace_doesNotExist() {
+ _addResources([
+ '/Users/user/test/READONLY/prime/',
+ '/Users/user/test/READONLY/prime/third_party/dart/foo/lib/foo1.dart',
+ '/Users/user/test/prime/bazel-genfiles/',
+ '/Users/user/test/prime/my/module/',
+ ], workspacePath: '/Users/user/test/prime/my/module');
+ _assertResolve('package:foo/foo2.dart',
+ '/Users/user/test/prime/third_party/dart/foo/lib/foo2.dart',
+ exists: false);
+ }
+
+ void test_resolveAbsolute_readonly_thirdParty_workspace_exists() {
+ _addResources([
+ '/Users/user/test/READONLY/prime/',
+ '/Users/user/test/READONLY/prime/third_party/dart/foo/lib/foo1.dart',
+ '/Users/user/test/prime/bazel-genfiles/',
+ '/Users/user/test/prime/my/module/',
+ ], workspacePath: '/Users/user/test/prime/my/module');
+ _assertResolve('package:foo/foo1.dart',
+ '/Users/user/test/READONLY/prime/third_party/dart/foo/lib/foo1.dart',
+ exists: true);
+ }
+
+ void test_resolveAbsolute_readonly_workspace_doesNotExist() {
+ _addResources([
+ '/Users/user/test/READONLY/prime/',
+ '/Users/user/test/prime/bazel-genfiles/',
+ '/Users/user/test/prime/my/module/',
+ ], workspacePath: '/Users/user/test/prime/my/module');
+ _assertResolve('package:my.foo/foo1.dart',
+ '/Users/user/test/prime/my/foo/lib/foo1.dart',
+ exists: false);
+ }
+
+ void test_resolveAbsolute_readonly_workspace_exists() {
+ _addResources([
+ '/Users/user/test/READONLY/prime/',
+ '/Users/user/test/READONLY/prime/my/foo/lib/foo1.dart',
+ '/Users/user/test/prime/bazel-genfiles/',
+ '/Users/user/test/prime/my/module/',
+ ], workspacePath: '/Users/user/test/prime/my/module');
+ _assertResolve('package:my.foo/foo1.dart',
+ '/Users/user/test/READONLY/prime/my/foo/lib/foo1.dart',
+ exists: true);
+ }
+
+ void test_resolveAbsolute_thirdParty_bin() {
+ _addResources([
+ '/workspace/WORKSPACE',
+ '/workspace/bazel-genfiles/',
+ '/workspace/third_party/dart/foo/lib/foo1.dart',
+ '/workspace/bazel-bin/third_party/dart/foo/lib/foo1.dart',
+ ]);
+ _assertResolve('package:foo/foo1.dart',
+ '/workspace/bazel-bin/third_party/dart/foo/lib/foo1.dart',
+ exists: true);
+ }
+
+ void test_resolveAbsolute_thirdParty_bin_notInWorkspace() {
+ _addResources([
+ '/workspace/WORKSPACE',
+ '/workspace/bazel-genfiles/',
+ '/workspace/bazel-bin/third_party/dart/foo/lib/foo1.dart',
+ ]);
+ _assertResolve('package:foo/foo1.dart',
+ '/workspace/bazel-bin/third_party/dart/foo/lib/foo1.dart',
+ exists: true);
+ }
+
+ void test_resolveAbsolute_thirdParty_doesNotExist() {
+ _addResources([
+ '/workspace/WORKSPACE',
+ '/workspace/bazel-genfiles/',
+ '/workspace/third_party/dart/foo/lib/foo1.dart',
+ ]);
+ _assertResolve('package:foo/foo2.dart',
+ '/workspace/third_party/dart/foo/lib/foo2.dart',
+ exists: false);
+ }
+
+ void test_resolveAbsolute_thirdParty_exists() {
+ _addResources([
+ '/workspace/WORKSPACE',
+ '/workspace/bazel-genfiles/',
+ '/workspace/third_party/dart/foo/lib/foo1.dart',
+ ]);
+ _assertResolve('package:foo/foo1.dart',
+ '/workspace/third_party/dart/foo/lib/foo1.dart',
+ exists: true);
+ }
+
+ void test_resolveAbsolute_thirdParty_genfiles() {
+ _addResources([
+ '/workspace/WORKSPACE',
+ '/workspace/bazel-genfiles/',
+ '/workspace/third_party/dart/foo/lib/foo1.dart',
+ '/workspace/bazel-genfiles/third_party/dart/foo/lib/foo1.dart',
+ ]);
+ _assertResolve('package:foo/foo1.dart',
+ '/workspace/bazel-genfiles/third_party/dart/foo/lib/foo1.dart',
+ exists: true);
+ }
+
+ void test_resolveAbsolute_thirdParty_genfiles_notInWorkspace() {
+ _addResources([
+ '/workspace/WORKSPACE',
+ '/workspace/bazel-genfiles/',
+ '/workspace/bazel-genfiles/third_party/dart/foo/lib/foo1.dart',
+ ]);
+ _assertResolve('package:foo/foo1.dart',
+ '/workspace/bazel-genfiles/third_party/dart/foo/lib/foo1.dart',
+ exists: true);
+ }
+
+ void test_resolveAbsolute_workspace_doesNotExist() {
+ _addResources([
+ '/workspace/WORKSPACE',
+ '/workspace/bazel-genfiles/',
+ ]);
+ _assertResolve('package:my.foo/doesNotExist.dart',
+ '/workspace/my/foo/lib/doesNotExist.dart',
+ exists: false);
+ }
+
+ void test_resolveAbsolute_workspace_exists() {
+ _addResources([
+ '/workspace/WORKSPACE',
+ '/workspace/bazel-genfiles/',
+ '/workspace/my/foo/lib/foo1.dart',
+ ]);
+ _assertResolve(
+ 'package:my.foo/foo1.dart', '/workspace/my/foo/lib/foo1.dart',
+ exists: true);
+ }
+
+ void test_restoreAbsolute_noPackageName_workspace() {
+ _addResources([
+ '/workspace/WORKSPACE',
+ '/workspace/bazel-genfiles/',
+ '/workspace/lib/foo1.dart',
+ '/workspace/foo/lib/foo2.dart',
+ ]);
+ _assertRestore('/workspace/lib/foo1.dart', null);
+ _assertRestore('/workspace/foo/lib/foo2.dart', null);
+ }
+
+ void test_restoreAbsolute_noPathInLib_bin() {
+ _addResources([
+ '/workspace/WORKSPACE',
+ '/workspace/bazel-genfiles/',
+ '/workspace/bazel-bin/my/foo/lib/foo1.dart',
+ ]);
+ _assertRestore('/workspace/bazel-bin', null);
+ _assertRestore('/workspace/bazel-bin/my', null);
+ _assertRestore('/workspace/bazel-bin/my/foo', null);
+ _assertRestore('/workspace/bazel-bin/my/foo/lib', null);
+ }
+
+ void test_restoreAbsolute_noPathInLib_genfiles() {
+ _addResources([
+ '/workspace/WORKSPACE',
+ '/workspace/bazel-genfiles/',
+ '/workspace/bazel-genfiles/my/foo/lib/foo1.dart',
+ ]);
+ _assertRestore('/workspace/bazel-genfiles', null);
+ _assertRestore('/workspace/bazel-genfiles/my', null);
+ _assertRestore('/workspace/bazel-genfiles/my/foo', null);
+ _assertRestore('/workspace/bazel-genfiles/my/foo/lib', null);
+ }
+
+ void test_restoreAbsolute_noPathInLib_workspace() {
+ _addResources([
+ '/workspace/WORKSPACE',
+ '/workspace/bazel-genfiles/',
+ '/workspace/my/foo/lib/foo1.dart',
+ ]);
+ _assertRestore('/workspace', null);
+ _assertRestore('/workspace/my', null);
+ _assertRestore('/workspace/my/foo', null);
+ _assertRestore('/workspace/my/foo/lib', null);
+ }
+
+ void _addResources(List<String> paths, {String workspacePath: '/workspace'}) {
+ for (String path in paths) {
+ if (path.endsWith('/')) {
+ provider.newFolder(_p(path.substring(0, path.length - 1)));
+ } else {
+ provider.newFile(_p(path), '');
+ }
+ }
+ workspace = BazelWorkspace.find(provider, _p(workspacePath));
+ resolver = new BazelPackageUriResolver(workspace);
+ }
+
+ void _assertResolve(String uriStr, String posixPath,
+ {bool exists: true, bool restore: true}) {
+ Uri uri = Uri.parse(uriStr);
+ Source source = resolver.resolveAbsolute(uri);
+ expect(source, isNotNull);
+ expect(source.fullName, _p(posixPath));
+ expect(source.uri, uri);
+ expect(source.exists(), exists);
+ // If enabled, test also "restoreAbsolute".
+ if (restore) {
+ Uri uri = resolver.restoreAbsolute(source);
+ expect(uri.toString(), uriStr);
+ }
+ }
+
+ void _assertRestore(String posixPath, String expectedUri) {
+ String path = _p(posixPath);
+ _MockSource source = new _MockSource(path);
+ Uri uri = resolver.restoreAbsolute(source);
+ expect(uri?.toString(), expectedUri);
+ }
+}
+
+@reflectiveTest
+class BazelWorkspaceTest extends _BaseTest {
+ void test_find_fail_notAbsolute() {
+ expect(() => BazelWorkspace.find(provider, _p('not_absolute')),
+ throwsArgumentError);
+ }
+
+ void test_find_hasReadonlyFolder() {
+ provider.newFolder(_p('/Users/user/test/READONLY/prime'));
+ provider.newFolder(_p('/Users/user/test/prime'));
+ provider.newFolder(_p('/Users/user/test/prime/bazel-genfiles'));
+ BazelWorkspace workspace =
+ BazelWorkspace.find(provider, _p('/Users/user/test/prime/my/module'));
+ expect(workspace.root, _p('/Users/user/test/prime'));
+ expect(workspace.readonly, _p('/Users/user/test/READONLY/prime'));
+ expect(workspace.bin, _p('/Users/user/test/prime/bazel-bin'));
+ expect(workspace.genfiles, _p('/Users/user/test/prime/bazel-genfiles'));
+ }
+
+ void test_find_hasReadonlyFolder_bad_actuallyHasWorkspaceFile() {
+ provider.newFolder(_p('/Users/user/test/READONLY'));
+ provider.newFile(_p('/Users/user/test/prime/WORKSPACE'), '');
+ provider.newFolder(_p('/Users/user/test/prime/bazel-genfiles'));
+ BazelWorkspace workspace =
+ BazelWorkspace.find(provider, _p('/Users/user/test/prime/my/module'));
+ expect(workspace.root, _p('/Users/user/test/prime'));
+ expect(workspace.readonly, isNull);
+ expect(workspace.bin, _p('/Users/user/test/prime/bazel-bin'));
+ expect(workspace.genfiles, _p('/Users/user/test/prime/bazel-genfiles'));
+ }
+
+ void test_find_hasReadonlyFolder_blaze() {
+ provider.newFolder(_p('/Users/user/test/READONLY/prime'));
+ provider.newFolder(_p('/Users/user/test/prime'));
+ provider.newFolder(_p('/Users/user/test/prime/blaze-genfiles'));
+ BazelWorkspace workspace =
+ BazelWorkspace.find(provider, _p('/Users/user/test/prime/my/module'));
+ expect(workspace.root, _p('/Users/user/test/prime'));
+ expect(workspace.readonly, _p('/Users/user/test/READONLY/prime'));
+ expect(workspace.bin, _p('/Users/user/test/prime/blaze-bin'));
+ expect(workspace.genfiles, _p('/Users/user/test/prime/blaze-genfiles'));
+ }
+
+ void test_find_hasWorkspaceFile() {
+ provider.newFile(_p('/workspace/WORKSPACE'), '');
+ provider.newFolder(_p('/workspace/bazel-genfiles'));
+ BazelWorkspace workspace =
+ BazelWorkspace.find(provider, _p('/workspace/my/module'));
+ expect(workspace.root, _p('/workspace'));
+ expect(workspace.readonly, isNull);
+ expect(workspace.bin, _p('/workspace/bazel-bin'));
+ expect(workspace.genfiles, _p('/workspace/bazel-genfiles'));
+ }
+
+ void test_find_hasWorkspaceFile_forModuleInWorkspace() {
+ provider.newFile(_p('/workspace/WORKSPACE'), '');
+ provider.newFolder(_p('/workspace/bazel-genfiles'));
+ BazelWorkspace workspace =
+ BazelWorkspace.find(provider, _p('/workspace/my/module'));
+ expect(workspace.root, _p('/workspace'));
+ expect(workspace.readonly, isNull);
+ expect(workspace.bin, _p('/workspace/bazel-bin'));
+ expect(workspace.genfiles, _p('/workspace/bazel-genfiles'));
+ }
+
+ void test_find_hasWorkspaceFile_forWorkspace() {
+ provider.newFile(_p('/workspace/WORKSPACE'), '');
+ provider.newFolder(_p('/workspace/bazel-genfiles'));
+ BazelWorkspace workspace = BazelWorkspace.find(provider, _p('/workspace'));
+ expect(workspace.root, _p('/workspace'));
+ expect(workspace.readonly, isNull);
+ expect(workspace.bin, _p('/workspace/bazel-bin'));
+ expect(workspace.genfiles, _p('/workspace/bazel-genfiles'));
+ }
+
+ void test_find_hasWorkspaceFile_forWorkspace_blaze() {
+ provider.newFile(_p('/workspace/WORKSPACE'), '');
+ provider.newFolder(_p('/workspace/blaze-genfiles'));
+ BazelWorkspace workspace = BazelWorkspace.find(provider, _p('/workspace'));
+ expect(workspace.root, _p('/workspace'));
+ expect(workspace.readonly, isNull);
+ expect(workspace.bin, _p('/workspace/blaze-bin'));
+ expect(workspace.genfiles, _p('/workspace/blaze-genfiles'));
+ }
+
+ void test_find_null_noWorkspaceMarkers() {
+ BazelWorkspace workspace =
+ BazelWorkspace.find(provider, _p('/workspace/my/module'));
+ expect(workspace, isNull);
+ }
+
+ void test_find_null_noWorkspaceMarkers_inRoot() {
+ BazelWorkspace workspace = BazelWorkspace.find(provider, _p('/'));
+ expect(workspace, isNull);
+ }
+
+ void test_find_null_symlinkPrefix() {
+ provider.newFile(_p('/workspace/WORKSPACE'), '');
+ BazelWorkspace workspace =
+ BazelWorkspace.find(provider, _p('/workspace/my/module'));
+ expect(workspace, isNull);
+ }
+
+ void test_findFile_hasReadonlyFolder() {
+ provider.newFolder(_p('/Users/user/test/READONLY/prime'));
+ provider.newFolder(_p('/Users/user/test/prime'));
+ provider.newFile(_p('/Users/user/test/prime/my/module/test1.dart'), '');
+ provider.newFile(_p('/Users/user/test/prime/my/module/test2.dart'), '');
+ provider.newFile(_p('/Users/user/test/prime/my/module/test3.dart'), '');
+ provider.newFile(
+ _p('/Users/user/test/prime/bazel-bin/my/module/test2.dart'), '');
+ provider.newFile(
+ _p('/Users/user/test/prime/bazel-genfiles/my/module/test3.dart'), '');
+ provider.newFile(
+ _p('/Users/user/test/READONLY/prime/other/module/test4.dart'), '');
+ BazelWorkspace workspace =
+ BazelWorkspace.find(provider, _p('/Users/user/test/prime/my/module'));
+ expect(
+ workspace
+ .findFile(_p('/Users/user/test/prime/my/module/test1.dart'))
+ .path,
+ _p('/Users/user/test/prime/my/module/test1.dart'));
+ expect(
+ workspace
+ .findFile(_p('/Users/user/test/prime/my/module/test2.dart'))
+ .path,
+ _p('/Users/user/test/prime/bazel-bin/my/module/test2.dart'));
+ expect(
+ workspace
+ .findFile(_p('/Users/user/test/prime/my/module/test3.dart'))
+ .path,
+ _p('/Users/user/test/prime/bazel-genfiles/my/module/test3.dart'));
+ expect(
+ workspace
+ .findFile(_p('/Users/user/test/prime/other/module/test4.dart'))
+ .path,
+ _p('/Users/user/test/READONLY/prime/other/module/test4.dart'));
+ }
+
+ void test_findFile_noReadOnly() {
+ provider.newFile(_p('/workspace/WORKSPACE'), '');
+ provider.newFile(_p('/workspace/my/module/test1.dart'), '');
+ provider.newFile(_p('/workspace/my/module/test2.dart'), '');
+ provider.newFile(_p('/workspace/my/module/test3.dart'), '');
+ provider.newFile(_p('/workspace/bazel-bin/my/module/test2.dart'), '');
+ provider.newFile(_p('/workspace/bazel-genfiles/my/module/test3.dart'), '');
+ BazelWorkspace workspace =
+ BazelWorkspace.find(provider, _p('/workspace/my/module'));
+ expect(workspace.findFile(_p('/workspace/my/module/test1.dart')).path,
+ _p('/workspace/my/module/test1.dart'));
+ expect(workspace.findFile(_p('/workspace/my/module/test2.dart')).path,
+ _p('/workspace/bazel-bin/my/module/test2.dart'));
+ expect(workspace.findFile(_p('/workspace/my/module/test3.dart')).path,
+ _p('/workspace/bazel-genfiles/my/module/test3.dart'));
+ }
+}
+
+class _BaseTest {
+ final MemoryResourceProvider provider = new MemoryResourceProvider();
+
+ /**
+ * Return the [provider] specific path for the given Posix [path].
+ */
+ String _p(String path) => provider.convertPath(path);
+}
+
+class _MockSource extends TypedMock implements Source {
+ final String fullName;
+ _MockSource(this.fullName);
}
diff --git a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
index b252888..7fa42f2 100644
--- a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
@@ -8,12 +8,12 @@
import 'package:analyzer/src/generated/source_io.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../utils.dart';
import 'resolver_test_case.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(CheckedModeCompileTimeErrorCodeTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(CheckedModeCompileTimeErrorCodeTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analyzer/test/generated/compile_time_error_code_test.dart b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
index cae5fd7..e03cba6 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
@@ -9,15 +9,15 @@
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
import 'package:analyzer/src/generated/source_io.dart';
+import 'package:test/test.dart' show expect;
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart' show expect;
-import '../utils.dart';
import 'resolver_test_case.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(CompileTimeErrorCodeTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(CompileTimeErrorCodeTest);
+ });
}
@reflectiveTest
@@ -1959,6 +1959,30 @@
verify([source]);
}
+ void test_duplicatePart_sameSource() {
+ addNamedSource('/part.dart', 'part of lib;');
+ Source source = addSource(r'''
+library lib;
+part 'part.dart';
+part 'foo/../part.dart';
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [CompileTimeErrorCode.DUPLICATE_PART]);
+ verify([source]);
+ }
+
+ void test_duplicatePart_sameUri() {
+ addNamedSource('/part.dart', 'part of lib;');
+ Source source = addSource(r'''
+library lib;
+part 'part.dart';
+part 'part.dart';
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [CompileTimeErrorCode.DUPLICATE_PART]);
+ verify([source]);
+ }
+
void test_exportInternalLibrary() {
Source source = addSource("export 'dart:_interceptors';");
computeLibrarySourceErrors(source);
@@ -6145,7 +6169,7 @@
// Check that the file is represented as missing.
Source target =
- analysisContext2.getSourcesWithFullName("/target.dart").first;
+ analysisContext2.getSourcesWithFullName(resourceProvider.convertPath("/target.dart")).first;
expect(analysisContext2.getModificationStamp(target), -1);
// Add an overlay in the same way as AnalysisServer.
diff --git a/pkg/analyzer/test/generated/constant_test.dart b/pkg/analyzer/test/generated/constant_test.dart
index a136753..c267a84 100644
--- a/pkg/analyzer/test/generated/constant_test.dart
+++ b/pkg/analyzer/test/generated/constant_test.dart
@@ -11,16 +11,16 @@
import 'package:analyzer/src/generated/constant.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../utils.dart';
import 'resolver_test_case.dart';
import 'test_support.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(ConstantEvaluatorTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConstantEvaluatorTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analyzer/test/generated/declaration_resolver_test.dart b/pkg/analyzer/test/generated/declaration_resolver_test.dart
index fd1dd8a..9226efe 100644
--- a/pkg/analyzer/test/generated/declaration_resolver_test.dart
+++ b/pkg/analyzer/test/generated/declaration_resolver_test.dart
@@ -8,23 +8,23 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
+import 'package:analyzer/src/generated/declaration_resolver.dart';
import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/task/dart.dart';
import 'package:analyzer/task/dart.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../utils.dart';
import 'resolver_test_case.dart';
import 'test_support.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(DeclarationResolverMetadataTest);
- defineReflectiveTests(DeclarationResolverTest);
- defineReflectiveTests(StrongModeDeclarationResolverTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(DeclarationResolverMetadataTest);
+ defineReflectiveTests(DeclarationResolverTest);
+ defineReflectiveTests(StrongModeDeclarationResolverTest);
+ });
}
CompilationUnit _cloneResolveUnit(CompilationUnit unit) {
diff --git a/pkg/analyzer/test/generated/element_resolver_test.dart b/pkg/analyzer/test/generated/element_resolver_test.dart
index e911f73..90acbe9 100644
--- a/pkg/analyzer/test/generated/element_resolver_test.dart
+++ b/pkg/analyzer/test/generated/element_resolver_test.dart
@@ -18,18 +18,18 @@
import 'package:analyzer/src/generated/testing/element_factory.dart';
import 'package:analyzer/src/generated/testing/test_type_provider.dart';
import 'package:analyzer/src/source/source_resource.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../utils.dart';
import 'analysis_context_factory.dart';
import 'resolver_test_case.dart';
import 'test_support.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(ElementResolverCodeTest);
- defineReflectiveTests(ElementResolverTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ElementResolverCodeTest);
+ defineReflectiveTests(ElementResolverTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analyzer/test/generated/engine_test.dart b/pkg/analyzer/test/generated/engine_test.dart
index 1c681c4..e6ec9d96 100644
--- a/pkg/analyzer/test/generated/engine_test.dart
+++ b/pkg/analyzer/test/generated/engine_test.dart
@@ -22,15 +22,14 @@
import 'package:analyzer/src/string_source.dart';
import 'package:analyzer/task/model.dart';
import 'package:html/dom.dart' show Document;
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:typed_mock/typed_mock.dart';
-import 'package:unittest/unittest.dart';
-
-import '../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(SourcesChangedEventTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(SourcesChangedEventTest);
+ });
}
/**
diff --git a/pkg/analyzer/test/generated/error_suppression_test.dart b/pkg/analyzer/test/generated/error_suppression_test.dart
index 00355f6..20a3312 100644
--- a/pkg/analyzer/test/generated/error_suppression_test.dart
+++ b/pkg/analyzer/test/generated/error_suppression_test.dart
@@ -7,12 +7,12 @@
import 'package:analyzer/src/generated/source_io.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../utils.dart';
import 'resolver_test_case.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(ErrorSuppressionTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ErrorSuppressionTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analyzer/test/generated/hint_code_test.dart b/pkg/analyzer/test/generated/hint_code_test.dart
index bbec137..6dd9fb6 100644
--- a/pkg/analyzer/test/generated/hint_code_test.dart
+++ b/pkg/analyzer/test/generated/hint_code_test.dart
@@ -9,16 +9,16 @@
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/parser.dart';
import 'package:analyzer/src/generated/source_io.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../utils.dart';
import 'analysis_context_factory.dart';
import 'resolver_test_case.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(HintCodeTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(HintCodeTest);
+ });
}
@reflectiveTest
@@ -62,7 +62,7 @@
const JS([String js]) { }
}
'''
- });
+ }, resourceProvider: resourceProvider);
}
void test_abstractSuperMemberReference_getter() {
diff --git a/pkg/analyzer/test/generated/incremental_resolver_test.dart b/pkg/analyzer/test/generated/incremental_resolver_test.dart
index e80ea99..eba3450 100644
--- a/pkg/analyzer/test/generated/incremental_resolver_test.dart
+++ b/pkg/analyzer/test/generated/incremental_resolver_test.dart
@@ -29,8 +29,8 @@
import 'package:analyzer/src/task/dart.dart';
import 'package:analyzer/task/dart.dart';
import 'package:analyzer/task/model.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import 'analysis_context_factory.dart';
import 'resolver_test_case.dart';
@@ -38,9 +38,11 @@
main() {
initializeTestEnvironment();
- defineReflectiveTests(IncrementalResolverTest);
- defineReflectiveTests(PoorMansIncrementalResolutionTest);
- defineReflectiveTests(ResolutionContextBuilderTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(IncrementalResolverTest);
+ defineReflectiveTests(PoorMansIncrementalResolutionTest);
+ defineReflectiveTests(ResolutionContextBuilderTest);
+ });
}
void initializeTestEnvironment() {}
@@ -144,16 +146,6 @@
LibraryElement library;
CompilationUnit unit;
- @override
- void reset() {
- analysisContext2 = AnalysisContextFactory.contextWithCore();
- }
-
- @override
- void resetWithOptions(AnalysisOptions options) {
- AnalysisContextFactory.contextWithCoreAndOptions(options);
- }
-
void setUp() {
super.setUp();
logging.logger = logging.NULL_LOGGER;
diff --git a/pkg/analyzer/test/generated/inheritance_manager_test.dart b/pkg/analyzer/test/generated/inheritance_manager_test.dart
index 0be0549..5b3ba8e 100644
--- a/pkg/analyzer/test/generated/inheritance_manager_test.dart
+++ b/pkg/analyzer/test/generated/inheritance_manager_test.dart
@@ -21,16 +21,16 @@
import 'package:analyzer/src/generated/testing/test_type_provider.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/source/source_resource.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../utils.dart';
import 'analysis_context_factory.dart';
import 'test_support.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(InheritanceManagerTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(InheritanceManagerTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analyzer/test/generated/java_core_test.dart b/pkg/analyzer/test/generated/java_core_test.dart
index f98895e..9571c87 100644
--- a/pkg/analyzer/test/generated/java_core_test.dart
+++ b/pkg/analyzer/test/generated/java_core_test.dart
@@ -5,12 +5,9 @@
library analyzer.test.generated.java_core_test;
import 'package:analyzer/src/generated/java_core.dart';
-import 'package:unittest/unittest.dart';
-
-import '../utils.dart';
+import 'package:test/test.dart';
main() {
- initializeTestEnvironment();
group('Character', () {
group('isLetter', () {
test('digits', () {
diff --git a/pkg/analyzer/test/generated/java_io_test.dart b/pkg/analyzer/test/generated/java_io_test.dart
index 0316817..c844cda 100644
--- a/pkg/analyzer/test/generated/java_io_test.dart
+++ b/pkg/analyzer/test/generated/java_io_test.dart
@@ -5,34 +5,32 @@
library analyzer.test.generated.java_io_test;
import 'package:analyzer/src/generated/java_io.dart';
-import 'package:unittest/unittest.dart';
-
-import '../utils.dart';
+import 'package:path/path.dart' as path;
+import 'package:test/test.dart';
main() {
- initializeTestEnvironment();
group('JavaFile', () {
group('toURI', () {
test('forAbsolute', () {
String tempPath = '/temp';
- String path = JavaFile.pathContext.join(tempPath, 'foo.dart');
+ String absolutePath = path.context.join(tempPath, 'foo.dart');
// we use an absolute path
- expect(JavaFile.pathContext.isAbsolute(path), isTrue,
- reason: '"$path" is not absolute');
+ expect(path.context.isAbsolute(absolutePath), isTrue,
+ reason: '"$absolutePath" is not absolute');
// test that toURI() returns an absolute URI
- Uri uri = new JavaFile(path).toURI();
+ Uri uri = new JavaFile(absolutePath).toURI();
expect(uri.isAbsolute, isTrue);
expect(uri.scheme, 'file');
});
test('forRelative', () {
String tempPath = '/temp';
- String path = JavaFile.pathContext.join(tempPath, 'foo.dart');
- expect(JavaFile.pathContext.isAbsolute(path), isTrue,
- reason: '"$path" is not absolute');
+ String absolutePath = path.context.join(tempPath, 'foo.dart');
+ expect(path.context.isAbsolute(absolutePath), isTrue,
+ reason: '"$absolutePath" is not absolute');
// prepare a relative path
// We should not check that "relPath" is actually relative -
// it may be not on Windows, if "temp" is on other disk.
- String relPath = JavaFile.pathContext.relative(path);
+ String relPath = path.context.relative(absolutePath);
// test that toURI() returns an absolute URI
Uri uri = new JavaFile(relPath).toURI();
expect(uri.isAbsolute, isTrue);
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
index 6dd2519..fd4487f 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_test.dart
@@ -11,16 +11,16 @@
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
import 'package:analyzer/src/generated/source_io.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../utils.dart';
import 'resolver_test_case.dart';
import 'test_support.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(NonErrorResolverTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(NonErrorResolverTest);
+ });
}
@reflectiveTest
@@ -1709,6 +1709,19 @@
verify([source]);
}
+ void test_duplicatePart() {
+ addNamedSource('/part1.dart', 'part of lib;');
+ addNamedSource('/part2.dart', 'part of lib;');
+ Source source = addSource(r'''
+library lib;
+part 'part1.dart';
+part 'part2.dart';
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
void test_dynamicIdentifier() {
Source source = addSource(r'''
main() {
diff --git a/pkg/analyzer/test/generated/non_hint_code_test.dart b/pkg/analyzer/test/generated/non_hint_code_test.dart
index b023ed5..2890551 100644
--- a/pkg/analyzer/test/generated/non_hint_code_test.dart
+++ b/pkg/analyzer/test/generated/non_hint_code_test.dart
@@ -9,12 +9,12 @@
import 'package:analyzer/src/generated/source_io.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../utils.dart';
import 'resolver_test_case.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(NonHintCodeTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(NonHintCodeTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analyzer/test/generated/package_test.dart b/pkg/analyzer/test/generated/package_test.dart
index d138acd..7a93dbe 100644
--- a/pkg/analyzer/test/generated/package_test.dart
+++ b/pkg/analyzer/test/generated/package_test.dart
@@ -5,24 +5,23 @@
library analyzer.test.generated.package_test;
import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/package.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:package_config/packages.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../src/context/mock_sdk.dart';
-import '../utils.dart';
import 'resolver_test_case.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(DependencyFinderTest);
- defineReflectiveTests(PackageDescriptionTest);
- defineReflectiveTests(PackageManagerTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(DependencyFinderTest);
+ defineReflectiveTests(PackageDescriptionTest);
+ defineReflectiveTests(PackageManagerTest);
+ });
}
/**
@@ -32,20 +31,10 @@
@reflectiveTest
class DependencyFinderTest extends ResolverTestCase {
- /**
- * The resource provider to be used by tests.
- */
- MemoryResourceProvider resourceProvider;
-
- @override
- void setUp() {
- resourceProvider = new MemoryResourceProvider();
- }
-
void test_transitiveDependenciesFor_circularDependencies() {
- String packageA = '/pub-cache/a-1.0';
- String packageB = '/pub-cache/b-1.0';
- String packageC = '/pub-cache/c-1.0';
+ String packageA = resourceProvider.convertPath('/pub-cache/a-1.0');
+ String packageB = resourceProvider.convertPath('/pub-cache/b-1.0');
+ String packageC = resourceProvider.convertPath('/pub-cache/c-1.0');
resourceProvider.newFile(
'$packageA/$pubspecName',
'''
@@ -101,10 +90,10 @@
}
void test_transitiveDependenciesFor_overlappingDependencies() {
- String packageA = '/pub-cache/a-1.0';
- String packageB = '/pub-cache/b-1.0';
- String packageC = '/pub-cache/c-1.0';
- String packageD = '/pub-cache/d-1.0';
+ String packageA = resourceProvider.convertPath('/pub-cache/a-1.0');
+ String packageB = resourceProvider.convertPath('/pub-cache/b-1.0');
+ String packageC = resourceProvider.convertPath('/pub-cache/c-1.0');
+ String packageD = resourceProvider.convertPath('/pub-cache/d-1.0');
resourceProvider.newFile(
'$packageA/$pubspecName',
'''
@@ -139,9 +128,9 @@
}
void test_transitiveDependenciesFor_simpleDependencies() {
- String packageA = '/pub-cache/a-1.0';
- String packageB = '/pub-cache/b-1.0';
- String packageC = '/pub-cache/c-1.0';
+ String packageA = resourceProvider.convertPath('/pub-cache/a-1.0');
+ String packageB = resourceProvider.convertPath('/pub-cache/b-1.0');
+ String packageC = resourceProvider.convertPath('/pub-cache/c-1.0');
resourceProvider.newFile(
'$packageA/$pubspecName',
'''
@@ -212,21 +201,11 @@
@reflectiveTest
class PackageManagerTest extends ResolverTestCase {
- /**
- * The resource provider to be used by tests.
- */
- MemoryResourceProvider resourceProvider;
-
- @override
- void setUp() {
- resourceProvider = new MemoryResourceProvider();
- }
-
void test_getContext() {
- String packageA = '/pub-cache/a-1.0';
- String packageB1 = '/pub-cache/b-1.0';
- String packageB2 = '/pub-cache/b-2.0';
- String packageC = '/pub-cache/c-1.0';
+ String packageA = resourceProvider.convertPath('/pub-cache/a-1.0');
+ String packageB1 = resourceProvider.convertPath('/pub-cache/b-1.0');
+ String packageB2 = resourceProvider.convertPath('/pub-cache/b-2.0');
+ String packageC = resourceProvider.convertPath('/pub-cache/c-1.0');
resourceProvider.newFile(
'$packageA/$pubspecName',
'''
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index fa7e4e6..2e46dfe 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -15,19 +15,19 @@
import 'package:analyzer/src/generated/testing/ast_factory.dart';
import 'package:analyzer/src/generated/testing/token_factory.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart' hide Configuration;
-import '../utils.dart';
import 'test_support.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(ComplexParserTest);
- defineReflectiveTests(ErrorParserTest);
- defineReflectiveTests(NonErrorParserTest);
- defineReflectiveTests(RecoveryParserTest);
- defineReflectiveTests(SimpleParserTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ComplexParserTest);
+ defineReflectiveTests(ErrorParserTest);
+ defineReflectiveTests(NonErrorParserTest);
+ defineReflectiveTests(RecoveryParserTest);
+ defineReflectiveTests(SimpleParserTest);
+ });
}
/**
@@ -2770,14 +2770,6 @@
listener.assertErrorsWithCodes([ParserErrorCode.WITH_WITHOUT_EXTENDS]);
}
- void test_wrongSeparatorForNamedParameter() {
- createParser('(a, {b = 0})');
- FormalParameterList list = parser.parseFormalParameterList();
- expectNotNullIfNoErrors(list);
- listener.assertErrorsWithCodes(
- [ParserErrorCode.WRONG_SEPARATOR_FOR_NAMED_PARAMETER]);
- }
-
void test_wrongSeparatorForPositionalParameter() {
createParser('(a, [b : 0])');
FormalParameterList list = parser.parseFormalParameterList();
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index 1abacd6..cc31a71 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -24,30 +24,30 @@
import 'package:analyzer/src/generated/testing/test_type_provider.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/source/source_resource.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../utils.dart';
import 'analysis_context_factory.dart';
import 'resolver_test_case.dart';
import 'test_support.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(AnalysisDeltaTest);
- defineReflectiveTests(ChangeSetTest);
- defineReflectiveTests(EnclosedScopeTest);
- defineReflectiveTests(ErrorResolverTest);
- defineReflectiveTests(LibraryImportScopeTest);
- defineReflectiveTests(LibraryScopeTest);
- defineReflectiveTests(PrefixedNamespaceTest);
- defineReflectiveTests(ScopeTest);
- defineReflectiveTests(StrictModeTest);
- defineReflectiveTests(SubtypeManagerTest);
- defineReflectiveTests(TypeOverrideManagerTest);
- defineReflectiveTests(TypePropagationTest);
- defineReflectiveTests(TypeProviderImplTest);
- defineReflectiveTests(TypeResolverVisitorTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AnalysisDeltaTest);
+ defineReflectiveTests(ChangeSetTest);
+ defineReflectiveTests(EnclosedScopeTest);
+ defineReflectiveTests(ErrorResolverTest);
+ defineReflectiveTests(LibraryImportScopeTest);
+ defineReflectiveTests(LibraryScopeTest);
+ defineReflectiveTests(PrefixedNamespaceTest);
+ defineReflectiveTests(ScopeTest);
+ defineReflectiveTests(StrictModeTest);
+ defineReflectiveTests(SubtypeManagerTest);
+ defineReflectiveTests(TypeOverrideManagerTest);
+ defineReflectiveTests(TypePropagationTest);
+ defineReflectiveTests(TypeProviderImplTest);
+ defineReflectiveTests(TypeResolverVisitorTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analyzer/test/generated/resolver_test_case.dart b/pkg/analyzer/test/generated/resolver_test_case.dart
index 1b7f5e2..1997423 100644
--- a/pkg/analyzer/test/generated/resolver_test_case.dart
+++ b/pkg/analyzer/test/generated/resolver_test_case.dart
@@ -9,7 +9,7 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/error/error.dart';
-import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/error/codes.dart';
@@ -19,7 +19,7 @@
import 'package:analyzer/src/generated/source_io.dart';
import 'package:analyzer/src/generated/testing/ast_factory.dart';
import 'package:analyzer/src/generated/testing/element_factory.dart';
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
import 'analysis_context_factory.dart';
import 'test_support.dart';
@@ -299,6 +299,11 @@
class ResolverTestCase extends EngineTestCase {
/**
+ * The resource provider used by the test case.
+ */
+ MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
+
+ /**
* The analysis context used to parse the compilation units being resolved.
*/
InternalAnalysisContext analysisContext2;
@@ -332,14 +337,13 @@
TypeSystem get typeSystem => analysisContext2.typeSystem;
/**
- * Add a source file to the content provider. The file path should be absolute.
- *
- * @param filePath the path of the file being added
- * @param contents the contents to be returned by the content provider for the specified file
- * @return the source object representing the added file
+ * Add a source file with the given [filePath] in the root of the file system.
+ * The file path should be absolute. The file will have the given [contents]
+ * set in the content provider. Return the source representing the added file.
*/
Source addNamedSource(String filePath, String contents) {
- Source source = cacheSource(filePath, contents);
+ Source source =
+ cacheSource(resourceProvider.convertPath(filePath), contents);
ChangeSet changeSet = new ChangeSet();
changeSet.addedSource(source);
analysisContext2.applyChanges(changeSet);
@@ -347,10 +351,9 @@
}
/**
- * Add a source file to the content provider.
- *
- * @param contents the contents to be returned by the content provider for the specified file
- * @return the source object representing the added file
+ * Add a source file named 'test.dart' in the root of the file system. The
+ * file will have the given [contents] set in the content provider. Return the
+ * source representing the added file.
*/
Source addSource(String contents) => addNamedSource("/test.dart", contents);
@@ -477,8 +480,7 @@
* source to the analysis context. The file path must be absolute.
*/
Source cacheSource(String filePath, String contents) {
- Source source =
- PhysicalResourceProvider.INSTANCE.getFile(filePath).createSource();
+ Source source = resourceProvider.getFile(filePath).createSource();
analysisContext2.setContents(source, contents);
return source;
}
@@ -516,8 +518,7 @@
* give it an empty content. Return the source that was created.
*/
Source createNamedSource(String fileName) {
- Source source =
- PhysicalResourceProvider.INSTANCE.getFile(fileName).createSource();
+ Source source = resourceProvider.getFile(fileName).createSource();
analysisContext2.setContents(source, '');
return source;
}
@@ -614,21 +615,20 @@
}
/**
- * In the rare cases we want to group several tests into single "test_" method, so need a way to
- * reset test instance to reuse it.
+ * Re-create the analysis context being used by the test case.
*/
void reset() {
- analysisContext2 = AnalysisContextFactory.contextWithCore();
+ analysisContext2 = AnalysisContextFactory.contextWithCore(
+ resourceProvider: resourceProvider);
}
/**
- * Reset the analysis context to have the given options applied.
- *
- * @param options the analysis options to be applied to the context
+ * Re-create the analysis context being used by the test case and set the
+ * [options] in the newly created context to the given [options].
*/
void resetWithOptions(AnalysisOptions options) {
- analysisContext2 =
- AnalysisContextFactory.contextWithCoreAndOptions(options);
+ analysisContext2 = AnalysisContextFactory.contextWithCoreAndOptions(options,
+ resourceProvider: resourceProvider);
}
/**
diff --git a/pkg/analyzer/test/generated/scanner_test.dart b/pkg/analyzer/test/generated/scanner_test.dart
index 3937ce8..748bab4 100644
--- a/pkg/analyzer/test/generated/scanner_test.dart
+++ b/pkg/analyzer/test/generated/scanner_test.dart
@@ -11,18 +11,18 @@
import 'package:analyzer/src/dart/scanner/reader.dart';
import 'package:analyzer/src/dart/scanner/scanner.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../utils.dart';
import 'test_support.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(CharSequenceReaderTest);
- defineReflectiveTests(KeywordStateTest);
- defineReflectiveTests(ScannerTest);
- defineReflectiveTests(TokenTypeTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(CharSequenceReaderTest);
+ defineReflectiveTests(KeywordStateTest);
+ defineReflectiveTests(ScannerTest);
+ defineReflectiveTests(TokenTypeTest);
+ });
}
class CharacterRangeReaderTest extends EngineTestCase {
diff --git a/pkg/analyzer/test/generated/sdk_test.dart b/pkg/analyzer/test/generated/sdk_test.dart
index 5e40081..69c774e 100644
--- a/pkg/analyzer/test/generated/sdk_test.dart
+++ b/pkg/analyzer/test/generated/sdk_test.dart
@@ -6,24 +6,23 @@
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../src/context/mock_sdk.dart';
-import '../utils.dart';
import 'test_support.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(DartSdkManagerTest);
- defineReflectiveTests(SdkDescriptionTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(DartSdkManagerTest);
+ defineReflectiveTests(SdkDescriptionTest);
+ });
}
@reflectiveTest
class DartSdkManagerTest extends EngineTestCase {
void test_anySdk() {
- DartSdkManager manager =
- new DartSdkManager('/a/b/c', false, _failIfCreated);
+ DartSdkManager manager = new DartSdkManager('/a/b/c', false);
expect(manager.anySdk, isNull);
AnalysisOptions options = new AnalysisOptionsImpl();
@@ -34,8 +33,7 @@
}
void test_getSdk_differentDescriptors() {
- DartSdkManager manager =
- new DartSdkManager('/a/b/c', false, _failIfCreated);
+ DartSdkManager manager = new DartSdkManager('/a/b/c', false);
AnalysisOptions options = new AnalysisOptionsImpl();
SdkDescription description1 = new SdkDescription(<String>['/c/d'], options);
DartSdk sdk1 = new MockSdk();
@@ -51,8 +49,7 @@
}
void test_getSdk_sameDescriptor() {
- DartSdkManager manager =
- new DartSdkManager('/a/b/c', false, _failIfCreated);
+ DartSdkManager manager = new DartSdkManager('/a/b/c', false);
AnalysisOptions options = new AnalysisOptionsImpl();
SdkDescription description = new SdkDescription(<String>['/c/d'], options);
DartSdk sdk = new MockSdk();
@@ -65,11 +62,6 @@
fail('Use of ifAbsent function');
return null;
}
-
- DartSdk _failIfCreated(AnalysisOptions _) {
- fail('Use of sdkCreator');
- return null;
- }
}
@reflectiveTest
diff --git a/pkg/analyzer/test/generated/simple_resolver_test.dart b/pkg/analyzer/test/generated/simple_resolver_test.dart
index 13a0766..8a3059b 100644
--- a/pkg/analyzer/test/generated/simple_resolver_test.dart
+++ b/pkg/analyzer/test/generated/simple_resolver_test.dart
@@ -12,16 +12,16 @@
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source_io.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../utils.dart';
import 'resolver_test_case.dart';
import 'test_support.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(SimpleResolverTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(SimpleResolverTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analyzer/test/generated/source_factory_test.dart b/pkg/analyzer/test/generated/source_factory_test.dart
index bc1e830..e373d67 100644
--- a/pkg/analyzer/test/generated/source_factory_test.dart
+++ b/pkg/analyzer/test/generated/source_factory_test.dart
@@ -18,17 +18,17 @@
import 'package:package_config/packages.dart';
import 'package:package_config/packages_file.dart' as pkgfile show parse;
import 'package:package_config/src/packages_impl.dart';
-import 'package:path/path.dart';
+import 'package:path/path.dart' as pathos;
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../utils.dart';
import 'test_support.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(SourceFactoryTest);
runPackageMapTests();
+ defineReflectiveSuite(() {
+ defineReflectiveTests(SourceFactoryTest);
+ });
}
Source createSource({String path, String uri}) =>
@@ -284,7 +284,7 @@
void test_resolveUri_nonAbsolute_relative_package() {
MemoryResourceProvider provider = new MemoryResourceProvider();
- Context context = provider.pathContext;
+ pathos.Context context = provider.pathContext;
String packagePath =
context.joinAll([context.separator, 'path', 'to', 'package']);
String libPath = context.joinAll([packagePath, 'lib']);
diff --git a/pkg/analyzer/test/generated/static_type_analyzer_test.dart b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
index 60854a9..5ccf569 100644
--- a/pkg/analyzer/test/generated/static_type_analyzer_test.dart
+++ b/pkg/analyzer/test/generated/static_type_analyzer_test.dart
@@ -23,18 +23,18 @@
import 'package:analyzer/src/generated/testing/test_type_provider.dart';
import 'package:analyzer/src/generated/testing/token_factory.dart';
import 'package:analyzer/src/source/source_resource.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../utils.dart';
import 'analysis_context_factory.dart';
import 'resolver_test_case.dart';
import 'test_support.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(StaticTypeAnalyzerTest);
- defineReflectiveTests(StaticTypeAnalyzer2Test);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(StaticTypeAnalyzerTest);
+ defineReflectiveTests(StaticTypeAnalyzer2Test);
+ });
}
/**
diff --git a/pkg/analyzer/test/generated/static_type_warning_code_test.dart b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
index 858d10a..982f643 100644
--- a/pkg/analyzer/test/generated/static_type_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
@@ -9,16 +9,16 @@
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/java_core.dart' show formatList;
import 'package:analyzer/src/generated/source_io.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../utils.dart';
import 'resolver_test_case.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(StaticTypeWarningCodeTest);
- defineReflectiveTests(StrongModeStaticTypeWarningCodeTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(StaticTypeWarningCodeTest);
+ defineReflectiveTests(StrongModeStaticTypeWarningCodeTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analyzer/test/generated/static_warning_code_test.dart b/pkg/analyzer/test/generated/static_warning_code_test.dart
index 3acd138..0a7087d 100644
--- a/pkg/analyzer/test/generated/static_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_warning_code_test.dart
@@ -8,15 +8,15 @@
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source_io.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../utils.dart';
import 'resolver_test_case.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(StaticWarningCodeTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(StaticWarningCodeTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analyzer/test/generated/strong_mode_test.dart b/pkg/analyzer/test/generated/strong_mode_test.dart
index ec467c7..783b462 100644
--- a/pkg/analyzer/test/generated/strong_mode_test.dart
+++ b/pkg/analyzer/test/generated/strong_mode_test.dart
@@ -11,17 +11,18 @@
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source_io.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../utils.dart';
import 'resolver_test_case.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(StrongModeDownwardsInferenceTest);
- defineReflectiveTests(StrongModeStaticTypeAnalyzer2Test);
- defineReflectiveTests(StrongModeTypePropagationTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(StrongModeDownwardsInferenceTest);
+ defineReflectiveTests(StrongModeStaticTypeAnalyzer2Test);
+ defineReflectiveTests(StrongModeTypePropagationTest);
+ });
}
/**
diff --git a/pkg/analyzer/test/generated/test_all.dart b/pkg/analyzer/test/generated/test_all.dart
index 63b357d..37c9268 100644
--- a/pkg/analyzer/test/generated/test_all.dart
+++ b/pkg/analyzer/test/generated/test_all.dart
@@ -4,9 +4,8 @@
library analyzer.test.generated.test_all;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../utils.dart';
import 'all_the_rest_test.dart' as all_the_rest;
import 'bazel_test.dart' as bazel_test;
import 'checked_mode_compile_time_error_code_test.dart'
@@ -40,8 +39,7 @@
/// Utility for manually running all tests.
main() {
- initializeTestEnvironment();
- group('generated tests', () {
+ defineReflectiveSuite(() {
all_the_rest.main();
bazel_test.main();
checked_mode_compile_time_error_code_test.main();
@@ -71,5 +69,5 @@
type_system_test.main();
utilities_dart_test.main();
utilities_test.main();
- });
+ }, name: 'generated');
}
diff --git a/pkg/analyzer/test/generated/test_support.dart b/pkg/analyzer/test/generated/test_support.dart
index 7b36770..6ec7c36 100644
--- a/pkg/analyzer/test/generated/test_support.dart
+++ b/pkg/analyzer/test/generated/test_support.dart
@@ -18,7 +18,7 @@
import 'package:analyzer/src/generated/source.dart';
import 'package:plugin/manager.dart';
import 'package:plugin/plugin.dart';
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
import 'analysis_context_factory.dart';
diff --git a/pkg/analyzer/test/generated/type_system_test.dart b/pkg/analyzer/test/generated/type_system_test.dart
index af08bb4..6aa2ad1 100644
--- a/pkg/analyzer/test/generated/type_system_test.dart
+++ b/pkg/analyzer/test/generated/type_system_test.dart
@@ -14,20 +14,20 @@
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/testing/element_factory.dart';
import 'package:analyzer/src/generated/testing/test_type_provider.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../utils.dart';
import 'analysis_context_factory.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(StrongAssignabilityTest);
- defineReflectiveTests(StrongSubtypingTest);
- defineReflectiveTests(StrongGenericFunctionInferenceTest);
- defineReflectiveTests(LeastUpperBoundTest);
- defineReflectiveTests(StrongLeastUpperBoundTest);
- defineReflectiveTests(StrongGreatestLowerBoundTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(StrongAssignabilityTest);
+ defineReflectiveTests(StrongSubtypingTest);
+ defineReflectiveTests(StrongGenericFunctionInferenceTest);
+ defineReflectiveTests(LeastUpperBoundTest);
+ defineReflectiveTests(StrongLeastUpperBoundTest);
+ defineReflectiveTests(StrongGreatestLowerBoundTest);
+ });
}
/**
diff --git a/pkg/analyzer/test/generated/utilities_dart_test.dart b/pkg/analyzer/test/generated/utilities_dart_test.dart
index c300c21..1917b16 100644
--- a/pkg/analyzer/test/generated/utilities_dart_test.dart
+++ b/pkg/analyzer/test/generated/utilities_dart_test.dart
@@ -5,14 +5,13 @@
library analyzer.test.generated.utilities_dart_test;
import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(ResolveRelativeUriTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ResolveRelativeUriTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analyzer/test/generated/utilities_test.dart b/pkg/analyzer/test/generated/utilities_test.dart
index 8e23ae1..2c57df9 100644
--- a/pkg/analyzer/test/generated/utilities_test.dart
+++ b/pkg/analyzer/test/generated/utilities_test.dart
@@ -8,6 +8,7 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/src/dart/ast/token.dart';
import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/dart/scanner/reader.dart';
@@ -18,24 +19,25 @@
import 'package:analyzer/src/generated/testing/ast_factory.dart';
import 'package:analyzer/src/generated/testing/token_factory.dart';
import 'package:analyzer/src/generated/utilities_collection.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../utils.dart';
import 'test_support.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(AstClonerTest);
- defineReflectiveTests(NodeReplacerTest);
- defineReflectiveTests(LineInfoTest);
- defineReflectiveTests(SourceRangeTest);
- defineReflectiveTests(BooleanArrayTest);
- defineReflectiveTests(DirectedGraphTest);
- defineReflectiveTests(MultipleMapIteratorTest);
- defineReflectiveTests(SingleMapIteratorTest);
- defineReflectiveTests(TokenMapTest);
- defineReflectiveTests(StringUtilitiesTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AstClonerTest);
+ defineReflectiveTests(BooleanArrayTest);
+ defineReflectiveTests(DirectedGraphTest);
+ defineReflectiveTests(ExceptionHandlingDelegatingAstVisitorTest);
+ defineReflectiveTests(LineInfoTest);
+ defineReflectiveTests(MultipleMapIteratorTest);
+ defineReflectiveTests(NodeReplacerTest);
+ defineReflectiveTests(SingleMapIteratorTest);
+ defineReflectiveTests(SourceRangeTest);
+ defineReflectiveTests(StringUtilitiesTest);
+ defineReflectiveTests(TokenMapTest);
+ });
}
class AstCloneComparator extends AstComparator {
@@ -1594,6 +1596,21 @@
*/
class DirectedGraphTest_Node {}
+@reflectiveTest
+class ExceptionHandlingDelegatingAstVisitorTest extends EngineTestCase {
+ void test_handlerIsCalled() {
+ AstVisitor exceptionThrowingVisitor = new _ExceptionThrowingVisitor();
+ bool handlerInvoked = false;
+ AstVisitor visitor = new ExceptionHandlingDelegatingAstVisitor(
+ [exceptionThrowingVisitor], (AstNode node, AstVisitor visitor,
+ dynamic exception, StackTrace stackTrace) {
+ handlerInvoked = true;
+ });
+ new NullLiteral(null).accept(visitor);
+ expect(handlerInvoked, isTrue);
+ }
+}
+
class Getter_NodeReplacerTest_test_annotation
implements NodeReplacerTest_Getter<Annotation, ArgumentList> {
@override
@@ -4340,3 +4357,9 @@
expect(tokenMap.get(key), same(value));
}
}
+
+class _ExceptionThrowingVisitor extends SimpleAstVisitor {
+ visitNullLiteral(NullLiteral node) {
+ throw new ArgumentError('');
+ }
+}
diff --git a/pkg/analyzer/test/instrumentation/instrumentation_test.dart b/pkg/analyzer/test/instrumentation/instrumentation_test.dart
index e6cafc0..8eff1cf 100644
--- a/pkg/analyzer/test/instrumentation/instrumentation_test.dart
+++ b/pkg/analyzer/test/instrumentation/instrumentation_test.dart
@@ -7,14 +7,12 @@
import 'dart:async';
import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
main() {
- group('instrumentation', () {
- defineReflectiveTests(InstrumentationServiceTest);
- defineReflectiveTests(MulticastInstrumentationServerTest);
- });
+ defineReflectiveTests(InstrumentationServiceTest);
+ defineReflectiveTests(MulticastInstrumentationServerTest);
}
@reflectiveTest
diff --git a/pkg/analyzer/test/instrumentation/test_all.dart b/pkg/analyzer/test/instrumentation/test_all.dart
index 46bb206..8ef3a56 100644
--- a/pkg/analyzer/test/instrumentation/test_all.dart
+++ b/pkg/analyzer/test/instrumentation/test_all.dart
@@ -4,14 +4,13 @@
library analyzer.test.instrumentation.test_all;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'instrumentation_test.dart' as instrumentation_test;
/// Utility for manually running all tests.
main() {
- groupSep = ' | ';
- group('instrumentation', () {
+ defineReflectiveSuite(() {
instrumentation_test.main();
- });
+ }, name: 'instrumentation');
}
diff --git a/pkg/analyzer/test/parse_compilation_unit_test.dart b/pkg/analyzer/test/parse_compilation_unit_test.dart
index c5313da..87f441d 100644
--- a/pkg/analyzer/test/parse_compilation_unit_test.dart
+++ b/pkg/analyzer/test/parse_compilation_unit_test.dart
@@ -5,12 +5,9 @@
library analyzer.test.parse_compilation_unit_test;
import 'package:analyzer/analyzer.dart';
-import 'package:unittest/unittest.dart';
-
-import 'utils.dart';
+import 'package:test/test.dart';
void main() {
- initializeTestEnvironment();
test("parses a valid compilation unit successfully", () {
var unit = parseCompilationUnit("void main() => print('Hello, world!');");
expect(unit.toString(), equals("void main() => print('Hello, world!');"));
diff --git a/pkg/analyzer/test/resource_utils.dart b/pkg/analyzer/test/resource_utils.dart
index ef01daf..c03eb1d 100644
--- a/pkg/analyzer/test/resource_utils.dart
+++ b/pkg/analyzer/test/resource_utils.dart
@@ -12,7 +12,7 @@
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/util/absolute_path.dart';
import 'package:path/path.dart' as path;
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
bool get isWindows => path.Style.platform == path.Style.windows;
diff --git a/pkg/analyzer/test/source/analysis_options_provider_test.dart b/pkg/analyzer/test/source/analysis_options_provider_test.dart
index adbadc7..5ea408a 100644
--- a/pkg/analyzer/test/source/analysis_options_provider_test.dart
+++ b/pkg/analyzer/test/source/analysis_options_provider_test.dart
@@ -10,17 +10,17 @@
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/source/analysis_options_provider.dart';
import 'package:analyzer/src/generated/engine.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import 'package:yaml/yaml.dart';
import '../resource_utils.dart';
-import '../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(AnalysisOptionsProviderOldTest);
- defineReflectiveTests(AnalysisOptionsProviderNewTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AnalysisOptionsProviderOldTest);
+ defineReflectiveTests(AnalysisOptionsProviderNewTest);
+ });
group('AnalysisOptionsProvider', () {
void expectMergesTo(String defaults, String overrides, String expected) {
var optionsProvider = new AnalysisOptionsProvider();
@@ -120,7 +120,7 @@
String get optionsFileName;
void setUp() {
- var rawProvider = new MemoryResourceProvider(isWindows: isWindows);
+ var rawProvider = new MemoryResourceProvider();
resourceProvider = new TestResourceProvider(rawProvider);
pathTranslator = new TestPathTranslator(rawProvider);
}
diff --git a/pkg/analyzer/test/source/config_test.dart b/pkg/analyzer/test/source/config_test.dart
index ccbc056..6ce08cd 100644
--- a/pkg/analyzer/test/source/config_test.dart
+++ b/pkg/analyzer/test/source/config_test.dart
@@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/source/config.dart';
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
import 'package:yaml/yaml.dart';
main() {
diff --git a/pkg/analyzer/test/source/embedder_test.dart b/pkg/analyzer/test/source/embedder_test.dart
index fb3df17..2068361 100644
--- a/pkg/analyzer/test/source/embedder_test.dart
+++ b/pkg/analyzer/test/source/embedder_test.dart
@@ -11,16 +11,18 @@
import 'package:analyzer/source/embedder.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../embedder_tests.dart';
import '../resource_utils.dart';
main() {
- defineReflectiveTests(DartUriResolverTest);
- defineReflectiveTests(EmbedderSdkTest);
- defineReflectiveTests(EmbedderUriResolverTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(DartUriResolverTest);
+ defineReflectiveTests(EmbedderSdkTest);
+ defineReflectiveTests(EmbedderUriResolverTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analyzer/test/source/error_processor_test.dart b/pkg/analyzer/test/source/error_processor_test.dart
index c170fc9..fcf3f1e 100644
--- a/pkg/analyzer/test/source/error_processor_test.dart
+++ b/pkg/analyzer/test/source/error_processor_test.dart
@@ -13,7 +13,7 @@
import 'package:analyzer/src/task/options.dart';
import 'package:plugin/manager.dart';
import 'package:plugin/plugin.dart';
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
import 'package:yaml/src/yaml_node.dart';
import '../generated/test_support.dart';
diff --git a/pkg/analyzer/test/source/package_map_provider_test.dart b/pkg/analyzer/test/source/package_map_provider_test.dart
index 23b8511..5959e42 100644
--- a/pkg/analyzer/test/source/package_map_provider_test.dart
+++ b/pkg/analyzer/test/source/package_map_provider_test.dart
@@ -10,23 +10,21 @@
import 'package:analyzer/source/pub_package_map_provider.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/generated/sdk.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(PubPackageMapProviderTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(PubPackageMapProviderTest);
+ });
}
@reflectiveTest
class PubPackageMapProviderTest {
- static const String projectPath = '/path/to/project';
-
DartSdk sdk;
MemoryResourceProvider resourceProvider;
PubPackageMapProvider packageMapProvider;
+ String projectPath;
Folder projectFolder;
PackageMapInfo parsePackageMap(Map obj) {
@@ -35,9 +33,11 @@
void setUp() {
resourceProvider = new MemoryResourceProvider();
- sdk = new FolderBasedDartSdk(resourceProvider,
- FolderBasedDartSdk.defaultSdkDirectory(resourceProvider));
+ Folder sdkFolder = resourceProvider
+ .newFolder(resourceProvider.convertPath('/Users/user/dart-sdk'));
+ sdk = new FolderBasedDartSdk(resourceProvider, sdkFolder);
packageMapProvider = new PubPackageMapProvider(resourceProvider, sdk);
+ projectPath = resourceProvider.convertPath('/path/to/project');
projectFolder = resourceProvider.newFolder(projectPath);
}
@@ -48,12 +48,15 @@
});
PackageMapInfo info = packageMapProvider.computePackageMap(projectFolder);
expect(info.packageMap, isNull);
- expect(info.dependencies, unorderedEquals(['$projectPath/pubspec.lock']));
+ expect(
+ info.dependencies,
+ unorderedEquals(
+ [resourceProvider.pathContext.join(projectPath, 'pubspec.lock')]));
}
void test_parsePackageMap_dontIgnoreNonExistingFolder() {
String packageName = 'foo';
- String folderPath = '/path/to/folder';
+ String folderPath = resourceProvider.convertPath('/path/to/folder');
Map<String, List<Folder>> result = parsePackageMap({
'packages': {packageName: folderPath}
}).packageMap;
@@ -65,8 +68,10 @@
}
void test_parsePackageMap_handleDependencies() {
- String path1 = '/path/to/folder1/pubspec.lock';
- String path2 = '/path/to/folder2/pubspec.lock';
+ String path1 =
+ resourceProvider.convertPath('/path/to/folder1/pubspec.lock');
+ String path2 =
+ resourceProvider.convertPath('/path/to/folder2/pubspec.lock');
resourceProvider.newFile(path1, '...');
resourceProvider.newFile(path2, '...');
Set<String> dependencies = parsePackageMap({
@@ -80,7 +85,7 @@
void test_parsePackageMap_normalFolder() {
String packageName = 'foo';
- String folderPath = '/path/to/folder';
+ String folderPath = resourceProvider.convertPath('/path/to/folder');
resourceProvider.newFolder(folderPath);
Map<String, List<Folder>> result = parsePackageMap({
'packages': {packageName: folderPath}
@@ -94,8 +99,8 @@
void test_parsePackageMap_packageMapsToList() {
String packageName = 'foo';
- String folderPath1 = '/path/to/folder1';
- String folderPath2 = '/path/to/folder2';
+ String folderPath1 = resourceProvider.convertPath('/path/to/folder1');
+ String folderPath2 = resourceProvider.convertPath('/path/to/folder2');
resourceProvider.newFolder(folderPath1);
resourceProvider.newFolder(folderPath2);
Map<String, List<Folder>> result = parsePackageMap({
@@ -113,7 +118,7 @@
}
void test_parsePackageMap_relativePahInPackages() {
- String packagePath = '/path/to/package';
+ String packagePath = resourceProvider.convertPath('/path/to/package');
String relativePackagePath = '../package';
String packageName = 'foo';
resourceProvider.newFolder(projectPath);
@@ -127,7 +132,8 @@
}
void test_parsePackageMap_relativePathInDependencies() {
- String dependencyPath = '/path/to/pubspec.lock';
+ String dependencyPath =
+ resourceProvider.convertPath('/path/to/pubspec.lock');
String relativeDependencyPath = '../pubspec.lock';
resourceProvider.newFolder(projectPath);
resourceProvider.newFile(dependencyPath, 'contents');
diff --git a/pkg/analyzer/test/source/package_map_resolver_test.dart b/pkg/analyzer/test/source/package_map_resolver_test.dart
index bcdd5be..f6b9a3d 100644
--- a/pkg/analyzer/test/source/package_map_resolver_test.dart
+++ b/pkg/analyzer/test/source/package_map_resolver_test.dart
@@ -9,14 +9,13 @@
import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:path/path.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(_PackageMapUriResolverTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(_PackageMapUriResolverTest);
+ });
}
@reflectiveTest
@@ -56,15 +55,15 @@
}
void test_resolve_multiple_folders() {
- const pkgFileA = '/part1/lib/libA.dart';
- const pkgFileB = '/part2/lib/libB.dart';
+ String pkgFileA = provider.convertPath('/part1/lib/libA.dart');
+ String pkgFileB = provider.convertPath('/part2/lib/libB.dart');
provider.newFile(pkgFileA, 'library lib_a');
provider.newFile(pkgFileB, 'library lib_b');
PackageMapUriResolver resolver =
new PackageMapUriResolver(provider, <String, List<Folder>>{
'pkg': <Folder>[
- provider.getResource('/part1/lib/'),
- provider.getResource('/part2/lib/')
+ provider.getResource(provider.convertPath('/part1/lib/')),
+ provider.getResource(provider.convertPath('/part2/lib/'))
]
});
{
@@ -93,14 +92,16 @@
}
void test_resolve_OK() {
- const pkgFileA = '/pkgA/lib/libA.dart';
- const pkgFileB = '/pkgB/lib/libB.dart';
+ String pkgFileA = provider.convertPath('/pkgA/lib/libA.dart');
+ String pkgFileB = provider.convertPath('/pkgB/lib/libB.dart');
provider.newFile(pkgFileA, 'library lib_a;');
provider.newFile(pkgFileB, 'library lib_b;');
PackageMapUriResolver resolver =
new PackageMapUriResolver(provider, <String, List<Folder>>{
- 'pkgA': <Folder>[provider.getResource('/pkgA/lib/')],
- 'pkgB': <Folder>[provider.getResource('/pkgB/lib/')]
+ 'pkgA': <Folder>[
+ provider.getResource(provider.convertPath('/pkgA/lib/'))
+ ],
+ 'pkgB': <Folder>[provider.getResource(provider.convertPath('/pkgB/lib/'))]
});
{
Uri uri = Uri.parse('package:pkgA/libA.dart');
@@ -152,23 +153,27 @@
}
void test_restoreAbsolute() {
- const pkgFileA = '/pkgA/lib/libA.dart';
- const pkgFileB = '/pkgB/lib/src/libB.dart';
+ String pkgFileA = provider.convertPath('/pkgA/lib/libA.dart');
+ String pkgFileB = provider.convertPath('/pkgB/lib/src/libB.dart');
provider.newFile(pkgFileA, 'library lib_a;');
provider.newFile(pkgFileB, 'library lib_b;');
PackageMapUriResolver resolver =
new PackageMapUriResolver(provider, <String, List<Folder>>{
- 'pkgA': <Folder>[provider.getResource('/pkgA/lib/')],
- 'pkgB': <Folder>[provider.getResource('/pkgB/lib/')]
+ 'pkgA': <Folder>[
+ provider.getResource(provider.convertPath('/pkgA/lib/'))
+ ],
+ 'pkgB': <Folder>[provider.getResource(provider.convertPath('/pkgB/lib/'))]
});
{
- Source source = _createFileSource('/pkgA/lib/libA.dart');
+ Source source =
+ _createFileSource(provider.convertPath('/pkgA/lib/libA.dart'));
Uri uri = resolver.restoreAbsolute(source);
expect(uri, isNotNull);
expect(uri.toString(), 'package:pkgA/libA.dart');
}
{
- Source source = _createFileSource('/pkgB/lib/src/libB.dart');
+ Source source =
+ _createFileSource(provider.convertPath('/pkgB/lib/src/libB.dart'));
Uri uri = resolver.restoreAbsolute(source);
expect(uri, isNotNull);
expect(uri.toString(), 'package:pkgB/src/libB.dart');
@@ -181,15 +186,15 @@
}
void test_restoreAbsolute_ambiguous() {
- const file1 = '/foo1/lib/bar.dart';
- const file2 = '/foo2/lib/bar.dart';
+ String file1 = provider.convertPath('/foo1/lib/bar.dart');
+ String file2 = provider.convertPath('/foo2/lib/bar.dart');
provider.newFile(file1, 'library bar');
provider.newFile(file2, 'library bar');
PackageMapUriResolver resolver =
new PackageMapUriResolver(provider, <String, List<Folder>>{
'foo': <Folder>[
- provider.getResource('/foo1/lib'),
- provider.getResource('/foo2/lib')
+ provider.getResource(provider.convertPath('/foo1/lib')),
+ provider.getResource(provider.convertPath('/foo2/lib'))
]
});
// Restoring file1 should yield a package URI, and that package URI should
@@ -205,19 +210,19 @@
}
void test_restoreAbsolute_longestMatch() {
- const file1 = '/foo1/bar1/lib.dart';
- const file2 = '/foo2/bar2/lib.dart';
+ String file1 = provider.convertPath('/foo1/bar1/lib.dart');
+ String file2 = provider.convertPath('/foo2/bar2/lib.dart');
provider.newFile(file1, 'library lib');
provider.newFile(file2, 'library lib');
PackageMapUriResolver resolver =
new PackageMapUriResolver(provider, <String, List<Folder>>{
'pkg1': <Folder>[
- provider.getResource('/foo1'),
- provider.getResource('/foo2/bar2')
+ provider.getResource(provider.convertPath('/foo1')),
+ provider.getResource(provider.convertPath('/foo2/bar2'))
],
'pkg2': <Folder>[
- provider.getResource('/foo1/bar1'),
- provider.getResource('/foo2')
+ provider.getResource(provider.convertPath('/foo1/bar1')),
+ provider.getResource(provider.convertPath('/foo2'))
]
});
// Restoring file1 should yield a package URI for pkg2, since pkg2's match
diff --git a/pkg/analyzer/test/source/path_filter_test.dart b/pkg/analyzer/test/source/path_filter_test.dart
index 1cada77..172a421 100644
--- a/pkg/analyzer/test/source/path_filter_test.dart
+++ b/pkg/analyzer/test/source/path_filter_test.dart
@@ -6,12 +6,9 @@
import 'package:analyzer/source/path_filter.dart';
import 'package:path/path.dart';
-import 'package:unittest/unittest.dart';
-
-import '../utils.dart';
+import 'package:test/test.dart';
main() {
- initializeTestEnvironment();
String root(String path) => context.absolute(context.normalize(path));
group('PathFilterTest', () {
setUp(() {});
diff --git a/pkg/analyzer/test/source/sdk_ext_test.dart b/pkg/analyzer/test/source/sdk_ext_test.dart
index 7c6b19f..0ca54be 100644
--- a/pkg/analyzer/test/source/sdk_ext_test.dart
+++ b/pkg/analyzer/test/source/sdk_ext_test.dart
@@ -7,14 +7,13 @@
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/source/sdk_ext.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(SdkExtUriResolverTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(SdkExtUriResolverTest);
+ });
}
@reflectiveTest
@@ -22,17 +21,23 @@
MemoryResourceProvider resourceProvider;
void setUp() {
+ String joinAndEscape(List<String> components) {
+ return resourceProvider.pathContext
+ .joinAll(components)
+ .replaceAll(r'\', r'\\');
+ }
+
resourceProvider = new MemoryResourceProvider();
- resourceProvider.newFolder('/empty');
- resourceProvider.newFolder('/tmp');
+ resourceProvider.newFolder(resourceProvider.convertPath('/empty'));
+ resourceProvider.newFolder(resourceProvider.convertPath('/tmp'));
resourceProvider.newFile(
- '/tmp/_sdkext',
- r'''
+ resourceProvider.convertPath('/tmp/_sdkext'),
+ '''
{
"dart:fox": "slippy.dart",
"dart:bear": "grizzly.dart",
- "dart:relative": "../relative.dart",
- "dart:deep": "deep/directory/file.dart",
+ "dart:relative": "${joinAndEscape(['..', 'relative.dart'])}",
+ "dart:deep": "${joinAndEscape(['deep', 'directory', 'file.dart'])}",
"fart:loudly": "nomatter.dart"
}''');
}
@@ -45,7 +50,9 @@
test_create_noSdkExtPackageMap() {
var resolver = new SdkExtUriResolver({
- 'fox': <Folder>[resourceProvider.getResource('/empty')]
+ 'fox': <Folder>[
+ resourceProvider.getFolder(resourceProvider.convertPath('/empty'))
+ ]
});
expect(resolver.length, equals(0));
}
@@ -57,20 +64,28 @@
test_create_sdkExtPackageMap() {
var resolver = new SdkExtUriResolver({
- 'fox': <Folder>[resourceProvider.getResource('/tmp')]
+ 'fox': <Folder>[
+ resourceProvider.newFolder(resourceProvider.convertPath('/tmp'))
+ ]
});
// We have four mappings.
expect(resolver.length, equals(4));
// Check that they map to the correct paths.
- expect(resolver['dart:fox'], equals("/tmp/slippy.dart"));
- expect(resolver['dart:bear'], equals("/tmp/grizzly.dart"));
- expect(resolver['dart:relative'], equals("/relative.dart"));
- expect(resolver['dart:deep'], equals("/tmp/deep/directory/file.dart"));
+ expect(resolver['dart:fox'],
+ equals(resourceProvider.convertPath('/tmp/slippy.dart')));
+ expect(resolver['dart:bear'],
+ equals(resourceProvider.convertPath('/tmp/grizzly.dart')));
+ expect(resolver['dart:relative'],
+ equals(resourceProvider.convertPath('/relative.dart')));
+ expect(resolver['dart:deep'],
+ equals(resourceProvider.convertPath('/tmp/deep/directory/file.dart')));
}
test_restoreAbsolute() {
var resolver = new SdkExtUriResolver({
- 'fox': <Folder>[resourceProvider.getResource('/tmp')]
+ 'fox': <Folder>[
+ resourceProvider.newFolder(resourceProvider.convertPath('/tmp'))
+ ]
});
var source = resolver.resolveAbsolute(Uri.parse('dart:fox'));
expect(source, isNotNull);
diff --git a/pkg/analyzer/test/source/test_all.dart b/pkg/analyzer/test/source/test_all.dart
index bca740b..98f3cde 100644
--- a/pkg/analyzer/test/source/test_all.dart
+++ b/pkg/analyzer/test/source/test_all.dart
@@ -4,9 +4,8 @@
library analyzer.test.source.test_all;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../utils.dart';
import 'analysis_options_provider_test.dart' as analysis_options_provider_test;
import 'config_test.dart' as config_test;
import 'embedder_test.dart' as embedder_test;
@@ -18,8 +17,7 @@
/// Utility for manually running all tests.
main() {
- initializeTestEnvironment();
- group('source', () {
+ defineReflectiveSuite(() {
analysis_options_provider_test.main();
config_test.main();
embedder_test.main();
@@ -28,5 +26,5 @@
package_map_resolver_test.main();
path_filter_test.main();
sdk_ext_test.main();
- });
+ }, name: 'source');
}
diff --git a/pkg/analyzer/test/src/abstract_single_unit.dart b/pkg/analyzer/test/src/abstract_single_unit.dart
index 428948e..550e2ff 100644
--- a/pkg/analyzer/test/src/abstract_single_unit.dart
+++ b/pkg/analyzer/test/src/abstract_single_unit.dart
@@ -10,7 +10,7 @@
import 'package:analyzer/src/dart/ast/utilities.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/source.dart';
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
import 'context/abstract_context.dart';
diff --git a/pkg/analyzer/test/src/context/abstract_context.dart b/pkg/analyzer/test/src/context/abstract_context.dart
index ba11f84..ae77652 100644
--- a/pkg/analyzer/test/src/context/abstract_context.dart
+++ b/pkg/analyzer/test/src/context/abstract_context.dart
@@ -18,7 +18,7 @@
import 'package:analyzer/task/model.dart';
import 'package:plugin/manager.dart';
import 'package:plugin/plugin.dart';
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
import 'mock_sdk.dart';
@@ -126,7 +126,8 @@
DartSdk createDartSdk() => new MockSdk(resourceProvider: resourceProvider);
Source newSource(String path, [String content = '']) {
- File file = resourceProvider.newFile(path, content);
+ File file =
+ resourceProvider.newFile(resourceProvider.convertPath(path), content);
return file.createSource();
}
diff --git a/pkg/analyzer/test/src/context/builder_test.dart b/pkg/analyzer/test/src/context/builder_test.dart
index 6de0ec6..fe5031c 100644
--- a/pkg/analyzer/test/src/context/builder_test.dart
+++ b/pkg/analyzer/test/src/context/builder_test.dart
@@ -7,9 +7,9 @@
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/bazel.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
@@ -18,18 +18,18 @@
import 'package:package_config/src/packages_impl.dart';
import 'package:path/path.dart' as path;
import 'package:plugin/src/plugin_impl.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../../embedder_tests.dart';
import '../../generated/test_support.dart';
-import '../../utils.dart';
import 'mock_sdk.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(ContextBuilderTest);
- defineReflectiveTests(EmbedderYamlLocatorTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ContextBuilderTest);
+ defineReflectiveTests(EmbedderYamlLocatorTest);
+ });
}
@reflectiveTest
@@ -65,6 +65,11 @@
*/
String defaultSdkPath = null;
+ Uri convertedDirectoryUri(String directoryPath) {
+ return new Uri.directory(resourceProvider.convertPath(directoryPath),
+ windows: pathContext.style == path.windows.style);
+ }
+
void createDefaultSdk(Folder sdkDir) {
defaultSdkPath = pathContext.join(sdkDir.path, 'default', 'sdk');
String librariesFilePath = pathContext.join(defaultSdkPath, 'lib',
@@ -77,8 +82,7 @@
"core": const LibraryInfo("core/core.dart"),
};
''');
- sdkManager =
- new DartSdkManager(defaultSdkPath, false, (_) => new MockSdk());
+ sdkManager = new DartSdkManager(defaultSdkPath, false);
builder = new ContextBuilder(resourceProvider, sdkManager, contentCache);
}
@@ -91,9 +95,8 @@
resourceProvider = new MemoryResourceProvider();
pathContext = resourceProvider.pathContext;
new MockSdk(resourceProvider: resourceProvider);
- sdkManager = new DartSdkManager('/', false, (_) {
- fail('Should not be used to create an SDK');
- });
+ sdkManager =
+ new DartSdkManager(resourceProvider.convertPath('/sdk'), false);
contentCache = new ContentCache();
builder = new ContextBuilder(resourceProvider, sdkManager, contentCache);
}
@@ -113,11 +116,11 @@
void test_convertPackagesToMap_packages() {
String fooName = 'foo';
- String fooPath = '/pkg/foo';
- Uri fooUri = new Uri.directory(fooPath);
+ String fooPath = resourceProvider.convertPath('/pkg/foo');
+ Uri fooUri = pathContext.toUri(fooPath);
String barName = 'bar';
- String barPath = '/pkg/bar';
- Uri barUri = new Uri.directory(barPath);
+ String barPath = resourceProvider.convertPath('/pkg/bar');
+ Uri barUri = pathContext.toUri(barPath);
MapPackages packages = new MapPackages({fooName: fooUri, barName: barUri});
Map<String, List<Folder>> result = builder.convertPackagesToMap(packages);
@@ -151,7 +154,7 @@
void test_createPackageMap_fromPackageDirectory_explicit() {
// Use a package directory that is outside the project directory.
- String rootPath = '/root';
+ String rootPath = resourceProvider.convertPath('/root');
String projectPath = pathContext.join(rootPath, 'project');
String packageDirPath = pathContext.join(rootPath, 'packages');
String fooName = 'foo';
@@ -168,13 +171,13 @@
expect(packages, isNotNull);
Map<String, Uri> map = packages.asMap();
expect(map, hasLength(2));
- expect(map[fooName], new Uri.directory(fooPath));
- expect(map[barName], new Uri.directory(barPath));
+ expect(map[fooName], convertedDirectoryUri(fooPath));
+ expect(map[barName], convertedDirectoryUri(barPath));
}
void test_createPackageMap_fromPackageDirectory_inRoot() {
// Use a package directory that is inside the project directory.
- String projectPath = '/root/project';
+ String projectPath = resourceProvider.convertPath('/root/project');
String packageDirPath = pathContext.join(projectPath, 'packages');
String fooName = 'foo';
String fooPath = pathContext.join(packageDirPath, fooName);
@@ -187,21 +190,23 @@
expect(packages, isNotNull);
Map<String, Uri> map = packages.asMap();
expect(map, hasLength(2));
- expect(map[fooName], new Uri.directory(fooPath));
- expect(map[barName], new Uri.directory(barPath));
+ expect(map[fooName], convertedDirectoryUri(fooPath));
+ expect(map[barName], convertedDirectoryUri(barPath));
}
void test_createPackageMap_fromPackageFile_explicit() {
// Use a package file that is outside the project directory's hierarchy.
- String rootPath = '/root';
+ String rootPath = resourceProvider.convertPath('/root');
String projectPath = pathContext.join(rootPath, 'project');
String packageFilePath = pathContext.join(rootPath, 'child', '.packages');
resourceProvider.newFolder(projectPath);
+ Uri fooUri = convertedDirectoryUri('/pkg/foo');
+ Uri barUri = convertedDirectoryUri('/pkg/bar');
createFile(
packageFilePath,
- r'''
-foo:/pkg/foo
-bar:/pkg/bar
+ '''
+foo:$fooUri
+bar:$barUri
''');
builder.defaultPackageFilePath = packageFilePath;
@@ -209,82 +214,83 @@
expect(packages, isNotNull);
Map<String, Uri> map = packages.asMap();
expect(map, hasLength(2));
- expect(map['foo'], new Uri.directory('/pkg/foo'));
- expect(map['bar'], new Uri.directory('/pkg/bar'));
+ expect(map['foo'], fooUri);
+ expect(map['bar'], barUri);
}
void test_createPackageMap_fromPackageFile_inParentOfRoot() {
// Use a package file that is inside the parent of the project directory.
- String rootPath = '/root';
+ String rootPath = resourceProvider.convertPath('/root');
String projectPath = pathContext.join(rootPath, 'project');
String packageFilePath = pathContext.join(rootPath, '.packages');
resourceProvider.newFolder(projectPath);
+ Uri fooUri = convertedDirectoryUri('/pkg/foo');
+ Uri barUri = convertedDirectoryUri('/pkg/bar');
createFile(
packageFilePath,
- r'''
-foo:/pkg/foo
-bar:/pkg/bar
+ '''
+foo:$fooUri
+bar:$barUri
''');
Packages packages = builder.createPackageMap(projectPath);
expect(packages, isNotNull);
Map<String, Uri> map = packages.asMap();
expect(map, hasLength(2));
- expect(map['foo'], new Uri.directory('/pkg/foo'));
- expect(map['bar'], new Uri.directory('/pkg/bar'));
+ expect(map['foo'], fooUri);
+ expect(map['bar'], barUri);
}
void test_createPackageMap_fromPackageFile_inRoot() {
// Use a package file that is inside the project directory.
- String rootPath = '/root';
+ String rootPath = resourceProvider.convertPath('/root');
String projectPath = pathContext.join(rootPath, 'project');
String packageFilePath = pathContext.join(projectPath, '.packages');
resourceProvider.newFolder(projectPath);
+ Uri fooUri = convertedDirectoryUri('/pkg/foo');
+ Uri barUri = convertedDirectoryUri('/pkg/bar');
createFile(
packageFilePath,
- r'''
-foo:/pkg/foo
-bar:/pkg/bar
+ '''
+foo:$fooUri
+bar:$barUri
''');
Packages packages = builder.createPackageMap(projectPath);
expect(packages, isNotNull);
Map<String, Uri> map = packages.asMap();
expect(map, hasLength(2));
- expect(map['foo'], new Uri.directory('/pkg/foo'));
- expect(map['bar'], new Uri.directory('/pkg/bar'));
+ expect(map['foo'], fooUri);
+ expect(map['bar'], barUri);
}
void test_createPackageMap_none() {
- String rootPath = '/root';
+ String rootPath = resourceProvider.convertPath('/root');
+ resourceProvider.newFolder(rootPath);
Packages packages = builder.createPackageMap(rootPath);
expect(packages, same(Packages.noPackages));
}
- void test_createSourceFactory_fileProvider() {
- String rootPath = '/root';
- Folder rootFolder = resourceProvider.getFolder(rootPath);
- createDefaultSdk(rootFolder);
- String projectPath = pathContext.join(rootPath, 'project');
- String packageFilePath = pathContext.join(projectPath, '.packages');
- String packageA = pathContext.join(rootPath, 'pkgs', 'a');
- String packageB = pathContext.join(rootPath, 'pkgs', 'b');
- createFile(
- packageFilePath,
- '''
-a:${pathContext.toUri(packageA)}
-b:${pathContext.toUri(packageB)}
-''');
+ void test_createSourceFactory_bazelWorkspace_fileProvider() {
+ String _p(String path) => resourceProvider.convertPath(path);
+
+ String projectPath = _p('/workspace/my/module');
+ resourceProvider.newFile(_p('/workspace/WORKSPACE'), '');
+ resourceProvider.newFolder(_p('/workspace/bazel-bin'));
+ resourceProvider.newFolder(_p('/workspace/bazel-genfiles'));
+ resourceProvider.newFolder(projectPath);
+
AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- UriResolver resolver = new ResourceUriResolver(resourceProvider);
- builder.fileResolverProvider = (folder) => resolver;
SourceFactoryImpl factory =
builder.createSourceFactory(projectPath, options);
- expect(factory.resolvers, contains(same(resolver)));
+ expect(factory.resolvers,
+ contains(predicate((r) => r is BazelFileUriResolver)));
+ expect(factory.resolvers,
+ contains(predicate((r) => r is BazelPackageUriResolver)));
}
void test_createSourceFactory_noProvider_packages_embedder_extensions() {
- String rootPath = '/root';
+ String rootPath = resourceProvider.convertPath('/root');
Folder rootFolder = resourceProvider.getFolder(rootPath);
createDefaultSdk(rootFolder);
String projectPath = pathContext.join(rootPath, 'project');
@@ -332,7 +338,7 @@
}
void test_createSourceFactory_noProvider_packages_embedder_noExtensions() {
- String rootPath = '/root';
+ String rootPath = resourceProvider.convertPath('/root');
Folder rootFolder = resourceProvider.getFolder(rootPath);
createDefaultSdk(rootFolder);
String projectPath = pathContext.join(rootPath, 'project');
@@ -374,7 +380,7 @@
}
void test_createSourceFactory_noProvider_packages_noEmbedder_noExtensions() {
- String rootPath = '/root';
+ String rootPath = resourceProvider.convertPath('/root');
Folder rootFolder = resourceProvider.getFolder(rootPath);
createDefaultSdk(rootFolder);
String projectPath = pathContext.join(rootPath, 'project');
@@ -393,26 +399,14 @@
Source dartSource = factory.forUri('dart:core');
expect(dartSource, isNotNull);
- expect(dartSource.fullName, '$defaultSdkPath/lib/core/core.dart');
+ expect(dartSource.fullName,
+ pathContext.join(defaultSdkPath, 'lib', 'core', 'core.dart'));
Source packageSource = factory.forUri('package:a/a.dart');
expect(packageSource, isNotNull);
expect(packageSource.fullName, pathContext.join(packageA, 'a.dart'));
}
- void test_createSourceFactory_packageProvider() {
- String rootPath = '/root';
- Folder rootFolder = resourceProvider.getFolder(rootPath);
- createDefaultSdk(rootFolder);
- String projectPath = pathContext.join(rootPath, 'project');
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- UriResolver resolver = new PackageMapUriResolver(resourceProvider, {});
- builder.packageResolverProvider = (folder) => resolver;
- SourceFactoryImpl factory =
- builder.createSourceFactory(projectPath, options);
- expect(factory.resolvers, contains(same(resolver)));
- }
-
void test_declareVariables_emptyMap() {
AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
Iterable<String> expected = context.declaredVariables.variableNames;
@@ -471,14 +465,38 @@
expect(sdk, isNotNull);
}
+ void test_findSdk_noPackageMap_html_spec() {
+ DartSdk sdk = builder.findSdk(null, new AnalysisOptionsImpl());
+ expect(sdk, isNotNull);
+ Source htmlSource = sdk.mapDartUri('dart:html');
+ expect(
+ htmlSource.fullName,
+ resourceProvider
+ .convertPath('/sdk/lib/html/dartium/html_dartium.dart'));
+ expect(htmlSource.exists(), isTrue);
+ }
+
+ void test_findSdk_noPackageMap_html_strong() {
+ DartSdk sdk =
+ builder.findSdk(null, new AnalysisOptionsImpl()..strongMode = true);
+ expect(sdk, isNotNull);
+ Source htmlSource = sdk.mapDartUri('dart:html');
+ expect(
+ htmlSource.fullName,
+ resourceProvider
+ .convertPath('/sdk/lib/html/dart2js/html_dart2js.dart'));
+ expect(htmlSource.exists(), isTrue);
+ }
+
void test_getAnalysisOptions_default_noOverrides() {
AnalysisOptionsImpl defaultOptions = new AnalysisOptionsImpl();
defaultOptions.enableGenericMethods = true;
builder.defaultOptions = defaultOptions;
AnalysisOptionsImpl expected = new AnalysisOptionsImpl();
expected.enableGenericMethods = true;
- String path = '/some/directory/path';
- String filePath = '$path/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}';
+ String path = resourceProvider.convertPath('/some/directory/path');
+ String filePath =
+ pathContext.join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
resourceProvider.newFile(
filePath,
'''
@@ -499,8 +517,9 @@
AnalysisOptionsImpl expected = new AnalysisOptionsImpl();
expected.enableSuperMixins = true;
expected.enableGenericMethods = true;
- String path = '/some/directory/path';
- String filePath = '$path/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}';
+ String path = resourceProvider.convertPath('/some/directory/path');
+ String filePath =
+ pathContext.join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
resourceProvider.newFile(
filePath,
'''
@@ -530,8 +549,9 @@
}
void test_getAnalysisOptions_invalid() {
- String path = '/some/directory/path';
- String filePath = '$path/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}';
+ String path = resourceProvider.convertPath('/some/directory/path');
+ String filePath =
+ pathContext.join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
resourceProvider.newFile(filePath, ';');
AnalysisEngine engine = AnalysisEngine.instance;
@@ -551,8 +571,9 @@
}
void test_getAnalysisOptions_noDefault_noOverrides() {
- String path = '/some/directory/path';
- String filePath = '$path/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}';
+ String path = resourceProvider.convertPath('/some/directory/path');
+ String filePath =
+ pathContext.join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
resourceProvider.newFile(
filePath,
'''
@@ -569,8 +590,9 @@
void test_getAnalysisOptions_noDefault_overrides() {
AnalysisOptionsImpl expected = new AnalysisOptionsImpl();
expected.enableSuperMixins = true;
- String path = '/some/directory/path';
- String filePath = '$path/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}';
+ String path = resourceProvider.convertPath('/some/directory/path');
+ String filePath =
+ pathContext.join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
resourceProvider.newFile(
filePath,
'''
@@ -585,8 +607,8 @@
}
void test_getOptionsFile_explicit() {
- String path = '/some/directory/path';
- String filePath = '/options/analysis.yaml';
+ String path = resourceProvider.convertPath('/some/directory/path');
+ String filePath = resourceProvider.convertPath('/options/analysis.yaml');
resourceProvider.newFile(filePath, '');
builder.defaultAnalysisOptionsFilePath = filePath;
@@ -596,10 +618,10 @@
}
void test_getOptionsFile_inParentOfRoot_new() {
- String parentPath = '/some/directory';
- String path = '$parentPath/path';
+ String parentPath = resourceProvider.convertPath('/some/directory');
+ String path = pathContext.join(parentPath, 'path');
String filePath =
- '$parentPath/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}';
+ pathContext.join(parentPath, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
resourceProvider.newFile(filePath, '');
File result = builder.getOptionsFile(path);
@@ -608,9 +630,10 @@
}
void test_getOptionsFile_inParentOfRoot_old() {
- String parentPath = '/some/directory';
- String path = '$parentPath/path';
- String filePath = '$parentPath/${AnalysisEngine.ANALYSIS_OPTIONS_FILE}';
+ String parentPath = resourceProvider.convertPath('/some/directory');
+ String path = pathContext.join(parentPath, 'path');
+ String filePath =
+ pathContext.join(parentPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE);
resourceProvider.newFile(filePath, '');
File result = builder.getOptionsFile(path);
@@ -619,8 +642,9 @@
}
void test_getOptionsFile_inRoot_new() {
- String path = '/some/directory/path';
- String filePath = '$path/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}';
+ String path = resourceProvider.convertPath('/some/directory/path');
+ String filePath =
+ pathContext.join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
resourceProvider.newFile(filePath, '');
File result = builder.getOptionsFile(path);
@@ -629,8 +653,9 @@
}
void test_getOptionsFile_inRoot_old() {
- String path = '/some/directory/path';
- String filePath = '$path/${AnalysisEngine.ANALYSIS_OPTIONS_FILE}';
+ String path = resourceProvider.convertPath('/some/directory/path');
+ String filePath =
+ pathContext.join(path, AnalysisEngine.ANALYSIS_OPTIONS_FILE);
resourceProvider.newFile(filePath, '');
File result = builder.getOptionsFile(path);
@@ -643,7 +668,6 @@
// TODO(brianwilkerson) Consider moving this to AnalysisOptionsImpl.==.
expect(actual.analyzeFunctionBodiesPredicate,
same(expected.analyzeFunctionBodiesPredicate));
- expect(actual.cacheSize, expected.cacheSize);
expect(actual.dart2jsHint, expected.dart2jsHint);
expect(actual.enableAssertMessage, expected.enableAssertMessage);
expect(actual.enableStrictCallChecks, expected.enableStrictCallChecks);
@@ -663,6 +687,7 @@
expect(actual.implicitCasts, expected.implicitCasts);
expect(actual.implicitDynamic, expected.implicitDynamic);
expect(actual.trackCacheDependencies, expected.trackCacheDependencies);
+ expect(actual.disableCacheFlushing, expected.disableCacheFlushing);
expect(actual.finerGrainedInvalidation, expected.finerGrainedInvalidation);
}
diff --git a/pkg/analyzer/test/src/context/cache_test.dart b/pkg/analyzer/test/src/context/cache_test.dart
index d6af6ce..e91b8d9 100644
--- a/pkg/analyzer/test/src/context/cache_test.dart
+++ b/pkg/analyzer/test/src/context/cache_test.dart
@@ -16,21 +16,21 @@
import 'package:analyzer/src/generated/utilities_collection.dart';
import 'package:analyzer/src/task/model.dart';
import 'package:analyzer/task/model.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:typed_mock/typed_mock.dart';
-import 'package:unittest/unittest.dart';
import '../../generated/test_support.dart';
-import '../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(AnalysisCacheTest);
- defineReflectiveTests(CacheEntryTest);
- defineReflectiveTests(CacheFlushManagerTest);
- defineReflectiveTests(SdkCachePartitionTest);
- defineReflectiveTests(UniversalCachePartitionTest);
- defineReflectiveTests(ResultDataTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AnalysisCacheTest);
+ defineReflectiveTests(CacheEntryTest);
+ defineReflectiveTests(CacheFlushManagerTest);
+ defineReflectiveTests(SdkCachePartitionTest);
+ defineReflectiveTests(UniversalCachePartitionTest);
+ defineReflectiveTests(ResultDataTest);
+ });
}
AnalysisCache createCache({AnalysisContext context}) {
@@ -1287,7 +1287,10 @@
}
class _InternalAnalysisContextMock extends TypedMock
- implements InternalAnalysisContext {}
+ implements InternalAnalysisContext {
+ @override
+ final AnalysisOptions analysisOptions = new AnalysisOptionsImpl();
+}
/**
* Keep the given [keepDescriptor], invalidate all the other results.
diff --git a/pkg/analyzer/test/src/context/context_test.dart b/pkg/analyzer/test/src/context/context_test.dart
index 7da5f3f..d5f9766 100644
--- a/pkg/analyzer/test/src/context/context_test.dart
+++ b/pkg/analyzer/test/src/context/context_test.dart
@@ -31,8 +31,8 @@
import 'package:analyzer/task/general.dart';
import 'package:analyzer/task/model.dart';
import 'package:html/dom.dart' show Document;
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import 'package:watcher/src/utils.dart';
import '../../generated/engine_test.dart';
@@ -41,9 +41,10 @@
import 'abstract_context.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(AnalysisContextImplTest);
- defineReflectiveTests(LimitedInvalidateTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AnalysisContextImplTest);
+ defineReflectiveTests(LimitedInvalidateTest);
+ });
}
@reflectiveTest
@@ -319,7 +320,7 @@
}
void test_applyChanges_changedSource_updateModificationTime() {
- String path = '/test.dart';
+ String path = resourceProvider.convertPath('/test.dart');
File file = resourceProvider.newFile(path, 'var V = 1;');
Source source = file.createSource();
context.applyChanges(new ChangeSet()..addedSource(source));
@@ -1116,7 +1117,7 @@
String newCode = r'''
import 'dart:async';
''';
- String path = '/test.dart';
+ String path = resourceProvider.convertPath('/test.dart');
Source source = resourceProvider.newFile(path, oldCode).createSource();
context.applyChanges(new ChangeSet()..addedSource(source));
context.resolveCompilationUnit2(source, source);
@@ -1142,7 +1143,7 @@
import 'dart:async';
main() {}
''';
- String path = '/test.dart';
+ String path = resourceProvider.convertPath('/test.dart');
Source source = resourceProvider.newFile(path, oldCode).createSource();
context.applyChanges(new ChangeSet()..addedSource(source));
context.resolveCompilationUnit2(source, source);
@@ -1751,7 +1752,8 @@
// 3. Notify the context, and because this is the first time when we
// update the content cache, we don't know "originalContents".
// The source must be invalidated, because it has different contents now.
- resourceProvider.updateFile('/test.dart', newCode);
+ resourceProvider.updateFile(
+ resourceProvider.convertPath('/test.dart'), newCode);
contentCache.setContents(source, newCode);
context.handleContentsChanged(source, null, newCode, true);
expect(context.getResolvedCompilationUnit2(source, source), isNull);
@@ -1900,7 +1902,7 @@
void test_parseCompilationUnit_nonExistentSource() {
Source source = newSource('/test.dart');
- resourceProvider.deleteFile('/test.dart');
+ resourceProvider.deleteFile(resourceProvider.convertPath('/test.dart'));
try {
context.parseCompilationUnit(source);
fail("Expected AnalysisException because file does not exist");
@@ -2358,9 +2360,13 @@
addSource('/test.dart', 'main() {}');
_analyzeAll_assertFinished();
// verify
- expect(libraryElementUris, contains('file:///test.dart'));
- expect(parsedUnitUris, contains('file:///test.dart'));
- expect(resolvedUnitUris, contains('file:///test.dart'));
+ String testUri = resourceProvider
+ .getFile(resourceProvider.convertPath('/test.dart'))
+ .toUri()
+ .toString();
+ expect(libraryElementUris, contains(testUri));
+ expect(parsedUnitUris, contains(testUri));
+ expect(resolvedUnitUris, contains(testUri));
}
void test_performAnalysisTask_switchPackageVersion() {
@@ -2537,12 +2543,10 @@
void test_setAnalysisOptions() {
AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- options.cacheSize = 42;
options.dart2jsHint = false;
options.hint = false;
context.analysisOptions = options;
AnalysisOptions result = context.analysisOptions;
- expect(result.cacheSize, options.cacheSize);
expect(result.dart2jsHint, options.dart2jsHint);
expect(result.hint, options.hint);
}
@@ -2714,8 +2718,10 @@
void test_validateCacheConsistency_deletedFile() {
MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
- var fileA = resourceProvider.newFile('/a.dart', "");
- var fileB = resourceProvider.newFile('/b.dart', "import 'a.dart';");
+ String pathA = resourceProvider.convertPath('/a.dart');
+ String pathB = resourceProvider.convertPath('/b.dart');
+ var fileA = resourceProvider.newFile(pathA, "");
+ var fileB = resourceProvider.newFile(pathB, "import 'a.dart';");
Source sourceA = fileA.createSource();
Source sourceB = fileB.createSource();
context.applyChanges(
@@ -2723,7 +2729,7 @@
// analyze everything
_analyzeAll_assertFinished();
// delete a.dart
- resourceProvider.deleteFile('/a.dart');
+ resourceProvider.deleteFile(pathA);
// analysis should eventually stop
_analyzeAll_assertFinished();
}
@@ -2732,7 +2738,6 @@
int maxCacheSize = 4;
AnalysisOptionsImpl options =
new AnalysisOptionsImpl.from(context.analysisOptions);
- options.cacheSize = maxCacheSize;
context.analysisOptions = options;
int sourceCount = maxCacheSize + 2;
List<Source> sources = <Source>[];
@@ -3676,7 +3681,7 @@
''');
_performPendingAnalysisTasks();
resourceProvider.updateFile(
- '/a.dart',
+ resourceProvider.convertPath('/a.dart'),
r'''
class A2 {}
class B {}
diff --git a/pkg/analyzer/test/src/context/mock_sdk.dart b/pkg/analyzer/test/src/context/mock_sdk.dart
index b864e53..464dec0 100644
--- a/pkg/analyzer/test/src/context/mock_sdk.dart
+++ b/pkg/analyzer/test/src/context/mock_sdk.dart
@@ -20,7 +20,9 @@
"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"),
+ "html": const LibraryInfo(
+ "html/dartium/html_dartium.dart",
+ dart2jsPath: "html/dart2js/html_dart2js.dart"),
"math": const LibraryInfo("math/math.dart"),
"_foreign_helper": const LibraryInfo("_internal/js_runtime/lib/foreign_helper.dart"),
};
@@ -265,7 +267,15 @@
{}
''');
-const _MockSdkLibrary _LIB_HTML = const _MockSdkLibrary(
+const _MockSdkLibrary _LIB_HTML_DART2JS = const _MockSdkLibrary(
+ 'dart:html',
+ '$sdkRoot/lib/html/dart2js/html_dart2js.dart',
+ '''
+library dart.html;
+class HtmlElement {}
+''');
+
+const _MockSdkLibrary _LIB_HTML_DARTIUM = const _MockSdkLibrary(
'dart:html',
'$sdkRoot/lib/html/dartium/html_dartium.dart',
'''
@@ -303,7 +313,8 @@
_LIB_CONVERT,
_LIB_FOREIGN_HELPER,
_LIB_MATH,
- _LIB_HTML,
+ _LIB_HTML_DART2JS,
+ _LIB_HTML_DARTIUM,
];
class MockSdk implements DartSdk {
@@ -339,18 +350,21 @@
*/
PackageBundle _bundle;
- MockSdk({bool dartAsync: true, resource.ResourceProvider resourceProvider})
+ MockSdk(
+ {bool dartAsync: true, resource.MemoryResourceProvider resourceProvider})
: provider = resourceProvider ?? new resource.MemoryResourceProvider(),
sdkLibraries = dartAsync ? _LIBRARIES : [_LIB_CORE],
uriMap = dartAsync ? FULL_URI_MAP : NO_ASYNC_URI_MAP {
for (_MockSdkLibrary library in sdkLibraries) {
- provider.newFile(library.path, library.content);
+ provider.newFile(provider.convertPath(library.path), library.content);
library.parts.forEach((String path, String content) {
- provider.newFile(path, content);
+ provider.newFile(provider.convertPath(path), content);
});
}
provider.newFile(
- '/_internal/sdk_library_metadata/lib/libraries.dart', librariesContent);
+ provider.convertPath(
+ '$sdkRoot/lib/_internal/sdk_library_metadata/lib/libraries.dart'),
+ librariesContent);
}
@override
@@ -381,7 +395,8 @@
String libraryPath = library.path;
if (filePath.replaceAll('\\', '/') == libraryPath) {
try {
- resource.File file = provider.getResource(uri.path);
+ resource.File file =
+ provider.getResource(provider.convertPath(filePath));
Uri dartUri = Uri.parse(library.shortName);
return file.createSource(dartUri);
} catch (exception) {
@@ -392,7 +407,8 @@
String pathInLibrary = filePath.substring(libraryPath.length + 1);
String path = '${library.shortName}/$pathInLibrary';
try {
- resource.File file = provider.getResource(uri.path);
+ resource.File file =
+ provider.getResource(provider.convertPath(filePath));
Uri dartUri = new Uri(scheme: 'dart', path: path);
return file.createSource(dartUri);
} catch (exception) {
@@ -429,11 +445,10 @@
Source mapDartUri(String dartUri) {
String path = uriMap[dartUri];
if (path != null) {
- resource.File file = provider.getResource(path);
+ resource.File file = provider.getResource(provider.convertPath(path));
Uri uri = new Uri(scheme: 'dart', path: dartUri.substring(5));
return file.createSource(uri);
}
-
// If we reach here then we tried to use a dartUri that's not in the
// table above.
return null;
@@ -447,6 +462,7 @@
assert(_analysisContext == null);
String path = FULL_URI_MAP[uri];
assert(path != null);
+ path = provider.convertPath(path);
String content = provider.getFile(path).readAsStringSync();
String newContent = updateContent(content);
provider.updateFile(path, newContent);
@@ -482,6 +498,9 @@
@override
bool get isVmLibrary => throw new UnimplementedError();
+
+ @override
+ List<String> getPatches(int platform) => const <String>[];
}
/**
diff --git a/pkg/analyzer/test/src/context/test_all.dart b/pkg/analyzer/test/src/context/test_all.dart
index d0f1619..ec38b52 100644
--- a/pkg/analyzer/test/src/context/test_all.dart
+++ b/pkg/analyzer/test/src/context/test_all.dart
@@ -4,19 +4,17 @@
library analyzer.test.src.context.test_all;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../utils.dart';
import 'builder_test.dart' as builder_test;
import 'cache_test.dart' as cache_test;
import 'context_test.dart' as context_test;
/// Utility for manually running all tests.
main() {
- initializeTestEnvironment();
- group('context tests', () {
+ defineReflectiveSuite(() {
builder_test.main();
cache_test.main();
context_test.main();
- });
+ }, name: 'context');
}
diff --git a/pkg/analyzer/test/src/dart/ast/test_all.dart b/pkg/analyzer/test/src/dart/ast/test_all.dart
index f0648c4..da75f77 100644
--- a/pkg/analyzer/test/src/dart/ast/test_all.dart
+++ b/pkg/analyzer/test/src/dart/ast/test_all.dart
@@ -4,15 +4,13 @@
library analyzer.test.src.dart.ast.test_all;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../../utils.dart';
import 'utilities_test.dart' as utilities;
/// Utility for manually running all tests.
main() {
- initializeTestEnvironment();
- group('ast tests', () {
+ defineReflectiveSuite(() {
utilities.main();
- });
+ }, name: 'ast');
}
diff --git a/pkg/analyzer/test/src/dart/ast/utilities_test.dart b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
index a48fb6e..7e83cf7 100644
--- a/pkg/analyzer/test/src/dart/ast/utilities_test.dart
+++ b/pkg/analyzer/test/src/dart/ast/utilities_test.dart
@@ -16,20 +16,20 @@
import 'package:analyzer/src/generated/testing/ast_factory.dart';
import 'package:analyzer/src/generated/testing/element_factory.dart';
import 'package:analyzer/src/generated/testing/token_factory.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../../../generated/parser_test.dart' show ParserTestCase;
import '../../../generated/test_support.dart';
-import '../../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(ConstantEvaluatorTest);
- defineReflectiveTests(NodeLocatorTest);
- defineReflectiveTests(NodeLocator2Test);
- defineReflectiveTests(ResolutionCopierTest);
- defineReflectiveTests(ToSourceVisitorTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConstantEvaluatorTest);
+ defineReflectiveTests(NodeLocatorTest);
+ defineReflectiveTests(NodeLocator2Test);
+ defineReflectiveTests(ResolutionCopierTest);
+ defineReflectiveTests(ToSourceVisitorTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
index 9de8247..39ded27 100644
--- a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
@@ -21,18 +21,18 @@
import 'package:analyzer/src/generated/testing/test_type_provider.dart';
import 'package:analyzer/src/task/dart.dart';
import 'package:path/path.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../../../generated/resolver_test_case.dart';
import '../../../generated/test_support.dart';
-import '../../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(ConstantValueComputerTest);
- defineReflectiveTests(ConstantVisitorTest);
- defineReflectiveTests(StrongConstantValueComputerTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConstantValueComputerTest);
+ defineReflectiveTests(ConstantVisitorTest);
+ defineReflectiveTests(StrongConstantValueComputerTest);
+ });
}
/**
diff --git a/pkg/analyzer/test/src/dart/constant/test_all.dart b/pkg/analyzer/test/src/dart/constant/test_all.dart
index a6eb5b6..6eea24d 100644
--- a/pkg/analyzer/test/src/dart/constant/test_all.dart
+++ b/pkg/analyzer/test/src/dart/constant/test_all.dart
@@ -4,19 +4,17 @@
library analyzer.test.src.dart.constant.test_all;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../../utils.dart';
import 'evaluation_test.dart' as evaluation;
import 'utilities_test.dart' as utilities;
import 'value_test.dart' as value;
/// Utility for manually running all tests.
main() {
- initializeTestEnvironment();
- group('constant tests', () {
+ defineReflectiveSuite(() {
evaluation.main();
utilities.main();
value.main();
- });
+ }, name: 'constant');
}
diff --git a/pkg/analyzer/test/src/dart/constant/utilities_test.dart b/pkg/analyzer/test/src/dart/constant/utilities_test.dart
index aa9bd5c..6da39c1 100644
--- a/pkg/analyzer/test/src/dart/constant/utilities_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/utilities_test.dart
@@ -19,17 +19,17 @@
import 'package:analyzer/src/generated/testing/test_type_provider.dart';
import 'package:analyzer/src/generated/utilities_collection.dart';
import 'package:analyzer/src/task/dart.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../../../generated/engine_test.dart';
import '../../../generated/test_support.dart';
-import '../../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(ConstantFinderTest);
- defineReflectiveTests(ReferenceFinderTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConstantFinderTest);
+ defineReflectiveTests(ReferenceFinderTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analyzer/test/src/dart/constant/value_test.dart b/pkg/analyzer/test/src/dart/constant/value_test.dart
index 1323714..7e79afa 100644
--- a/pkg/analyzer/test/src/dart/constant/value_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/value_test.dart
@@ -7,15 +7,15 @@
import 'package:analyzer/src/generated/constant.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/testing/test_type_provider.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../../../generated/test_support.dart';
-import '../../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(DartObjectImplTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(DartObjectImplTest);
+ });
}
const Matcher isEvaluationException = const isInstanceOf<EvaluationException>();
diff --git a/pkg/analyzer/test/src/dart/element/element_test.dart b/pkg/analyzer/test/src/dart/element/element_test.dart
index a1f72b8..394fcd5 100644
--- a/pkg/analyzer/test/src/dart/element/element_test.dart
+++ b/pkg/analyzer/test/src/dart/element/element_test.dart
@@ -17,34 +17,34 @@
import 'package:analyzer/src/generated/testing/ast_factory.dart';
import 'package:analyzer/src/generated/testing/element_factory.dart';
import 'package:analyzer/src/generated/testing/test_type_provider.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../../../generated/analysis_context_factory.dart'
show AnalysisContextHelper;
import '../../../generated/resolver_test_case.dart';
import '../../../generated/test_support.dart';
-import '../../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(ElementAnnotationImplTest);
- defineReflectiveTests(FieldElementImplTest);
- defineReflectiveTests(FunctionTypeImplTest);
- defineReflectiveTests(InterfaceTypeImplTest);
- defineReflectiveTests(LocalVariableElementImplTest);
- defineReflectiveTests(TypeParameterTypeImplTest);
- defineReflectiveTests(VoidTypeImplTest);
- defineReflectiveTests(ClassElementImplTest);
- defineReflectiveTests(CompilationUnitElementImplTest);
- defineReflectiveTests(ElementLocationImplTest);
- defineReflectiveTests(ElementImplTest);
- defineReflectiveTests(LibraryElementImplTest);
- defineReflectiveTests(MethodElementImplTest);
- defineReflectiveTests(MultiplyDefinedElementImplTest);
- defineReflectiveTests(ParameterElementImplTest);
- defineReflectiveTests(PropertyAccessorElementImplTest);
- defineReflectiveTests(TopLevelVariableElementImplTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ElementAnnotationImplTest);
+ defineReflectiveTests(FieldElementImplTest);
+ defineReflectiveTests(FunctionTypeImplTest);
+ defineReflectiveTests(InterfaceTypeImplTest);
+ defineReflectiveTests(LocalVariableElementImplTest);
+ defineReflectiveTests(TypeParameterTypeImplTest);
+ defineReflectiveTests(VoidTypeImplTest);
+ defineReflectiveTests(ClassElementImplTest);
+ defineReflectiveTests(CompilationUnitElementImplTest);
+ defineReflectiveTests(ElementLocationImplTest);
+ defineReflectiveTests(ElementImplTest);
+ defineReflectiveTests(LibraryElementImplTest);
+ defineReflectiveTests(MethodElementImplTest);
+ defineReflectiveTests(MultiplyDefinedElementImplTest);
+ defineReflectiveTests(ParameterElementImplTest);
+ defineReflectiveTests(PropertyAccessorElementImplTest);
+ defineReflectiveTests(TopLevelVariableElementImplTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analyzer/test/src/dart/element/test_all.dart b/pkg/analyzer/test/src/dart/element/test_all.dart
index 1997466..2577db8 100644
--- a/pkg/analyzer/test/src/dart/element/test_all.dart
+++ b/pkg/analyzer/test/src/dart/element/test_all.dart
@@ -4,15 +4,13 @@
library analyzer.test.src.dart.element.test_all;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../../utils.dart';
import 'element_test.dart' as element;
/// Utility for manually running all tests.
main() {
- initializeTestEnvironment();
- group('element tests', () {
+ defineReflectiveSuite(() {
element.main();
- });
+ }, name: 'element');
}
diff --git a/pkg/analyzer/test/src/dart/sdk/patch_test.dart b/pkg/analyzer/test/src/dart/sdk/patch_test.dart
new file mode 100644
index 0000000..dc3a903
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/sdk/patch_test.dart
@@ -0,0 +1,837 @@
+// 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:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/file_system/memory_file_system.dart';
+import 'package:analyzer/src/dart/sdk/patch.dart';
+import 'package:analyzer/src/dart/sdk/sdk.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/util/fast_uri.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(SdkPatcherTest);
+ });
+}
+
+@reflectiveTest
+class SdkPatcherTest {
+ MemoryResourceProvider provider = new MemoryResourceProvider();
+ Folder sdkFolder;
+ FolderBasedDartSdk sdk;
+
+ SdkPatcher patcher = new SdkPatcher();
+ RecordingErrorListener listener = new RecordingErrorListener();
+
+ void setUp() {
+ sdkFolder = provider.getFolder(_p('/sdk'));
+ }
+
+ test_class_constructor_append_fail_notPrivate_named() {
+ expect(() {
+ _doTopLevelPatching(
+ r'''
+class C {}
+''',
+ r'''
+@patch
+class C {
+ C.named() {}
+}
+''');
+ }, throwsArgumentError);
+ }
+
+ test_class_constructor_append_fail_notPrivate_unnamed() {
+ expect(() {
+ _doTopLevelPatching(
+ r'''
+class C {}
+''',
+ r'''
+@patch
+class C {
+ C() {}
+}
+''');
+ }, throwsArgumentError);
+ }
+
+ test_class_constructor_append_named() {
+ CompilationUnit unit = _doTopLevelPatching(
+ r'''
+class C {
+}
+''',
+ r'''
+@patch
+class C {
+ C._named() {}
+}
+''');
+ _assertUnitCode(unit, 'class C {C._named() {}}');
+ ClassDeclaration clazz = unit.declarations[0];
+ ConstructorDeclaration constructor = clazz.members[0];
+ _assertPrevNextToken(clazz.leftBracket, constructor.beginToken);
+ _assertPrevNextToken(constructor.endToken, clazz.rightBracket);
+ }
+
+ test_class_constructor_append_unnamed() {
+ CompilationUnit unit = _doTopLevelPatching(
+ r'''
+class _C {
+}
+''',
+ r'''
+@patch
+class _C {
+ _C() {}
+}
+''');
+ _assertUnitCode(unit, 'class _C {_C() {}}');
+ ClassDeclaration clazz = unit.declarations[0];
+ ConstructorDeclaration constructor = clazz.members[0];
+ _assertPrevNextToken(clazz.leftBracket, constructor.beginToken);
+ _assertPrevNextToken(constructor.endToken, clazz.rightBracket);
+ }
+
+ test_class_constructor_patch() {
+ CompilationUnit unit = _doTopLevelPatching(
+ r'''
+class C {
+ external C.named();
+}
+''',
+ r'''
+@patch
+class C {
+ @patch
+ C.named() {
+ print(42);
+ }
+}
+''');
+ _assertUnitCode(unit, 'class C {C.named() {print(42);}}');
+ ClassDeclaration clazz = unit.declarations[0];
+ ConstructorDeclaration constructor = clazz.members[0];
+ expect(constructor.externalKeyword, isNull);
+ _assertPrevNextToken(
+ constructor.parameters.endToken, constructor.body.beginToken);
+ _assertPrevNextToken(constructor.endToken, clazz.rightBracket);
+ }
+
+ test_class_constructor_patch_fail_baseFactory_patchGenerative() {
+ expect(() {
+ _doTopLevelPatching(
+ r'''
+class C {
+ external factory C.named();
+}
+''',
+ r'''
+@patch
+class C {
+ @patch
+ C.named() {}
+}
+''');
+ }, throwsArgumentError);
+ }
+
+ test_class_constructor_patch_fail_baseGenerative_patchFactory() {
+ expect(() {
+ _doTopLevelPatching(
+ r'''
+class C {
+ external C.named();
+}
+''',
+ r'''
+@patch
+class C {
+ @patch
+ factory C.named() {}
+}
+''');
+ }, throwsArgumentError);
+ }
+
+ test_class_constructor_patch_fail_hasInitializers() {
+ expect(() {
+ _doTopLevelPatching(
+ r'''
+class C {
+ int f;
+ external C.named() : f = 1;
+}
+''',
+ r'''
+@patch
+class C {
+ @patch
+ C.named() : f = 2 {}
+}
+''');
+ }, throwsArgumentError);
+ }
+
+ test_class_constructor_patch_fail_noExternalKeyword() {
+ expect(() {
+ _doTopLevelPatching(
+ r'''
+class C {
+ C.named();
+}
+''',
+ r'''
+@patch
+class C {
+ @patch
+ C.named() {}
+}
+''');
+ }, throwsArgumentError);
+ }
+
+ test_class_constructor_patch_initializers() {
+ CompilationUnit unit = _doTopLevelPatching(
+ r'''
+class C {
+ int f;
+ external C.named();
+}
+''',
+ r'''
+@patch
+class C {
+ @patch
+ C.named() : f = 2 {
+ print(42);
+ }
+}
+''');
+ _assertUnitCode(unit, 'class C {int f; C.named() : f = 2 {print(42);}}');
+ ClassDeclaration clazz = unit.declarations[0];
+ ConstructorDeclaration constructor = clazz.members[1];
+ expect(constructor.externalKeyword, isNull);
+ _assertPrevNextToken(constructor.parameters.endToken,
+ constructor.initializers.beginToken.previous);
+ _assertPrevNextToken(constructor.endToken, clazz.rightBracket);
+ }
+
+ test_class_field_append() {
+ CompilationUnit unit = _doTopLevelPatching(
+ r'''
+class C {
+ void a() {}
+}
+''',
+ r'''
+@patch
+class C {
+ int _b = 42;
+}
+''');
+ _assertUnitCode(unit, 'class C {void a() {} int _b = 42;}');
+ ClassDeclaration clazz = unit.declarations[0];
+ MethodDeclaration a = clazz.members[0];
+ FieldDeclaration b = clazz.members[1];
+ _assertPrevNextToken(a.endToken, b.beginToken);
+ _assertPrevNextToken(b.endToken, clazz.rightBracket);
+ }
+
+ test_class_field_append_fail_moreThanOne() {
+ expect(() {
+ _doTopLevelPatching(
+ r'''
+class A {}
+''',
+ r'''
+@patch
+class A {
+ @patch
+ int _f1, _f2;
+}
+''');
+ }, throwsArgumentError);
+ }
+
+ test_class_field_append_fail_notPrivate() {
+ expect(() {
+ _doTopLevelPatching(
+ r'''
+class A {}
+''',
+ r'''
+@patch
+class A {
+ @patch
+ int b;
+}
+''');
+ }, throwsArgumentError);
+ }
+
+ test_class_field_append_publicInPrivateClass() {
+ CompilationUnit unit = _doTopLevelPatching(
+ r'''
+class _C {
+ void a() {}
+}
+''',
+ r'''
+@patch
+class _C {
+ int b = 42;
+}
+''');
+ _assertUnitCode(unit, 'class _C {void a() {} int b = 42;}');
+ ClassDeclaration clazz = unit.declarations[0];
+ MethodDeclaration a = clazz.members[0];
+ FieldDeclaration b = clazz.members[1];
+ _assertPrevNextToken(a.endToken, b.beginToken);
+ _assertPrevNextToken(b.endToken, clazz.rightBracket);
+ }
+
+ test_class_field_patch_fail() {
+ expect(() {
+ _doTopLevelPatching(
+ r'''
+class A {}
+''',
+ r'''
+@patch
+class A {
+ @patch
+ int _f;
+}
+''');
+ }, throwsArgumentError);
+ }
+
+ test_class_getter_append() {
+ CompilationUnit unit = _doTopLevelPatching(
+ r'''
+class C {
+ void a() {}
+}
+''',
+ r'''
+@patch
+class C {
+ int get _b => 2;
+}
+''');
+ _assertUnitCode(unit, 'class C {void a() {} int get _b => 2;}');
+ }
+
+ test_class_method_append() {
+ CompilationUnit unit = _doTopLevelPatching(
+ r'''
+class C {
+ void a() {}
+}
+''',
+ r'''
+@patch
+class C {
+ void _b() {}
+ void _c() {}
+}
+''');
+ _assertUnitCode(unit, 'class C {void a() {} void _b() {} void _c() {}}');
+ ClassDeclaration clazz = unit.declarations[0];
+ MethodDeclaration a = clazz.members[0];
+ MethodDeclaration b = clazz.members[1];
+ MethodDeclaration c = clazz.members[2];
+ _assertPrevNextToken(a.endToken, b.beginToken);
+ _assertPrevNextToken(b.endToken, c.beginToken);
+ _assertPrevNextToken(c.endToken, clazz.rightBracket);
+ }
+
+ test_class_method_fail_notPrivate() {
+ expect(() {
+ _doTopLevelPatching(
+ r'''
+class A {}
+''',
+ r'''
+@patch
+class A {
+ void m() {}
+}
+''');
+ }, throwsArgumentError);
+ }
+
+ test_class_method_patch() {
+ CompilationUnit unit = _doTopLevelPatching(
+ r'''
+class C {
+ external int m();
+}
+''',
+ r'''
+@patch
+class C {
+ @patch
+ int m() => 42;
+}
+''');
+ _assertUnitCode(unit, 'class C {int m() => 42;}');
+ ClassDeclaration clazz = unit.declarations[0];
+ MethodDeclaration m = clazz.members[0];
+ expect(m.externalKeyword, isNull);
+ _assertPrevNextToken(m.parameters.rightParenthesis, m.body.beginToken);
+ _assertPrevNextToken(m.body.endToken, clazz.rightBracket);
+ }
+
+ test_class_method_patch_fail_noExternalKeyword() {
+ expect(() {
+ _doTopLevelPatching(
+ r'''
+class C {
+ int m();
+}
+''',
+ r'''
+@patch
+class C {
+ @patch
+ int m() => 42;
+}
+''');
+ }, throwsArgumentError);
+ }
+
+ test_class_setter_append() {
+ CompilationUnit unit = _doTopLevelPatching(
+ r'''
+class C {
+ void a() {}
+}
+''',
+ r'''
+@patch
+class C {
+ void set _b(_) {}
+}
+''');
+ _assertUnitCode(unit, 'class C {void a() {} void set _b(_) {}}');
+ }
+
+ test_directive_fail_export() {
+ expect(() {
+ _doTopLevelPatching(
+ r'''
+import 'a.dart';
+''',
+ r'''
+export 'c.dart';
+''');
+ }, throwsArgumentError);
+ }
+
+ test_directive_import() {
+ CompilationUnit unit = _doTopLevelPatching(
+ r'''
+import 'a.dart';
+part 'b.dart';
+int bar() => 0;
+''',
+ r'''
+import 'c.dart';
+''');
+ _assertUnitCode(unit,
+ "import 'a.dart'; part 'b.dart'; import 'c.dart'; int bar() => 0;");
+ }
+
+ test_fail_noSuchLibrary() {
+ expect(() {
+ _setSdkLibraries('const LIBRARIES = const {};');
+ _createSdk();
+ File file = provider.newFile(_p('/sdk/lib/test/test.dart'), '');
+ Source source = file.createSource(FastUri.parse('dart:test'));
+ CompilationUnit unit = SdkPatcher.parse(source, true, listener);
+ patcher.patch(sdk, SdkLibraryImpl.VM_PLATFORM, listener, source, unit);
+ }, throwsArgumentError);
+ }
+
+ test_fail_patchFileDoesNotExist() {
+ expect(() {
+ _setSdkLibraries(r'''
+final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
+ 'test' : const LibraryInfo(
+ 'test/test.dart',
+ patches: {VM_PLATFORM: ['does_not_exists.dart']}),
+};''');
+ _createSdk();
+ File file = provider.newFile(_p('/sdk/lib/test/test.dart'), '');
+ Source source = file.createSource(FastUri.parse('dart:test'));
+ CompilationUnit unit = SdkPatcher.parse(source, true, listener);
+ patcher.patch(sdk, SdkLibraryImpl.VM_PLATFORM, listener, source, unit);
+ }, throwsArgumentError);
+ }
+
+ test_internal_allowNewPublicNames() {
+ _setSdkLibraries(r'''
+final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
+ '_internal' : const LibraryInfo(
+ 'internal/internal.dart',
+ patches: {VM_PLATFORM: ['internal/internal_patch.dart']}),
+};''');
+ File file = provider.newFile(
+ _p('/sdk/lib/internal/internal.dart'),
+ r'''
+library dart._internal;
+class A {}
+class B {
+ B();
+}
+''');
+ provider.newFile(
+ _p('/sdk/lib/internal/internal_patch.dart'),
+ r'''
+@patch
+class B {
+ int newField;
+ B.newConstructor();
+ int newMethod() => 1;
+}
+class NewClass {}
+int newFunction() => 2;
+''');
+
+ _createSdk();
+
+ Source source = file.createSource(FastUri.parse('dart:_internal'));
+ CompilationUnit unit = SdkPatcher.parse(source, true, listener);
+ patcher.patch(sdk, SdkLibraryImpl.VM_PLATFORM, listener, source, unit);
+ _assertUnitCode(
+ unit,
+ 'library dart._internal; class A {} '
+ 'class B {B(); int newField; B.newConstructor(); int newMethod() => 1;} '
+ 'class NewClass {} int newFunction() => 2;');
+ }
+
+ test_part() {
+ String baseLibCode = r'''
+library test;
+part 'test_part.dart';
+class A {}
+''';
+ String basePartCode = r'''
+part of test;
+class B {}
+''';
+ _setSdkLibraries(r'''
+final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
+ 'test' : const LibraryInfo(
+ 'test/test.dart',
+ patches: {VM_PLATFORM: ['test/test_patch.dart']}),
+};''');
+ File fileLib = provider.newFile(_p('/sdk/lib/test/test.dart'), baseLibCode);
+ File filePart =
+ provider.newFile(_p('/sdk/lib/test/test_part.dart'), basePartCode);
+ provider.newFile(
+ _p('/sdk/lib/test/test_patch.dart'),
+ r'''
+import 'foo.dart';
+
+@patch
+class A {
+ int _a() => 1;
+}
+
+@patch
+class B {
+ int _b() => 1;
+}
+
+class _C {}
+''');
+
+ _createSdk();
+
+ {
+ Uri uri = FastUri.parse('dart:test');
+ Source source = fileLib.createSource(uri);
+ CompilationUnit unit = SdkPatcher.parse(source, true, listener);
+ patcher.patch(sdk, SdkLibraryImpl.VM_PLATFORM, listener, source, unit);
+ _assertUnitCode(
+ unit,
+ "library test; part 'test_part.dart'; import 'foo.dart'; "
+ "class A {int _a() => 1;} class _C {}");
+ }
+
+ {
+ Uri uri = FastUri.parse('dart:test/test_part.dart');
+ Source source = filePart.createSource(uri);
+ CompilationUnit unit = SdkPatcher.parse(source, true, listener);
+ patcher.patch(sdk, SdkLibraryImpl.VM_PLATFORM, listener, source, unit);
+ _assertUnitCode(unit, "part of test; class B {int _b() => 1;}");
+ }
+ }
+
+ test_topLevel_class_append() {
+ CompilationUnit unit = _doTopLevelPatching(
+ r'''
+class A {}
+''',
+ r'''
+class _B {
+ void mmm() {}
+}
+''');
+ _assertUnitCode(unit, 'class A {} class _B {void mmm() {}}');
+ ClassDeclaration a = unit.declarations[0];
+ ClassDeclaration b = unit.declarations[1];
+ _assertPrevNextToken(a.endToken, b.beginToken);
+ }
+
+ test_topLevel_class_fail_mixinApplication() {
+ expect(() {
+ _doTopLevelPatching(
+ r'''
+class A {}
+''',
+ r'''
+class _B {}
+class _C = Object with _B;
+''');
+ }, throwsArgumentError);
+ }
+
+ test_topLevel_class_fail_notPrivate() {
+ expect(() {
+ _doTopLevelPatching(
+ r'''
+class A {}
+''',
+ r'''
+class B {}
+''');
+ }, throwsArgumentError);
+ }
+
+ test_topLevel_fail_topLevelVariable() {
+ expect(() {
+ _doTopLevelPatching(
+ r'''
+int foo() => 0;
+''',
+ r'''
+int _bar;
+''');
+ }, throwsArgumentError);
+ }
+
+ test_topLevel_function_append() {
+ CompilationUnit unit = _doTopLevelPatching(
+ r'''
+int foo() => 0;
+''',
+ r'''
+int _bar1() => 1;
+int _bar2() => 2;
+''');
+ _assertUnitCode(
+ unit, 'int foo() => 0; int _bar1() => 1; int _bar2() => 2;');
+
+ FunctionDeclaration foo = unit.declarations[0];
+ FunctionDeclaration bar1 = unit.declarations[1];
+ FunctionDeclaration bar2 = unit.declarations[2];
+
+ _assertPrevNextToken(foo.endToken, bar1.beginToken);
+ _assertPrevNextToken(bar1.endToken, bar2.beginToken);
+ }
+
+ test_topLevel_function_fail_noExternalKeyword() {
+ expect(() {
+ _doTopLevelPatching(
+ r'''
+int foo();
+''',
+ r'''
+@patch
+int foo() => 1;
+''');
+ }, throwsArgumentError);
+ }
+
+ test_topLevel_function_fail_notPrivate() {
+ expect(() {
+ _doTopLevelPatching(
+ r'''
+int foo() => 1;
+''',
+ r'''
+int bar() => 2;
+''');
+ }, throwsArgumentError);
+ }
+
+ test_topLevel_functionTypeAlias_append() {
+ CompilationUnit unit = _doTopLevelPatching(
+ r'''
+int foo() => 0;
+''',
+ r'''
+typedef int _bar1();
+typedef int _bar2();
+''');
+ _assertUnitCode(
+ unit, 'int foo() => 0; typedef int _bar1(); typedef int _bar2();');
+
+ FunctionDeclaration foo = unit.declarations[0];
+ FunctionTypeAlias bar1 = unit.declarations[1];
+ FunctionTypeAlias bar2 = unit.declarations[2];
+
+ _assertPrevNextToken(foo.endToken, bar1.beginToken);
+ _assertPrevNextToken(bar1.endToken, bar2.beginToken);
+ expect(unit.endToken.type, TokenType.EOF);
+ expect(bar2.endToken.next, same(unit.endToken));
+ }
+
+ test_topLevel_functionTypeAlias_fail_hasAnnotation() {
+ expect(() {
+ _doTopLevelPatching(
+ r'''
+int foo() => 0;
+''',
+ r'''
+@patch
+typedef int _bar();
+''');
+ }, throwsArgumentError);
+ }
+
+ test_topLevel_functionTypeAlias_fail_notPrivate() {
+ expect(() {
+ _doTopLevelPatching(
+ r'''
+int foo() => 0;
+''',
+ r'''
+typedef int bar();
+''');
+ }, throwsArgumentError);
+ }
+
+ test_topLevel_patch_function() {
+ CompilationUnit unit = _doTopLevelPatching(
+ r'''
+external int foo();
+int bar() => 2;
+''',
+ r'''
+@patch
+int foo() => 1;
+''');
+ _assertUnitCode(unit, 'int foo() => 1; int bar() => 2;');
+
+ // Prepare functions.
+ FunctionDeclaration foo = unit.declarations[0];
+ FunctionDeclaration bar = unit.declarations[1];
+
+ // The "external" token is removed from the stream.
+ {
+ expect(foo.externalKeyword, isNull);
+ Token token = foo.beginToken;
+ expect(token.lexeme, 'int');
+ expect(token.previous.type, TokenType.EOF);
+ }
+
+ // The body tokens are included into the patched token stream.
+ {
+ FunctionExpression fooExpr = foo.functionExpression;
+ FunctionBody fooBody = fooExpr.body;
+ expect(fooBody.beginToken.previous, same(fooExpr.parameters.endToken));
+ expect(fooBody.endToken.next, same(bar.beginToken));
+ }
+ }
+
+ test_topLevel_patch_function_blockBody() {
+ CompilationUnit unit = _doTopLevelPatching(
+ r'''
+external int foo();
+''',
+ r'''
+@patch
+int foo() {int v = 1; return v + 2;}
+''');
+ _assertUnitCode(unit, 'int foo() {int v = 1; return v + 2;}');
+ }
+
+ test_topLevel_patch_getter() {
+ CompilationUnit unit = _doTopLevelPatching(
+ r'''
+external int get foo;
+int bar() => 2;
+''',
+ r'''
+@patch
+int get foo => 1;
+''');
+ _assertUnitCode(unit, 'int get foo => 1; int bar() => 2;');
+ }
+
+ test_topLevel_patch_setter() {
+ CompilationUnit unit = _doTopLevelPatching(
+ r'''
+external void set foo(int val);
+int bar() => 2;
+''',
+ r'''
+@patch
+void set foo(int val) {}
+''');
+ _assertUnitCode(unit, 'void set foo(int val) {} int bar() => 2;');
+ }
+
+ void _assertUnitCode(CompilationUnit unit, String expectedCode) {
+ expect(unit.toSource(), expectedCode);
+ }
+
+ void _createSdk() {
+ sdk = new FolderBasedDartSdk(provider, sdkFolder);
+ sdk.analysisOptions = new AnalysisOptionsImpl()..strongMode = true;
+ }
+
+ CompilationUnit _doTopLevelPatching(String baseCode, String patchCode) {
+ _setSdkLibraries(r'''
+final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
+ 'test' : const LibraryInfo(
+ 'test/test.dart',
+ patches: {VM_PLATFORM: ['test/test_patch.dart']}),
+};''');
+ File file = provider.newFile(_p('/sdk/lib/test/test.dart'), baseCode);
+ provider.newFile(_p('/sdk/lib/test/test_patch.dart'), patchCode);
+
+ _createSdk();
+
+ Source source = file.createSource(FastUri.parse('dart:test'));
+ CompilationUnit unit = SdkPatcher.parse(source, true, listener);
+ patcher.patch(sdk, SdkLibraryImpl.VM_PLATFORM, listener, source, unit);
+ return unit;
+ }
+
+ String _p(String path) => provider.convertPath(path);
+
+ void _setSdkLibraries(String code) {
+ provider.newFile(
+ _p('/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart'), code);
+ }
+
+ static void _assertPrevNextToken(Token prev, Token next) {
+ expect(prev.next, same(next));
+ expect(next.previous, same(prev));
+ }
+}
diff --git a/pkg/analyzer/test/src/dart/sdk/sdk_test.dart b/pkg/analyzer/test/src/dart/sdk/sdk_test.dart
index 7444827..dbc0d01 100644
--- a/pkg/analyzer/test/src/dart/sdk/sdk_test.dart
+++ b/pkg/analyzer/test/src/dart/sdk/sdk_test.dart
@@ -13,20 +13,21 @@
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/summary/summarize_elements.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../../../embedder_tests.dart';
import '../../../generated/test_support.dart';
import '../../../resource_utils.dart';
-import '../../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(EmbedderSdkTest);
- defineReflectiveTests(FolderBasedDartSdkTest);
- defineReflectiveTests(SdkExtensionFinderTest);
- defineReflectiveTests(SDKLibrariesReaderTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(EmbedderSdkTest);
+ defineReflectiveTests(FolderBasedDartSdkTest);
+ defineReflectiveTests(SdkExtensionFinderTest);
+ defineReflectiveTests(SdkLibrariesReaderTest);
+ defineReflectiveTests(SdkLibraryImplTest);
+ });
}
@reflectiveTest
@@ -274,7 +275,8 @@
FolderBasedDartSdk _createDartSdk() {
resourceProvider = new MemoryResourceProvider();
- Folder sdkDirectory = resourceProvider.getFolder('/sdk');
+ Folder sdkDirectory =
+ resourceProvider.getFolder(resourceProvider.convertPath('/sdk'));
_createFile(sdkDirectory,
['lib', '_internal', 'sdk_library_metadata', 'lib', 'libraries.dart'],
content: _librariesFileContent());
@@ -340,10 +342,10 @@
void setUp() {
resourceProvider = new MemoryResourceProvider();
- resourceProvider.newFolder('/empty');
- resourceProvider.newFolder('/tmp');
+ resourceProvider.newFolder(resourceProvider.convertPath('/empty'));
+ resourceProvider.newFolder(resourceProvider.convertPath('/tmp'));
resourceProvider.newFile(
- '/tmp/_sdkext',
+ resourceProvider.convertPath('/tmp/_sdkext'),
r'''
{
"dart:fox": "slippy.dart",
@@ -356,7 +358,9 @@
test_create_noSdkExtPackageMap() {
var resolver = new SdkExtensionFinder({
- 'fox': <Folder>[resourceProvider.getResource('/empty')]
+ 'fox': <Folder>[
+ resourceProvider.getResource(resourceProvider.convertPath('/empty'))
+ ]
});
expect(resolver.urlMappings.length, equals(0));
}
@@ -368,21 +372,27 @@
test_create_sdkExtPackageMap() {
var resolver = new SdkExtensionFinder({
- 'fox': <Folder>[resourceProvider.getResource('/tmp')]
+ 'fox': <Folder>[
+ resourceProvider.getResource(resourceProvider.convertPath('/tmp'))
+ ]
});
// We have four mappings.
Map<String, String> urlMappings = resolver.urlMappings;
expect(urlMappings.length, equals(4));
// Check that they map to the correct paths.
- expect(urlMappings['dart:fox'], equals("/tmp/slippy.dart"));
- expect(urlMappings['dart:bear'], equals("/tmp/grizzly.dart"));
- expect(urlMappings['dart:relative'], equals("/relative.dart"));
- expect(urlMappings['dart:deep'], equals("/tmp/deep/directory/file.dart"));
+ expect(urlMappings['dart:fox'],
+ equals(resourceProvider.convertPath("/tmp/slippy.dart")));
+ expect(urlMappings['dart:bear'],
+ equals(resourceProvider.convertPath("/tmp/grizzly.dart")));
+ expect(urlMappings['dart:relative'],
+ equals(resourceProvider.convertPath("/relative.dart")));
+ expect(urlMappings['dart:deep'],
+ equals(resourceProvider.convertPath("/tmp/deep/directory/file.dart")));
}
}
@reflectiveTest
-class SDKLibrariesReaderTest extends EngineTestCase {
+class SdkLibrariesReaderTest extends EngineTestCase {
/**
* The resource provider used by these tests.
*/
@@ -464,4 +474,148 @@
expect(second.isImplementation, true);
expect(second.isVmLibrary, false);
}
+
+ void test_readFrom_patches() {
+ LibraryMap libraryMap = new SdkLibrariesReader(false).readFromFile(
+ resourceProvider.getFile('/libs.dart'),
+ r'''
+final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
+ 'foo' : const LibraryInfo(
+ 'foo/foo.dart',
+ patches: {
+ DART2JS_PLATFORM | VM_PLATFORM: ['a', 'b'],
+ DART2JS_PLATFORM: ['c', 'd'],
+ VM_PLATFORM: ['e']}),
+};''');
+ expect(libraryMap, isNotNull);
+ expect(libraryMap.size(), 1);
+ SdkLibrary library = libraryMap.getLibrary('dart:foo');
+ expect(library, isNotNull);
+ expect(library.path, 'foo/foo.dart');
+ expect(library.shortName, 'dart:foo');
+ expect(library.getPatches(SdkLibraryImpl.DART2JS_PLATFORM),
+ unorderedEquals(['a', 'b', 'c', 'd']));
+ expect(library.getPatches(SdkLibraryImpl.VM_PLATFORM),
+ unorderedEquals(['a', 'b', 'e']));
+ }
+
+ void test_readFrom_patches_invalid_notList() {
+ expect(() {
+ new SdkLibrariesReader(false).readFromFile(
+ resourceProvider.getFile('/libs.dart'),
+ r'''
+final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
+ 'foo' : const LibraryInfo(
+ 'foo/foo.dart',
+ patches: {
+ VM_PLATFORM: 'X'}),
+};''');
+ }, throwsArgumentError);
+ }
+
+ void test_readFrom_patches_invalid_notString_inList() {
+ expect(() {
+ new SdkLibrariesReader(false).readFromFile(
+ resourceProvider.getFile('/libs.dart'),
+ r'''
+final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
+ 'foo' : const LibraryInfo(
+ 'foo/foo.dart',
+ patches: {
+ VM_PLATFORM: [42]}),
+};''');
+ }, throwsArgumentError);
+ }
+
+ void test_readFrom_patches_invalid_path_hasDotDot() {
+ _assertPatchPathIsInvalid('foo/../bar.dart');
+ _assertPatchPathIsInvalid('../foo/bar.dart');
+ _assertPatchPathIsInvalid('foo/bar..dart');
+ }
+
+ void test_readFrom_patches_invalid_path_isAbsolute() {
+ _assertPatchPathIsInvalid('/foo.dart');
+ _assertPatchPathIsInvalid('/foo/bar.dart');
+ }
+
+ void test_readFrom_patches_invalid_path_notPosix() {
+ _assertPatchPathIsInvalid(r'foo\bar.dart');
+ }
+
+ void test_readFrom_patches_invalid_platformCombinator() {
+ expect(() {
+ new SdkLibrariesReader(false).readFromFile(
+ resourceProvider.getFile('/libs.dart'),
+ r'''
+final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
+ 'foo' : const LibraryInfo(
+ 'foo/foo.dart',
+ patches: {
+ DART2JS_PLATFORM + VM_PLATFORM: ['X']}),
+};''');
+ }, throwsArgumentError);
+ }
+
+ void test_readFrom_patches_invalid_unknownPlatform() {
+ expect(() {
+ new SdkLibrariesReader(false).readFromFile(
+ resourceProvider.getFile('/libs.dart'),
+ r'''
+final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
+ 'foo' : const LibraryInfo(
+ 'foo/foo.dart',
+ patches: {
+ MY_UNKNOWN_PLATFORM: ['foo/bar_patch.dart']}),
+};''');
+ }, throwsArgumentError);
+ }
+
+ void test_readFrom_patches_no() {
+ LibraryMap libraryMap = new SdkLibrariesReader(false).readFromFile(
+ resourceProvider.getFile('/libs.dart'),
+ r'''
+final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
+ 'my' : const LibraryInfo('my/my.dart')
+};''');
+ expect(libraryMap, isNotNull);
+ expect(libraryMap.size(), 1);
+ SdkLibrary library = libraryMap.getLibrary('dart:my');
+ expect(library, isNotNull);
+ expect(library.path, 'my/my.dart');
+ expect(library.shortName, 'dart:my');
+ expect(library.getPatches(SdkLibraryImpl.VM_PLATFORM), isEmpty);
+ expect(library.getPatches(SdkLibraryImpl.DART2JS_PLATFORM), isEmpty);
+ }
+
+ void _assertPatchPathIsInvalid(String patchPath) {
+ expect(() {
+ new SdkLibrariesReader(false).readFromFile(
+ resourceProvider.getFile('/libs.dart'),
+ '''
+final Map<String, LibraryInfo> LIBRARIES = const <String, LibraryInfo> {
+ 'foo' : const LibraryInfo(
+ 'foo/foo.dart',
+ patches: {
+ VM_PLATFORM: [r'$patchPath']}),
+};''');
+ }, throwsArgumentError);
+ }
+}
+
+@reflectiveTest
+class SdkLibraryImplTest extends EngineTestCase {
+ void test_patches() {
+ SdkLibraryImpl library = new SdkLibraryImpl('dart:foo');
+ // Set patches.
+ library.setPatchPaths(
+ SdkLibraryImpl.DART2JS_PLATFORM | SdkLibraryImpl.VM_PLATFORM,
+ ['a', 'b']);
+ library.setPatchPaths(SdkLibraryImpl.DART2JS_PLATFORM, ['c', 'd']);
+ library.setPatchPaths(SdkLibraryImpl.VM_PLATFORM, ['e']);
+ // Get patches.
+ expect(library.getPatches(SdkLibraryImpl.DART2JS_PLATFORM),
+ unorderedEquals(['a', 'b', 'c', 'd']));
+ expect(library.getPatches(SdkLibraryImpl.VM_PLATFORM),
+ unorderedEquals(['a', 'b', 'e']));
+ }
}
diff --git a/pkg/analyzer/test/src/dart/sdk/test_all.dart b/pkg/analyzer/test/src/dart/sdk/test_all.dart
index 8052c9e..cb044fd 100644
--- a/pkg/analyzer/test/src/dart/sdk/test_all.dart
+++ b/pkg/analyzer/test/src/dart/sdk/test_all.dart
@@ -4,15 +4,15 @@
library analyzer.test.src.dart.sdk.test_all;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../../utils.dart';
+import 'patch_test.dart' as patch_test;
import 'sdk_test.dart' as sdk;
/// Utility for manually running all tests.
main() {
- initializeTestEnvironment();
- group('sdk tests', () {
+ defineReflectiveSuite(() {
+ patch_test.main();
sdk.main();
- });
+ }, name: 'sdk');
}
diff --git a/pkg/analyzer/test/src/dart/test_all.dart b/pkg/analyzer/test/src/dart/test_all.dart
index 26e34d3..11368b5 100644
--- a/pkg/analyzer/test/src/dart/test_all.dart
+++ b/pkg/analyzer/test/src/dart/test_all.dart
@@ -4,9 +4,8 @@
library analyzer.test.src.dart.test_all;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../utils.dart';
import 'ast/test_all.dart' as ast;
import 'constant/test_all.dart' as constant;
import 'element/test_all.dart' as element;
@@ -14,11 +13,10 @@
/// Utility for manually running all tests.
main() {
- initializeTestEnvironment();
- group('dart tests', () {
+ defineReflectiveSuite(() {
ast.main();
constant.main();
element.main();
sdk.main();
- });
+ }, name: 'dart');
}
diff --git a/pkg/analyzer/test/src/plugin/plugin_config_test.dart b/pkg/analyzer/test/src/plugin/plugin_config_test.dart
index 2c9fa04..84ec8c8 100644
--- a/pkg/analyzer/test/src/plugin/plugin_config_test.dart
+++ b/pkg/analyzer/test/src/plugin/plugin_config_test.dart
@@ -6,7 +6,7 @@
import 'package:analyzer/source/analysis_options_provider.dart';
import 'package:analyzer/src/plugin/plugin_configuration.dart';
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
import 'package:yaml/yaml.dart';
main() {
@@ -16,7 +16,7 @@
const optionsSrc = '''
analyzer:
plugins:
- my_plugin1: ^0.1.0 #shorthand
+ my_plugin1: ^0.1.0 #shorthand
my_plugin2:
version: ^0.2.0
my_plugin3:
@@ -42,7 +42,7 @@
const optionsSrc = '''
analyzer:
plugins:
- # my_plugin1: ^0.1.0 #shorthand
+ # my_plugin1: ^0.1.0 #shorthand
''';
var config = parseConfig(optionsSrc);
// Commented out plugins shouldn't cause a parse failure.
@@ -53,7 +53,7 @@
const manifestSrc = '''
class_name: AnalyzerPlugin
library_uri: myplugin/analyzer_plugin.dart
-contributes_to: analyzer
+contributes_to: analyzer
''';
var manifest = parsePluginManifestString(manifestSrc);
var plugin = manifest.plugin;
@@ -66,9 +66,9 @@
const manifestSrc = '''
class_name: AnalyzerPlugin
library_uri: myplugin/analyzer_plugin.dart
-contributes_to:
+contributes_to:
- analyzer
- - analysis_server
+ - analysis_server
''';
var manifest = parsePluginManifestString(manifestSrc);
var plugin = manifest.plugin;
diff --git a/pkg/analyzer/test/src/source/source_resource_test.dart b/pkg/analyzer/test/src/source/source_resource_test.dart
index 8079c17..29474a0 100644
--- a/pkg/analyzer/test/src/source/source_resource_test.dart
+++ b/pkg/analyzer/test/src/source/source_resource_test.dart
@@ -12,15 +12,15 @@
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:analyzer/src/source/source_resource.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../utils.dart';
import '../context/mock_sdk.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(FileSourceTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(FileSourceTest);
+ });
}
@reflectiveTest
@@ -93,7 +93,7 @@
void test_getEncoding() {
SourceFactory factory =
new SourceFactory([new ResourceUriResolver(resourceProvider)]);
- String fullPath = "/does/not/exist.dart";
+ String fullPath = resourceProvider.convertPath("/does/not/exist.dart");
File file = resourceProvider.getFile(fullPath);
FileSource source = new FileSource(file);
expect(factory.fromEncoding(source.encoding), source);
diff --git a/pkg/analyzer/test/src/source/test_all.dart b/pkg/analyzer/test/src/source/test_all.dart
index fea6306..5b7a464 100644
--- a/pkg/analyzer/test/src/source/test_all.dart
+++ b/pkg/analyzer/test/src/source/test_all.dart
@@ -4,15 +4,13 @@
library analyzer.test.src.source.test_all;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../utils.dart';
import 'source_resource_test.dart' as source_resource_test;
/// Utility for manually running all tests.
main() {
- initializeTestEnvironment();
- group('context tests', () {
+ defineReflectiveSuite(() {
source_resource_test.main();
- });
+ }, name: 'source');
}
diff --git a/pkg/analyzer/test/src/summary/api_signature_test.dart b/pkg/analyzer/test/src/summary/api_signature_test.dart
index a8c3459..eb8700b 100644
--- a/pkg/analyzer/test/src/summary/api_signature_test.dart
+++ b/pkg/analyzer/test/src/summary/api_signature_test.dart
@@ -8,12 +8,13 @@
import 'package:analyzer/src/summary/format.dart';
import 'package:convert/convert.dart';
import 'package:crypto/crypto.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
main() {
- groupSep = ' | ';
- defineReflectiveTests(ApiSignatureTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ApiSignatureTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analyzer/test/src/summary/bazel_summary_test.dart b/pkg/analyzer/test/src/summary/bazel_summary_test.dart
index afa2265..a020a32 100644
--- a/pkg/analyzer/test/src/summary/bazel_summary_test.dart
+++ b/pkg/analyzer/test/src/summary/bazel_summary_test.dart
@@ -4,8 +4,10 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/context/cache.dart';
import 'package:analyzer/src/dart/scanner/reader.dart';
import 'package:analyzer/src/dart/scanner/scanner.dart';
import 'package:analyzer/src/generated/engine.dart';
@@ -13,99 +15,496 @@
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/summary/bazel_summary.dart';
import 'package:analyzer/src/summary/format.dart';
+import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary/summarize_ast.dart';
import 'package:analyzer/src/summary/summarize_elements.dart';
import 'package:analyzer/src/util/fast_uri.dart';
+import 'package:analyzer/task/dart.dart';
import 'package:path/path.dart' as pathos;
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../utils.dart';
import '../context/abstract_context.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(SummaryProviderTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(BazelResultProviderTest);
+ defineReflectiveTests(SummaryProviderTest);
+ });
}
-const OUT_ROOT = '$SRC_ROOT/bazel-bin';
-const SRC_ROOT = '/company/src/user/project/root';
+@reflectiveTest
+class BazelResultProviderTest extends _BaseTest {
+ BazelResultProvider provider;
+
+ @override
+ void setUp() {
+ super.setUp();
+ provider = new BazelResultProvider(new SummaryProvider(
+ resourceProvider,
+ '_.temp',
+ _getOutputFolder,
+ resourceProvider
+ .getFolder(resourceProvider.convertPath('/tmp/dart/bazel/linked')),
+ context));
+ }
+
+ test_failure_inconsistent_directDependency() {
+ _setComponentFile('aaa', 'a.dart', 'class A {}');
+ _setComponentFile(
+ 'bbb',
+ 'b.dart',
+ r'''
+import 'package:components.aaa/a.dart';
+class B extends A {}
+''');
+ _writeUnlinkedBundle('components.aaa');
+ _writeUnlinkedBundle('components.bbb');
+ _setComponentFile('aaa', 'a.dart', 'class A2 {}');
+ // The 'aaa' unlinked bundle in inconsistent, so 'bbb' linking fails.
+ Source source = _resolveUri('package:components.bbb/b.dart');
+ CacheEntry entry = context.getCacheEntry(source);
+ expect(provider.compute(entry, LIBRARY_ELEMENT), isFalse);
+ }
+
+ test_failure_missingDirectDependency() {
+ _setComponentFile('aaa', 'a.dart', 'class A {}');
+ _setComponentFile(
+ 'bbb',
+ 'b.dart',
+ r'''
+import 'package:components.aaa/a.dart';
+class B extends A {}
+''');
+ _writeUnlinkedBundle('components.bbb');
+ // We cannot find 'aaa' bundle, so 'bbb' linking fails.
+ Source source = _resolveUri('package:components.bbb/b.dart');
+ CacheEntry entry = context.getCacheEntry(source);
+ expect(provider.compute(entry, LIBRARY_ELEMENT), isFalse);
+ }
+
+ test_success_withoutDependencies() {
+ _setComponentFile('aaa', 'a.dart', 'class A {}');
+ _writeUnlinkedBundle('components.aaa');
+ // Resynthesize 'aaa' library.
+ Source source = _resolveUri('package:components.aaa/a.dart');
+ LibraryElement library = _resynthesizeLibrary(source);
+ List<ClassElement> types = library.definingCompilationUnit.types;
+ expect(types, hasLength(1));
+ expect(types.single.name, 'A');
+ }
+
+ test_withDependency_import() {
+ _setComponentFile('aaa', 'a.dart', 'class A {}');
+ _setComponentFile(
+ 'bbb',
+ 'b.dart',
+ r'''
+import 'package:components.aaa/a.dart';
+class B extends A {}
+''');
+ _writeUnlinkedBundle('components.aaa');
+ _writeUnlinkedBundle('components.bbb');
+ // Prepare sources.
+ Source sourceA = _resolveUri('package:components.aaa/a.dart');
+ Source sourceB = _resolveUri('package:components.bbb/b.dart');
+ // Resynthesize 'bbb' library.
+ LibraryElement libraryB = _resynthesizeLibrary(sourceB);
+ List<ClassElement> types = libraryB.definingCompilationUnit.types;
+ expect(types, hasLength(1));
+ ClassElement typeB = types.single;
+ expect(typeB.name, 'B');
+ expect(typeB.supertype.name, 'A');
+ // The LibraryElement for 'aaa' is not created at all.
+ expect(context.getResult(sourceA, LIBRARY_ELEMENT), isNull);
+ // But we can resynthesize it, and it's the same as from 'bbb'.
+ expect(provider.compute(context.getCacheEntry(sourceA), LIBRARY_ELEMENT),
+ isTrue);
+ LibraryElement libraryA = context.getResult(sourceA, LIBRARY_ELEMENT);
+ expect(libraryA, isNotNull);
+ expect(typeB.supertype.element.library, same(libraryA));
+ }
+
+ LibraryElement _resynthesizeLibrary(Source source) {
+ CacheEntry entry = context.getCacheEntry(source);
+ expect(provider.compute(entry, LIBRARY_ELEMENT), isTrue);
+ return context.getResult(source, LIBRARY_ELEMENT);
+ }
+}
@reflectiveTest
-class SummaryProviderTest extends AbstractContextTest {
+class SummaryProviderTest extends _BaseTest {
SummaryProvider manager;
@override
void setUp() {
super.setUp();
- // Include a 'package' URI resolver.
- sourceFactory = new SourceFactory(<UriResolver>[
- sdkResolver,
- resourceResolver,
- new _TestPackageResolver(resourceProvider)
- ], null, resourceProvider);
- context.sourceFactory = sourceFactory;
- // Create a new SummaryProvider instance.
- manager = new SummaryProvider(resourceProvider, _getOutputPath, context);
+ _createManager();
}
- test_getPackageForUri() {
- String pathA = '$SRC_ROOT/components/aaa/lib';
- resourceProvider.newFile(
- '$pathA/a1.dart',
+ test_getLinkedPackages_cached() {
+ _setComponentFile('aaa', 'a.dart', 'class A {}');
+ _setComponentFile(
+ 'bbb',
+ 'b.dart',
r'''
-class A1 {}
+import 'package:components.aaa/a.dart';
+class B extends A {}
''');
- resourceProvider.newFile(
- '$pathA/a2.dart',
+ _writeUnlinkedBundle('components.aaa');
+ _writeUnlinkedBundle('components.bbb');
+ Source source = _resolveUri('package:components.bbb/b.dart');
+
+ // Session 1.
+ // Create linked bundles and store them in files.
+ {
+ List<Package> packages = manager.getLinkedPackages(source);
+ expect(packages, hasLength(2));
+ }
+
+ // Session 2.
+ // Recreate manager (with disabled linking) and ask again.
+ {
+ _createManager(allowLinking: false);
+ List<Package> packages = manager.getLinkedPackages(source);
+ expect(packages, hasLength(2));
+ }
+ }
+
+ test_getLinkedPackages_cached_declaredVariables_export() {
+ _testImpl_getLinkedPackages_cached_declaredVariables('export');
+ }
+
+ test_getLinkedPackages_cached_declaredVariables_import() {
+ _testImpl_getLinkedPackages_cached_declaredVariables('import');
+ }
+
+ test_getLinkedPackages_null_inconsistent_directDependency() {
+ _setComponentFile('aaa', 'a.dart', 'class A {}');
+ _setComponentFile(
+ 'bbb',
+ 'b.dart',
r'''
-class A2 {}
+import 'package:components.aaa/a.dart';
+class B extends A {}
''');
_writeUnlinkedBundle('components.aaa');
+ _writeUnlinkedBundle('components.bbb');
+ _setComponentFile('aaa', 'a.dart', 'class A2 {}');
+ // The 'aaa' unlinked bundle in inconsistent, so 'bbb' linking fails.
+ Source source = _resolveUri('package:components.bbb/b.dart');
+ List<Package> packages = manager.getLinkedPackages(source);
+ expect(packages, isNull);
+ }
+
+ test_getLinkedPackages_null_missingBundle() {
+ _setComponentFile('aaa', 'a.dart', 'class A {}');
+ // We don't write 'aaa', so we cannot get its package.
+ // Ask the package for the URI.
+ Source source = _resolveUri('package:components.aaa/a.dart');
+ List<Package> packages = manager.getLinkedPackages(source);
+ expect(packages, isNull);
+ }
+
+ test_getLinkedPackages_null_missingDirectDependency() {
+ _setComponentFile('aaa', 'a.dart', 'class A {}');
+ _setComponentFile(
+ 'bbb',
+ 'b.dart',
+ r'''
+import 'package:components.aaa/a.dart';
+class B extends A {}
+''');
+ _writeUnlinkedBundle('components.bbb');
+ // We cannot find 'aaa' bundle, so 'bbb' linking fails.
+ Source source = _resolveUri('package:components.bbb/b.dart');
+ List<Package> packages = manager.getLinkedPackages(source);
+ expect(packages, isNull);
+ }
+
+ test_getLinkedPackages_null_missingIndirectDependency() {
+ _setComponentFile('aaa', 'a.dart', 'class A {}');
+ _setComponentFile(
+ 'bbb',
+ 'b.dart',
+ r'''
+import 'package:components.aaa/a.dart';
+class B extends A {}
+''');
+ _setComponentFile(
+ 'ccc',
+ 'c.dart',
+ r'''
+import 'package:components.bbb/b.dart';
+class C extends B {}
+''');
+ _writeUnlinkedBundle('components.bbb');
+ _writeUnlinkedBundle('components.ccc');
+ // We cannot find 'aaa' bundle, so 'ccc' linking fails.
+ Source source = _resolveUri('package:components.ccc/c.dart');
+ List<Package> packages = manager.getLinkedPackages(source);
+ expect(packages, isNull);
+ }
+
+ test_getLinkedPackages_withDependency_export() {
+ _setComponentFile('aaa', 'a.dart', 'class A {}');
+ _setComponentFile(
+ 'bbb',
+ 'b.dart',
+ r'''
+export 'package:components.aaa/a.dart';
+''');
+ _writeUnlinkedBundle('components.aaa');
+ _writeUnlinkedBundle('components.bbb');
+ Source source = _resolveUri('package:components.bbb/b.dart');
+ List<Package> packages = manager.getLinkedPackages(source);
+ expect(packages, hasLength(2));
+ }
+
+ test_getLinkedPackages_withDependency_import() {
+ _setComponentFile('aaa', 'a.dart', 'class A {}');
+ _setComponentFile(
+ 'bbb',
+ 'b.dart',
+ r'''
+import 'package:components.aaa/a.dart';
+class B extends A {}
+''');
+ _writeUnlinkedBundle('components.aaa');
+ _writeUnlinkedBundle('components.bbb');
+ Source source = _resolveUri('package:components.bbb/b.dart');
+ List<Package> packages = manager.getLinkedPackages(source);
+ expect(packages, hasLength(2));
+ }
+
+ test_getLinkedPackages_withDependency_import_cycle() {
+ _setComponentFile(
+ 'aaa',
+ 'a.dart',
+ r'''
+import 'package:components.bbb/b.dart';
+class A {}
+class A2 extends B {}
+''');
+ _setComponentFile(
+ 'bbb',
+ 'b.dart',
+ r'''
+import 'package:components.aaa/a.dart';
+class B extends A {}
+class B2 extends A2 {}
+''');
+ _writeUnlinkedBundle('components.aaa');
+ _writeUnlinkedBundle('components.bbb');
+ Source source = _resolveUri('package:components.bbb/b.dart');
+ List<Package> packages = manager.getLinkedPackages(source);
+ expect(packages, hasLength(2));
+ }
+
+ test_getLinkedPackages_withDependency_import_indirect() {
+ _setComponentFile('aaa', 'a.dart', 'class A {}');
+ _setComponentFile(
+ 'bbb',
+ 'b.dart',
+ r'''
+import 'package:components.aaa/a.dart';
+class B extends A {}
+''');
+ _setComponentFile(
+ 'ccc',
+ 'c.dart',
+ r'''
+import 'package:components.bbb/b.dart';
+class C extends B {}
+''');
+ _writeUnlinkedBundle('components.aaa');
+ _writeUnlinkedBundle('components.bbb');
+ _writeUnlinkedBundle('components.ccc');
+ Source source = _resolveUri('package:components.ccc/c.dart');
+ List<Package> packages = manager.getLinkedPackages(source);
+ expect(packages, hasLength(3));
+ }
+
+ test_getLinkedPackages_withoutDependencies() {
+ _setComponentFile('aaa', 'a.dart', 'class A {}');
+ _writeUnlinkedBundle('components.aaa');
+ // Ask the package for the URI.
+ Source source = _resolveUri('package:components.aaa/a.dart');
+ List<Package> packages = manager.getLinkedPackages(source);
+ expect(packages, hasLength(1));
+ }
+
+ test_getUnlinkedForUri() {
+ _setComponentFile('aaa', 'a1.dart', 'class A1 {}');
+ _setComponentFile('aaa', 'a2.dart', 'class A2 {}');
+ _writeUnlinkedBundle('components.aaa');
// Ask the package for the URI.
Source source1 = _resolveUri('package:components.aaa/a1.dart');
Source source2 = _resolveUri('package:components.aaa/a2.dart');
- Package package = manager.getPackageForUri(source1.uri);
+ Package package = manager.getUnlinkedForUri(source1.uri);
expect(package, isNotNull);
// The same instance is returned to another URI in the same package.
- expect(manager.getPackageForUri(source2.uri), same(package));
+ expect(manager.getUnlinkedForUri(source2.uri), same(package));
}
- test_getPackageForUri_inconsistent() {
- String pathA = '$SRC_ROOT/components/aaa/lib';
- File fileA1 = resourceProvider.newFile(
- '$pathA/a1.dart',
- r'''
-class A1 {}
-''');
- resourceProvider.newFile(
- '$pathA/a2.dart',
- r'''
-class A2 {}
-''');
+ test_getUnlinkedForUri_inconsistent_fileContent() {
+ File file1 = _setComponentFile('aaa', 'a1.dart', 'class A1 {}');
+ _setComponentFile('aaa', 'a2.dart', 'class A2 {}');
_writeUnlinkedBundle('components.aaa');
- // Update one of the files file, so the bundle is not consistent.
- fileA1.writeAsStringSync('// different');
+ // Update one of the files, so the bundle is not consistent.
+ file1.writeAsStringSync('\nclass A1 {}');
Source source1 = _resolveUri('package:components.aaa/a1.dart');
Source source2 = _resolveUri('package:components.aaa/a2.dart');
- expect(manager.getPackageForUri(source1.uri), isNull);
- expect(manager.getPackageForUri(source2.uri), isNull);
+ expect(manager.getUnlinkedForUri(source1.uri), isNull);
+ expect(manager.getUnlinkedForUri(source2.uri), isNull);
+ }
+
+ test_getUnlinkedForUri_inconsistent_majorVersion() {
+ _setComponentFile('aaa', 'a.dart', 'class A {}');
+ _writeUnlinkedBundle('components.aaa');
+ Source source = _resolveUri('package:components.aaa/a.dart');
+
+ // Create manager with a different major version.
+ // The unlinked bundle cannot be used.
+ _createManager(majorVersion: 12345);
+ Package package = manager.getUnlinkedForUri(source.uri);
+ expect(package, isNull);
+ }
+
+ void _createManager(
+ {bool allowLinking: true,
+ int majorVersion: PackageBundleAssembler.currentMajorVersion}) {
+ manager = new SummaryProvider(resourceProvider, '_.temp', _getOutputFolder,
+ resourceProvider.getFolder('/tmp/dart/bazel/linked'), context,
+ allowLinking: allowLinking, majorVersion: majorVersion);
+ }
+
+ void _testImpl_getLinkedPackages_cached_declaredVariables(
+ String importOrExport) {
+ _setComponentFile(
+ 'aaa',
+ 'user.dart',
+ '''
+ $importOrExport 'foo.dart'
+ if (dart.library.io) 'foo_io.dart'
+ if (dart.library.html) 'foo_html.dart';
+ ''');
+ _setComponentFile('aaa', 'foo.dart', 'class B {}');
+ _setComponentFile('aaa', 'foo_io.dart', 'class B {}');
+ _setComponentFile('aaa', 'foo_dart.dart', 'class B {}');
+ _writeUnlinkedBundle('components.aaa');
+ Source source = _resolveUri('package:components.aaa/user.dart');
+
+ void _assertDependencyInUser(PackageBundle bundle, String shortName) {
+ for (var i = 0; i < bundle.linkedLibraryUris.length; i++) {
+ if (bundle.linkedLibraryUris[i].endsWith('user.dart')) {
+ LinkedLibrary library = bundle.linkedLibraries[i];
+ expect(library.dependencies.map((d) => d.uri),
+ unorderedEquals(['', 'dart:core', shortName]));
+ return;
+ }
+ }
+ fail('Not found user.dart in $bundle');
+ }
+
+ // Session 1.
+ // Create linked bundles and store them in files.
+ {
+ List<Package> packages = manager.getLinkedPackages(source);
+ expect(packages, hasLength(1));
+ _assertDependencyInUser(packages.single.linked, 'foo.dart');
+ }
+
+ // Session 2.
+ // Recreate manager and don't allow it to perform new linking.
+ // Set a declared variable, which is not used in the package.
+ // We still can get the cached linked bundle.
+ {
+ context.declaredVariables.define('not.used.variable', 'baz');
+ _createManager(allowLinking: false);
+ List<Package> packages = manager.getLinkedPackages(source);
+ expect(packages, hasLength(1));
+ _assertDependencyInUser(packages.single.linked, 'foo.dart');
+ }
+
+ // Session 3.
+ // Recreate manager and don't allow it to perform new linking.
+ // Set the value of a referenced declared variable.
+ // So, we cannot use the previously cached linked bundle.
+ {
+ context.declaredVariables.define('dart.library.io', 'does-not-matter');
+ _createManager(allowLinking: false);
+ List<Package> packages = manager.getLinkedPackages(source);
+ expect(packages, isEmpty);
+ }
+
+ // Session 4.
+ // Enable new linking, and configure to use 'foo_html.dart'.
+ {
+ context.declaredVariables.define('dart.library.html', 'true');
+ _createManager(allowLinking: true);
+ List<Package> packages = manager.getLinkedPackages(source);
+ expect(packages, hasLength(1));
+ _assertDependencyInUser(packages.single.linked, 'foo_html.dart');
+ }
+ }
+}
+
+class _BaseTest extends AbstractContextTest {
+ String sourceRoot;
+ String outRoot;
+
+ @override
+ void setUp() {
+ super.setUp();
+ // Include a 'package' URI resolver.
+ sourceRoot = resourceProvider.convertPath('/company/src/user/project/root');
+ outRoot = resourceProvider.pathContext.join(sourceRoot, 'bazel-bin');
+ sourceFactory = new SourceFactory(<UriResolver>[
+ sdkResolver,
+ resourceResolver,
+ new _TestPackageResolver(resourceProvider, sourceRoot)
+ ], null, resourceProvider);
+ context.sourceFactory = sourceFactory;
+ }
+
+ Folder _getOutputFolder(Uri absoluteUri) {
+ var pathContext = resourceProvider.pathContext;
+ if (absoluteUri.scheme == 'package') {
+ List<String> segments = absoluteUri.pathSegments;
+ if (segments.isNotEmpty) {
+ String packageName = segments.first;
+ String path = pathContext.join(
+ outRoot, packageName.replaceAll('.', pathContext.separator));
+ return resourceProvider.getFolder(path);
+ }
+ }
+ return null;
}
Source _resolveUri(String uri) {
return context.sourceFactory.resolveUri(null, uri);
}
+ File _setComponentFile(String componentName, String fileName, String code) {
+ String path = resourceProvider.pathContext
+ .join(sourceRoot, 'components', componentName, 'lib', fileName);
+ return resourceProvider.newFile(path, code);
+ }
+
void _writeUnlinkedBundle(String packageName) {
- String packagePath = packageName.replaceAll('.', '/');
- var unlinkedBundle = _computeUnlinkedBundle(
+ var pathContext = resourceProvider.pathContext;
+ String packagePath = packageName.replaceAll('.', pathContext.separator);
+ PackageBundleBuilder unlinkedBundle = _computeUnlinkedBundle(
resourceProvider,
packageName,
- resourceProvider.getFolder(SRC_ROOT + '/' + packagePath + '/lib'),
+ resourceProvider
+ .getFolder(pathContext.join(sourceRoot, packagePath, 'lib')),
true);
String shortName = packageName.substring(packageName.lastIndexOf('.') + 1);
resourceProvider.newFileWithBytes(
- '$OUT_ROOT/$packagePath/$shortName.full.ds', unlinkedBundle.toBuffer());
+ pathContext.join(outRoot, packagePath, shortName) + '.full.ds',
+ unlinkedBundle.toBuffer());
}
static PackageBundleBuilder _computeUnlinkedBundle(ResourceProvider provider,
@@ -160,17 +559,6 @@
return assembler.assemble();
}
- static String _getOutputPath(ResourceProvider provider, Uri uri) {
- if (uri.scheme == 'package') {
- List<String> segments = uri.pathSegments;
- if (segments.isNotEmpty) {
- String packageName = segments.first;
- return OUT_ROOT + '/' + packageName.replaceAll('.', '/');
- }
- }
- return null;
- }
-
/**
* Parse the given [source] into AST.
*/
@@ -192,8 +580,9 @@
class _TestPackageResolver implements UriResolver {
final ResourceProvider resourceProvider;
+ final String sourceRoot;
- _TestPackageResolver(this.resourceProvider);
+ _TestPackageResolver(this.resourceProvider, this.sourceRoot);
@override
Source resolveAbsolute(Uri uri, [Uri actualUri]) {
@@ -203,7 +592,7 @@
pathos.Context pathContext = resourceProvider.pathContext;
String packageName = segments.first;
String folderPath = pathContext.join(
- SRC_ROOT, packageName.replaceAll('.', pathContext.separator));
+ sourceRoot, packageName.replaceAll('.', pathContext.separator));
String path = pathContext.join(
folderPath, 'lib', pathContext.joinAll(segments.skip(1)));
return resourceProvider.getFile(path).createSource(uri);
diff --git a/pkg/analyzer/test/src/summary/flat_buffers_test.dart b/pkg/analyzer/test/src/summary/flat_buffers_test.dart
index 112f2bb..2498fca 100644
--- a/pkg/analyzer/test/src/summary/flat_buffers_test.dart
+++ b/pkg/analyzer/test/src/summary/flat_buffers_test.dart
@@ -7,12 +7,13 @@
import 'dart:typed_data';
import 'package:analyzer/src/summary/flat_buffers.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
main() {
- groupSep = ' | ';
- defineReflectiveTests(BuilderTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(BuilderTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analyzer/test/src/summary/in_summary_source_test.dart b/pkg/analyzer/test/src/summary/in_summary_source_test.dart
index b48669d..91e662a 100644
--- a/pkg/analyzer/test/src/summary/in_summary_source_test.dart
+++ b/pkg/analyzer/test/src/summary/in_summary_source_test.dart
@@ -10,12 +10,13 @@
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary/package_bundle_reader.dart';
import 'package:path/path.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
main() {
- groupSep = ' | ';
- defineReflectiveTests(InSummarySourceTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(InSummarySourceTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analyzer/test/src/summary/linker_test.dart b/pkg/analyzer/test/src/summary/linker_test.dart
index b6fdf2c..2a0706c 100644
--- a/pkg/analyzer/test/src/summary/linker_test.dart
+++ b/pkg/analyzer/test/src/summary/linker_test.dart
@@ -7,14 +7,15 @@
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary/link.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import 'summarize_ast_test.dart';
main() {
- groupSep = ' | ';
- defineReflectiveTests(LinkerUnitTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(LinkerUnitTest);
+ });
}
@reflectiveTest
@@ -237,6 +238,33 @@
expect(classC.unnamedConstructor.isCycleFree, false);
}
+ void test_covariance() {
+ // Note: due to dartbug.com/27393, the keyword "checked" is identified by
+ // its presence in a library called "meta". If that bug is fixed, this test
+ // may need to be changed.
+ createLinker('''
+library meta;
+const checked = null;
+class A<T> {
+ void f(@checked T t) {}
+}
+class B<T> extends A<T> {
+ void f(T t) {}
+}
+''');
+ testLibrary.libraryCycleForLink.ensureLinked();
+ ClassElementForLink classA = testLibrary.getContainedName('A');
+ MethodElementForLink methodAF = classA.getContainedName('f');
+ ParameterElementForLink parameterAFT = methodAF.parameters[0];
+ expect(parameterAFT.isCovariant, isTrue);
+ expect(parameterAFT.inheritsCovariant, isFalse);
+ ClassElementForLink classB = testLibrary.getContainedName('B');
+ MethodElementForLink methodBF = classB.getContainedName('f');
+ ParameterElementForLink parameterBFT = methodBF.parameters[0];
+ expect(parameterAFT.isCovariant, isTrue);
+ expect(parameterBFT.inheritsCovariant, isTrue);
+ }
+
void test_createPackageBundle_withPackageUri() {
PackageBundle bundle = createPackageBundle(
'''
@@ -251,8 +279,9 @@
UnlinkedExecutable cf = bundle.unlinkedUnits[0].classes[1].executables[0];
UnlinkedParam cfi = cf.parameters[0];
expect(cfi.inferredTypeSlot, isNot(0));
- EntityRef typeRef =
- bundle.linkedLibraries[0].units[0].types[cfi.inferredTypeSlot];
+ EntityRef typeRef = _lookupInferredType(
+ bundle.linkedLibraries[0].units[0], cfi.inferredTypeSlot);
+ expect(typeRef, isNotNull);
expect(bundle.unlinkedUnits[0].references[typeRef.reference].name, 'int');
}
@@ -916,4 +945,16 @@
VariableElementForLink _getVariable(ReferenceableElementForLink element) {
return (element as PropertyAccessorElementForLink_Variable).variable;
}
+
+ /**
+ * Finds the first inferred type stored in [unit] whose slot matches [slot].
+ */
+ EntityRef _lookupInferredType(LinkedUnit unit, int slot) {
+ for (EntityRef ref in unit.types) {
+ if (ref.slot == slot) {
+ return ref;
+ }
+ }
+ return null;
+ }
}
diff --git a/pkg/analyzer/test/src/summary/name_filter_test.dart b/pkg/analyzer/test/src/summary/name_filter_test.dart
index ff2d294..ef66cc5 100644
--- a/pkg/analyzer/test/src/summary/name_filter_test.dart
+++ b/pkg/analyzer/test/src/summary/name_filter_test.dart
@@ -5,12 +5,13 @@
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/name_filter.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
main() {
- groupSep = ' | ';
- defineReflectiveTests(NameFilterTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(NameFilterTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analyzer/test/src/summary/package_bundle_reader_test.dart b/pkg/analyzer/test/src/summary/package_bundle_reader_test.dart
index 663147f..7b6fab2 100644
--- a/pkg/analyzer/test/src/summary/package_bundle_reader_test.dart
+++ b/pkg/analyzer/test/src/summary/package_bundle_reader_test.dart
@@ -11,14 +11,15 @@
import 'package:analyzer/src/util/fast_uri.dart';
import 'package:analyzer/task/dart.dart';
import 'package:analyzer/task/general.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:typed_mock/typed_mock.dart';
-import 'package:unittest/unittest.dart';
main() {
- groupSep = ' | ';
- defineReflectiveTests(ResynthesizerResultProviderTest);
- defineReflectiveTests(SummaryDataStoreTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ResynthesizerResultProviderTest);
+ defineReflectiveTests(SummaryDataStoreTest);
+ });
}
UnlinkedPublicNamespace _namespaceWithParts(List<String> parts) {
diff --git a/pkg/analyzer/test/src/summary/prelinker_test.dart b/pkg/analyzer/test/src/summary/prelinker_test.dart
index 89e0059..1fcc9bc 100644
--- a/pkg/analyzer/test/src/summary/prelinker_test.dart
+++ b/pkg/analyzer/test/src/summary/prelinker_test.dart
@@ -8,14 +8,14 @@
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary/prelink.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import 'summarize_ast_test.dart';
import 'summary_common.dart';
main() {
- groupSep = ' | ';
- defineReflectiveTests(PrelinkerTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(PrelinkerTest);
+ });
}
/**
@@ -26,9 +26,6 @@
@reflectiveTest
class PrelinkerTest extends LinkedSummarizeAstTest {
@override
- bool get expectAbsoluteUrisInDependencies => false;
-
- @override
bool get skipFullyLinkedData => true;
@override
diff --git a/pkg/analyzer/test/src/summary/pub_summary_test.dart b/pkg/analyzer/test/src/summary/pub_summary_test.dart
index 62804a3..0724cef 100644
--- a/pkg/analyzer/test/src/summary/pub_summary_test.dart
+++ b/pkg/analyzer/test/src/summary/pub_summary_test.dart
@@ -11,24 +11,41 @@
import 'package:analyzer/src/summary/summarize_elements.dart';
import 'package:analyzer/src/util/fast_uri.dart';
import 'package:path/path.dart' as pathos;
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart' hide ERROR;
-import '../../utils.dart';
import '../context/abstract_context.dart';
import '../context/mock_sdk.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(PubSummaryManagerTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(PubSummaryManagerTest);
+ });
}
@reflectiveTest
class PubSummaryManagerTest extends AbstractContextTest {
+ /**
+ * The path to the root of the pubcache directory used in these tests. The
+ * path has not been converted to the current platform, and is therefore only
+ * appropriate for composing paths that will later be converted.
+ */
static const String CACHE = '/home/.pub-cache/hosted/pub.dartlang.org';
PubSummaryManager manager;
+ Folder getFolder(String path) =>
+ resourceProvider.getFolder(resourceProvider.convertPath(path));
+
+ File newFile(String path, String content) {
+ //, [int stamp]) {
+ return resourceProvider.newFile(
+ resourceProvider.convertPath(path), content);
+ }
+
+ Folder newFolder(String path) =>
+ resourceProvider.newFolder(resourceProvider.convertPath(path));
+
void setUp() {
super.setUp();
_createManager();
@@ -36,20 +53,20 @@
test_computeUnlinkedForFolder() async {
// Create package files.
- resourceProvider.newFile(
+ newFile(
'/flutter/aaa/lib/a.dart',
'''
class A {}
''');
- resourceProvider.newFile(
+ newFile(
'/flutter/bbb/lib/b.dart',
'''
class B {}
''');
// Configure packages resolution.
- Folder libFolderA = resourceProvider.newFolder('/flutter/aaa/lib');
- Folder libFolderB = resourceProvider.newFolder('/flutter/bbb/lib');
+ Folder libFolderA = newFolder('/flutter/aaa/lib');
+ Folder libFolderB = newFolder('/flutter/bbb/lib');
context.sourceFactory = new SourceFactory(<UriResolver>[
sdkResolver,
resourceResolver,
@@ -72,32 +89,32 @@
test_getLinkedBundles_cached() async {
String pathA1 = '$CACHE/aaa-1.0.0';
String pathA2 = '$CACHE/aaa-2.0.0';
- resourceProvider.newFile(
+ newFile(
'$pathA1/lib/a.dart',
'''
class A {}
int a;
''');
- resourceProvider.newFile(
+ newFile(
'$pathA2/lib/a.dart',
'''
class A2 {}
int a;
''');
- resourceProvider.newFile(
+ newFile(
'$CACHE/bbb/lib/b.dart',
'''
import 'package:aaa/a.dart';
A b;
''');
- Folder folderA1 = resourceProvider.getFolder(pathA1);
- Folder folderA2 = resourceProvider.getFolder(pathA2);
- Folder folderB = resourceProvider.getFolder('$CACHE/bbb');
+ Folder folderA1 = getFolder(pathA1);
+ Folder folderA2 = getFolder(pathA2);
+ Folder folderB = getFolder('$CACHE/bbb');
// Configure packages resolution.
- Folder libFolderA1 = resourceProvider.newFolder('$pathA1/lib');
- Folder libFolderA2 = resourceProvider.newFolder('$pathA2/lib');
- Folder libFolderB = resourceProvider.newFolder('$CACHE/bbb/lib');
+ Folder libFolderA1 = newFolder('$pathA1/lib');
+ Folder libFolderA2 = newFolder('$pathA2/lib');
+ Folder libFolderB = newFolder('$CACHE/bbb/lib');
context.sourceFactory = new SourceFactory(<UriResolver>[
sdkResolver,
resourceResolver,
@@ -184,24 +201,24 @@
test_getLinkedBundles_cached_differentSdk() async {
String pathA = '$CACHE/aaa';
- resourceProvider.newFile(
+ newFile(
'$pathA/lib/a.dart',
'''
class A {}
int a;
''');
- resourceProvider.newFile(
+ newFile(
'$CACHE/bbb/lib/b.dart',
'''
import 'package:aaa/a.dart';
A b;
''');
- Folder folderA = resourceProvider.getFolder(pathA);
- Folder folderB = resourceProvider.getFolder('$CACHE/bbb');
+ Folder folderA = getFolder(pathA);
+ Folder folderB = getFolder('$CACHE/bbb');
// Configure packages resolution.
- Folder libFolderA = resourceProvider.newFolder('$pathA/lib');
- Folder libFolderB = resourceProvider.newFolder('$CACHE/bbb/lib');
+ Folder libFolderA = newFolder('$pathA/lib');
+ Folder libFolderB = newFolder('$CACHE/bbb/lib');
context.sourceFactory = new SourceFactory(<UriResolver>[
sdkResolver,
resourceResolver,
@@ -237,7 +254,7 @@
// Use DartSdk with a different API signature.
// Different linked bundles should be created.
{
- MockSdk sdk = new MockSdk();
+ MockSdk sdk = new MockSdk(resourceProvider: resourceProvider);
sdk.updateUriFile('dart:math', (String content) {
return content + ' class NewMathClass {}';
});
@@ -270,14 +287,14 @@
test_getLinkedBundles_cached_inconsistent_majorVersion() async {
String pathA = '$CACHE/aaa';
- resourceProvider.newFile(
+ newFile(
'$pathA/lib/a.dart',
'''
class A {}
int a;
''');
// Configure packages resolution.
- Folder libFolderA = resourceProvider.newFolder('$pathA/lib');
+ Folder libFolderA = newFolder('$pathA/lib');
context.sourceFactory = new SourceFactory(<UriResolver>[
sdkResolver,
resourceResolver,
@@ -310,7 +327,7 @@
}
test_getLinkedBundles_hasCycle() async {
- resourceProvider.newFile(
+ newFile(
'$CACHE/aaa/lib/a.dart',
'''
import 'package:bbb/b.dart';
@@ -318,14 +335,14 @@
int a1;
B a2;
''');
- resourceProvider.newFile(
+ newFile(
'$CACHE/bbb/lib/b.dart',
'''
import 'package:ccc/c.dart';
class B {}
C b;
''');
- resourceProvider.newFile(
+ newFile(
'$CACHE/ccc/lib/c.dart',
'''
import 'package:aaa/a.dart';
@@ -334,7 +351,7 @@
A c1;
D c2;
''');
- resourceProvider.newFile(
+ newFile(
'$CACHE/ddd/lib/d.dart',
'''
class D {}
@@ -342,10 +359,10 @@
''');
// Configure packages resolution.
- Folder libFolderA = resourceProvider.newFolder('$CACHE/aaa/lib');
- Folder libFolderB = resourceProvider.newFolder('$CACHE/bbb/lib');
- Folder libFolderC = resourceProvider.newFolder('$CACHE/ccc/lib');
- Folder libFolderD = resourceProvider.newFolder('$CACHE/ddd/lib');
+ Folder libFolderA = newFolder('$CACHE/aaa/lib');
+ Folder libFolderB = newFolder('$CACHE/bbb/lib');
+ Folder libFolderC = newFolder('$CACHE/ccc/lib');
+ Folder libFolderD = newFolder('$CACHE/ddd/lib');
context.sourceFactory = new SourceFactory(<UriResolver>[
sdkResolver,
resourceResolver,
@@ -407,21 +424,21 @@
}
test_getLinkedBundles_missingBundle_listed() async {
- resourceProvider.newFile(
+ newFile(
'$CACHE/aaa/lib/a.dart',
'''
import 'package:bbb/b.dart';
B a;
''');
- resourceProvider.newFile(
+ newFile(
'$CACHE/bbb/lib/b.dart',
'''
class B {}
''');
// Configure packages resolution.
- Folder libFolderA = resourceProvider.newFolder('$CACHE/aaa/lib');
- Folder libFolderB = resourceProvider.newFolder('$CACHE/bbb/lib');
+ Folder libFolderA = newFolder('$CACHE/aaa/lib');
+ Folder libFolderB = newFolder('$CACHE/bbb/lib');
context.sourceFactory = new SourceFactory(<UriResolver>[
sdkResolver,
resourceResolver,
@@ -443,26 +460,26 @@
}
test_getLinkedBundles_missingBundle_listed_chained() async {
- resourceProvider.newFile(
+ newFile(
'$CACHE/aaa/lib/a.dart',
'''
import 'package:bbb/b.dart';
''');
- resourceProvider.newFile(
+ newFile(
'$CACHE/bbb/lib/b.dart',
'''
import 'package:ccc/c.dart';
''');
- resourceProvider.newFile(
+ newFile(
'$CACHE/ccc/lib/c.dart',
'''
class C {}
''');
// Configure packages resolution.
- Folder libFolderA = resourceProvider.newFolder('$CACHE/aaa/lib');
- Folder libFolderB = resourceProvider.newFolder('$CACHE/bbb/lib');
- Folder libFolderC = resourceProvider.newFolder('$CACHE/ccc/lib');
+ Folder libFolderA = newFolder('$CACHE/aaa/lib');
+ Folder libFolderB = newFolder('$CACHE/bbb/lib');
+ Folder libFolderC = newFolder('$CACHE/ccc/lib');
context.sourceFactory = new SourceFactory(<UriResolver>[
sdkResolver,
resourceResolver,
@@ -485,27 +502,27 @@
}
test_getLinkedBundles_missingBundle_listed_partial() async {
- resourceProvider.newFile(
+ newFile(
'$CACHE/aaa/lib/a.dart',
'''
int a;
''');
- resourceProvider.newFile(
+ newFile(
'$CACHE/bbb/lib/b.dart',
'''
import 'package:ccc/c.dart';
C b;
''');
- resourceProvider.newFile(
+ newFile(
'$CACHE/ccc/lib/c.dart',
'''
class C {}
''');
// Configure packages resolution.
- Folder libFolderA = resourceProvider.newFolder('$CACHE/aaa/lib');
- Folder libFolderB = resourceProvider.newFolder('$CACHE/bbb/lib');
- Folder libFolderC = resourceProvider.newFolder('$CACHE/ccc/lib');
+ Folder libFolderA = newFolder('$CACHE/aaa/lib');
+ Folder libFolderB = newFolder('$CACHE/bbb/lib');
+ Folder libFolderC = newFolder('$CACHE/ccc/lib');
context.sourceFactory = new SourceFactory(<UriResolver>[
sdkResolver,
resourceResolver,
@@ -536,12 +553,12 @@
}
test_getLinkedBundles_missingBundle_notListed() async {
- resourceProvider.newFile(
+ newFile(
'$CACHE/aaa/lib/a.dart',
'''
int a;
''');
- resourceProvider.newFile(
+ newFile(
'$CACHE/bbb/lib/b.dart',
'''
import 'package:ccc/c.dart';
@@ -550,8 +567,8 @@
''');
// Configure packages resolution.
- Folder libFolderA = resourceProvider.newFolder('$CACHE/aaa/lib');
- Folder libFolderB = resourceProvider.newFolder('$CACHE/bbb/lib');
+ Folder libFolderA = newFolder('$CACHE/aaa/lib');
+ Folder libFolderB = newFolder('$CACHE/bbb/lib');
context.sourceFactory = new SourceFactory(<UriResolver>[
sdkResolver,
resourceResolver,
@@ -592,14 +609,14 @@
}
test_getLinkedBundles_missingLibrary() async {
- resourceProvider.newFile(
+ newFile(
'$CACHE/aaa/lib/a.dart',
'''
import 'package:bbb/b2.dart';
int a1;
B2 a2;
''');
- resourceProvider.newFile(
+ newFile(
'$CACHE/bbb/lib/b.dart',
'''
class B {}
@@ -607,8 +624,8 @@
''');
// Configure packages resolution.
- Folder libFolderA = resourceProvider.newFolder('$CACHE/aaa/lib');
- Folder libFolderB = resourceProvider.newFolder('$CACHE/bbb/lib');
+ Folder libFolderA = newFolder('$CACHE/aaa/lib');
+ Folder libFolderB = newFolder('$CACHE/bbb/lib');
context.sourceFactory = new SourceFactory(<UriResolver>[
sdkResolver,
resourceResolver,
@@ -648,13 +665,13 @@
}
test_getLinkedBundles_missingLibrary_hasCycle() async {
- resourceProvider.newFile(
+ newFile(
'$CACHE/aaa/lib/a.dart',
'''
import 'package:bbb/b.dart';
B a;
''');
- resourceProvider.newFile(
+ newFile(
'$CACHE/bbb/lib/b.dart',
'''
import 'package:aaa/a.dart';
@@ -663,7 +680,7 @@
int b1;
C2 b2;
''');
- resourceProvider.newFile(
+ newFile(
'$CACHE/ccc/lib/c.dart',
'''
class C {}
@@ -671,9 +688,9 @@
''');
// Configure packages resolution.
- Folder libFolderA = resourceProvider.newFolder('$CACHE/aaa/lib');
- Folder libFolderB = resourceProvider.newFolder('$CACHE/bbb/lib');
- Folder libFolderC = resourceProvider.newFolder('$CACHE/ccc/lib');
+ Folder libFolderA = newFolder('$CACHE/aaa/lib');
+ Folder libFolderB = newFolder('$CACHE/bbb/lib');
+ Folder libFolderC = newFolder('$CACHE/ccc/lib');
context.sourceFactory = new SourceFactory(<UriResolver>[
sdkResolver,
resourceResolver,
@@ -725,13 +742,13 @@
}
test_getLinkedBundles_noCycle() async {
- resourceProvider.newFile(
+ newFile(
'$CACHE/aaa/lib/a.dart',
'''
class A {}
int a;
''');
- resourceProvider.newFile(
+ newFile(
'$CACHE/bbb/lib/b.dart',
'''
import 'package:aaa/a.dart';
@@ -739,8 +756,8 @@
''');
// Configure packages resolution.
- Folder libFolderA = resourceProvider.newFolder('$CACHE/aaa/lib');
- Folder libFolderB = resourceProvider.newFolder('$CACHE/bbb/lib');
+ Folder libFolderA = newFolder('$CACHE/aaa/lib');
+ Folder libFolderB = newFolder('$CACHE/bbb/lib');
context.sourceFactory = new SourceFactory(<UriResolver>[
sdkResolver,
resourceResolver,
@@ -776,20 +793,20 @@
}
test_getLinkedBundles_noCycle_relativeUri() async {
- resourceProvider.newFile(
+ newFile(
'$CACHE/aaa/lib/a.dart',
'''
import 'src/a2.dart';
A a;
''');
- resourceProvider.newFile(
+ newFile(
'$CACHE/aaa/lib/src/a2.dart',
'''
class A {}
''');
// Configure packages resolution.
- Folder libFolderA = resourceProvider.newFolder('$CACHE/aaa/lib');
+ Folder libFolderA = newFolder('$CACHE/aaa/lib');
context.sourceFactory = new SourceFactory(<UriResolver>[
sdkResolver,
resourceResolver,
@@ -816,27 +833,27 @@
}
test_getLinkedBundles_noCycle_withExport() async {
- resourceProvider.newFile(
+ newFile(
'$CACHE/aaa/lib/a.dart',
'''
import 'package:bbb/b.dart';
C a;
''');
- resourceProvider.newFile(
+ newFile(
'$CACHE/bbb/lib/b.dart',
'''
export 'package:ccc/c.dart';
''');
- resourceProvider.newFile(
+ newFile(
'$CACHE/ccc/lib/c.dart',
'''
class C {}
''');
// Configure packages resolution.
- Folder libFolderA = resourceProvider.newFolder('$CACHE/aaa/lib');
- Folder libFolderB = resourceProvider.newFolder('$CACHE/bbb/lib');
- Folder libFolderC = resourceProvider.newFolder('$CACHE/ccc/lib');
+ Folder libFolderA = newFolder('$CACHE/aaa/lib');
+ Folder libFolderB = newFolder('$CACHE/bbb/lib');
+ Folder libFolderC = newFolder('$CACHE/ccc/lib');
context.sourceFactory = new SourceFactory(<UriResolver>[
sdkResolver,
resourceResolver,
@@ -865,7 +882,7 @@
}
test_getLinkedBundles_wrongScheme() async {
- resourceProvider.newFile(
+ newFile(
'$CACHE/aaa/lib/a.dart',
'''
import 'xxx:yyy/zzz.dart';
@@ -874,7 +891,7 @@
''');
// Configure packages resolution.
- Folder libFolderA = resourceProvider.newFolder('$CACHE/aaa/lib');
+ Folder libFolderA = newFolder('$CACHE/aaa/lib');
context.sourceFactory = new SourceFactory(<UriResolver>[
sdkResolver,
resourceResolver,
@@ -907,25 +924,25 @@
test_getUnlinkedBundles() async {
// Create package files.
- resourceProvider.newFile(
+ newFile(
'$CACHE/aaa/lib/a.dart',
'''
class A {}
''');
- resourceProvider.newFile(
+ newFile(
'$CACHE/aaa/lib/src/a2.dart',
'''
class A2 {}
''');
- resourceProvider.newFile(
+ newFile(
'$CACHE/bbb/lib/b.dart',
'''
class B {}
''');
// Configure packages resolution.
- Folder libFolderA = resourceProvider.newFolder('$CACHE/aaa/lib');
- Folder libFolderB = resourceProvider.newFolder('$CACHE/bbb/lib');
+ Folder libFolderA = newFolder('$CACHE/aaa/lib');
+ Folder libFolderB = newFolder('$CACHE/bbb/lib');
context.sourceFactory = new SourceFactory(<UriResolver>[
sdkResolver,
resourceResolver,
@@ -975,14 +992,14 @@
test_getUnlinkedBundles_inconsistent_majorVersion() async {
// Create package files.
- resourceProvider.newFile(
+ newFile(
'$CACHE/aaa/lib/a.dart',
'''
class A {}
''');
// Configure packages resolution.
- Folder libFolder = resourceProvider.newFolder('$CACHE/aaa/lib');
+ Folder libFolder = newFolder('$CACHE/aaa/lib');
context.sourceFactory = new SourceFactory(<UriResolver>[
sdkResolver,
resourceResolver,
@@ -1026,20 +1043,20 @@
test_getUnlinkedBundles_notPubCache_dontCreate() async {
String aaaPath = '/Users/user/projects/aaa';
// Create package files.
- resourceProvider.newFile(
+ newFile(
'$aaaPath/lib/a.dart',
'''
class A {}
''');
- resourceProvider.newFile(
+ newFile(
'$CACHE/bbb/lib/b.dart',
'''
class B {}
''');
// Configure packages resolution.
- Folder libFolderA = resourceProvider.getFolder('$aaaPath/lib');
- Folder libFolderB = resourceProvider.newFolder('$CACHE/bbb/lib');
+ Folder libFolderA = getFolder('$aaaPath/lib');
+ Folder libFolderB = newFolder('$CACHE/bbb/lib');
context.sourceFactory = new SourceFactory(<UriResolver>[
sdkResolver,
resourceResolver,
@@ -1080,7 +1097,7 @@
String aaaPath = '/Users/user/projects/aaa';
// Create package files.
{
- File file = resourceProvider.newFile(
+ File file = newFile(
'$aaaPath/lib/a.dart',
'''
class A {}
@@ -1090,18 +1107,19 @@
file.createSource(FastUri.parse('package:aaa/a.dart')),
new UnlinkedUnitBuilder());
resourceProvider.newFileWithBytes(
- '$aaaPath/${PubSummaryManager.UNLINKED_SPEC_NAME}',
+ resourceProvider
+ .convertPath('$aaaPath/${PubSummaryManager.UNLINKED_SPEC_NAME}'),
assembler.assemble().toBuffer());
}
- resourceProvider.newFile(
+ newFile(
'$CACHE/bbb/lib/b.dart',
'''
class B {}
''');
// Configure packages resolution.
- Folder libFolderA = resourceProvider.getFolder('$aaaPath/lib');
- Folder libFolderB = resourceProvider.newFolder('$CACHE/bbb/lib');
+ Folder libFolderA = getFolder('$aaaPath/lib');
+ Folder libFolderB = newFolder('$CACHE/bbb/lib');
context.sourceFactory = new SourceFactory(<UriResolver>[
sdkResolver,
resourceResolver,
@@ -1150,14 +1168,14 @@
test_getUnlinkedBundles_notPubCache_useExisting_inconsistent() async {
String aaaPath = '/Users/user/projects/aaa';
// Create package files.
- resourceProvider.newFile(
+ newFile(
'$aaaPath/lib/a.dart',
'''
class A {}
''');
// Compute the bundles.
- Folder libFolderA = resourceProvider.getFolder('$aaaPath/lib');
+ Folder libFolderA = getFolder('$aaaPath/lib');
await new PubSummaryManager(resourceProvider, '_.temp')
.computeUnlinkedForFolder('aaa', libFolderA);
@@ -1176,7 +1194,7 @@
// Update a Dart file.
// So, the cached bundle cannot be reused.
resourceProvider.updateFile(
- '$aaaPath/lib/a.dart',
+ resourceProvider.convertPath('$aaaPath/lib/a.dart'),
'''
class A2 {}
''');
@@ -1281,10 +1299,10 @@
_testImpl_getLinkedBundles_cached_declaredVariables(
String importOrExport) async {
String pathA = '$CACHE/aaa/lib';
- resourceProvider.newFile('$pathA/foo.dart', 'class A {}');
- resourceProvider.newFile('$pathA/foo_io.dart', 'class A {}');
- resourceProvider.newFile('$pathA/foo_html.dart', 'class A {}');
- resourceProvider.newFile(
+ newFile('$pathA/foo.dart', 'class A {}');
+ newFile('$pathA/foo_io.dart', 'class A {}');
+ newFile('$pathA/foo_html.dart', 'class A {}');
+ newFile(
'$pathA/user.dart',
'''
$importOrExport 'foo.dart'
@@ -1292,7 +1310,7 @@
if (dart.library.html) 'foo_html.dart';
''');
// Configure packages resolution.
- Folder libFolderA = resourceProvider.newFolder(pathA);
+ Folder libFolderA = newFolder(pathA);
context.sourceFactory = new SourceFactory(<UriResolver>[
sdkResolver,
resourceResolver,
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
index d547b6b..804e845 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
@@ -21,8 +21,8 @@
show PackageBundleAssembler;
import 'package:analyzer/task/dart.dart' show PARSED_UNIT;
import 'package:analyzer/task/general.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../context/abstract_context.dart';
import '../task/strong/inferred_type_test.dart';
@@ -30,10 +30,11 @@
import 'summary_common.dart';
main() {
- groupSep = ' | ';
- defineReflectiveTests(ResynthesizeAstSpecTest);
- defineReflectiveTests(ResynthesizeAstStrongTest);
- defineReflectiveTests(AstInferredTypeTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ResynthesizeAstSpecTest);
+ defineReflectiveTests(ResynthesizeAstStrongTest);
+ defineReflectiveTests(AstInferredTypeTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 88b8985..5f1f619 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -22,8 +22,8 @@
import 'package:analyzer/src/generated/testing/ast_factory.dart';
import 'package:analyzer/src/summary/idl.dart';
import 'package:analyzer/src/summary/resynthesize.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../../generated/test_support.dart';
import '../abstract_single_unit.dart';
@@ -542,18 +542,7 @@
}
compareConstAstLists(
r.arguments?.arguments, o.arguments?.arguments, desc);
- Element expectedElement = o.element;
- if (oName is PrefixedIdentifier &&
- o.constructorName != null &&
- o.element != null) {
- // Due to dartbug.com/25706, [o.element] incorrectly points to the
- // class rather than the named constructor. Hack around this.
- // TODO(paulberry): when dartbug.com/25706 is fixed, remove this.
- expectedElement = (expectedElement as ClassElement)
- .getNamedConstructor(o.constructorName.name);
- expect(expectedElement, isNotNull, reason: desc);
- }
- compareElements(r.element, expectedElement, desc);
+ compareElements(r.element, o.element, desc);
// elementAnnotation should be null; it is only used in the full AST.
expect(o.elementAnnotation, isNull);
expect(r.elementAnnotation, isNull);
@@ -928,6 +917,7 @@
}
expect(resynthesized.defaultValueCode, original.defaultValueCode,
reason: desc);
+ expect(resynthesized.isCovariant, original.isCovariant, reason: desc);
ParameterElementImpl resynthesizedActual =
getActualElement(resynthesized, desc);
ParameterElementImpl originalActual = getActualElement(original, desc);
@@ -1645,6 +1635,14 @@
''');
}
+ test_closure_in_variable_declaration_in_part() {
+ addSource('/a.dart', 'part of lib; final f = (int i) => i.toDouble();');
+ checkLibrary('''
+library lib;
+part "a.dart";
+''');
+ }
+
test_const_invalid_field_const() {
variablesWithNotConstInitializers.add('f');
checkLibrary(
@@ -2748,6 +2746,35 @@
''');
}
+ void test_covariant_parameter() {
+ // Note: due to dartbug.com/27393, the keyword "checked" is identified by
+ // its presence in a library called "meta". If that bug is fixed, this test
+ // my need to be changed.
+ checkLibrary(r'''
+library meta;
+const checked = null;
+class A<T> {
+ void f(@checked T t) {}
+}
+''');
+ }
+
+ void test_covariant_parameter_inherited() {
+ // Note: due to dartbug.com/27393, the keyword "checked" is identified by
+ // its presence in a library called "meta". If that bug is fixed, this test
+ // my need to be changed.
+ checkLibrary(r'''
+library meta;
+const checked = null;
+class A<T> {
+ void f(@checked T t) {}
+}
+class B<T> extends A<T> {
+ void f(T t) {}
+}
+''');
+ }
+
test_defaultValue_refersToGenericClass_constructor() {
checkLibrary('''
class B<T> {
@@ -4492,7 +4519,6 @@
checkLibrary('import "dart:async" as foo; @foo.bar.baz() class C {}');
}
- @failingTest // See dartbug.com/25706
test_unresolved_annotation_prefixedNamedConstructorCall_noConstructor() {
checkLibrary('import "dart:async" as foo; @foo.Future.bar() class C {}');
}
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 95e0ff8..05563d2 100644
--- a/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart
+++ b/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart
@@ -5,13 +5,13 @@
library analyzer.test.src.summary.summarize_ast_strong_test;
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import 'summarize_ast_test.dart';
main() {
- groupSep = ' | ';
- defineReflectiveTests(LinkedSummarizeAstStrongTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(LinkedSummarizeAstStrongTest);
+ });
}
/**
diff --git a/pkg/analyzer/test/src/summary/summarize_ast_test.dart b/pkg/analyzer/test/src/summary/summarize_ast_test.dart
index b17b6da..1a02706 100644
--- a/pkg/analyzer/test/src/summary/summarize_ast_test.dart
+++ b/pkg/analyzer/test/src/summary/summarize_ast_test.dart
@@ -18,14 +18,15 @@
import 'package:analyzer/src/summary/package_bundle_reader.dart';
import 'package:analyzer/src/summary/summarize_ast.dart';
import 'package:analyzer/src/summary/summarize_elements.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import 'summary_common.dart';
main() {
- groupSep = ' | ';
- defineReflectiveTests(LinkedSummarizeAstSpecTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(LinkedSummarizeAstSpecTest);
+ });
}
@reflectiveTest
@@ -134,9 +135,6 @@
LinkerInputs linkerInputs;
@override
- bool get expectAbsoluteUrisInDependencies => false;
-
- @override
bool get skipFullyLinkedData => false;
@override
diff --git a/pkg/analyzer/test/src/summary/summary_common.dart b/pkg/analyzer/test/src/summary/summary_common.dart
index 7d90d0a..a5834ac 100644
--- a/pkg/analyzer/test/src/summary/summary_common.dart
+++ b/pkg/analyzer/test/src/summary/summary_common.dart
@@ -17,7 +17,7 @@
import 'package:analyzer/src/summary/public_namespace_computer.dart'
as public_namespace;
import 'package:path/path.dart' show posix;
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
import '../context/mock_sdk.dart';
@@ -141,13 +141,6 @@
LinkedUnit get definingUnit => linked.units[0];
/**
- * `true` if the linked portion of the summary is expected to contain
- * absolute URIs. This happens because the element model doesn't (yet) store
- * enough information to recover relative URIs, TODO(paulberry): fix this.
- */
- bool get expectAbsoluteUrisInDependencies;
-
- /**
* Get access to the linked summary that results from serializing and
* then deserializing the library under test.
*/
@@ -217,12 +210,7 @@
*/
void checkDependency(int dependency, String absoluteUri, String relativeUri) {
expect(dependency, new isInstanceOf<int>());
- if (expectAbsoluteUrisInDependencies) {
- // The element model doesn't (yet) store enough information to recover
- // relative URIs, so we have to use the absolute URI.
- // TODO(paulberry): fix this.
- expect(linked.dependencies[dependency].uri, absoluteUri);
- } else if (dependency >= linked.numPrelinkedDependencies) {
+ if (dependency >= linked.numPrelinkedDependencies) {
// Fully-linked dependencies are always absolute URIs.
expect(linked.dependencies[dependency].uri, absoluteUri);
} else {
@@ -231,17 +219,11 @@
}
/**
- * Verify that the given [dependency] lists the given [absoluteUris] or
+ * Verify that the given [dependency] lists the given
* [relativeUris] as its parts.
*/
- void checkDependencyParts(LinkedDependency dependency,
- List<String> absoluteUris, List<String> relativeUris) {
- if (expectAbsoluteUrisInDependencies) {
- // The element model doesn't (yet) store enough information to recover
- // relative URIs, so we have to use the absolute URI.
- // TODO(paulberry): fix this.
- relativeUris = absoluteUris;
- }
+ void checkDependencyParts(
+ LinkedDependency dependency, List<String> relativeUris) {
expect(dependency.parts, relativeUris);
}
@@ -295,20 +277,13 @@
/**
* Verify that the dependency table contains an entry for a file reachable
- * via the given [absoluteUri] and [relativeUri]. If [fullyLinked] is
+ * via the given [relativeUri]. If [fullyLinked] is
* `true`, then the dependency should be a fully-linked dependency; otherwise
* it should be a prelinked dependency.
*
* The index of the [LinkedDependency] is returned.
*/
- int checkHasDependency(String absoluteUri, String relativeUri,
- {bool fullyLinked: false}) {
- if (expectAbsoluteUrisInDependencies) {
- // The element model doesn't (yet) store enough information to recover
- // relative URIs, so we have to use the absolute URI.
- // TODO(paulberry): fix this.
- relativeUri = absoluteUri;
- }
+ int checkHasDependency(String relativeUri, {bool fullyLinked: false}) {
List<String> found = <String>[];
for (int i = 0; i < linked.dependencies.length; i++) {
LinkedDependency dep = linked.dependencies[i];
@@ -359,15 +334,9 @@
/**
* Verify that the dependency table *does not* contain any entries for a file
- * reachable via the given [absoluteUri] and [relativeUri].
+ * reachable via the given [relativeUri].
*/
- void checkLacksDependency(String absoluteUri, String relativeUri) {
- if (expectAbsoluteUrisInDependencies) {
- // The element model doesn't (yet) store enough information to recover
- // relative URIs, so we have to use the absolute URI.
- // TODO(paulberry): fix this.
- relativeUri = absoluteUri;
- }
+ void checkLacksDependency(String relativeUri) {
for (LinkedDependency dep in linked.dependencies) {
if (dep.uri == relativeUri) {
fail('Unexpected dependency found: $relativeUri');
@@ -620,6 +589,37 @@
checkTypeRef(typeRef, null, null, 'void');
}
+ fail_invalid_prefix_dynamic() {
+// if (checkAstDerivedData) {
+// // TODO(paulberry): get this to work properly.
+// return;
+// }
+ var t = serializeTypeText('dynamic.T', allowErrors: true);
+ checkUnresolvedTypeRef(t, 'dynamic', 'T');
+ }
+
+ fail_invalid_prefix_type_parameter() {
+// if (checkAstDerivedData) {
+// // TODO(paulberry): get this to work properly.
+// return;
+// }
+ checkUnresolvedTypeRef(
+ serializeClassText('class C<T> { T.U x; }', allowErrors: true)
+ .fields[0]
+ .type,
+ 'T',
+ 'U');
+ }
+
+ fail_invalid_prefix_void() {
+// if (checkAstDerivedData) {
+// // TODO(paulberry): get this to work properly.
+// return;
+// }
+ checkUnresolvedTypeRef(
+ serializeTypeText('void.T', allowErrors: true), 'void', 'T');
+ }
+
/**
* Find the class with the given [className] in the summary, and return its
* [UnlinkedClass] data structure. If [unit] is not given, the class is
@@ -1363,7 +1363,7 @@
checkInferredTypeSlot(executable.localFunctions[0].inferredReturnTypeSlot,
absUri('/a.dart'), 'a.dart', 'D',
onlyInStrongMode: false);
- checkHasDependency(absUri('/a.dart'), 'a.dart', fullyLinked: false);
+ checkHasDependency('a.dart', fullyLinked: false);
}
test_closure_executable_with_return_type_from_closure() {
@@ -1408,7 +1408,7 @@
absUri('/b.dart'), 'b.dart', 'D',
onlyInStrongMode: false);
if (!skipFullyLinkedData) {
- checkHasDependency(absUri('/b.dart'), 'b.dart', fullyLinked: true);
+ checkHasDependency('b.dart', fullyLinked: true);
}
}
@@ -4699,7 +4699,7 @@
// re-export any names defined in b.dart, because a change to b.dart might
// cause it to start exporting a name that the main test library *does*
// use.
- checkHasDependency(absUri('/b.dart'), 'b.dart');
+ checkHasDependency('b.dart');
}
test_dependencies_export_unused() {
@@ -4709,17 +4709,17 @@
// re-export any names defined in a.dart, because a change to a.dart might
// cause it to start exporting a name that the main test library *will*
// re-export.
- checkHasDependency(absUri('/a.dart'), 'a.dart');
+ checkHasDependency('a.dart');
}
test_dependencies_import_to_export() {
addNamedSource('/a.dart', 'library a; export "b.dart"; class A {}');
addNamedSource('/b.dart', 'library b;');
serializeLibraryText('import "a.dart"; A a;');
- checkHasDependency(absUri('/a.dart'), 'a.dart');
+ checkHasDependency('a.dart');
// The main test library depends on b.dart, because names defined in
// b.dart are exported by a.dart.
- checkHasDependency(absUri('/b.dart'), 'b.dart');
+ checkHasDependency('b.dart');
}
test_dependencies_import_to_export_in_subdirs_absolute_export() {
@@ -4727,40 +4727,40 @@
'library a; export "${absUri('/a/b/b.dart')}"; class A {}');
addNamedSource('/a/b/b.dart', 'library b;');
serializeLibraryText('import "a/a.dart"; A a;');
- checkHasDependency(absUri('/a/a.dart'), 'a/a.dart');
+ checkHasDependency('a/a.dart');
// The main test library depends on b.dart, because names defined in
// b.dart are exported by a.dart.
- checkHasDependency(absUri('/a/b/b.dart'), absUri('/a/b/b.dart'));
+ checkHasDependency(absUri('/a/b/b.dart'));
}
test_dependencies_import_to_export_in_subdirs_absolute_import() {
addNamedSource('/a/a.dart', 'library a; export "b/b.dart"; class A {}');
addNamedSource('/a/b/b.dart', 'library b;');
serializeLibraryText('import "${absUri('/a/a.dart')}"; A a;');
- checkHasDependency(absUri('/a/a.dart'), absUri('/a/a.dart'));
+ checkHasDependency(absUri('/a/a.dart'));
// The main test library depends on b.dart, because names defined in
// b.dart are exported by a.dart.
- checkHasDependency(absUri('/a/b/b.dart'), absUri('/a/b/b.dart'));
+ checkHasDependency(absUri('/a/b/b.dart'));
}
test_dependencies_import_to_export_in_subdirs_relative() {
addNamedSource('/a/a.dart', 'library a; export "b/b.dart"; class A {}');
addNamedSource('/a/b/b.dart', 'library b;');
serializeLibraryText('import "a/a.dart"; A a;');
- checkHasDependency(absUri('/a/a.dart'), 'a/a.dart');
+ checkHasDependency('a/a.dart');
// The main test library depends on b.dart, because names defined in
// b.dart are exported by a.dart.
- checkHasDependency(absUri('/a/b/b.dart'), 'a/b/b.dart');
+ checkHasDependency('a/b/b.dart');
}
test_dependencies_import_to_export_loop() {
addNamedSource('/a.dart', 'library a; export "b.dart"; class A {}');
addNamedSource('/b.dart', 'library b; export "a.dart";');
serializeLibraryText('import "a.dart"; A a;');
- checkHasDependency(absUri('/a.dart'), 'a.dart');
+ checkHasDependency('a.dart');
// Serialization should have been able to walk the transitive export
// dependencies to b.dart without going into an infinite loop.
- checkHasDependency(absUri('/b.dart'), 'b.dart');
+ checkHasDependency('b.dart');
}
test_dependencies_import_to_export_transitive_closure() {
@@ -4768,10 +4768,10 @@
addNamedSource('/b.dart', 'library b; export "c.dart";');
addNamedSource('/c.dart', 'library c;');
serializeLibraryText('import "a.dart"; A a;');
- checkHasDependency(absUri('/a.dart'), 'a.dart');
+ checkHasDependency('a.dart');
// The main test library depends on c.dart, because names defined in
// c.dart are exported by b.dart and then re-exported by a.dart.
- checkHasDependency(absUri('/c.dart'), 'c.dart');
+ checkHasDependency('c.dart');
}
test_dependencies_import_to_export_unused() {
@@ -4781,7 +4781,7 @@
// The main test library depends on b.dart, even though it doesn't use any
// names defined in b.dart, because a change to b.dart might cause it to
// start exporting a name that the main test library *does* use.
- checkHasDependency(absUri('/b.dart'), 'b.dart');
+ checkHasDependency('b.dart');
}
test_dependencies_import_transitive_closure() {
@@ -4789,10 +4789,10 @@
'/a.dart', 'library a; import "b.dart"; class A extends B {}');
addNamedSource('/b.dart', 'library b; class B {}');
serializeLibraryText('import "a.dart"; A a;');
- checkHasDependency(absUri('/a.dart'), 'a.dart');
+ checkHasDependency('a.dart');
// The main test library doesn't depend on b.dart, because no change to
// b.dart can possibly affect the serialized element model for it.
- checkLacksDependency(absUri('/b.dart'), 'b.dart');
+ checkLacksDependency('b.dart');
}
test_dependencies_import_unused() {
@@ -4801,7 +4801,7 @@
// The main test library depends on a.dart, even though it doesn't use any
// names defined in a.dart, because a change to a.dart might cause it to
// start exporting a name that the main test library *does* use.
- checkHasDependency(absUri('/a.dart'), 'a.dart');
+ checkHasDependency('a.dart');
}
test_dependencies_parts() {
@@ -4810,9 +4810,8 @@
addNamedSource('/b.dart', 'part of a;');
addNamedSource('/c.dart', 'part of a;');
serializeLibraryText('import "a.dart"; A a;');
- int dep = checkHasDependency(absUri('/a.dart'), 'a.dart');
- checkDependencyParts(linked.dependencies[dep],
- [absUri('/b.dart'), absUri('/c.dart')], ['b.dart', 'c.dart']);
+ int dep = checkHasDependency('a.dart');
+ checkDependencyParts(linked.dependencies[dep], ['b.dart', 'c.dart']);
}
test_dependencies_parts_relative_to_importing_library() {
@@ -4822,11 +4821,9 @@
addNamedSource('/a/c/e/f.dart', 'part of d;');
addNamedSource('/a/c/g/h.dart', 'part of d;');
serializeLibraryText('import "a/b.dart"; D d;');
- int dep = checkHasDependency(absUri('/a/c/d.dart'), 'a/c/d.dart');
+ int dep = checkHasDependency('a/c/d.dart');
checkDependencyParts(
- linked.dependencies[dep],
- [absUri('/a/c/e/f.dart'), absUri('/a/c/g/h.dart')],
- ['a/c/e/f.dart', 'a/c/g/h.dart']);
+ linked.dependencies[dep], ['a/c/e/f.dart', 'a/c/g/h.dart']);
}
test_elements_in_part() {
@@ -5802,6 +5799,49 @@
expect(executable.parameters, isEmpty);
}
+ test_executable_param_of_constructor_no_covariance() {
+ UnlinkedExecutable executable =
+ serializeClassText('class C { C(x); }').executables[0];
+ expect(executable.parameters[0].inheritsCovariantSlot, 0);
+ }
+
+ test_executable_param_of_local_function_no_covariance() {
+ UnlinkedExecutable executable =
+ serializeClassText('class C { m() { f(x) {} } }')
+ .executables[0]
+ .localFunctions[0];
+ expect(executable.parameters[0].inheritsCovariantSlot, 0);
+ }
+
+ test_executable_param_of_method_covariance() {
+ UnlinkedExecutable executable =
+ serializeClassText('class C { m(x) {} }').executables[0];
+ expect(executable.parameters[0].inheritsCovariantSlot, isNot(0));
+ }
+
+ test_executable_param_of_param_no_covariance() {
+ UnlinkedExecutable executable =
+ serializeClassText('class C { m(f(x)) {} }').executables[0];
+ expect(executable.parameters[0].parameters[0].inheritsCovariantSlot, 0);
+ }
+
+ test_executable_param_of_setter_covariance() {
+ UnlinkedExecutable executable =
+ serializeClassText('class C { void set s(x) {} }').executables[0];
+ expect(executable.parameters[0].inheritsCovariantSlot, isNot(0));
+ }
+
+ test_executable_param_of_static_method_no_covariance() {
+ UnlinkedExecutable executable =
+ serializeClassText('class C { static m(x) {} }').executables[0];
+ expect(executable.parameters[0].inheritsCovariantSlot, 0);
+ }
+
+ test_executable_param_of_top_level_function_no_covariance() {
+ UnlinkedExecutable executable = serializeExecutableText('f(x) {}');
+ expect(executable.parameters[0].inheritsCovariantSlot, 0);
+ }
+
test_executable_param_order() {
UnlinkedExecutable executable = serializeExecutableText('f(x, y) {}');
expect(executable.parameters, hasLength(2));
@@ -7792,10 +7832,8 @@
// The dependency on b.dart is implicit, so it should be placed at the end
// of the dependency list, after a.dart, even though the code that refers
// to b.dart comes before the code that refers to a.dart.
- int aDep =
- checkHasDependency(absUri('/a.dart'), 'a.dart', fullyLinked: false);
- int bDep =
- checkHasDependency(absUri('/b.dart'), 'b.dart', fullyLinked: true);
+ int aDep = checkHasDependency('a.dart', fullyLinked: false);
+ int bDep = checkHasDependency('b.dart', fullyLinked: true);
expect(aDep, lessThan(bDep));
}
@@ -8379,7 +8417,7 @@
checkInferredTypeSlot(variable.initializer.inferredReturnTypeSlot,
absUri('/a.dart'), 'a.dart', 'D',
onlyInStrongMode: false);
- checkHasDependency(absUri('/a.dart'), 'a.dart', fullyLinked: false);
+ checkHasDependency('a.dart', fullyLinked: false);
}
test_initializer_executable_with_return_type_from_closure() {
@@ -8490,41 +8528,10 @@
absUri('/b.dart'), 'b.dart', 'D',
onlyInStrongMode: false);
if (!skipFullyLinkedData) {
- checkHasDependency(absUri('/b.dart'), 'b.dart', fullyLinked: true);
+ checkHasDependency('b.dart', fullyLinked: true);
}
}
- fail_invalid_prefix_dynamic() {
-// if (checkAstDerivedData) {
-// // TODO(paulberry): get this to work properly.
-// return;
-// }
- var t = serializeTypeText('dynamic.T', allowErrors: true);
- checkUnresolvedTypeRef(t, 'dynamic', 'T');
- }
-
- fail_invalid_prefix_type_parameter() {
-// if (checkAstDerivedData) {
-// // TODO(paulberry): get this to work properly.
-// return;
-// }
- checkUnresolvedTypeRef(
- serializeClassText('class C<T> { T.U x; }', allowErrors: true)
- .fields[0]
- .type,
- 'T',
- 'U');
- }
-
- fail_invalid_prefix_void() {
-// if (checkAstDerivedData) {
-// // TODO(paulberry): get this to work properly.
-// return;
-// }
- checkUnresolvedTypeRef(
- serializeTypeText('void.T', allowErrors: true), 'void', 'T');
- }
-
test_library_documented() {
String text = '''
// Extra comment so doc comment offset != 0
diff --git a/pkg/analyzer/test/src/summary/test_all.dart b/pkg/analyzer/test/src/summary/test_all.dart
index 2c9966b..dd63f2f 100644
--- a/pkg/analyzer/test/src/summary/test_all.dart
+++ b/pkg/analyzer/test/src/summary/test_all.dart
@@ -4,9 +4,8 @@
library test.src.serialization.test_all;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../utils.dart';
import 'api_signature_test.dart' as api_signature_test;
import 'bazel_summary_test.dart' as bazel_summary_test;
import 'flat_buffers_test.dart' as flat_buffers_test;
@@ -22,8 +21,7 @@
/// Utility for manually running all tests.
main() {
- initializeTestEnvironment();
- group('summary tests', () {
+ defineReflectiveSuite(() {
api_signature_test.main();
bazel_summary_test.main();
flat_buffers_test.main();
@@ -36,5 +34,5 @@
resynthesize_ast_test.main();
summarize_ast_strong_test.main();
summarize_ast_test.main();
- });
+ }, name: 'summary');
}
diff --git a/pkg/analyzer/test/src/task/dart_test.dart b/pkg/analyzer/test/src/task/dart_test.dart
index 403467e..b974563 100644
--- a/pkg/analyzer/test/src/task/dart_test.dart
+++ b/pkg/analyzer/test/src/task/dart_test.dart
@@ -26,8 +26,8 @@
import 'package:analyzer/task/dart.dart';
import 'package:analyzer/task/general.dart';
import 'package:analyzer/task/model.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../../generated/resolver_test_case.dart';
import '../../generated/test_support.dart';
@@ -35,46 +35,47 @@
import '../context/abstract_context.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(BuildCompilationUnitElementTaskTest);
- defineReflectiveTests(BuildDirectiveElementsTaskTest);
- defineReflectiveTests(BuildEnumMemberElementsTaskTest);
- defineReflectiveTests(BuildExportNamespaceTaskTest);
- defineReflectiveTests(BuildLibraryElementTaskTest);
- defineReflectiveTests(BuildPublicNamespaceTaskTest);
- defineReflectiveTests(BuildSourceExportClosureTaskTest);
- defineReflectiveTests(BuildTypeProviderTaskTest);
- defineReflectiveTests(ComputeConstantDependenciesTaskTest);
- defineReflectiveTests(ComputeConstantValueTaskTest);
- defineReflectiveTests(ComputeInferableStaticVariableDependenciesTaskTest);
- defineReflectiveTests(ComputeLibraryCycleTaskTest);
- defineReflectiveTests(ContainingLibrariesTaskTest);
- defineReflectiveTests(DartErrorsTaskTest);
- defineReflectiveTests(EvaluateUnitConstantsTaskTest);
- defineReflectiveTests(GatherUsedImportedElementsTaskTest);
- defineReflectiveTests(GatherUsedLocalElementsTaskTest);
- defineReflectiveTests(GenerateHintsTaskTest);
- defineReflectiveTests(GenerateLintsTaskTest);
- defineReflectiveTests(InferInstanceMembersInUnitTaskTest);
- defineReflectiveTests(InferStaticVariableTypesInUnitTaskTest);
- defineReflectiveTests(InferStaticVariableTypeTaskTest);
- defineReflectiveTests(LibraryErrorsReadyTaskTest);
- defineReflectiveTests(LibraryUnitErrorsTaskTest);
- defineReflectiveTests(ParseDartTaskTest);
- defineReflectiveTests(PartiallyResolveUnitReferencesTaskTest);
- defineReflectiveTests(ReferencedNamesBuilderTest);
- defineReflectiveTests(ResolveDirectiveElementsTaskTest);
- defineReflectiveTests(ResolveInstanceFieldsInUnitTaskTest);
- defineReflectiveTests(ResolveLibraryTaskTest);
- defineReflectiveTests(ResolveLibraryTypeNamesTaskTest);
- defineReflectiveTests(ResolveTopLevelUnitTypeBoundsTaskTest);
- defineReflectiveTests(ResolveUnitTaskTest);
- defineReflectiveTests(ResolveUnitTypeNamesTaskTest);
- defineReflectiveTests(ResolveVariableReferencesTaskTest);
- defineReflectiveTests(ScanDartTaskTest);
- defineReflectiveTests(StrongModeInferenceTest);
- defineReflectiveTests(StrongModeVerifyUnitTaskTest);
- defineReflectiveTests(VerifyUnitTaskTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(BuildCompilationUnitElementTaskTest);
+ defineReflectiveTests(BuildDirectiveElementsTaskTest);
+ defineReflectiveTests(BuildEnumMemberElementsTaskTest);
+ defineReflectiveTests(BuildExportNamespaceTaskTest);
+ defineReflectiveTests(BuildLibraryElementTaskTest);
+ defineReflectiveTests(BuildPublicNamespaceTaskTest);
+ defineReflectiveTests(BuildSourceExportClosureTaskTest);
+ defineReflectiveTests(BuildTypeProviderTaskTest);
+ defineReflectiveTests(ComputeConstantDependenciesTaskTest);
+ defineReflectiveTests(ComputeConstantValueTaskTest);
+ defineReflectiveTests(ComputeInferableStaticVariableDependenciesTaskTest);
+ defineReflectiveTests(ComputeLibraryCycleTaskTest);
+ defineReflectiveTests(ContainingLibrariesTaskTest);
+ defineReflectiveTests(DartErrorsTaskTest);
+ defineReflectiveTests(EvaluateUnitConstantsTaskTest);
+ defineReflectiveTests(GatherUsedImportedElementsTaskTest);
+ defineReflectiveTests(GatherUsedLocalElementsTaskTest);
+ defineReflectiveTests(GenerateHintsTaskTest);
+ defineReflectiveTests(GenerateLintsTaskTest);
+ defineReflectiveTests(InferInstanceMembersInUnitTaskTest);
+ defineReflectiveTests(InferStaticVariableTypesInUnitTaskTest);
+ defineReflectiveTests(InferStaticVariableTypeTaskTest);
+ defineReflectiveTests(LibraryErrorsReadyTaskTest);
+ defineReflectiveTests(LibraryUnitErrorsTaskTest);
+ defineReflectiveTests(ParseDartTaskTest);
+ defineReflectiveTests(PartiallyResolveUnitReferencesTaskTest);
+ defineReflectiveTests(ReferencedNamesBuilderTest);
+ defineReflectiveTests(ResolveDirectiveElementsTaskTest);
+ defineReflectiveTests(ResolveInstanceFieldsInUnitTaskTest);
+ defineReflectiveTests(ResolveLibraryTaskTest);
+ defineReflectiveTests(ResolveLibraryTypeNamesTaskTest);
+ defineReflectiveTests(ResolveTopLevelUnitTypeBoundsTaskTest);
+ defineReflectiveTests(ResolveUnitTaskTest);
+ defineReflectiveTests(ResolveUnitTypeNamesTaskTest);
+ defineReflectiveTests(ResolveVariableReferencesTaskTest);
+ defineReflectiveTests(ScanDartTaskTest);
+ defineReflectiveTests(StrongModeInferenceTest);
+ defineReflectiveTests(StrongModeVerifyUnitTaskTest);
+ defineReflectiveTests(VerifyUnitTaskTest);
+ });
}
isInstanceOf isBuildCompilationUnitElementTask =
@@ -926,10 +927,13 @@
}
test_perform_invalidUri_part() {
+ String invalidUri = resourceProvider.pathContext.separator == '/'
+ ? '//////////'
+ : '\\\\\\\\\\\\';
_performBuildTask({
'/lib.dart': '''
library lib;
-part '//////////';
+part '$invalidUri';
'''
});
expect(libraryElement.parts, isEmpty);
@@ -3375,7 +3379,9 @@
void _performParseTask(String content) {
if (content == null) {
- source = resourceProvider.getFile('/test.dart').createSource();
+ source = resourceProvider
+ .getFile(resourceProvider.convertPath('/test.dart'))
+ .createSource();
} else {
source = newSource('/test.dart', content);
}
diff --git a/pkg/analyzer/test/src/task/dart_work_manager_test.dart b/pkg/analyzer/test/src/task/dart_work_manager_test.dart
index 12388d0..ff2092c 100644
--- a/pkg/analyzer/test/src/task/dart_work_manager_test.dart
+++ b/pkg/analyzer/test/src/task/dart_work_manager_test.dart
@@ -12,6 +12,8 @@
import 'package:analyzer/src/generated/engine.dart'
show
AnalysisErrorInfoImpl,
+ AnalysisOptions,
+ AnalysisOptionsImpl,
CacheState,
ChangeNoticeImpl,
InternalAnalysisContext;
@@ -23,16 +25,16 @@
import 'package:analyzer/task/dart.dart';
import 'package:analyzer/task/general.dart';
import 'package:analyzer/task/model.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:typed_mock/typed_mock.dart';
-import 'package:unittest/unittest.dart';
import '../../generated/test_support.dart';
-import '../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(DartWorkManagerTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(DartWorkManagerTest);
+ });
}
@reflectiveTest
@@ -827,6 +829,9 @@
Map<Source, ChangeNoticeImpl> _pendingNotices = <Source, ChangeNoticeImpl>{};
@override
+ final AnalysisOptions analysisOptions = new AnalysisOptionsImpl();
+
+ @override
final ReentrantSynchronousStream<InvalidatedResult> onResultInvalidated =
new ReentrantSynchronousStream<InvalidatedResult>();
diff --git a/pkg/analyzer/test/src/task/driver_test.dart b/pkg/analyzer/test/src/task/driver_test.dart
index 35ff657..99be5d5 100644
--- a/pkg/analyzer/test/src/task/driver_test.dart
+++ b/pkg/analyzer/test/src/task/driver_test.dart
@@ -11,20 +11,20 @@
import 'package:analyzer/src/task/inputs.dart';
import 'package:analyzer/src/task/manager.dart';
import 'package:analyzer/task/model.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:typed_mock/typed_mock.dart';
-import 'package:unittest/unittest.dart';
import '../../generated/test_support.dart';
-import '../../utils.dart';
import 'test_support.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(AnalysisDriverTest);
- defineReflectiveTests(CycleAwareDependencyWalkerTest);
- defineReflectiveTests(WorkItemTest);
- defineReflectiveTests(WorkOrderTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AnalysisDriverTest);
+ defineReflectiveTests(CycleAwareDependencyWalkerTest);
+ defineReflectiveTests(WorkItemTest);
+ defineReflectiveTests(WorkOrderTest);
+ });
}
class AbstractDriverTest {
diff --git a/pkg/analyzer/test/src/task/general_test.dart b/pkg/analyzer/test/src/task/general_test.dart
index fc1f789..819a3af 100644
--- a/pkg/analyzer/test/src/task/general_test.dart
+++ b/pkg/analyzer/test/src/task/general_test.dart
@@ -9,16 +9,16 @@
import 'package:analyzer/src/task/general.dart';
import 'package:analyzer/task/general.dart';
import 'package:analyzer/task/model.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:typed_mock/typed_mock.dart';
-import 'package:unittest/unittest.dart';
import '../../generated/test_support.dart';
-import '../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(GetContentTaskTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(GetContentTaskTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analyzer/test/src/task/html_test.dart b/pkg/analyzer/test/src/task/html_test.dart
index 78fee27..c2e652b 100644
--- a/pkg/analyzer/test/src/task/html_test.dart
+++ b/pkg/analyzer/test/src/task/html_test.dart
@@ -10,17 +10,17 @@
import 'package:analyzer/task/html.dart';
import 'package:analyzer/task/model.dart';
import 'package:html/dom.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../utils.dart';
import '../context/abstract_context.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(DartScriptsTaskTest);
- defineReflectiveTests(HtmlErrorsTaskTest);
- defineReflectiveTests(ParseHtmlTaskTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(DartScriptsTaskTest);
+ defineReflectiveTests(HtmlErrorsTaskTest);
+ defineReflectiveTests(ParseHtmlTaskTest);
+ });
}
isInstanceOf isDartScriptsTask = new isInstanceOf<DartScriptsTask>();
diff --git a/pkg/analyzer/test/src/task/html_work_manager_test.dart b/pkg/analyzer/test/src/task/html_work_manager_test.dart
index 55698a0..ee102d4 100644
--- a/pkg/analyzer/test/src/task/html_work_manager_test.dart
+++ b/pkg/analyzer/test/src/task/html_work_manager_test.dart
@@ -23,16 +23,16 @@
import 'package:analyzer/task/general.dart';
import 'package:analyzer/task/html.dart';
import 'package:analyzer/task/model.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:typed_mock/typed_mock.dart';
-import 'package:unittest/unittest.dart';
import '../../generated/test_support.dart';
-import '../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(HtmlWorkManagerTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(HtmlWorkManagerTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analyzer/test/src/task/incremental_element_builder_test.dart b/pkg/analyzer/test/src/task/incremental_element_builder_test.dart
index b5765eb..7147906 100644
--- a/pkg/analyzer/test/src/task/incremental_element_builder_test.dart
+++ b/pkg/analyzer/test/src/task/incremental_element_builder_test.dart
@@ -14,15 +14,15 @@
import 'package:analyzer/src/task/dart.dart';
import 'package:analyzer/src/task/incremental_element_builder.dart';
import 'package:analyzer/task/dart.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../utils.dart';
import '../context/abstract_context.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(IncrementalCompilationUnitElementBuilderTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(IncrementalCompilationUnitElementBuilderTest);
+ });
}
@reflectiveTest
@@ -97,7 +97,7 @@
expect(newConstructorElement.name, 'a');
// classElement.constructors
ClassElement classElement = helper.element;
- expect(classElement.constructors, unorderedEquals([newConstructorElement]));
+ expect(classElement.constructors, [newConstructorElement]);
// verify delta
expect(helper.delta.hasUnnamedConstructorChange, isTrue);
expect(helper.delta.addedConstructors,
@@ -231,7 +231,7 @@
expect(elementB.name, 'b');
// classElement.constructors
ClassElement classElement = helper.element;
- expect(classElement.constructors, unorderedEquals([elementA, elementB]));
+ expect(classElement.constructors, [elementA, elementB]);
// verify delta
expect(helper.delta.addedConstructors, unorderedEquals([elementB]));
expect(helper.delta.removedConstructors, unorderedEquals([]));
@@ -267,7 +267,7 @@
expect(elementB.name, 'b');
// classElement.constructors
ClassElement classElement = helper.element;
- expect(classElement.constructors, unorderedEquals([elementB]));
+ expect(classElement.constructors, [elementB]);
// verify delta
expect(helper.delta.addedConstructors, unorderedEquals([]));
expect(helper.delta.removedConstructors, unorderedEquals([oldElementA]));
@@ -307,7 +307,7 @@
expect(elementA.name, 'a');
// classElement.constructors
ClassElement classElement = helper.element;
- expect(classElement.constructors, unorderedEquals([elementB, elementA]));
+ expect(classElement.constructors, [elementB, elementA]);
// verify delta
expect(helper.delta.addedConstructors, isEmpty);
expect(helper.delta.removedConstructors, isEmpty);
@@ -463,12 +463,17 @@
// nodes
FieldDeclaration nodeA = helper.newMembers[0];
FieldDeclaration newNodeB = helper.newMembers[1];
+ List<VariableDeclaration> fieldsA = nodeA.fields.variables;
List<VariableDeclaration> newFieldsB = newNodeB.fields.variables;
expect(nodeA, same(helper.oldMembers[0]));
expect(newFieldsB, hasLength(1));
// elements
+ FieldElement fieldElementA = fieldsA[0].name.staticElement;
FieldElement newFieldElementB = newFieldsB[0].name.staticElement;
expect(newFieldElementB.name, 'bbb');
+ // members
+ ClassElement classElement = helper.element;
+ expect(classElement.fields, [fieldElementA, newFieldElementB]);
// verify delta
expect(helper.delta.hasAnnotationChanges, isFalse);
expect(helper.delta.addedConstructors, isEmpty);
@@ -541,17 +546,13 @@
FieldElement newFieldElement = newFieldNode.name.staticElement;
PropertyAccessorElement getterElement = getterNode.element;
expect(newFieldElement.name, '_foo');
- expect(
- helper.element.fields,
- unorderedMatches(
- [same(newFieldElement), same(getterElement.variable)]));
- expect(
- helper.element.accessors,
- unorderedMatches([
- same(newFieldElement.getter),
- same(newFieldElement.setter),
- same(getterElement)
- ]));
+ expect(helper.element.fields,
+ [same(newFieldElement), same(getterElement.variable)]);
+ expect(helper.element.accessors, [
+ same(newFieldElement.getter),
+ same(newFieldElement.setter),
+ same(getterElement)
+ ]);
// verify delta
expect(helper.delta.addedConstructors, isEmpty);
expect(helper.delta.removedConstructors, isEmpty);
@@ -589,6 +590,7 @@
expect(elementA.name, 'aaa');
expect(newElementB, isNotNull);
expect(newElementB.name, 'bbb');
+ expect(helper.element.accessors, [elementA, newElementB]);
// verify delta
expect(helper.delta.addedConstructors, isEmpty);
expect(helper.delta.removedConstructors, isEmpty);
@@ -657,6 +659,7 @@
expect(elementA.name, 'aaa');
expect(newElementB, isNotNull);
expect(newElementB.name, 'bbb');
+ expect(helper.element.methods, [elementA, newElementB]);
// verify delta
expect(helper.delta.addedConstructors, isEmpty);
expect(helper.delta.removedConstructors, isEmpty);
@@ -698,6 +701,7 @@
expect(newElementA.parameters, hasLength(1));
expect(elementB, isNotNull);
expect(elementB.name, 'bbb');
+ expect(helper.element.methods, [newElementA, elementB]);
// verify delta
expect(helper.delta.addedConstructors, isEmpty);
expect(helper.delta.removedConstructors, isEmpty);
@@ -750,6 +754,7 @@
expect(newElementA.name, 'aaa2');
expect(elementB, isNotNull);
expect(elementB.name, 'bbb');
+ expect(helper.element.methods, [newElementA, elementB]);
// verify delta
expect(helper.delta.addedConstructors, isEmpty);
expect(helper.delta.removedConstructors, isEmpty);
@@ -824,6 +829,7 @@
expect(newElementA.parameters, hasLength(0));
expect(elementB, isNotNull);
expect(elementB.name, 'bbb');
+ expect(helper.element.methods, [newElementA, elementB]);
// verify delta
expect(helper.delta.addedConstructors, isEmpty);
expect(helper.delta.removedConstructors, isEmpty);
@@ -833,6 +839,48 @@
expect(helper.delta.removedMethods, unorderedEquals([oldElementA]));
}
+ test_classDelta_newOrder() {
+ var helper = new _ClassDeltaHelper('A');
+ _buildOldUnit(r'''
+class A {
+ bbb() {}
+}
+''');
+ helper.initOld(oldUnit);
+ _buildNewUnit(r'''
+class A {
+ aaa() {}
+ bbb() {}
+ ccc() {}
+}
+''');
+ helper.initNew(newUnit, unitDelta);
+ // nodes
+ ClassMember newNodeA = helper.newMembers[0];
+ ClassMember nodeB = helper.oldMembers[0];
+ ClassMember newNodeC = helper.newMembers[2];
+ expect(nodeB, same(helper.oldMembers[0]));
+ // elements
+ MethodElement newElementA = newNodeA.element;
+ MethodElement elementB = nodeB.element;
+ MethodElement newElementC = newNodeC.element;
+ expect(newElementA, isNotNull);
+ expect(newElementA.name, 'aaa');
+ expect(elementB, isNotNull);
+ expect(elementB.name, 'bbb');
+ expect(newElementC, isNotNull);
+ expect(newElementC.name, 'ccc');
+ expect(helper.element.methods, [newElementA, elementB, newElementC]);
+ // verify delta
+ expect(helper.delta.addedConstructors, isEmpty);
+ expect(helper.delta.removedConstructors, isEmpty);
+ expect(helper.delta.addedAccessors, isEmpty);
+ expect(helper.delta.removedAccessors, isEmpty);
+ expect(
+ helper.delta.addedMethods, unorderedEquals([newElementA, newElementC]));
+ expect(helper.delta.removedMethods, isEmpty);
+ }
+
test_classDelta_null_abstractKeyword_add() {
_verifyNoClassDeltaForTheLast(
r'''
@@ -1027,6 +1075,7 @@
expect(elementA.name, 'aaa=');
expect(newElementB, isNotNull);
expect(newElementB.name, 'bbb=');
+ expect(helper.element.accessors, [elementA, newElementB]);
// verify delta
expect(helper.delta.addedConstructors, isEmpty);
expect(helper.delta.removedConstructors, isEmpty);
@@ -1374,9 +1423,9 @@
expect(elementA.name, 'a');
expect(elementB.name, 'b');
// unit.types
- expect(unitElement.topLevelVariables,
- unorderedEquals([elementA.variable, elementB.variable]));
- expect(unitElement.accessors, unorderedEquals([elementA, elementB]));
+ expect(
+ unitElement.topLevelVariables, [elementA.variable, elementB.variable]);
+ expect(unitElement.accessors, [elementA, elementB]);
}
test_unitMembers_class_add() {
@@ -1401,7 +1450,7 @@
expect(elementA.name, 'A');
expect(elementB.name, 'B');
// unit.types
- expect(unitElement.types, unorderedEquals([elementA, elementB]));
+ expect(unitElement.types, [elementA, elementB]);
// verify delta
expect(unitDelta.addedDeclarations, unorderedEquals([elementB]));
expect(unitDelta.removedDeclarations, unorderedEquals([]));
@@ -1512,7 +1561,7 @@
expect(elementA.name, 'A');
expect(elementB.name, 'B');
// unit.types
- expect(unitElement.types, unorderedEquals([elementA]));
+ expect(unitElement.types, [elementA]);
// verify delta
expect(unitDelta.addedDeclarations, unorderedEquals([]));
expect(unitDelta.removedDeclarations, unorderedEquals([elementB]));
@@ -1593,7 +1642,7 @@
expect(elementB.accessors.map((a) => a.name),
unorderedEquals(['index', 'values', 'B1', 'B2']));
// unit.types
- expect(unitElement.enums, unorderedEquals([elementA, elementB]));
+ expect(unitElement.enums, [elementA, elementB]);
// verify delta
expect(unitDelta.addedDeclarations, unorderedEquals([elementB]));
expect(unitDelta.removedDeclarations, unorderedEquals([]));
@@ -1621,7 +1670,7 @@
expect(elementA.name, 'a');
expect(elementB.name, 'b');
// unit.types
- expect(unitElement.functions, unorderedEquals([elementA, elementB]));
+ expect(unitElement.functions, [elementA, elementB]);
// verify delta
expect(unitDelta.addedDeclarations, unorderedEquals([elementB]));
expect(unitDelta.removedDeclarations, unorderedEquals([]));
@@ -1649,13 +1698,50 @@
expect(elementA.name, 'A');
expect(elementB.name, 'B');
// unit.types
- expect(
- unitElement.functionTypeAliases, unorderedEquals([elementA, elementB]));
+ expect(unitElement.functionTypeAliases, [elementA, elementB]);
// verify delta
expect(unitDelta.addedDeclarations, unorderedEquals([elementB]));
expect(unitDelta.removedDeclarations, unorderedEquals([]));
}
+ test_unitMembers_newOrder() {
+ _buildOldUnit(r'''
+int b;
+''');
+ List<CompilationUnitMember> oldNodes = oldUnit.declarations.toList();
+ _buildNewUnit(r'''
+int a;
+int b;
+int c;
+''');
+ List<CompilationUnitMember> newNodes = newUnit.declarations;
+ // nodes
+ TopLevelVariableDeclaration node1 = newNodes[0];
+ TopLevelVariableDeclaration node2 = newNodes[1];
+ TopLevelVariableDeclaration node3 = newNodes[2];
+ expect(node2, same(oldNodes[0]));
+ // elements
+ TopLevelVariableElement elementA = node1.variables.variables[0].element;
+ TopLevelVariableElement elementB = node2.variables.variables[0].element;
+ TopLevelVariableElement elementC = node3.variables.variables[0].element;
+ expect(elementA, isNotNull);
+ expect(elementB, isNotNull);
+ expect(elementC, isNotNull);
+ expect(elementA.name, 'a');
+ expect(elementB.name, 'b');
+ expect(elementC.name, 'c');
+ // unit.types
+ expect(unitElement.topLevelVariables, [elementA, elementB, elementC]);
+ expect(unitElement.accessors, [
+ elementA.getter,
+ elementA.setter,
+ elementB.getter,
+ elementB.setter,
+ elementC.getter,
+ elementC.setter,
+ ]);
+ }
+
test_unitMembers_topLevelVariable() {
_buildOldUnit(r'''
bool a = 1, b = 2;
@@ -1733,19 +1819,17 @@
expect(elementD.name, 'd');
// unit.types
expect(unitElement.topLevelVariables,
- unorderedEquals([elementA, elementB, elementC, elementD]));
- expect(
- unitElement.accessors,
- unorderedEquals([
- elementA.getter,
- elementA.setter,
- elementB.getter,
- elementB.setter,
- elementC.getter,
- elementC.setter,
- elementD.getter,
- elementD.setter
- ]));
+ [elementA, elementB, elementC, elementD]);
+ expect(unitElement.accessors, [
+ elementA.getter,
+ elementA.setter,
+ elementB.getter,
+ elementB.setter,
+ elementC.getter,
+ elementC.setter,
+ elementD.getter,
+ elementD.setter
+ ]);
}
test_unitMembers_topLevelVariable_final() {
diff --git a/pkg/analyzer/test/src/task/inputs_test.dart b/pkg/analyzer/test/src/task/inputs_test.dart
index 33bcbee..e2bd0fa 100644
--- a/pkg/analyzer/test/src/task/inputs_test.dart
+++ b/pkg/analyzer/test/src/task/inputs_test.dart
@@ -7,26 +7,26 @@
import 'package:analyzer/src/task/inputs.dart';
import 'package:analyzer/src/task/model.dart';
import 'package:analyzer/task/model.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../../generated/test_support.dart';
-import '../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(ConstantTaskInputBuilderTest);
- defineReflectiveTests(ConstantTaskInputTest);
- defineReflectiveTests(ListTaskInputImplTest);
- defineReflectiveTests(ListToListTaskInputTest);
- defineReflectiveTests(ListToListTaskInputBuilderTest);
- defineReflectiveTests(ListToMapTaskInputBuilderTest);
- defineReflectiveTests(ListToMapTaskInputTest);
- defineReflectiveTests(ObjectToListTaskInputBuilderTest);
- defineReflectiveTests(ObjectToListTaskInputTest);
- defineReflectiveTests(SimpleTaskInputTest);
- defineReflectiveTests(SimpleTaskInputBuilderTest);
- defineReflectiveTests(TopLevelTaskInputBuilderTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ConstantTaskInputBuilderTest);
+ defineReflectiveTests(ConstantTaskInputTest);
+ defineReflectiveTests(ListTaskInputImplTest);
+ defineReflectiveTests(ListToListTaskInputTest);
+ defineReflectiveTests(ListToListTaskInputBuilderTest);
+ defineReflectiveTests(ListToMapTaskInputBuilderTest);
+ defineReflectiveTests(ListToMapTaskInputTest);
+ defineReflectiveTests(ObjectToListTaskInputBuilderTest);
+ defineReflectiveTests(ObjectToListTaskInputTest);
+ defineReflectiveTests(SimpleTaskInputTest);
+ defineReflectiveTests(SimpleTaskInputBuilderTest);
+ defineReflectiveTests(TopLevelTaskInputBuilderTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analyzer/test/src/task/manager_test.dart b/pkg/analyzer/test/src/task/manager_test.dart
index cc35b85..3a406b0 100644
--- a/pkg/analyzer/test/src/task/manager_test.dart
+++ b/pkg/analyzer/test/src/task/manager_test.dart
@@ -7,15 +7,15 @@
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/src/task/manager.dart';
import 'package:analyzer/task/model.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../../generated/test_support.dart';
-import '../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(TaskManagerTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(TaskManagerTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analyzer/test/src/task/model_test.dart b/pkg/analyzer/test/src/task/model_test.dart
index edc8f28..e698152 100644
--- a/pkg/analyzer/test/src/task/model_test.dart
+++ b/pkg/analyzer/test/src/task/model_test.dart
@@ -4,23 +4,23 @@
library analyzer.test.src.task.model_test;
-import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/exception/exception.dart';
+import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/task/model.dart';
import 'package:analyzer/task/model.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import '../../generated/test_support.dart';
-import '../../utils.dart';
import 'test_support.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(AnalysisTaskTest);
- defineReflectiveTests(ResultDescriptorImplTest);
- defineReflectiveTests(SimpleResultCachingPolicyTest);
- defineReflectiveTests(TaskDescriptorImplTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AnalysisTaskTest);
+ defineReflectiveTests(ResultDescriptorImplTest);
+ defineReflectiveTests(SimpleResultCachingPolicyTest);
+ defineReflectiveTests(TaskDescriptorImplTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analyzer/test/src/task/options_test.dart b/pkg/analyzer/test/src/task/options_test.dart
index 8e50dc0..b422eba 100644
--- a/pkg/analyzer/test/src/task/options_test.dart
+++ b/pkg/analyzer/test/src/task/options_test.dart
@@ -15,20 +15,20 @@
import 'package:analyzer/src/task/options.dart';
import 'package:analyzer/task/general.dart';
import 'package:analyzer/task/model.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import 'package:yaml/yaml.dart';
import '../../generated/test_support.dart';
-import '../../utils.dart';
import '../context/abstract_context.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(ContextConfigurationTest);
- defineReflectiveTests(GenerateNewOptionsErrorsTaskTest);
- defineReflectiveTests(GenerateOldOptionsErrorsTaskTest);
- defineReflectiveTests(OptionsFileValidatorTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ContextConfigurationTest);
+ defineReflectiveTests(GenerateNewOptionsErrorsTaskTest);
+ defineReflectiveTests(GenerateOldOptionsErrorsTaskTest);
+ defineReflectiveTests(OptionsFileValidatorTest);
+ });
}
isInstanceOf isGenerateOptionsErrorsTask =
diff --git a/pkg/analyzer/test/src/task/options_work_manager_test.dart b/pkg/analyzer/test/src/task/options_work_manager_test.dart
index d52286b..5c8712e 100644
--- a/pkg/analyzer/test/src/task/options_work_manager_test.dart
+++ b/pkg/analyzer/test/src/task/options_work_manager_test.dart
@@ -22,17 +22,17 @@
import 'package:analyzer/task/dart.dart';
import 'package:analyzer/task/general.dart';
import 'package:analyzer/task/model.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:typed_mock/typed_mock.dart';
-import 'package:unittest/unittest.dart';
import '../../generated/test_support.dart';
-import '../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(OptionsWorkManagerNewFileTest);
- defineReflectiveTests(OptionsWorkManagerOldFileTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(OptionsWorkManagerNewFileTest);
+ defineReflectiveTests(OptionsWorkManagerOldFileTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index 9013f21..40fd228 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -9,12 +9,34 @@
import 'strong_test_helper.dart';
void main() {
- initStrongModeTests();
- defineReflectiveTests(CheckerTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(CheckerTest);
+ });
+}
+
+void _addMetaLibrary() {
+ addFile(
+ r'''
+library meta;
+class _Checked { const _Checked(); }
+const Object checked = const _Checked();
+
+class _Virtual { const _Virtual(); }
+const Object virtual = const _Virtual();
+ ''',
+ name: '/meta.dart');
}
@reflectiveTest
class CheckerTest {
+ void setUp() {
+ doSetUp();
+ }
+
+ void tearDown() {
+ doTearDown();
+ }
+
void test_awaitForInCastsStreamElementToVariable() {
checkFile('''
import 'dart:async';
@@ -239,6 +261,20 @@
''');
}
+ 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_compoundAssignments() {
checkFile('''
class A {
@@ -380,20 +416,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('''
@@ -3175,6 +3197,19 @@
check(implicitCasts: false);
}
+ void test_overrideNarrowsType_legalWithChecked() {
+ // Regression test for https://github.com/dart-lang/sdk/issues/25232
+ _addMetaLibrary();
+ checkFile(r'''
+import 'meta.dart';
+abstract class A { void test(A arg) { } }
+abstract class B extends A { void test(@checked B arg) { } }
+abstract class X implements A { }
+class C extends B with X { }
+class D extends B implements A { }
+ ''');
+ }
+
void test_overrideNarrowsType_noDuplicateError() {
// Regression test for https://github.com/dart-lang/sdk/issues/25232
_addMetaLibrary();
@@ -3193,19 +3228,6 @@
''');
}
- void test_overrideNarrowsType_legalWithChecked() {
- // Regression test for https://github.com/dart-lang/sdk/issues/25232
- _addMetaLibrary();
- checkFile(r'''
-import 'meta.dart';
-abstract class A { void test(A arg) { } }
-abstract class B extends A { void test(@checked B arg) { } }
-abstract class X implements A { }
-class C extends B with X { }
-class D extends B implements A { }
- ''');
- }
-
void test_privateOverride() {
addFile(
'''
@@ -3945,14 +3967,3 @@
''');
}
}
-
-void _addMetaLibrary() {
- addFile(r'''
-library meta;
-class _Checked { const _Checked(); }
-const Object checked = const _Checked();
-
-class _Virtual { const _Virtual(); }
-const Object virtual = const _Virtual();
- ''', name: '/meta.dart');
-}
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 5a0bc4d..da86f94 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -8,14 +8,15 @@
library analyzer.test.src.task.strong.inferred_type_test;
import 'package:analyzer/dart/element/element.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import 'strong_test_helper.dart' as helper;
void main() {
- helper.initStrongModeTests();
- defineReflectiveTests(InferredTypeTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(InferredTypeTest);
+ });
}
abstract class InferredTypeMixin {
@@ -4630,4 +4631,12 @@
CompilationUnitElement checkFile(String content) {
return helper.checkFile(content).element;
}
+
+ void setUp() {
+ helper.doSetUp();
+ }
+
+ void tearDown() {
+ helper.doTearDown();
+ }
}
diff --git a/pkg/analyzer/test/src/task/strong/non_null_checker_test.dart b/pkg/analyzer/test/src/task/strong/non_null_checker_test.dart
index d130a54..82aef195 100644
--- a/pkg/analyzer/test/src/task/strong/non_null_checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/non_null_checker_test.dart
@@ -14,8 +14,9 @@
import '../strong/strong_test_helper.dart';
void main() {
- initStrongModeTests();
- defineReflectiveTests(NonNullCheckerTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(NonNullCheckerTest);
+ });
}
String _withError(String file, String error) {
@@ -73,6 +74,14 @@
}
''';
+ void setUp() {
+ doSetUp();
+ }
+
+ void tearDown() {
+ doTearDown();
+ }
+
void test_assign_null_to_nonnullable() {
addFile('''
int x = 0;
@@ -85,27 +94,6 @@
check(nonnullableTypes: <String>['dart:core,int']);
}
- void test_forLoop() {
- checkFile('''
-class MyList {
- int length;
- MyList() {
- length = 6;
- }
- String operator [](int i) {
- return <String>["Dart", "Java", "JS", "C", "C++", "C#"][i];
- }
-}
-
-main() {
- var languages = new MyList();
- for (int i = 0; i < languages.length; ++i) {
- print(languages[i]);
- }
-}
-''');
- }
-
void test_compoundAssignment() {
addFile('''
void main() {
@@ -130,98 +118,25 @@
check(nonnullableTypes: <String>['dart:core,int']);
}
- void test_initialize_nonnullable_with_null() {
- addFile('int x = /*error:INVALID_ASSIGNMENT*/null;');
- check(nonnullableTypes: <String>['dart:core,int']);
+ void test_forLoop() {
+ checkFile('''
+class MyList {
+ int length;
+ MyList() {
+ length = 6;
}
-
- void test_initialize_nonnullable_with_valid_value() {
- addFile('int x = 0;');
- check(nonnullableTypes: <String>['dart:core,int']);
+ String operator [](int i) {
+ return <String>["Dart", "Java", "JS", "C", "C++", "C#"][i];
}
+}
- void test_nonnullable_fields() {
- addFile(defaultNnbdExample);
- // `null` can be passed as an argument to `Point` in default mode.
- addFile(_withError(defaultNnbdExampleMod1, "error:INVALID_ASSIGNMENT"));
- // A nullable expression can be passed as an argument to `Point` in default
- // mode.
- addFile(_withError(defaultNnbdExampleMod2, "error:INVALID_ASSIGNMENT"));
- check(nonnullableTypes: <String>['dart:core,int']);
+main() {
+ var languages = new MyList();
+ for (int i = 0; i < languages.length; ++i) {
+ print(languages[i]);
}
-
- void test_nullable_fields() {
- addFile(defaultNnbdExample);
- // `null` can be passed as an argument to `Point` in default mode.
- addFile(defaultNnbdExampleMod1);
- // A nullable expression can be passed as an argument to `Point` in default
- // mode.
- addFile(defaultNnbdExampleMod2);
- check();
- }
-
- // Default example from NNBD document.
- void test_nullableTypes() {
- // By default x can be set to null.
- checkFile('int x = null;');
- }
-
- void test_prefer_final_to_non_nullable_error() {
- addFile('main() { final int /*error:FINAL_NOT_INITIALIZED*/x; }');
- addFile('final int /*error:FINAL_NOT_INITIALIZED*/x;');
- addFile('''
-void foo() {}
-
-class A {
- final int x;
-
- /*warning:FINAL_NOT_INITIALIZED_CONSTRUCTOR_1*/A();
}
''');
- check(nonnullableTypes: <String>['dart:core,int']);
- }
-
- void test_uninitialized_nonnullable_field_declaration() {
- addFile('''
-void foo() {}
-
-class A {
- // Ideally, we should allow x to be init in the constructor, but that requires
- // too much complication in the checker, so for now we throw a static error at
- // the declaration site.
- int /*error:NON_NULLABLE_FIELD_NOT_INITIALIZED*/x;
-
- A();
-}
-''');
- check(nonnullableTypes: <String>['dart:core,int']);
- }
-
- void test_uninitialized_nonnullable_local_variable() {
- // Ideally, we will do flow analysis and throw an error only if a variable
- // is used before it has been initialized.
- addFile('main() { int /*error:NON_NULLABLE_FIELD_NOT_INITIALIZED*/x; }');
- check(nonnullableTypes: <String>['dart:core,int']);
- }
-
- void test_uninitialized_nonnullable_top_level_variable_declaration() {
- // If `int`s are non-nullable, then this code should throw an error.
- addFile('int /*error:NON_NULLABLE_FIELD_NOT_INITIALIZED*/x;');
- check(nonnullableTypes: <String>['dart:core,int']);
- }
-
- void test_method_call() {
- addFile('''
-int s(int x) {
- return x + 1;
-}
-
-void main() {
- s(10);
- s(/*error:INVALID_ASSIGNMENT*/null);
-}
-''');
- check(nonnullableTypes: <String>['dart:core,int']);
}
void test_generics() {
@@ -259,6 +174,16 @@
check(nonnullableTypes: <String>['dart:core,int']);
}
+ void test_initialize_nonnullable_with_null() {
+ addFile('int x = /*error:INVALID_ASSIGNMENT*/null;');
+ check(nonnullableTypes: <String>['dart:core,int']);
+ }
+
+ void test_initialize_nonnullable_with_valid_value() {
+ addFile('int x = 0;');
+ check(nonnullableTypes: <String>['dart:core,int']);
+ }
+
void test_map() {
addFile('''
class Pair<K, V> {
@@ -312,4 +237,88 @@
''');
check(nonnullableTypes: <String>['dart:core,int']);
}
+
+ // Default example from NNBD document.
+ void test_method_call() {
+ addFile('''
+int s(int x) {
+ return x + 1;
+}
+
+void main() {
+ s(10);
+ s(/*error:INVALID_ASSIGNMENT*/null);
+}
+''');
+ check(nonnullableTypes: <String>['dart:core,int']);
+ }
+
+ void test_nonnullable_fields() {
+ addFile(defaultNnbdExample);
+ // `null` can be passed as an argument to `Point` in default mode.
+ addFile(_withError(defaultNnbdExampleMod1, "error:INVALID_ASSIGNMENT"));
+ // A nullable expression can be passed as an argument to `Point` in default
+ // mode.
+ addFile(_withError(defaultNnbdExampleMod2, "error:INVALID_ASSIGNMENT"));
+ check(nonnullableTypes: <String>['dart:core,int']);
+ }
+
+ void test_nullable_fields() {
+ addFile(defaultNnbdExample);
+ // `null` can be passed as an argument to `Point` in default mode.
+ addFile(defaultNnbdExampleMod1);
+ // A nullable expression can be passed as an argument to `Point` in default
+ // mode.
+ addFile(defaultNnbdExampleMod2);
+ check();
+ }
+
+ void test_nullableTypes() {
+ // By default x can be set to null.
+ checkFile('int x = null;');
+ }
+
+ void test_prefer_final_to_non_nullable_error() {
+ addFile('main() { final int /*error:FINAL_NOT_INITIALIZED*/x; }');
+ addFile('final int /*error:FINAL_NOT_INITIALIZED*/x;');
+ addFile('''
+void foo() {}
+
+class A {
+ final int x;
+
+ /*warning:FINAL_NOT_INITIALIZED_CONSTRUCTOR_1*/A();
+}
+''');
+ check(nonnullableTypes: <String>['dart:core,int']);
+ }
+
+ void test_uninitialized_nonnullable_field_declaration() {
+ addFile('''
+void foo() {}
+
+class A {
+ // Ideally, we should allow x to be init in the constructor, but that requires
+ // too much complication in the checker, so for now we throw a static error at
+ // the declaration site.
+ int /*error:NON_NULLABLE_FIELD_NOT_INITIALIZED*/x;
+
+ A();
+}
+''');
+ check(nonnullableTypes: <String>['dart:core,int']);
+ }
+
+ void test_uninitialized_nonnullable_local_variable() {
+ // Ideally, we will do flow analysis and throw an error only if a variable
+ // is used before it has been initialized.
+ addFile('main() { int /*error:NON_NULLABLE_FIELD_NOT_INITIALIZED*/x; }');
+ check(nonnullableTypes: <String>['dart:core,int']);
+ }
+
+ void test_uninitialized_nonnullable_top_level_variable_declaration() {
+ // If `int`s are non-nullable, then this code should throw an error.
+ addFile('int /*error:NON_NULLABLE_FIELD_NOT_INITIALIZED*/x;');
+ check(nonnullableTypes: <String>['dart:core,int']);
+ }
}
diff --git a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
index dd03301..2b8314d 100644
--- a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
+++ b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
@@ -19,7 +19,7 @@
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:source_span/source_span.dart';
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
import '../../context/mock_sdk.dart';
@@ -46,7 +46,7 @@
/// For a single file, you may also use [checkFile].
void addFile(String content, {String name: '/main.dart'}) {
name = name.replaceFirst('^package:', '/packages/');
- files.newFile(name, content);
+ files.newFile(files.convertPath(name), content);
}
/// Run the checker on a program, staring from '/main.dart', and verifies that
@@ -62,8 +62,8 @@
List<String> nonnullableTypes: AnalysisOptionsImpl.NONNULLABLE_TYPES}) {
_checkCalled = true;
- expect(files.getFile('/main.dart').exists, true,
- reason: '`/main.dart` is missing');
+ File mainFile = files.getFile(files.convertPath('/main.dart'));
+ expect(mainFile.exists, true, reason: '`/main.dart` is missing');
var uriResolver = new _TestUriResolver(files);
// Enable task model strong mode
@@ -74,13 +74,13 @@
options.implicitCasts = implicitCasts;
options.implicitDynamic = implicitDynamic;
options.nonnullableTypes = nonnullableTypes;
- var mockSdk = new MockSdk();
+ var mockSdk = new MockSdk(resourceProvider: files);
(mockSdk.context.analysisOptions as AnalysisOptionsImpl).strongMode = true;
context.sourceFactory =
new SourceFactory([new DartUriResolver(mockSdk), uriResolver]);
// Run the checker on /main.dart.
- Source mainSource = uriResolver.resolveAbsolute(new Uri.file('/main.dart'));
+ Source mainSource = uriResolver.resolveAbsolute(mainFile.toUri());
var initialLibrary = context.resolveCompilationUnit2(mainSource, mainSource);
var collector = new _ErrorCollector(context);
@@ -123,18 +123,16 @@
return check();
}
-void initStrongModeTests() {
- setUp(() {
- AnalysisEngine.instance.processRequiredPlugins();
- files = new MemoryResourceProvider();
- _checkCalled = false;
- });
+void doSetUp() {
+ AnalysisEngine.instance.processRequiredPlugins();
+ files = new MemoryResourceProvider();
+ _checkCalled = false;
+}
- tearDown(() {
- // This is a sanity check, in case only addFile is called.
- expect(_checkCalled, true, reason: 'must call check() method in test case');
- files = null;
- });
+void doTearDown() {
+ // This is a sanity check, in case only addFile is called.
+ expect(_checkCalled, true, reason: 'must call check() method in test case');
+ files = null;
}
SourceSpanWithContext _createSpanHelper(
@@ -402,7 +400,8 @@
@override
Source resolveAbsolute(Uri uri, [Uri actualUri]) {
if (uri.scheme == 'package') {
- return (provider.getResource('/packages/' + uri.path) as File)
+ return (provider.getResource(
+ provider.convertPath('/packages/' + uri.path)) as File)
.createSource(uri);
}
return super.resolveAbsolute(uri, actualUri);
diff --git a/pkg/analyzer/test/src/task/strong/test_all.dart b/pkg/analyzer/test/src/task/strong/test_all.dart
index 698e2ae..7b65843 100644
--- a/pkg/analyzer/test/src/task/strong/test_all.dart
+++ b/pkg/analyzer/test/src/task/strong/test_all.dart
@@ -4,17 +4,15 @@
library analyzer.test.src.task.strong.test_all;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../../utils.dart';
import 'checker_test.dart' as checker_test;
import 'inferred_type_test.dart' as inferred_type_test;
/// Utility for manually running all tests.
main() {
- initializeTestEnvironment();
- group('strong tests', () {
+ defineReflectiveSuite(() {
checker_test.main();
inferred_type_test.main();
- });
+ }, name: 'strong');
}
diff --git a/pkg/analyzer/test/src/task/strong_mode_test.dart b/pkg/analyzer/test/src/task/strong_mode_test.dart
index 0ede013..fa2877c 100644
--- a/pkg/analyzer/test/src/task/strong_mode_test.dart
+++ b/pkg/analyzer/test/src/task/strong_mode_test.dart
@@ -10,17 +10,17 @@
import 'package:analyzer/src/dart/resolver/inheritance_manager.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/task/strong_mode.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-import '../../utils.dart';
import '../context/abstract_context.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(InstanceMemberInferrerTest);
- defineReflectiveTests(SetFieldTypeTest);
- defineReflectiveTests(VariableGathererTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(InstanceMemberInferrerTest);
+ defineReflectiveTests(SetFieldTypeTest);
+ defineReflectiveTests(VariableGathererTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analyzer/test/src/task/test_all.dart b/pkg/analyzer/test/src/task/test_all.dart
index 22108ff..f34c36c 100644
--- a/pkg/analyzer/test/src/task/test_all.dart
+++ b/pkg/analyzer/test/src/task/test_all.dart
@@ -4,9 +4,8 @@
library analyzer.test.src.task.test_all;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../utils.dart';
import 'dart_test.dart' as dart_test;
import 'dart_work_manager_test.dart' as dart_work_manager_test;
import 'driver_test.dart' as driver_test;
@@ -26,8 +25,7 @@
/// Utility for manually running all tests.
main() {
- initializeTestEnvironment();
- group('task tests', () {
+ defineReflectiveSuite(() {
dart_test.main();
dart_work_manager_test.main();
driver_test.main();
@@ -43,5 +41,5 @@
strong_mode_test_all.main();
strong_mode_test.main();
yaml_test.main();
- });
+ }, name: 'task');
}
diff --git a/pkg/analyzer/test/src/task/yaml_test.dart b/pkg/analyzer/test/src/task/yaml_test.dart
index 34e5dc7..4601360 100644
--- a/pkg/analyzer/test/src/task/yaml_test.dart
+++ b/pkg/analyzer/test/src/task/yaml_test.dart
@@ -8,16 +8,16 @@
import 'package:analyzer/src/task/yaml.dart';
import 'package:analyzer/task/general.dart';
import 'package:analyzer/task/yaml.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
import 'package:yaml/yaml.dart';
-import '../../utils.dart';
import '../context/abstract_context.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(ParseYamlTaskTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ParseYamlTaskTest);
+ });
}
isInstanceOf isParseYamlTask = new isInstanceOf<ParseYamlTask>();
diff --git a/pkg/analyzer/test/src/test_all.dart b/pkg/analyzer/test/src/test_all.dart
index 94cbace..41743e2 100644
--- a/pkg/analyzer/test/src/test_all.dart
+++ b/pkg/analyzer/test/src/test_all.dart
@@ -4,9 +4,8 @@
library analyzer.test.src.test_all;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../utils.dart';
import 'context/test_all.dart' as context;
import 'dart/test_all.dart' as dart;
import 'plugin/plugin_config_test.dart' as plugin;
@@ -17,8 +16,7 @@
/// Utility for manually running all tests.
main() {
- initializeTestEnvironment();
- group('src tests', () {
+ defineReflectiveSuite(() {
context.main();
dart.main();
plugin.main();
@@ -26,5 +24,5 @@
summary.main();
task.main();
util.main();
- });
+ }, name: 'src');
}
diff --git a/pkg/analyzer/test/src/util/absolute_path_test.dart b/pkg/analyzer/test/src/util/absolute_path_test.dart
index f8be96b..42c8449 100644
--- a/pkg/analyzer/test/src/util/absolute_path_test.dart
+++ b/pkg/analyzer/test/src/util/absolute_path_test.dart
@@ -5,15 +5,14 @@
library analyzer.test.src.util.absolute_path_test;
import 'package:analyzer/src/util/absolute_path.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(AbsolutePathContextPosixTest);
- defineReflectiveTests(AbsolutePathContextWindowsTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AbsolutePathContextPosixTest);
+ defineReflectiveTests(AbsolutePathContextWindowsTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analyzer/test/src/util/asserts_test.dart b/pkg/analyzer/test/src/util/asserts_test.dart
index 3d8ade7..fdea26a 100644
--- a/pkg/analyzer/test/src/util/asserts_test.dart
+++ b/pkg/analyzer/test/src/util/asserts_test.dart
@@ -5,14 +5,13 @@
library analyzer.test.src.util.asserts_test;
import 'package:analyzer/src/util/asserts.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(AnalysisTaskTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(AnalysisTaskTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analyzer/test/src/util/fast_uri_test.dart b/pkg/analyzer/test/src/util/fast_uri_test.dart
index a076c96..8ed7be6 100644
--- a/pkg/analyzer/test/src/util/fast_uri_test.dart
+++ b/pkg/analyzer/test/src/util/fast_uri_test.dart
@@ -5,14 +5,13 @@
library analyzer.test.src.util.fast_uri_test;
import 'package:analyzer/src/util/fast_uri.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(_FastUriTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(_FastUriTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analyzer/test/src/util/glob_test.dart b/pkg/analyzer/test/src/util/glob_test.dart
index c4c037e..8fffbf7 100644
--- a/pkg/analyzer/test/src/util/glob_test.dart
+++ b/pkg/analyzer/test/src/util/glob_test.dart
@@ -5,15 +5,14 @@
library analyzer.test.src.util.glob_test;
import 'package:analyzer/src/util/glob.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(GlobPosixTest);
- defineReflectiveTests(GlobWindowsTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(GlobPosixTest);
+ defineReflectiveTests(GlobWindowsTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analyzer/test/src/util/lru_map_test.dart b/pkg/analyzer/test/src/util/lru_map_test.dart
index 5d7f86a..369906a 100644
--- a/pkg/analyzer/test/src/util/lru_map_test.dart
+++ b/pkg/analyzer/test/src/util/lru_map_test.dart
@@ -5,14 +5,13 @@
library analyzer.test.src.util.lru_map_test;
import 'package:analyzer/src/util/lru_map.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../utils.dart';
main() {
- initializeTestEnvironment();
- defineReflectiveTests(_LRUCacheTest);
+ defineReflectiveSuite(() {
+ defineReflectiveTests(_LRUCacheTest);
+ });
}
@reflectiveTest
diff --git a/pkg/analyzer/test/src/util/test_all.dart b/pkg/analyzer/test/src/util/test_all.dart
index 6091c5b..c41d8c8 100644
--- a/pkg/analyzer/test/src/util/test_all.dart
+++ b/pkg/analyzer/test/src/util/test_all.dart
@@ -4,9 +4,8 @@
library analyzer.test.src.util.test_all;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
-import '../../utils.dart';
import 'absolute_path_test.dart' as absolute_path_test;
import 'asserts_test.dart' as asserts_test;
import 'fast_uri_test.dart' as fast_uri_test;
@@ -16,13 +15,12 @@
/// Utility for manually running all tests.
main() {
- initializeTestEnvironment();
- group('util tests', () {
+ defineReflectiveSuite(() {
absolute_path_test.main();
asserts_test.main();
fast_uri_test.main();
glob_test.main();
lru_map_test.main();
yaml_test.main();
- });
+ }, name: 'util');
}
diff --git a/pkg/analyzer/test/src/util/yaml_test.dart b/pkg/analyzer/test/src/util/yaml_test.dart
index feb812b..4e109ac 100644
--- a/pkg/analyzer/test/src/util/yaml_test.dart
+++ b/pkg/analyzer/test/src/util/yaml_test.dart
@@ -5,13 +5,9 @@
library analyzer.src.test.util.yaml_test;
import 'package:analyzer/src/util/yaml.dart';
-import 'package:unittest/unittest.dart';
-
-import '../../utils.dart';
+import 'package:test/test.dart';
main() {
- initializeTestEnvironment();
-
group('yaml', () {
group('merge', () {
test('map', () {
diff --git a/pkg/analyzer/test/stress/for_git_repository.dart b/pkg/analyzer/test/stress/for_git_repository.dart
index 858d7f3..0fe14f3 100644
--- a/pkg/analyzer/test/stress/for_git_repository.dart
+++ b/pkg/analyzer/test/stress/for_git_repository.dart
@@ -27,7 +27,7 @@
import 'package:analyzer/task/general.dart';
import 'package:analyzer/task/model.dart';
import 'package:path/path.dart' as path;
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
main() {
new StressTest().run();
@@ -244,8 +244,7 @@
pathContext = resourceProvider.pathContext;
fs.Folder sdkDirectory =
FolderBasedDartSdk.defaultSdkDirectory(resourceProvider);
- sdkManager = new DartSdkManager(sdkDirectory.path, false,
- (_) => new FolderBasedDartSdk(resourceProvider, sdkDirectory));
+ sdkManager = new DartSdkManager(sdkDirectory.path, false);
contentCache = new ContentCache();
ContextBuilder builder =
new ContextBuilder(resourceProvider, sdkManager, contentCache);
diff --git a/pkg/analyzer/test/test_all.dart b/pkg/analyzer/test/test_all.dart
index 1d598fb..d9cdf90 100644
--- a/pkg/analyzer/test/test_all.dart
+++ b/pkg/analyzer/test/test_all.dart
@@ -4,7 +4,7 @@
library analyzer.test.test_all;
-import 'package:unittest/unittest.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'cancelable_future_test.dart' as cancelable_future_test;
import 'context/test_all.dart' as context;
@@ -14,12 +14,10 @@
import 'parse_compilation_unit_test.dart' as parse_compilation_unit;
import 'source/test_all.dart' as source;
import 'src/test_all.dart' as src;
-import 'utils.dart';
/// Utility for manually running all tests.
main() {
- initializeTestEnvironment();
- group('analysis engine', () {
+ defineReflectiveSuite(() {
cancelable_future_test.main();
context.main();
file_system.main();
@@ -28,5 +26,5 @@
parse_compilation_unit.main();
source.main();
src.main();
- });
+ }, name: 'analyzer');
}
diff --git a/pkg/analyzer/test/utils.dart b/pkg/analyzer/test/utils.dart
index 863b0ee..be7e64d 100644
--- a/pkg/analyzer/test/utils.dart
+++ b/pkg/analyzer/test/utils.dart
@@ -7,15 +7,8 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/generated/java_io.dart';
import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
-import 'package:path/path.dart' as path;
-import 'package:unittest/unittest.dart';
-
-void initializeTestEnvironment([path.Context context]) {
- groupSep = ' | ';
- JavaFile.pathContext = context ?? path.posix;
-}
+import 'package:test/test.dart';
/**
* The type of an assertion which asserts properties of [T]s.
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart
index ec779a7..d46d3f5 100644
--- a/pkg/analyzer_cli/lib/src/driver.dart
+++ b/pkg/analyzer_cli/lib/src/driver.dart
@@ -311,6 +311,9 @@
options.buildSummaryInputs, _previousOptions.buildSummaryInputs)) {
return false;
}
+ if (options.disableCacheFlushing != _previousOptions.disableCacheFlushing) {
+ return false;
+ }
return true;
}
@@ -663,6 +666,7 @@
CommandLineOptions options) {
AnalysisOptionsImpl contextOptions = new AnalysisOptionsImpl();
contextOptions.trackCacheDependencies = false;
+ contextOptions.disableCacheFlushing = options.disableCacheFlushing;
contextOptions.hint = !options.disableHints;
contextOptions.enableInitializingFormalAccess =
options.enableInitializingFormalAccess;
diff --git a/pkg/analyzer_cli/lib/src/options.dart b/pkg/analyzer_cli/lib/src/options.dart
index c64eddc..be7dbae 100644
--- a/pkg/analyzer_cli/lib/src/options.dart
+++ b/pkg/analyzer_cli/lib/src/options.dart
@@ -74,6 +74,11 @@
/// A table mapping the names of defined variables to their values.
final Map<String, String> definedVariables;
+ /// Whether to disable cache flushing. This option can improve analysis
+ /// speed at the expense of memory usage. It may also be useful for working
+ /// around bugs.
+ final bool disableCacheFlushing;
+
/// Whether to report hints
final bool disableHints;
@@ -171,6 +176,7 @@
dartSdkSummaryPath = args['dart-sdk-summary'],
definedVariables = definedVariables,
analysisOptionsFile = args['options'],
+ disableCacheFlushing = args['disable-cache-flushing'],
disableHints = args['no-hints'],
displayVersion = args['version'],
enableInitializingFormalAccess = args['initializing-formal-access'],
@@ -314,6 +320,7 @@
help: 'Do not show hint results.',
defaultsTo: false,
negatable: false)
+ ..addFlag('disable-cache-flushing', defaultsTo: false, hide: true)
..addFlag('ignore-unrecognized-flags',
help: 'Ignore unrecognized command line flags.',
defaultsTo: false,
diff --git a/pkg/analyzer_cli/pubspec.yaml b/pkg/analyzer_cli/pubspec.yaml
index a19fecb..2c0108f 100644
--- a/pkg/analyzer_cli/pubspec.yaml
+++ b/pkg/analyzer_cli/pubspec.yaml
@@ -16,6 +16,6 @@
protobuf: ^0.5.0
yaml: ^2.1.2
dev_dependencies:
- test_reflective_loader: '>=0.0.3 <0.1.0'
+ test_reflective_loader: ^0.1.0
typed_mock: '>=0.0.4 <1.0.0'
- unittest: '>=0.9.0 <0.12.0'
+ test: ^0.12.0
diff --git a/pkg/analyzer_cli/test/boot_loader_test.dart b/pkg/analyzer_cli/test/boot_loader_test.dart
index d24d961..30223fb 100644
--- a/pkg/analyzer_cli/test/boot_loader_test.dart
+++ b/pkg/analyzer_cli/test/boot_loader_test.dart
@@ -11,7 +11,7 @@
import 'package:analyzer_cli/src/driver.dart';
import 'package:analyzer_cli/src/options.dart';
import 'package:path/path.dart' as path;
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
import 'utils.dart';
@@ -43,8 +43,6 @@
tearDown(() => _tearDown());
- initializeTestEnvironment();
-
group('Bootloader', () {
group('plugin processing', () {
test('bad format', () {
diff --git a/pkg/analyzer_cli/test/build_mode_test.dart b/pkg/analyzer_cli/test/build_mode_test.dart
index 5e16d95..22f20a9 100644
--- a/pkg/analyzer_cli/test/build_mode_test.dart
+++ b/pkg/analyzer_cli/test/build_mode_test.dart
@@ -11,8 +11,8 @@
import 'package:bazel_worker/bazel_worker.dart';
import 'package:bazel_worker/testing.dart';
import 'package:protobuf/protobuf.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
main() {
defineReflectiveTests(WorkerLoopTest);
diff --git a/pkg/analyzer_cli/test/driver_test.dart b/pkg/analyzer_cli/test/driver_test.dart
index cacbc28..0a41705 100644
--- a/pkg/analyzer_cli/test/driver_test.dart
+++ b/pkg/analyzer_cli/test/driver_test.dart
@@ -19,7 +19,7 @@
import 'package:analyzer_cli/src/options.dart';
import 'package:path/path.dart' as path;
import 'package:plugin/plugin.dart';
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
import 'package:yaml/src/yaml_node.dart';
import 'utils.dart';
@@ -52,8 +52,6 @@
tearDown(() => _tearDown());
- initializeTestEnvironment();
-
group('Driver', () {
group('options', () {
test('custom processor', () {
diff --git a/pkg/analyzer_cli/test/embedder_test.dart b/pkg/analyzer_cli/test/embedder_test.dart
index 93bbaf5..c1c544c 100644
--- a/pkg/analyzer_cli/test/embedder_test.dart
+++ b/pkg/analyzer_cli/test/embedder_test.dart
@@ -8,13 +8,11 @@
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer_cli/src/driver.dart' show Driver, errorSink, outSink;
import 'package:path/path.dart' as path;
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
import 'utils.dart';
main() {
- initializeTestEnvironment();
-
group('_embedder.yaml', () {
StringSink savedOutSink, savedErrorSink;
int savedExitCode;
diff --git a/pkg/analyzer_cli/test/error_test.dart b/pkg/analyzer_cli/test/error_test.dart
index ad80133..c1c7988 100644
--- a/pkg/analyzer_cli/test/error_test.dart
+++ b/pkg/analyzer_cli/test/error_test.dart
@@ -2,10 +2,9 @@
// 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 analyzer_cli.test.error;
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
import 'utils.dart';
@@ -20,35 +19,47 @@
});
test("an error on the first line", () {
- expect(errorsForFile('void foo;\n'), equals(
- "Error in test.dart: Variables cannot have a type of 'void'\n"));
+ expect(
+ errorsForFile('void foo;\n'),
+ equals(
+ "Error in test.dart: Variables cannot have a type of 'void'\n"));
});
test("an error on the last line", () {
- expect(errorsForFile('\nvoid foo;'), equals(
- "Error in test.dart: Variables cannot have a type of 'void'\n"));
+ expect(
+ errorsForFile('\nvoid foo;'),
+ equals(
+ "Error in test.dart: Variables cannot have a type of 'void'\n"));
});
test("an error in the middle", () {
- expect(errorsForFile('\nvoid foo;\n'), equals(
- "Error in test.dart: Variables cannot have a type of 'void'\n"));
+ expect(
+ errorsForFile('\nvoid foo;\n'),
+ equals(
+ "Error in test.dart: Variables cannot have a type of 'void'\n"));
});
var veryLongString = new List.filled(107, ' ').join('');
test("an error at the end of a very long line", () {
- expect(errorsForFile('$veryLongString void foo;'), equals(
- "Error in test.dart: Variables cannot have a type of 'void'\n"));
+ expect(
+ errorsForFile('$veryLongString void foo;'),
+ equals(
+ "Error in test.dart: Variables cannot have a type of 'void'\n"));
});
test("an error at the beginning of a very long line", () {
- expect(errorsForFile('void foo; $veryLongString'), equals(
- "Error in test.dart: Variables cannot have a type of 'void'\n"));
+ expect(
+ errorsForFile('void foo; $veryLongString'),
+ equals(
+ "Error in test.dart: Variables cannot have a type of 'void'\n"));
});
test("an error in the middle of a very long line", () {
- expect(errorsForFile('$veryLongString void foo;$veryLongString'), equals(
- "Error in test.dart: Variables cannot have a type of 'void'\n"));
+ expect(
+ errorsForFile('$veryLongString void foo;$veryLongString'),
+ equals(
+ "Error in test.dart: Variables cannot have a type of 'void'\n"));
});
});
}
diff --git a/pkg/analyzer_cli/test/options_test.dart b/pkg/analyzer_cli/test/options_test.dart
index b74edc1..f30a6e4 100644
--- a/pkg/analyzer_cli/test/options_test.dart
+++ b/pkg/analyzer_cli/test/options_test.dart
@@ -9,8 +9,8 @@
import 'package:analyzer_cli/src/driver.dart';
import 'package:analyzer_cli/src/options.dart';
import 'package:args/args.dart';
+import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
main() {
group('CommandLineOptions', () {
@@ -27,6 +27,7 @@
expect(options.buildSummaryOutputSemantic, isNull);
expect(options.buildSuppressExitCode, isFalse);
expect(options.dartSdkPath, isNotNull);
+ expect(options.disableCacheFlushing, isFalse);
expect(options.disableHints, isFalse);
expect(options.lints, isFalse);
expect(options.displayVersion, isFalse);
@@ -60,6 +61,12 @@
expect(options.definedVariables['bar'], isNull);
});
+ test('disable cache flushing', () {
+ CommandLineOptions options = CommandLineOptions
+ .parse(['--dart-sdk', '.', '--disable-cache-flushing', 'foo.dart']);
+ expect(options.disableCacheFlushing, isTrue);
+ });
+
test('enable strict call checks', () {
CommandLineOptions options = CommandLineOptions.parse(
['--dart-sdk', '.', '--enable-strict-call-checks', 'foo.dart']);
diff --git a/pkg/analyzer_cli/test/package_prefix_test.dart b/pkg/analyzer_cli/test/package_prefix_test.dart
index 22d71e1..1a3f9b0 100644
--- a/pkg/analyzer_cli/test/package_prefix_test.dart
+++ b/pkg/analyzer_cli/test/package_prefix_test.dart
@@ -3,7 +3,7 @@
import 'package:analyzer_cli/src/driver.dart' show Driver, outSink, errorSink;
import 'package:analyzer_cli/src/options.dart' show ExitHandler, exitHandler;
import 'package:path/path.dart';
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
import 'utils.dart' show testDirectory;
diff --git a/pkg/analyzer_cli/test/perf_report_test.dart b/pkg/analyzer_cli/test/perf_report_test.dart
index 19d91a1..313328d 100644
--- a/pkg/analyzer_cli/test/perf_report_test.dart
+++ b/pkg/analyzer_cli/test/perf_report_test.dart
@@ -9,7 +9,7 @@
import 'package:analyzer_cli/src/error_formatter.dart' show AnalysisStats;
import 'package:analyzer_cli/src/options.dart';
import 'package:analyzer_cli/src/perf_report.dart';
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
main() {
test('makePerfReport', () {
diff --git a/pkg/analyzer_cli/test/plugin_manager_test.dart b/pkg/analyzer_cli/test/plugin_manager_test.dart
index 16280b2..e257300 100644
--- a/pkg/analyzer_cli/test/plugin_manager_test.dart
+++ b/pkg/analyzer_cli/test/plugin_manager_test.dart
@@ -6,7 +6,7 @@
import 'package:analyzer/src/plugin/plugin_configuration.dart';
import 'package:analyzer_cli/src/plugin/plugin_manager.dart';
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
main() {
group('plugin manager tests', () {
diff --git a/pkg/analyzer_cli/test/reporter_test.dart b/pkg/analyzer_cli/test/reporter_test.dart
index 3a0853b..7e9070f 100644
--- a/pkg/analyzer_cli/test/reporter_test.dart
+++ b/pkg/analyzer_cli/test/reporter_test.dart
@@ -6,8 +6,8 @@
import 'package:analyzer/analyzer.dart';
import 'package:analyzer_cli/src/error_formatter.dart';
+import 'package:test/test.dart' hide ErrorFormatter;
import 'package:typed_mock/typed_mock.dart';
-import 'package:unittest/unittest.dart' hide ErrorFormatter;
import 'mocks.dart';
diff --git a/pkg/analyzer_cli/test/sdk_ext_test.dart b/pkg/analyzer_cli/test/sdk_ext_test.dart
index 3eb5c62..535897c 100644
--- a/pkg/analyzer_cli/test/sdk_ext_test.dart
+++ b/pkg/analyzer_cli/test/sdk_ext_test.dart
@@ -12,7 +12,7 @@
import 'package:analyzer_cli/src/driver.dart' show Driver, errorSink, outSink;
import 'package:analyzer_cli/src/options.dart';
import 'package:path/path.dart' as path;
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
import 'utils.dart';
diff --git a/pkg/analyzer_cli/test/strong_mode_test.dart b/pkg/analyzer_cli/test/strong_mode_test.dart
index 7060fa8..29644f9 100644
--- a/pkg/analyzer_cli/test/strong_mode_test.dart
+++ b/pkg/analyzer_cli/test/strong_mode_test.dart
@@ -8,7 +8,7 @@
import 'package:analyzer_cli/src/driver.dart' show Driver, errorSink, outSink;
import 'package:path/path.dart' as path;
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
import 'driver_test.dart';
import 'utils.dart';
diff --git a/pkg/analyzer_cli/test/super_mixin_test.dart b/pkg/analyzer_cli/test/super_mixin_test.dart
index d2b7afe..8606005 100644
--- a/pkg/analyzer_cli/test/super_mixin_test.dart
+++ b/pkg/analyzer_cli/test/super_mixin_test.dart
@@ -8,7 +8,7 @@
import 'package:analyzer_cli/src/driver.dart' show Driver, errorSink, outSink;
import 'package:path/path.dart' as path;
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
import 'utils.dart';
diff --git a/pkg/analyzer_cli/test/utils.dart b/pkg/analyzer_cli/test/utils.dart
index 8e28b93..85fa759 100644
--- a/pkg/analyzer_cli/test/utils.dart
+++ b/pkg/analyzer_cli/test/utils.dart
@@ -9,10 +9,8 @@
import 'package:analyzer/analyzer.dart';
import 'package:path/path.dart' as pathos;
-import 'package:unittest/unittest.dart';
-/// Gets the test directory in a way that works with
-/// package:test and package:unittest.
+/// Gets the test directory in a way that works with package:test
/// See <https://github.com/dart-lang/test/issues/110> for more info.
final String testDirectory = pathos.dirname(
pathos.fromUri((reflectClass(_TestUtils).owner as LibraryMirror).uri));
@@ -41,11 +39,6 @@
});
}
-/// Test env setup (copied from `analyzer/test/utils.dart`).
-void initializeTestEnvironment() {
- groupSep = ' | ';
-}
-
/// Creates a temporary directory and passes its path to [fn]. Once [fn]
/// completes, the temporary directory and all its contents will be deleted.
///
diff --git a/pkg/analyzer_cli/tool/perf.dart b/pkg/analyzer_cli/tool/perf.dart
index 3c97e23..40a747a 100644
--- a/pkg/analyzer_cli/tool/perf.dart
+++ b/pkg/analyzer_cli/tool/perf.dart
@@ -5,6 +5,7 @@
/// An entrypoint used to run portions of analyzer and measure its performance.
library analyzer_cli.tool.perf;
+import 'dart:async';
import 'dart:io' show exit;
import 'package:analyzer/dart/ast/ast.dart';
@@ -23,33 +24,36 @@
import 'package:analyzer/src/generated/source_io.dart';
import 'package:package_config/discovery.dart';
-/// Cummulative total number of chars scanned.
+/// Cumulative total number of chars scanned.
int scanTotalChars = 0;
-/// Cummulative time spent scanning.
+/// Cumulative time spent scanning.
Stopwatch scanTimer = new Stopwatch();
/// Factory to load and resolve app, packages, and sdk sources.
SourceFactory sources;
-main(args) {
+main(List<String> args) async {
// TODO(sigmund): provide sdk folder as well.
- if (args.length < 3) {
- print('usage: perf.dart <bench-id> <package-root> <entry.dart>');
+ if (args.length < 2) {
+ print('usage: perf.dart <bench-id> <entry.dart>');
exit(1);
}
var totalTimer = new Stopwatch()..start();
var bench = args[0];
- var packageRoot = Uri.base.resolve(args[1]);
- var entryUri = Uri.base.resolve(args[2]);
+ var entryUri = Uri.base.resolve(args[1]);
- setup(packageRoot);
+ await setup(entryUri);
+
if (bench == 'scan') {
- scanReachableFiles(entryUri);
+ Set<Source> files = scanReachableFiles(entryUri);
+ // TODO(sigmund): consider replacing the warmup with instrumented snapshots.
+ for (int i = 0; i < 10; i++) scanFiles(files);
} else if (bench == 'parse') {
Set<Source> files = scanReachableFiles(entryUri);
- parseFiles(files);
+ // TODO(sigmund): consider replacing the warmup with instrumented snapshots.
+ for (int i = 0; i < 10; i++) parseFiles(files);
} else {
print('unsupported bench-id: $bench. Please specify "scan" or "parse"');
// TODO(sigmund): implement the remaining benchmarks.
@@ -62,10 +66,10 @@
/// Sets up analyzer to be able to load and resolve app, packages, and sdk
/// sources.
-void setup(Uri packageRoot) {
+Future setup(Uri entryUri) async {
var provider = PhysicalResourceProvider.INSTANCE;
var packageMap = new ContextBuilder(provider, null, null)
- .convertPackagesToMap(getPackagesDirectory(packageRoot));
+ .convertPackagesToMap(await findPackages(entryUri));
sources = new SourceFactory([
new ResourceUriResolver(provider),
new PackageMapUriResolver(provider, packageMap),
@@ -80,16 +84,25 @@
var files = new Set<Source>();
var loadTimer = new Stopwatch()..start();
collectSources(sources.forUri2(entryUri), files);
- collectSources(sources.forUri("dart:async"), files);
- collectSources(sources.forUri("dart:collection"), files);
- collectSources(sources.forUri("dart:convert"), files);
- collectSources(sources.forUri("dart:core"), files);
- collectSources(sources.forUri("dart:developer"), files);
- collectSources(sources.forUri("dart:_internal"), files);
- collectSources(sources.forUri("dart:isolate"), files);
- collectSources(sources.forUri("dart:math"), files);
- collectSources(sources.forUri("dart:mirrors"), files);
- collectSources(sources.forUri("dart:typed_data"), files);
+
+ var libs = [
+ "dart:async",
+ "dart:collection",
+ "dart:convert",
+ "dart:core",
+ "dart:developer",
+ "dart:_internal",
+ "dart:isolate",
+ "dart:math",
+ "dart:mirrors",
+ "dart:typed_data",
+ "dart:io"
+ ];
+
+ for (var lib in libs) {
+ collectSources(sources.forUri(lib), files);
+ }
+
loadTimer.stop();
print('input size: ${scanTotalChars} chars');
@@ -99,6 +112,24 @@
return files;
}
+/// Scans every file in [files] and reports the time spent doing so.
+void scanFiles(Set<Source> files) {
+ // The code below will record again how many chars are scanned and how long it
+ // takes to scan them, even though we already did so in [scanReachableFiles].
+ // Recording and reporting this twice is unnecessary, but we do so for now to
+ // validate that the results are consistent.
+ scanTimer = new Stopwatch();
+ var old = scanTotalChars;
+ scanTotalChars = 0;
+ for (var source in files) {
+ tokenize(source);
+ }
+
+ // Report size and scanning time again. See discussion above.
+ if (old != scanTotalChars) print('input size changed? ${old} chars');
+ report("scan", scanTimer.elapsedMicroseconds);
+}
+
/// Parses every file in [files] and reports the time spent doing so.
void parseFiles(Set<Source> files) {
// The code below will record again how many chars are scanned and how long it
@@ -156,7 +187,7 @@
// TODO(sigmund): is there a way to scan from a random-access-file without
// first converting to String?
var scanner = new Scanner(source, new CharSequenceReader(contents),
- AnalysisErrorListener.NULL_LISTENER);
+ AnalysisErrorListener.NULL_LISTENER)..preserveComments = false;
var token = scanner.tokenize();
scanTimer.stop();
return token;
diff --git a/pkg/compiler/lib/src/closure.dart b/pkg/compiler/lib/src/closure.dart
index f44b2d2..e0c6826 100644
--- a/pkg/compiler/lib/src/closure.dart
+++ b/pkg/compiler/lib/src/closure.dart
@@ -19,36 +19,67 @@
import 'resolution/tree_elements.dart' show TreeElements;
import 'tokens/token.dart' show Token;
import 'tree/tree.dart';
-import 'universe/universe.dart' show CodegenUniverse;
+import 'universe/world_builder.dart' show CodegenWorldBuilder;
import 'util/util.dart';
class ClosureTask extends CompilerTask {
- Map<Node, ClosureClassMap> closureMappingCache;
+ Map<Element, ClosureClassMap> _closureMappingCache =
+ <Element, ClosureClassMap>{};
Compiler compiler;
ClosureTask(Compiler compiler)
- : closureMappingCache = new Map<Node, ClosureClassMap>(),
- compiler = compiler,
+ : compiler = compiler,
super(compiler.measurer);
String get name => "Closure Simplifier";
DiagnosticReporter get reporter => compiler.reporter;
+ /// Returns the [ClosureClassMap] computed for [resolvedAst].
+ ClosureClassMap getClosureToClassMapping(ResolvedAst resolvedAst) {
+ return measure(() {
+ Element element = resolvedAst.element;
+ if (element.isGenerativeConstructorBody) {
+ ConstructorBodyElement constructorBody = element;
+ element = constructorBody.constructor;
+ }
+ ClosureClassMap closureClassMap = _closureMappingCache[element];
+ assert(invariant(resolvedAst.element, closureClassMap != null,
+ message: "No ClosureClassMap computed for ${element}."));
+ return closureClassMap;
+ });
+ }
+
+ /// Create [ClosureClassMap]s for all live members.
+ void createClosureClasses() {
+ compiler.enqueuer.resolution.processedElements
+ .forEach((AstElement element) {
+ ResolvedAst resolvedAst = element.resolvedAst;
+ if (element.isAbstract) return;
+ if (element.isField &&
+ !element.isInstanceMember &&
+ resolvedAst.body == null) {
+ // Skip top-level/static fields without an initializer.
+ return;
+ }
+ computeClosureToClassMapping(resolvedAst);
+ });
+ }
+
ClosureClassMap computeClosureToClassMapping(ResolvedAst resolvedAst) {
return measure(() {
Element element = resolvedAst.element;
+ ClosureClassMap cached = _closureMappingCache[element];
+ if (cached != null) return cached;
if (resolvedAst.kind != ResolvedAstKind.PARSED) {
- return new ClosureClassMap(null, null, null, new ThisLocal(element));
+ return _closureMappingCache[element] =
+ new ClosureClassMap(null, null, null, new ThisLocal(element));
}
return reporter.withCurrentElement(element.implementation, () {
Node node = resolvedAst.node;
TreeElements elements = resolvedAst.elements;
- ClosureClassMap cached = closureMappingCache[node];
- if (cached != null) return cached;
-
ClosureTranslator translator =
- new ClosureTranslator(compiler, elements, closureMappingCache);
+ new ClosureTranslator(compiler, elements, _closureMappingCache);
// The translator will store the computed closure-mappings inside the
// cache. One for given node and one for each nested closure.
@@ -57,7 +88,8 @@
} else if (element.isSynthesized) {
reporter.internalError(
element, "Unexpected synthesized element: $element");
- return new ClosureClassMap(null, null, null, new ThisLocal(element));
+ _closureMappingCache[element] =
+ new ClosureClassMap(null, null, null, new ThisLocal(element));
} else {
assert(invariant(element, element.isField,
message: "Expected $element to be a field."));
@@ -69,26 +101,17 @@
assert(invariant(element, element.isInstanceMember,
message: "Expected $element (${element
.runtimeType}) to be an instance field."));
- closureMappingCache[node] =
+ _closureMappingCache[element] =
new ClosureClassMap(null, null, null, new ThisLocal(element));
}
}
- assert(closureMappingCache[node] != null);
- return closureMappingCache[node];
+ assert(invariant(element, _closureMappingCache[element] != null,
+ message: "No ClosureClassMap computed for ${element}."));
+ return _closureMappingCache[element];
});
});
}
- ClosureClassMap getMappingForNestedFunction(FunctionExpression node) {
- return measure(() {
- ClosureClassMap nestedClosureData = closureMappingCache[node];
- if (nestedClosureData == null) {
- reporter.internalError(node, "No closure cache.");
- }
- return nestedClosureData;
- });
- }
-
void forgetElement(var closure) {
ClosureClassElement cls;
if (closure is ClosureFieldElement) {
@@ -526,7 +549,7 @@
int boxedFieldCounter = 0;
bool inTryStatement = false;
- final Map<Node, ClosureClassMap> closureMappingCache;
+ final Map<Element, ClosureClassMap> closureMappingCache;
// Map of captured variables. Initially they will map to `null`. If
// a variable needs to be boxed then the scope declaring the variable
@@ -535,7 +558,7 @@
new Map<Local, BoxFieldElement>();
// List of encountered closures.
- List<Expression> closures = <Expression>[];
+ List<LocalFunctionElement> closures = <LocalFunctionElement>[];
// The local variables that have been declared in the current scope.
List<LocalVariableElement> scopeVariables;
@@ -630,7 +653,7 @@
// free variables to the boxed value. It also adds the field-elements to the
// class representing the closure.
void updateClosures() {
- for (Expression closure in closures) {
+ for (LocalFunctionElement closure in closures) {
// The captured variables that need to be stored in a field of the closure
// class.
Set<Local> fieldCaptures = new Set<Local>();
@@ -1074,7 +1097,7 @@
executableContext = element;
if (insideClosure) {
closure = element;
- closures.add(node);
+ closures.add(closure);
closureData = globalizeClosure(node, closure);
} else {
outermostElement = element;
@@ -1084,7 +1107,10 @@
}
closureData = new ClosureClassMap(null, null, null, thisElement);
}
- closureMappingCache[node] = closureData;
+ closureMappingCache[element.declaration] = closureData;
+ if (closureData.callElement != null) {
+ closureMappingCache[closureData.callElement] = closureData;
+ }
inNewScope(node, () {
DartType type = element.type;
diff --git a/pkg/compiler/lib/src/common/backend_api.dart b/pkg/compiler/lib/src/common/backend_api.dart
index b93ddee..b8944a1 100644
--- a/pkg/compiler/lib/src/common/backend_api.dart
+++ b/pkg/compiler/lib/src/common/backend_api.dart
@@ -213,7 +213,7 @@
return false;
}
- void registerStaticUse(Element element, Enqueuer enqueuer) {}
+ void registerStaticUse(Element element, {bool forResolution}) {}
/// This method is called immediately after the [LibraryElement] [library] has
/// been created.
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index 789cbe4..536a279 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -73,7 +73,8 @@
import 'types/types.dart' show GlobalTypeInferenceTask;
import 'types/masks.dart' show CommonMasks;
import 'universe/selector.dart' show Selector;
-import 'universe/universe.dart' show ResolutionUniverse, CodegenUniverse;
+import 'universe/world_builder.dart'
+ show ResolutionWorldBuilder, CodegenWorldBuilder;
import 'universe/use.dart' show StaticUse;
import 'universe/world_impact.dart' show ImpactStrategy, WorldImpact;
import 'util/util.dart' show Link, Setlet;
@@ -333,8 +334,8 @@
// TODO(johnniwinther): Rename these appropriately when unification of worlds/
// universes is complete.
- ResolutionUniverse get resolverWorld => enqueuer.resolution.universe;
- CodegenUniverse get codegenWorld => enqueuer.codegen.universe;
+ ResolutionWorldBuilder get resolverWorld => enqueuer.resolution.universe;
+ CodegenWorldBuilder get codegenWorld => enqueuer.codegen.universe;
bool get analyzeAll => options.analyzeAll || compileAll;
@@ -723,14 +724,8 @@
return;
}
assert(mainFunction != null);
- phase = PHASE_DONE_RESOLVING;
- openWorld.closeWorld();
- // Compute whole-program-knowledge that the backend needs. (This might
- // require the information computed in [world.populate].)
- backend.onResolutionComplete();
-
- deferredLoadTask.onResolutionComplete(mainFunction);
+ closeResolution();
reporter.log('Inferring types...');
globalInference.runGlobalTypeInference(mainFunction);
@@ -766,6 +761,22 @@
checkQueues();
});
+ /// Perform the steps needed to fully end the resolution phase.
+ void closeResolution() {
+ phase = PHASE_DONE_RESOLVING;
+
+ openWorld.closeWorld();
+ // Compute whole-program-knowledge that the backend needs. (This might
+ // require the information computed in [world.closeWorld].)
+ backend.onResolutionComplete();
+
+ deferredLoadTask.onResolutionComplete(mainFunction);
+
+ // TODO(johnniwinther): Move this after rti computation but before
+ // reflection members computation, and (re-)close the world afterwards.
+ closureToClassMapper.createClosureClasses();
+ }
+
void fullyEnqueueLibrary(LibraryElement library, Enqueuer world) {
void enqueueAll(Element element) {
fullyEnqueueTopLevelElement(element, world);
@@ -835,9 +846,9 @@
work.element,
() => selfTask.measureSubtask("world.applyImpact", () {
world.applyImpact(
- work.element,
selfTask.measureSubtask(
- "work.run", () => work.run(this, world)));
+ "work.run", () => work.run(this, world)),
+ impactSource: work.element);
}));
});
});
diff --git a/pkg/compiler/lib/src/constant_system_dart.dart b/pkg/compiler/lib/src/constant_system_dart.dart
index 0f9a0d6..e1d468d 100644
--- a/pkg/compiler/lib/src/constant_system_dart.dart
+++ b/pkg/compiler/lib/src/constant_system_dart.dart
@@ -348,20 +348,13 @@
apply(left, right) => left ?? right;
}
-abstract class CodeUnitAtOperation implements BinaryOperation {
- final String name = 'charCodeAt';
+class CodeUnitAtOperation implements BinaryOperation {
+ String get name => 'charCodeAt';
const CodeUnitAtOperation();
+ ConstantValue fold(ConstantValue left, ConstantValue right) => null;
apply(left, right) => left.codeUnitAt(right);
}
-class CodeUnitAtConstantOperation extends CodeUnitAtOperation {
- const CodeUnitAtConstantOperation();
- ConstantValue fold(ConstantValue left, ConstantValue right) {
- // 'a'.codeUnitAt(0) is not a constant expression.
- return null;
- }
-}
-
class CodeUnitAtRuntimeOperation extends CodeUnitAtOperation {
const CodeUnitAtRuntimeOperation();
IntConstantValue fold(ConstantValue left, ConstantValue right) {
@@ -379,6 +372,14 @@
}
}
+class UnfoldedUnaryOperation implements UnaryOperation {
+ final String name;
+ const UnfoldedUnaryOperation(this.name);
+ ConstantValue fold(ConstantValue constant) {
+ return null;
+ }
+}
+
/**
* A constant system implementing the Dart semantics. This system relies on
* the underlying runtime-system. That is, if dart2js is run in an environment
@@ -409,7 +410,8 @@
final shiftRight = const ShiftRightOperation();
final subtract = const SubtractOperation();
final truncatingDivide = const TruncatingDivideOperation();
- final codeUnitAt = const CodeUnitAtConstantOperation();
+ final codeUnitAt = const CodeUnitAtOperation();
+ final round = const UnfoldedUnaryOperation('round');
const DartConstantSystem();
diff --git a/pkg/compiler/lib/src/constants/constant_system.dart b/pkg/compiler/lib/src/constants/constant_system.dart
index 1a0da6a..edccf03 100644
--- a/pkg/compiler/lib/src/constants/constant_system.dart
+++ b/pkg/compiler/lib/src/constants/constant_system.dart
@@ -54,6 +54,7 @@
BinaryOperation get truncatingDivide;
BinaryOperation get codeUnitAt;
+ UnaryOperation get round;
const ConstantSystem();
diff --git a/pkg/compiler/lib/src/deferred_load.dart b/pkg/compiler/lib/src/deferred_load.dart
index b4e586a..6c93804 100644
--- a/pkg/compiler/lib/src/deferred_load.dart
+++ b/pkg/compiler/lib/src/deferred_load.dart
@@ -35,7 +35,7 @@
import 'resolution/resolution.dart' show AnalyzableElementX;
import 'resolution/tree_elements.dart' show TreeElements;
import 'tree/tree.dart' as ast;
-import 'universe/use.dart' show StaticUse, TypeUse, TypeUseKind;
+import 'universe/use.dart' show StaticUse, StaticUseKind, TypeUse, TypeUseKind;
import 'universe/world_impact.dart'
show ImpactUseCase, WorldImpact, WorldImpactVisitorImpl;
import 'util/setlet.dart' show Setlet;
@@ -330,6 +330,13 @@
worldImpact,
new WorldImpactVisitorImpl(visitStaticUse: (StaticUse staticUse) {
elements.add(staticUse.element);
+ switch (staticUse.kind) {
+ case StaticUseKind.CONSTRUCTOR_INVOKE:
+ case StaticUseKind.CONST_CONSTRUCTOR_INVOKE:
+ collectTypeDependencies(staticUse.type);
+ break;
+ default:
+ }
}, visitTypeUse: (TypeUse typeUse) {
DartType type = typeUse.type;
switch (typeUse.kind) {
diff --git a/pkg/compiler/lib/src/diagnostics/messages.dart b/pkg/compiler/lib/src/diagnostics/messages.dart
index e1715744..63fa370 100644
--- a/pkg/compiler/lib/src/diagnostics/messages.dart
+++ b/pkg/compiler/lib/src/diagnostics/messages.dart
@@ -326,7 +326,6 @@
MULTI_INHERITANCE,
NAMED_ARGUMENT_NOT_FOUND,
NAMED_FUNCTION_EXPRESSION,
- NAMED_PARAMETER_WITH_EQUALS,
NATIVE_NOT_SUPPORTED,
NO_BREAK_TARGET,
NO_CATCH_NOR_FINALLY,
@@ -1372,19 +1371,6 @@
}"""
]),
- MessageKind.NAMED_PARAMETER_WITH_EQUALS: const MessageTemplate(
- MessageKind.NAMED_PARAMETER_WITH_EQUALS,
- "Named optional parameters can't use '=' to specify a default "
- "value.",
- howToFix: "Try replacing '=' with ':'.",
- examples: const [
- """
-main() {
- foo({a = 1}) => print(a);
- foo(a: 2);
-}"""
- ]),
-
MessageKind.POSITIONAL_PARAMETER_WITH_EQUALS: const MessageTemplate(
MessageKind.POSITIONAL_PARAMETER_WITH_EQUALS,
"Positional optional parameters can't use ':' to specify a "
diff --git a/pkg/compiler/lib/src/dump_info.dart b/pkg/compiler/lib/src/dump_info.dart
index de65277..4b5d1a7 100644
--- a/pkg/compiler/lib/src/dump_info.dart
+++ b/pkg/compiler/lib/src/dump_info.dart
@@ -9,6 +9,7 @@
import 'package:dart2js_info/info.dart';
+import 'closure.dart';
import 'common/tasks.dart' show CompilerTask;
import 'common.dart';
import 'compiler.dart' show Compiler;
@@ -20,7 +21,7 @@
import 'js_backend/js_backend.dart' show JavaScriptBackend;
import 'js_emitter/full_emitter/emitter.dart' as full show Emitter;
import 'types/types.dart' show TypeMask;
-import 'universe/universe.dart' show ReceiverConstraint;
+import 'universe/world_builder.dart' show ReceiverConstraint;
import 'universe/world_impact.dart'
show ImpactUseCase, WorldImpact, WorldImpactVisitorImpl;
@@ -130,7 +131,6 @@
coverageId: '${element.hashCode}',
type: '${element.type}',
inferredType: '$inferredType',
- size: size,
code: code,
outputUnit: _unitInfoForElement(element),
isConst: element.isConst);
@@ -143,19 +143,9 @@
}
}
- List<FunctionInfo> nestedClosures = <FunctionInfo>[];
- for (Element closure in element.nestedClosures) {
- Info child = this.process(closure);
- if (child != null) {
- ClassInfo parent = this.process(closure.enclosingElement);
- if (parent != null) {
- child.name = "${parent.name}.${child.name}";
- }
- nestedClosures.add(child);
- size += child.size;
- }
- }
- info.closures = nestedClosures;
+ int closureSize = _addClosureInfo(info, element);
+ info.size = size + closureSize;
+
result.fields.add(info);
return info;
}
@@ -174,29 +164,14 @@
if (info is FieldInfo) {
classInfo.fields.add(info);
info.parent = classInfo;
+ for (ClosureInfo closureInfo in info.closures) {
+ size += closureInfo.size;
+ }
} else {
assert(info is FunctionInfo);
classInfo.functions.add(info);
info.parent = classInfo;
- }
-
- // Closures are placed in the library namespace, but we want to attribute
- // them to a function, and by extension, this class. Process and add the
- // sizes here.
- if (member is MemberElement) {
- for (Element closure in member.nestedClosures) {
- FunctionInfo closureInfo = this.process(closure);
- if (closureInfo == null) continue;
-
- // TODO(sigmund): remove this legacy update on the name, represent the
- // information explicitly in the info format.
- // Look for the parent element of this closure might be the enclosing
- // class or an enclosing function.
- Element parent = closure.enclosingElement;
- ClassInfo parentInfo = this.process(parent);
- if (parentInfo != null) {
- closureInfo.name = "${parentInfo.name}.${closureInfo.name}";
- }
+ for (ClosureInfo closureInfo in (info as FunctionInfo).closures) {
size += closureInfo.size;
}
}
@@ -215,6 +190,26 @@
return classInfo;
}
+ ClosureInfo visitClosureClassElement(ClosureClassElement element, _) {
+ ClosureInfo closureInfo = new ClosureInfo(
+ name: element.name,
+ outputUnit: _unitInfoForElement(element),
+ size: compiler.dumpInfoTask.sizeOf(element));
+ _elementToInfo[element] = closureInfo;
+
+ ClosureClassMap closureMap = compiler.closureToClassMapper
+ .getClosureToClassMapping(element.methodElement.resolvedAst);
+ assert(closureMap != null && closureMap.closureClassElement == element);
+
+ FunctionInfo functionInfo = this.process(closureMap.callElement);
+ if (functionInfo == null) return null;
+ closureInfo.function = functionInfo;
+ functionInfo.parent = closureInfo;
+
+ result.closures.add(closureInfo);
+ return closureInfo;
+ }
+
FunctionInfo visitFunctionElement(FunctionElement element, _) {
int size = compiler.dumpInfoTask.sizeOf(element);
// TODO(sigmund): consider adding a small info to represent unreachable
@@ -283,7 +278,6 @@
// available while we are doing codegen.
coverageId: '${element.hashCode}',
modifiers: modifiers,
- size: size,
returnType: returnType,
inferredReturnType: inferredReturnType,
parameters: parameters,
@@ -294,27 +288,42 @@
outputUnit: _unitInfoForElement(element));
_elementToInfo[element] = info;
- List<FunctionInfo> nestedClosures = <FunctionInfo>[];
if (element is MemberElement) {
- MemberElement member = element as MemberElement;
- for (Element closure in member.nestedClosures) {
- Info child = this.process(closure);
- if (child != null) {
- BasicInfo parent = this.process(closure.enclosingElement);
- if (parent != null) {
- child.name = "${parent.name}.${child.name}";
- }
- nestedClosures.add(child);
- child.parent = parent;
- size += child.size;
- }
- }
+ int closureSize = _addClosureInfo(info, element as MemberElement);
+ size += closureSize;
+ } else {
+ info.closures = <ClosureInfo>[];
}
- info.closures = nestedClosures;
+
+ info.size = size;
+
result.functions.add(info);
return info;
}
+ /// Adds closure information to [info], using all nested closures in [member].
+ ///
+ /// Returns the total size of the nested closures, to add to the info size.
+ int _addClosureInfo(Info info, MemberElement member) {
+ assert(info is FunctionInfo || info is FieldInfo);
+ int size = 0;
+ List<ClosureInfo> nestedClosures = <ClosureInfo>[];
+ for (Element function in member.nestedClosures) {
+ assert(function is SynthesizedCallMethodElementX);
+ SynthesizedCallMethodElementX callMethod = function;
+ ClosureInfo closure = this.process(callMethod.closureClass);
+ if (closure != null) {
+ closure.parent = info;
+ nestedClosures.add(closure);
+ size += closure.size;
+ }
+ }
+ if (info is FunctionInfo) info.closures = nestedClosures;
+ if (info is FieldInfo) info.closures = nestedClosures;
+
+ return size;
+ }
+
OutputUnitInfo _infoFromOutputUnit(OutputUnit outputUnit) {
return _outputToInfo.putIfAbsent(outputUnit, () {
// Dump-info currently only works with the full emitter. If another
@@ -580,8 +589,9 @@
compiler.options.hasBuildId ? compiler.options.buildId : null,
compilationMoment: new DateTime.now(),
compilationDuration: compiler.measurer.wallClock.elapsed,
- toJsonDuration: stopwatch.elapsedMilliseconds,
- dumpInfoDuration: this.timing,
+ toJsonDuration:
+ new Duration(milliseconds: stopwatch.elapsedMilliseconds),
+ dumpInfoDuration: new Duration(milliseconds: this.timing),
noSuchMethodEnabled: compiler.backend.enabledNoSuchMethod,
minified: compiler.options.enableMinification);
diff --git a/pkg/compiler/lib/src/enqueue.dart b/pkg/compiler/lib/src/enqueue.dart
index c29912a..271e3ec 100644
--- a/pkg/compiler/lib/src/enqueue.dart
+++ b/pkg/compiler/lib/src/enqueue.dart
@@ -32,7 +32,7 @@
import 'native/native.dart' as native;
import 'types/types.dart' show TypeMaskStrategy;
import 'universe/selector.dart' show Selector;
-import 'universe/universe.dart';
+import 'universe/world_builder.dart';
import 'universe/use.dart'
show DynamicUse, StaticUse, StaticUseKind, TypeUse, TypeUseKind;
import 'universe/world_impact.dart'
@@ -71,7 +71,7 @@
abstract class Enqueuer {
EnqueueTask task;
- Universe get universe;
+ WorldBuilder get universe;
native.NativeEnqueuer nativeEnqueuer; // Set by EnqueueTask
void forgetElement(Element element);
void processInstantiatedClassMembers(ClassElement cls);
@@ -110,7 +110,11 @@
void registerInstantiatedType(InterfaceType type, {bool mirrorUsage: false});
void forEach(void f(WorkItem work));
- void applyImpact(Element element, WorldImpact worldImpact);
+
+ /// Apply the [worldImpact] to this enqueuer. If the [impactSource] is provided
+ /// the impact strategy will remove it from the element impact cache, if it is
+ /// no longer needed.
+ void applyImpact(WorldImpact worldImpact, {Element impactSource});
bool checkNoEnqueuedInvokedInstanceMethods();
void logSummary(log(message));
@@ -131,8 +135,8 @@
new Map<String, Set<Element>>();
final Set<ClassElement> _processedClasses = new Set<ClassElement>();
Set<ClassElement> recentClasses = new Setlet<ClassElement>();
- final ResolutionUniverseImpl _universe =
- new ResolutionUniverseImpl(const TypeMaskStrategy());
+ final ResolutionWorldBuilderImpl _universe =
+ new ResolutionWorldBuilderImpl(const TypeMaskStrategy());
static final TRACE_MIRROR_ENQUEUING =
const bool.fromEnvironment("TRACE_MIRROR_ENQUEUING");
@@ -156,7 +160,7 @@
// TODO(johnniwinther): Move this to [ResolutionEnqueuer].
Resolution get resolution => compiler.resolution;
- ResolutionUniverse get universe => _universe;
+ ResolutionWorldBuilder get universe => _universe;
bool get queueIsEmpty => queue.isEmpty;
@@ -183,10 +187,9 @@
}
}
- /// Apply the [worldImpact] of processing [element] to this enqueuer.
- void applyImpact(Element element, WorldImpact worldImpact) {
+ void applyImpact(WorldImpact worldImpact, {Element impactSource}) {
compiler.impactStrategy
- .visitImpact(element, worldImpact, impactVisitor, impactUse);
+ .visitImpact(impactSource, worldImpact, impactVisitor, impactUse);
}
void registerInstantiatedType(InterfaceType type, {bool mirrorUsage: false}) {
@@ -574,7 +577,7 @@
assert(invariant(element, element.isDeclaration,
message: "Element ${element} is not the declaration."));
_universe.registerStaticUse(staticUse);
- compiler.backend.registerStaticUse(element, this);
+ compiler.backend.registerStaticUse(element, forResolution: true);
bool addElement = true;
switch (staticUse.kind) {
case StaticUseKind.STATIC_TEAR_OFF:
@@ -593,6 +596,10 @@
case StaticUseKind.SUPER_TEAR_OFF:
case StaticUseKind.GENERAL:
break;
+ case StaticUseKind.CONSTRUCTOR_INVOKE:
+ case StaticUseKind.CONST_CONSTRUCTOR_INVOKE:
+ registerTypeUse(new TypeUse.instantiation(staticUse.type));
+ break;
}
if (addElement) {
addToWorkList(element);
@@ -605,7 +612,6 @@
case TypeUseKind.INSTANTIATION:
registerInstantiatedType(type);
break;
- case TypeUseKind.INSTANTIATION:
case TypeUseKind.IS_CHECK:
case TypeUseKind.AS_CAST:
case TypeUseKind.CATCH_TYPE:
diff --git a/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart b/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
index 85e5dbd..f56483d 100644
--- a/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
+++ b/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
@@ -374,7 +374,7 @@
// each update, and reading them yields the type that was found in a
// previous analysis of [outermostElement].
ClosureClassMap closureData =
- compiler.closureToClassMapper.computeClosureToClassMapping(resolvedAst);
+ compiler.closureToClassMapper.getClosureToClassMapping(resolvedAst);
closureData.forEachCapturedVariable((variable, field) {
locals.setCaptured(variable, field);
});
@@ -558,8 +558,8 @@
// Record the types of captured non-boxed variables. Types of
// these variables may already be there, because of an analysis of
// a previous closure.
- ClosureClassMap nestedClosureData =
- compiler.closureToClassMapper.getMappingForNestedFunction(node);
+ ClosureClassMap nestedClosureData = compiler.closureToClassMapper
+ .getClosureToClassMapping(element.resolvedAst);
nestedClosureData.forEachCapturedVariable((variable, field) {
if (!nestedClosureData.isVariableBoxed(variable)) {
if (variable == nestedClosureData.thisLocal) {
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index 0899d1b..fe3684a 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -50,7 +50,7 @@
import '../universe/call_structure.dart' show CallStructure;
import '../universe/feature.dart';
import '../universe/selector.dart' show Selector;
-import '../universe/universe.dart';
+import '../universe/world_builder.dart';
import '../universe/use.dart'
show DynamicUse, StaticUse, StaticUseKind, TypeUse, TypeUseKind;
import '../universe/world_impact.dart'
@@ -1310,7 +1310,8 @@
enqueue(enqueuer, helpers.isJsIndexable, registry);
}
- customElementsAnalysis.registerInstantiatedClass(cls, enqueuer);
+ customElementsAnalysis.registerInstantiatedClass(cls,
+ forResolution: enqueuer.isResolutionQueue);
if (!enqueuer.isResolutionQueue) {
lookupMapAnalysis.registerInstantiatedClass(cls);
}
@@ -1904,7 +1905,7 @@
return compiler.closedWorld.hasOnlySubclasses(classElement);
}
- void registerStaticUse(Element element, Enqueuer enqueuer) {
+ void registerStaticUse(Element element, {bool forResolution}) {
if (element == helpers.disableTreeShakingMarker) {
isTreeShakingDisabled = true;
} else if (element == helpers.preserveNamesMarker) {
@@ -1927,7 +1928,8 @@
} else if (element == helpers.requiresPreambleMarker) {
requiresPreamble = true;
}
- customElementsAnalysis.registerStaticUse(element, enqueuer);
+ customElementsAnalysis.registerStaticUse(element,
+ forResolution: forResolution);
}
/// Called when [:const Symbol(name):] is seen.
@@ -2164,9 +2166,15 @@
});
// 3) all members, including fields via getter/setters (if resolved)
cls.forEachClassMember((Member member) {
- if (resolution.hasBeenProcessed(member.element)) {
+ MemberElement element = member.element;
+ if (resolution.hasBeenProcessed(element)) {
memberNames.add(member.name);
- reflectableMembers.add(member.element);
+ reflectableMembers.add(element);
+ element.nestedClosures
+ .forEach((SynthesizedCallMethodElementX callFunction) {
+ reflectableMembers.add(callFunction);
+ reflectableMembers.add(callFunction.closureClass);
+ });
}
});
// 4) all overriding members of subclasses/subtypes (should be resolved)
@@ -2351,9 +2359,12 @@
//
// Return early if any elements are added to avoid counting the elements as
// due to mirrors.
- customElementsAnalysis.onQueueEmpty(enqueuer);
- lookupMapAnalysis.onQueueEmpty(enqueuer);
- typeVariableHandler.onQueueEmpty(enqueuer);
+ enqueuer.applyImpact(customElementsAnalysis.flush(
+ forResolution: enqueuer.isResolutionQueue));
+ enqueuer.applyImpact(
+ lookupMapAnalysis.flush(forResolution: enqueuer.isResolutionQueue));
+ enqueuer.applyImpact(
+ typeVariableHandler.flush(forResolution: enqueuer.isResolutionQueue));
if (!enqueuer.queueIsEmpty) return false;
@@ -2365,7 +2376,7 @@
enabledNoSuchMethod = true;
}
- if (compiler.options.useKernel) {
+ if (compiler.options.useKernel && compiler.mainApp != null) {
kernelTask.buildKernelIr();
}
@@ -2424,7 +2435,7 @@
}
metadataConstants.clear();
}
- enqueuer.applyImpact(null, impactBuilder.flush());
+ enqueuer.applyImpact(impactBuilder.flush());
}
return true;
}
@@ -2946,14 +2957,21 @@
}
for (StaticUse staticUse in worldImpact.staticUses) {
- if (staticUse.kind == StaticUseKind.CLOSURE) {
- registerBackendImpact(transformed, impacts.closure);
- LocalFunctionElement closure = staticUse.element;
- if (closure.type.containsTypeVariables) {
- resolutionEnqueuer.universe.closuresWithFreeTypeVariables
- .add(closure);
- registerBackendImpact(transformed, impacts.computeSignature);
- }
+ switch (staticUse.kind) {
+ case StaticUseKind.CLOSURE:
+ registerBackendImpact(transformed, impacts.closure);
+ LocalFunctionElement closure = staticUse.element;
+ if (closure.type.containsTypeVariables) {
+ resolutionEnqueuer.universe.closuresWithFreeTypeVariables
+ .add(closure);
+ registerBackendImpact(transformed, impacts.computeSignature);
+ }
+ break;
+ case StaticUseKind.CONST_CONSTRUCTOR_INVOKE:
+ case StaticUseKind.CONSTRUCTOR_INVOKE:
+ registerRequiredType(staticUse.type);
+ break;
+ default:
}
}
@@ -3139,11 +3157,18 @@
}
for (StaticUse staticUse in impact.staticUses) {
- if (staticUse.kind == StaticUseKind.CLOSURE) {
- LocalFunctionElement closure = staticUse.element;
- if (backend.methodNeedsRti(closure)) {
- registerBackendImpact(transformed, impacts.computeSignature);
- }
+ switch (staticUse.kind) {
+ case StaticUseKind.CLOSURE:
+ LocalFunctionElement closure = staticUse.element;
+ if (backend.methodNeedsRti(closure)) {
+ registerBackendImpact(transformed, impacts.computeSignature);
+ }
+ break;
+ case StaticUseKind.CONST_CONSTRUCTOR_INVOKE:
+ case StaticUseKind.CONSTRUCTOR_INVOKE:
+ backend.lookupMapAnalysis.registerInstantiatedType(staticUse.type);
+ break;
+ default:
}
}
diff --git a/pkg/compiler/lib/src/js_backend/backend_helpers.dart b/pkg/compiler/lib/src/js_backend/backend_helpers.dart
index dc5bb12..f85e9d0 100644
--- a/pkg/compiler/lib/src/js_backend/backend_helpers.dart
+++ b/pkg/compiler/lib/src/js_backend/backend_helpers.dart
@@ -457,6 +457,15 @@
return findHelper('throwConcurrentModificationError');
}
+ Element get checkInt => _checkInt ??= findHelper('checkInt');
+ Element _checkInt;
+
+ Element get checkNum => _checkNum ??= findHelper('checkNum');
+ Element _checkNum;
+
+ Element get checkString => _checkString ??= findHelper('checkString');
+ Element _checkString;
+
Element get stringInterpolationHelper {
return findHelper('S');
}
diff --git a/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart b/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
index 7f86482..08174df 100644
--- a/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_system_javascript.dart
@@ -165,12 +165,50 @@
apply(left, right) => identical(left, right);
}
+class JavaScriptRoundOperation implements UnaryOperation {
+ const JavaScriptRoundOperation();
+ String get name => DART_CONSTANT_SYSTEM.round.name;
+ ConstantValue fold(ConstantValue constant) {
+ // Be careful to round() only values that do not throw on either the host or
+ // target platform.
+ ConstantValue tryToRound(num value) {
+ // Due to differences between browsers, only 'round' easy cases. Avoid
+ // cases where nudging the value up or down changes the answer.
+ // 13 digits is safely within the ~15 digit precision of doubles.
+ const severalULP = 0.0000000000001;
+ // Use 'roundToDouble()' to avoid exceptions on rounding the nudged value.
+ double rounded = value.roundToDouble();
+ double rounded1 = (value * (1.0 + severalULP)).roundToDouble();
+ double rounded2 = (value * (1.0 - severalULP)).roundToDouble();
+ if (rounded != rounded1 || rounded != rounded2) return null;
+ return JAVA_SCRIPT_CONSTANT_SYSTEM
+ .convertToJavaScriptConstant(new IntConstantValue(value.round()));
+ }
+
+ if (constant.isInt) {
+ IntConstantValue intConstant = constant;
+ int value = intConstant.primitiveValue;
+ if (value >= -double.MAX_FINITE && value <= double.MAX_FINITE) {
+ return tryToRound(value);
+ }
+ }
+ if (constant.isDouble) {
+ DoubleConstantValue doubleConstant = constant;
+ double value = doubleConstant.primitiveValue;
+ // NaN and infinities will throw.
+ if (value.isNaN) return null;
+ if (value.isInfinite) return null;
+ return tryToRound(value);
+ }
+ return null;
+ }
+}
+
/**
* Constant system following the semantics for Dart code that has been
* compiled to JavaScript.
*/
class JavaScriptConstantSystem extends ConstantSystem {
- final int BITS31 = 0x8FFFFFFF;
final int BITS32 = 0xFFFFFFFF;
final add = const JavaScriptAddOperation();
@@ -203,6 +241,7 @@
final truncatingDivide = const JavaScriptBinaryArithmeticOperation(
const TruncatingDivideOperation());
final codeUnitAt = const CodeUnitAtRuntimeOperation();
+ final round = const JavaScriptRoundOperation();
const JavaScriptConstantSystem();
diff --git a/pkg/compiler/lib/src/js_backend/custom_elements_analysis.dart b/pkg/compiler/lib/src/js_backend/custom_elements_analysis.dart
index 807bcb9..d87ffa3 100644
--- a/pkg/compiler/lib/src/js_backend/custom_elements_analysis.dart
+++ b/pkg/compiler/lib/src/js_backend/custom_elements_analysis.dart
@@ -71,10 +71,11 @@
codegenJoin.allClassesSelected = true;
}
- CustomElementsAnalysisJoin joinFor(Enqueuer enqueuer) =>
- enqueuer.isResolutionQueue ? resolutionJoin : codegenJoin;
+ CustomElementsAnalysisJoin joinFor({bool forResolution}) =>
+ forResolution ? resolutionJoin : codegenJoin;
- void registerInstantiatedClass(ClassElement classElement, Enqueuer enqueuer) {
+ void registerInstantiatedClass(ClassElement classElement,
+ {bool forResolution}) {
classElement.ensureResolved(compiler.resolution);
if (!backend.isNativeOrExtendsNative(classElement)) return;
if (classElement.isMixinApplication) return;
@@ -82,7 +83,7 @@
// JsInterop classes are opaque interfaces without a concrete
// implementation.
if (backend.isJsInterop(classElement)) return;
- joinFor(enqueuer).instantiatedClasses.add(classElement);
+ joinFor(forResolution: forResolution).instantiatedClasses.add(classElement);
}
void registerTypeLiteral(DartType type) {
@@ -104,19 +105,20 @@
codegenJoin.selectedClasses.add(element);
}
- void registerStaticUse(Element element, Enqueuer enqueuer) {
+ void registerStaticUse(Element element, {bool forResolution}) {
assert(element != null);
if (!fetchedTableAccessorMethod) {
fetchedTableAccessorMethod = true;
tableAccessorMethod = backend.helpers.findIndexForNativeSubclassType;
}
if (element == tableAccessorMethod) {
- joinFor(enqueuer).demanded = true;
+ joinFor(forResolution: forResolution).demanded = true;
}
}
- void onQueueEmpty(Enqueuer enqueuer) {
- joinFor(enqueuer).flush(enqueuer);
+ /// Computes the [WorldImpact] of the classes registered since last flush.
+ WorldImpact flush({bool forResolution}) {
+ return joinFor(forResolution: forResolution).flush();
}
bool get needsTable => codegenJoin.demanded;
@@ -152,8 +154,8 @@
CustomElementsAnalysisJoin(this.backend);
- void flush(Enqueuer enqueuer) {
- if (!demanded) return;
+ WorldImpact flush() {
+ if (!demanded) return const WorldImpact();
var newActiveClasses = new Set<ClassElement>();
for (ClassElement classElement in instantiatedClasses) {
bool isNative = backend.isNative(classElement);
@@ -168,7 +170,8 @@
Iterable<ConstructorElement> escapingConstructors =
computeEscapingConstructors(classElement);
for (ConstructorElement constructor in escapingConstructors) {
- enqueuer.registerStaticUse(new StaticUse.foreignUse(constructor));
+ impactBuilder
+ .registerStaticUse(new StaticUse.foreignUse(constructor));
}
escapingConstructors
.forEach(compiler.globalDependencies.registerDependency);
@@ -182,7 +185,7 @@
}
activeClasses.addAll(newActiveClasses);
instantiatedClasses.removeAll(newActiveClasses);
- enqueuer.applyImpact(null, impactBuilder.flush());
+ return impactBuilder.flush();
}
TypeConstantValue makeTypeConstant(ClassElement element) {
diff --git a/pkg/compiler/lib/src/js_backend/enqueuer.dart b/pkg/compiler/lib/src/js_backend/enqueuer.dart
index e4b3027..12872d8 100644
--- a/pkg/compiler/lib/src/js_backend/enqueuer.dart
+++ b/pkg/compiler/lib/src/js_backend/enqueuer.dart
@@ -34,7 +34,7 @@
import '../options.dart';
import '../types/types.dart' show TypeMaskStrategy;
import '../universe/selector.dart' show Selector;
-import '../universe/universe.dart';
+import '../universe/world_builder.dart';
import '../universe/use.dart'
show DynamicUse, StaticUse, StaticUseKind, TypeUse, TypeUseKind;
import '../universe/world_impact.dart'
@@ -54,8 +54,8 @@
new Map<String, Set<Element>>();
final Set<ClassElement> _processedClasses = new Set<ClassElement>();
Set<ClassElement> recentClasses = new Setlet<ClassElement>();
- final CodegenUniverseImpl _universe =
- new CodegenUniverseImpl(const TypeMaskStrategy());
+ final CodegenWorldBuilderImpl _universe =
+ new CodegenWorldBuilderImpl(const TypeMaskStrategy());
static final TRACE_MIRROR_ENQUEUING =
const bool.fromEnvironment("TRACE_MIRROR_ENQUEUING");
@@ -78,7 +78,7 @@
impactVisitor = new _EnqueuerImpactVisitor(this);
}
- CodegenUniverse get universe => _universe;
+ CodegenWorldBuilder get universe => _universe;
Backend get backend => _compiler.backend;
@@ -134,10 +134,9 @@
}
}
- /// Apply the [worldImpact] of processing [element] to this enqueuer.
- void applyImpact(Element element, WorldImpact worldImpact) {
+ void applyImpact(WorldImpact worldImpact, {Element impactSource}) {
_compiler.impactStrategy
- .visitImpact(element, worldImpact, impactVisitor, impactUse);
+ .visitImpact(impactSource, worldImpact, impactVisitor, impactUse);
}
void registerInstantiatedType(InterfaceType type, {bool mirrorUsage: false}) {
@@ -513,7 +512,7 @@
assert(invariant(element, element.isDeclaration,
message: "Element ${element} is not the declaration."));
_universe.registerStaticUse(staticUse);
- backend.registerStaticUse(element, this);
+ backend.registerStaticUse(element, forResolution: false);
bool addElement = true;
switch (staticUse.kind) {
case StaticUseKind.STATIC_TEAR_OFF:
@@ -532,6 +531,10 @@
case StaticUseKind.SUPER_TEAR_OFF:
case StaticUseKind.GENERAL:
break;
+ case StaticUseKind.CONSTRUCTOR_INVOKE:
+ case StaticUseKind.CONST_CONSTRUCTOR_INVOKE:
+ registerTypeUse(new TypeUse.instantiation(staticUse.type));
+ break;
}
if (addElement) {
addToWorkList(element);
@@ -544,7 +547,6 @@
case TypeUseKind.INSTANTIATION:
registerInstantiatedType(type);
break;
- case TypeUseKind.INSTANTIATION:
case TypeUseKind.IS_CHECK:
case TypeUseKind.AS_CAST:
case TypeUseKind.CATCH_TYPE:
diff --git a/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart b/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart
index 380d196..3b75b49 100644
--- a/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart
+++ b/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart
@@ -22,7 +22,7 @@
import '../js/js.dart' as jsAst;
import '../js/js.dart' show js;
import '../universe/selector.dart' show Selector;
-import '../universe/universe.dart' show SelectorConstraints;
+import '../universe/world_builder.dart' show SelectorConstraints;
import 'backend_helpers.dart' show BackendHelpers;
import 'js_backend.dart' show JavaScriptBackend;
diff --git a/pkg/compiler/lib/src/js_backend/kernel_task.dart b/pkg/compiler/lib/src/js_backend/kernel_task.dart
index ea32143..9f0c0d9 100644
--- a/pkg/compiler/lib/src/js_backend/kernel_task.dart
+++ b/pkg/compiler/lib/src/js_backend/kernel_task.dart
@@ -3,6 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
import '../compiler.dart';
+import '../common/names.dart';
+import '../elements/elements.dart';
import '../kernel/kernel.dart';
import 'package:kernel/ast.dart' as ir;
@@ -25,8 +27,16 @@
///
/// May enqueue more elements to the resolution queue.
void buildKernelIr() {
- program =
- new ir.Program(kernel.libraryDependencies(_compiler.options.entryPoint))
- ..mainMethod = kernel.functionToIr(_compiler.mainFunction);
+ program = buildProgram(_compiler.mainApp);
+ }
+
+ /// Builds the kernel IR program for the main function exported from
+ /// [library].
+ ///
+ /// May enqueue more elements to the resolution queue.
+ ir.Program buildProgram(LibraryElement library) {
+ return new ir.Program(kernel.libraryDependencies(library.canonicalUri))
+ ..mainMethod =
+ kernel.functionToIr(library.findExported(Identifiers.main));
}
}
diff --git a/pkg/compiler/lib/src/js_backend/lookup_map_analysis.dart b/pkg/compiler/lib/src/js_backend/lookup_map_analysis.dart
index d729e56..c6e204d 100644
--- a/pkg/compiler/lib/src/js_backend/lookup_map_analysis.dart
+++ b/pkg/compiler/lib/src/js_backend/lookup_map_analysis.dart
@@ -128,9 +128,10 @@
LookupMapAnalysis(this.backend, this.reporter);
- void onQueueEmpty(Enqueuer enqueuer) {
- if (enqueuer.isResolutionQueue) return;
- enqueuer.applyImpact(null, impactBuilder.flush());
+ /// Compute the [WorldImpact] for the constants registered since last flush.
+ WorldImpact flush({bool forResolution}) {
+ if (forResolution) return const WorldImpact();
+ return impactBuilder.flush();
}
/// Whether this analysis and optimization is enabled.
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types.dart b/pkg/compiler/lib/src/js_backend/runtime_types.dart
index f465f76..d3adc4b 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types.dart
@@ -46,7 +46,7 @@
///
/// This function must be called after all is-checks have been registered.
void addImplicitChecks(
- Universe universe, Iterable<ClassElement> classesUsingChecks);
+ WorldBuilder universe, Iterable<ClassElement> classesUsingChecks);
/// Return all classes that are referenced in the type of the function, i.e.,
/// in the return type or the argument types.
@@ -170,7 +170,7 @@
*/
@override
void addImplicitChecks(
- Universe universe, Iterable<ClassElement> classesUsingChecks) {
+ WorldBuilder universe, Iterable<ClassElement> classesUsingChecks) {
// If there are no classes that use their variables in checks, there is
// nothing to do.
if (classesUsingChecks.isEmpty) return;
@@ -364,7 +364,8 @@
computeChecks(allInstantiatedArguments, checkedArguments);
}
- Set<DartType> computeInstantiatedTypesAndClosures(CodegenUniverse universe) {
+ Set<DartType> computeInstantiatedTypesAndClosures(
+ CodegenWorldBuilder universe) {
Set<DartType> instantiatedTypes =
new Set<DartType>.from(universe.instantiatedTypes);
for (DartType instantiatedType in universe.instantiatedTypes) {
diff --git a/pkg/compiler/lib/src/js_backend/type_variable_handler.dart b/pkg/compiler/lib/src/js_backend/type_variable_handler.dart
index d7c3281..595da95 100644
--- a/pkg/compiler/lib/src/js_backend/type_variable_handler.dart
+++ b/pkg/compiler/lib/src/js_backend/type_variable_handler.dart
@@ -57,10 +57,11 @@
JavaScriptBackend get _backend => _compiler.backend;
DiagnosticReporter get reporter => _compiler.reporter;
- void onQueueEmpty(Enqueuer enqueuer) {
- if (enqueuer.isResolutionQueue) return;
-
- enqueuer.applyImpact(null, impactBuilder.flush());
+ /// Compute the [WorldImpact] for the type variables registered since last
+ /// flush.
+ WorldImpact flush({bool forResolution}) {
+ if (forResolution) return const WorldImpact();
+ return impactBuilder.flush();
}
void registerClassWithTypeVariables(
diff --git a/pkg/compiler/lib/src/js_emitter/js_emitter.dart b/pkg/compiler/lib/src/js_emitter/js_emitter.dart
index c1543de..e902ab5 100644
--- a/pkg/compiler/lib/src/js_emitter/js_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/js_emitter.dart
@@ -56,7 +56,7 @@
TypeVariableHandler;
import '../universe/call_structure.dart' show CallStructure;
import '../universe/selector.dart' show Selector;
-import '../universe/universe.dart' show SelectorConstraints;
+import '../universe/world_builder.dart' show SelectorConstraints;
import '../util/util.dart' show Setlet;
import 'full_emitter/emitter.dart' as full_js_emitter;
import 'lazy_emitter/emitter.dart' as lazy_js_emitter;
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
index b977ffe..9c2971b 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
@@ -32,7 +32,8 @@
import '../../js_backend/js_backend.dart'
show Namer, JavaScriptBackend, JavaScriptConstantCompiler, StringBackedName;
import '../../universe/selector.dart' show Selector;
-import '../../universe/universe.dart' show CodegenUniverse, SelectorConstraints;
+import '../../universe/world_builder.dart'
+ show CodegenWorldBuilder, SelectorConstraints;
import '../js_emitter.dart'
show
ClassStubGenerator,
@@ -79,7 +80,7 @@
JavaScriptBackend get backend => _compiler.backend;
BackendHelpers get helpers => backend.helpers;
- CodegenUniverse get universe => _compiler.codegenWorld;
+ CodegenWorldBuilder get universe => _compiler.codegenWorld;
/// Mapping from [ClassElement] to constructed [Class]. We need this to
/// update the superclass in the [Class].
@@ -168,8 +169,8 @@
List<Holder> holders = _registry.holders.toList(growable: false);
- bool needsNativeSupport = _compiler.enqueuer.codegen.nativeEnqueuer
- .hasInstantiatedNativeClasses;
+ bool needsNativeSupport =
+ _compiler.enqueuer.codegen.nativeEnqueuer.hasInstantiatedNativeClasses;
assert(!needsNativeSupport || nativeClasses.isNotEmpty);
diff --git a/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart b/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
index 77663d3..170d16d 100644
--- a/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
@@ -78,9 +78,9 @@
FunctionElement method, FunctionType type) {
assert(method.isImplementation);
jsAst.Expression thisAccess = new jsAst.This();
- ClosureClassMap closureData = compiler
- .closureToClassMapper.closureMappingCache[method.resolvedAst.node];
- if (closureData != null) {
+ if (!method.isAbstract) {
+ ClosureClassMap closureData = compiler.closureToClassMapper
+ .getClosureToClassMapping(method.resolvedAst);
ClosureFieldElement thisLocal =
closureData.freeVariableMap[closureData.thisLocal];
if (thisLocal != null) {
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
index 222b1c6..57e10a2 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
@@ -345,6 +345,9 @@
// Native-support uses setOrUpdateInterceptorsByTag and setOrUpdateLeafTags.
#nativeSupport;
+// Sets up the js-interop support.
+#jsInteropSupport;
+
// Invokes main (making sure that it records the 'current-script' value).
#invokeMain;
})()
@@ -497,6 +500,9 @@
'nativeSupport': program.needsNativeSupport
? emitNativeSupport(fragment)
: new js.EmptyStatement(),
+ 'jsInteropSupport': backend.jsInteropAnalysis.enabledJsInterop
+ ? backend.jsInteropAnalysis.buildJsInteropBootstrap()
+ : new js.EmptyStatement(),
'invokeMain': fragment.invokeMain,
});
}
@@ -1327,7 +1333,7 @@
Map<String, js.Expression> interceptorsByTag = <String, js.Expression>{};
Map<String, js.Expression> leafTags = <String, js.Expression>{};
- js.Statement subclassAssignment = new js.EmptyStatement();
+ List<js.Statement> subclassAssignments = <js.Statement>[];
for (Library library in fragment.libraries) {
for (Class cls in library.classes) {
@@ -1344,15 +1350,15 @@
}
if (cls.nativeExtensions != null) {
List<Class> subclasses = cls.nativeExtensions;
- js.Expression value = js.string(cls.nativeNonLeafTags[0]);
+ js.Expression base = js.string(cls.nativeNonLeafTags[0]);
+
for (Class subclass in subclasses) {
- value = js.js('#.# = #', [
+ subclassAssignments.add(js.js.statement('#.# = #;', [
classReference(subclass),
NATIVE_SUPERCLASS_TAG_NAME,
- js.string(cls.nativeNonLeafTags[0])
- ]);
+ base
+ ]));
}
- subclassAssignment = new js.ExpressionStatement(value);
}
}
}
@@ -1361,7 +1367,7 @@
js.objectLiteral(interceptorsByTag)));
statements.add(
js.js.statement("setOrUpdateLeafTags(#);", js.objectLiteral(leafTags)));
- statements.add(subclassAssignment);
+ statements.addAll(subclassAssignments);
return new js.Block(statements);
}
diff --git a/pkg/compiler/lib/src/kernel/fall_through_visitor.dart b/pkg/compiler/lib/src/kernel/fall_through_visitor.dart
deleted file mode 100644
index cd74708..0000000
--- a/pkg/compiler/lib/src/kernel/fall_through_visitor.dart
+++ /dev/null
@@ -1,99 +0,0 @@
-// 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.md file.
-
-import 'package:kernel/ast.dart'
- show
- AssertStatement,
- Block,
- BreakStatement,
- Catch,
- ContinueSwitchStatement,
- DoStatement,
- EmptyStatement,
- ExpressionStatement,
- ForInStatement,
- ForStatement,
- FunctionDeclaration,
- IfStatement,
- InvalidStatement,
- LabeledStatement,
- ReturnStatement,
- Statement,
- StatementVisitor,
- SwitchStatement,
- Throw,
- TryCatch,
- TryFinally,
- VariableDeclaration,
- WhileStatement,
- YieldStatement;
-
-/// Returns true if [node] would let execution reach the next node (aka
-/// fall-through in switch cases).
-bool fallsThrough(Statement node) => node.accept(const FallThroughVisitor());
-
-/// Visitor implementing [computeFallThrough].
-class FallThroughVisitor implements StatementVisitor<bool> {
- const FallThroughVisitor();
-
- bool defaultStatement(Statement node) => throw "Not implemented.";
-
- bool visitInvalidStatement(InvalidStatement node) => false;
-
- bool visitExpressionStatement(ExpressionStatement node) {
- return node.expression is! Throw;
- }
-
- bool visitBlock(Block node) {
- for (Statement statement in node.statements) {
- if (!statement.accept(this)) return false;
- }
- return true;
- }
-
- bool visitEmptyStatement(EmptyStatement node) => true;
-
- bool visitAssertStatement(AssertStatement node) => true;
-
- bool visitLabeledStatement(LabeledStatement node) => true;
-
- bool visitBreakStatement(BreakStatement node) => false;
-
- bool visitWhileStatement(WhileStatement node) => true;
-
- bool visitDoStatement(DoStatement node) => node.body.accept(this);
-
- bool visitForStatement(ForStatement node) => true;
-
- bool visitForInStatement(ForInStatement node) => true;
-
- bool visitSwitchStatement(SwitchStatement node) => true;
-
- bool visitContinueSwitchStatement(ContinueSwitchStatement node) => false;
-
- bool visitIfStatement(IfStatement node) {
- if (node.then == null || node.otherwise == null) return true;
- return node.then.accept(this) || node.otherwise.accept(this);
- }
-
- bool visitReturnStatement(ReturnStatement node) => false;
-
- bool visitTryCatch(TryCatch node) {
- if (node.body.accept(this)) return true;
- for (Catch catchNode in node.catches) {
- if (catchNode.body.accept(this)) return true;
- }
- return false;
- }
-
- bool visitTryFinally(TryFinally node) {
- return node.body.accept(this) && node.finalizer.accept(this);
- }
-
- bool visitYieldStatement(YieldStatement node) => true;
-
- bool visitVariableDeclaration(VariableDeclaration node) => true;
-
- bool visitFunctionDeclaration(FunctionDeclaration node) => true;
-}
diff --git a/pkg/compiler/lib/src/kernel/kernel.dart b/pkg/compiler/lib/src/kernel/kernel.dart
index 2fe3c70..35ff9ea 100644
--- a/pkg/compiler/lib/src/kernel/kernel.dart
+++ b/pkg/compiler/lib/src/kernel/kernel.dart
@@ -8,6 +8,8 @@
import 'package:kernel/ast.dart' as ir;
import 'package:kernel/checks.dart' show CheckParentPointers;
+import '../common.dart';
+import '../common/names.dart';
import '../compiler.dart' show Compiler;
import '../constants/expressions.dart' show TypeConstantExpression;
import '../dart_types.dart'
@@ -591,10 +593,26 @@
return false;
}
+ ir.Constructor getDartCoreConstructor(
+ String className, String constructorName) {
+ LibraryElement library =
+ compiler.libraryLoader.lookupLibrary(Uris.dart_core);
+ ClassElement cls = library.implementation.localLookup(className);
+ assert(invariant(CURRENT_ELEMENT_SPANNABLE, cls != null,
+ message: 'dart:core class $className not found.'));
+ ConstructorElement constructor = cls.lookupConstructor(constructorName);
+ assert(invariant(CURRENT_ELEMENT_SPANNABLE, constructor != null,
+ message: "Constructor '$constructorName' not found "
+ "in class '$className'."));
+ return functionToIr(constructor);
+ }
+
ir.Procedure getDartCoreMethod(String name) {
LibraryElement library =
- compiler.libraryLoader.lookupLibrary(Uri.parse("dart:core"));
+ compiler.libraryLoader.lookupLibrary(Uris.dart_core);
Element function = library.implementation.localLookup(name);
+ assert(invariant(CURRENT_ELEMENT_SPANNABLE, function != null,
+ message: "dart:core method '$name' not found."));
return functionToIr(function);
}
@@ -646,8 +664,8 @@
return getDartCoreMethod('_genericNoSuchMethod');
}
- ir.Procedure getFallThroughErrorBuilder() {
- return getDartCoreMethod('_fallThroughError');
+ ir.Constructor getFallThroughErrorConstructor() {
+ return getDartCoreConstructor('FallThroughError', '');
}
}
diff --git a/pkg/compiler/lib/src/kernel/kernel_visitor.dart b/pkg/compiler/lib/src/kernel/kernel_visitor.dart
index ef34ee9..e6ed1e4 100644
--- a/pkg/compiler/lib/src/kernel/kernel_visitor.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_visitor.dart
@@ -22,6 +22,7 @@
import 'package:kernel/transformations/flags.dart';
import '../common.dart';
+import '../common/names.dart';
import '../constants/expressions.dart'
show
BoolFromEnvironmentConstantExpression,
@@ -145,7 +146,6 @@
import '../universe/selector.dart' show Selector;
import '../util/util.dart' show Link;
import 'error.dart' show KernelError;
-import 'fall_through_visitor.dart' show fallsThrough;
import 'kernel.dart' show ConstructorTarget, Kernel;
import 'unavailable.dart' show UnavailableVisitor;
import 'unresolved.dart' show UnresolvedVisitor;
@@ -995,6 +995,15 @@
return new ir.SwitchCase(expressions, null, isDefault: node.isDefaultCase);
}
+ /// Returns true if [node] would let execution reach the next node (aka
+ /// fall-through in switch cases).
+ bool fallsThrough(ir.Statement node) {
+ return !(node is ir.BreakStatement ||
+ node is ir.ReturnStatement ||
+ node is ir.ContinueSwitchStatement ||
+ (node is ir.ExpressionStatement && node.expression is ir.Throw));
+ }
+
@override
ir.Statement visitSwitchStatement(SwitchStatement node) {
ir.Expression expression = visitForValue(node.expression);
@@ -1026,18 +1035,18 @@
hasVariableDeclaration = true;
}
}
- if (!isLastCase &&
- (statements.isEmpty || fallsThrough(statements.last))) {
- statements.add(new ir.ExpressionStatement(new ir.Throw(
- new ir.StaticInvocation(kernel.getFallThroughErrorBuilder(),
- new ir.Arguments.empty()))));
+ if (statements.isEmpty || fallsThrough(statements.last)) {
+ if (isLastCase) {
+ statements.add(new ir.BreakStatement(
+ getBreakTarget(elements.getTargetDefinition(node))));
+ } else {
+ statements.add(new ir.ExpressionStatement(new ir.Throw(
+ new ir.ConstructorInvocation(
+ kernel.getFallThroughErrorConstructor(),
+ new ir.Arguments.empty()))));
+ }
}
- ir.Statement body;
- if (!hasVariableDeclaration && statements.length == 1) {
- body = statements.single;
- } else {
- body = new ir.Block(statements);
- }
+ ir.Statement body = new ir.Block(statements);
irCase.body = body;
body.parent = irCase;
}
@@ -2042,13 +2051,23 @@
} else if (function.isConstructor) {
// TODO(johnniwinther): Clean this up pending kernel issue #28.
ConstructorElement constructor = function;
- if (constructor.isDefaultConstructor) {
+ if (bodyNode == null || bodyNode.asEmptyStatement() != null) {
body = new ir.EmptyStatement();
- } else if (bodyNode != null && bodyNode.asEmptyStatement() == null) {
+ } else {
body = buildStatementInBlock(bodyNode);
}
} else if (bodyNode != null) {
- body = buildStatementInBlock(bodyNode);
+ Return returnStatement = bodyNode.asReturn();
+ if ((function.isSetter || function.name == Names.INDEX_SET_NAME.text) &&
+ returnStatement != null) {
+ // Avoid encoding the implicit return of setters with arrow body:
+ // set setter(value) => this.value = value;
+ // operator []=(index, value) => this[index] = value;
+ body = new ir.ExpressionStatement(
+ visitForEffect(returnStatement.expression));
+ } else {
+ body = buildStatementInBlock(bodyNode);
+ }
}
return associateElement(
new ir.FunctionNode(body,
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index 0b54370..65ea1b8 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -197,10 +197,10 @@
/// The location of the serialized data from resolution.
final Uri resolutionOutput;
- // If `true`, sources are resolved and serialized.
+ /// If `true`, sources are resolved and serialized.
final bool resolveOnly;
- // If `true`, sources are only available from serialized data.
+ /// If `true`, sources are only available from serialized data.
final bool compileOnly;
/// URI where the compiler should generate the output source map file.
diff --git a/pkg/compiler/lib/src/parser/element_listener.dart b/pkg/compiler/lib/src/parser/element_listener.dart
index e5904f0..75cd0e9 100644
--- a/pkg/compiler/lib/src/parser/element_listener.dart
+++ b/pkg/compiler/lib/src/parser/element_listener.dart
@@ -731,19 +731,7 @@
beginMember(token);
}
- void endFields(fieldCount, start, token) {
- memberErrors = memberErrors.tail;
- }
-
- void endMethod(getOrSet, start, token) {
- memberErrors = memberErrors.tail;
- }
-
- void beginFactoryMethod(Token token) {
- memberErrors = memberErrors.prepend(false);
- }
-
- void endFactoryMethod(Token beginToken, Token endToken) {
+ void endMember() {
memberErrors = memberErrors.tail;
}
diff --git a/pkg/compiler/lib/src/parser/listener.dart b/pkg/compiler/lib/src/parser/listener.dart
index 3115343..b33bd84 100644
--- a/pkg/compiler/lib/src/parser/listener.dart
+++ b/pkg/compiler/lib/src/parser/listener.dart
@@ -212,6 +212,8 @@
void beginMember(Token token) {}
+ void endMember() {}
+
void endMethod(Token getOrSet, Token beginToken, Token endToken) {}
void beginMetadataStar(Token token) {}
diff --git a/pkg/compiler/lib/src/parser/member_listener.dart b/pkg/compiler/lib/src/parser/member_listener.dart
index c21f493..17ecce0 100644
--- a/pkg/compiler/lib/src/parser/member_listener.dart
+++ b/pkg/compiler/lib/src/parser/member_listener.dart
@@ -147,11 +147,7 @@
}
void endMetadata(Token beginToken, Token periodBeforeName, Token endToken) {
- popNode(); // Discard arguments.
- if (periodBeforeName != null) {
- popNode(); // Discard name.
- }
- popNode(); // Discard node (Send or Identifier).
+ super.endMetadata(beginToken, periodBeforeName, endToken);
pushMetadata(new PartialMetadataAnnotation(beginToken, endToken));
}
}
diff --git a/pkg/compiler/lib/src/parser/node_listener.dart b/pkg/compiler/lib/src/parser/node_listener.dart
index feaa44c..f3e343c 100644
--- a/pkg/compiler/lib/src/parser/node_listener.dart
+++ b/pkg/compiler/lib/src/parser/node_listener.dart
@@ -27,6 +27,53 @@
pushNode(tag);
}
+ void endLibraryName(Token libraryKeyword, Token semicolon) {
+ Expression name = popNode();
+ pushNode(new LibraryName(libraryKeyword, name,
+ // TODO(sigmund): Import AST nodes have pointers to MetadataAnnotation
+ // (element) instead of Metatada (node).
+ null));
+ }
+
+ void endImport(Token importKeyword, Token deferredKeyword, Token asKeyword,
+ Token semicolon) {
+ NodeList combinators = popNode();
+ Identifier prefix = asKeyword != null ? popNode() : null;
+ NodeList conditionalUris = popNode();
+ StringNode uri = popLiteralString();
+ pushNode(new Import(importKeyword, uri, conditionalUris, prefix,
+ combinators,
+ // TODO(sigmund): Import AST nodes have pointers to MetadataAnnotation
+ // (element) instead of Metatada (node).
+ null, isDeferred: deferredKeyword != null));
+ }
+
+ void endExport(Token exportKeyword, Token semicolon) {
+ NodeList combinators = popNode();
+ NodeList conditionalUris = popNode();
+ StringNode uri = popLiteralString();
+ pushNode(new Export(exportKeyword, uri, conditionalUris, combinators,
+ // TODO(sigmund): Import AST nodes have pointers to MetadataAnnotation
+ // (element) instead of Metatada (node).
+ null));
+ }
+
+ void endPart(Token partKeyword, Token semicolon) {
+ StringNode uri = popLiteralString();
+ pushNode(new Part(partKeyword, uri,
+ // TODO(sigmund): Import AST nodes have pointers to MetadataAnnotation
+ // (element) instead of Metatada (node).
+ null));
+ }
+
+ void endPartOf(Token partKeyword, Token semicolon) {
+ Expression name = popNode(); // name
+ pushNode(new PartOf(partKeyword, name,
+ // TODO(sigmund): Import AST nodes have pointers to MetadataAnnotation
+ // (element) instead of Metatada (node).
+ null));
+ }
+
void endClassDeclaration(int interfacesCount, Token beginToken,
Token extendsKeyword, Token implementsKeyword, Token endToken) {
NodeList body = popNode();
@@ -40,6 +87,15 @@
interfaces, beginToken, extendsKeyword, body, endToken));
}
+ void endTopLevelDeclaration(Token token) {
+ // TODO(sigmund): consider moving metadata into each declaration
+ // element instead.
+ Node node = popNode(); // top-level declaration
+ popNode(); // Discard metadata
+ pushNode(node);
+ super.endTopLevelDeclaration(token);
+ }
+
void endCompilationUnit(int count, Token token) {
pushNode(makeNodeList(count, null, null, '\n'));
}
@@ -82,15 +138,15 @@
}
void endTopLevelMethod(Token beginToken, Token getOrSet, Token endToken) {
- popNode(); // body
- popNode(); // formalParameters
- popNode(); // typeVariables
+ Statement body = popNode();
+ AsyncModifier asyncModifier = popNode();
+ NodeList formals = popNode();
+ NodeList typeVariables = popNode();
Identifier name = popNode();
- popNode(); // type
+ TypeAnnotation type = popNode();
Modifiers modifiers = popNode();
- PartialFunctionElement element = new PartialFunctionElement(name.source,
- beginToken, getOrSet, endToken, modifiers, compilationUnitElement);
- pushElement(element);
+ pushNode(new FunctionExpression(name, typeVariables, formals, body, type,
+ modifiers, null, getOrSet, asyncModifier));
}
void endFormalParameter(Token thisKeyword) {
@@ -481,6 +537,15 @@
pushNode(null);
}
+ void endMember() {
+ // TODO(sigmund): consider moving metadata into each declaration
+ // element instead.
+ Node node = popNode(); // member
+ popNode(); // Discard metadata
+ pushNode(node);
+ super.endMember();
+ }
+
void endFields(int count, Token beginToken, Token endToken) {
NodeList variables = makeNodeList(count, null, endToken, ",");
TypeAnnotation type = popNode();
@@ -693,13 +758,10 @@
}
void endMetadataStar(int count, bool forParameter) {
- // TODO(johnniwinther): Handle metadata for all node kinds.
- if (forParameter) {
- if (0 == count) {
- pushNode(null);
- } else {
- pushNode(makeNodeList(count, null, null, ' '));
- }
+ if (0 == count) {
+ pushNode(null);
+ } else {
+ pushNode(makeNodeList(count, null, null, ' '));
}
}
diff --git a/pkg/compiler/lib/src/parser/parser.dart b/pkg/compiler/lib/src/parser/parser.dart
index f9998ca..3cac037 100644
--- a/pkg/compiler/lib/src/parser/parser.dart
+++ b/pkg/compiler/lib/src/parser/parser.dart
@@ -112,7 +112,6 @@
int count = 0;
while (!identical(token.kind, EOF_TOKEN)) {
token = parseTopLevelDeclaration(token);
- listener.endTopLevelDeclaration(token);
count++;
}
listener.endCompilationUnit(count, token);
@@ -120,6 +119,12 @@
}
Token parseTopLevelDeclaration(Token token) {
+ token = _parseTopLevelDeclaration(token);
+ listener.endTopLevelDeclaration(token);
+ return token;
+ }
+
+ Token _parseTopLevelDeclaration(Token token) {
token = parseMetadataStar(token);
final String value = token.stringValue;
if ((identical(value, 'abstract') && optional('class', token.next)) ||
@@ -475,8 +480,6 @@
if (type.isRequired) {
listener.reportError(
equal, MessageKind.REQUIRED_PARAMETER_WITH_DEFAULT);
- } else if (type.isNamed && identical('=', value)) {
- listener.reportError(equal, MessageKind.NAMED_PARAMETER_WITH_EQUALS);
} else if (type.isPositional && identical(':', value)) {
listener.reportError(
equal, MessageKind.POSITIONAL_PARAMETER_WITH_EQUALS);
@@ -1357,11 +1360,14 @@
Token parseMember(Token token) {
token = parseMetadataStar(token);
- if (isFactoryDeclaration(token)) {
- return parseFactoryMethod(token);
- }
Token start = token;
listener.beginMember(token);
+ if (isFactoryDeclaration(token)) {
+ token = parseFactoryMethod(token);
+ listener.endMember();
+ assert (token != null);
+ return token;
+ }
Link<Token> identifiers = findMemberName(token);
if (identifiers.isEmpty) {
@@ -1427,15 +1433,18 @@
if (identical(token.kind, EOF_TOKEN)) {
// TODO(ahe): This is a hack, see parseTopLevelMember.
listener.endFields(1, start, token);
+ listener.endMember();
return token;
}
}
}
var modifiers = identifiers.reverse();
- return isField
+ token = isField
? parseFields(start, modifiers, type, getOrSet, name, false)
: parseMethod(start, modifiers, type, getOrSet, name);
+ listener.endMember();
+ return token;
}
Token parseMethod(Token start, Link<Token> modifiers, Token type,
diff --git a/pkg/compiler/lib/src/parser/partial_parser.dart b/pkg/compiler/lib/src/parser/partial_parser.dart
index 0868265..3e2c025 100644
--- a/pkg/compiler/lib/src/parser/partial_parser.dart
+++ b/pkg/compiler/lib/src/parser/partial_parser.dart
@@ -26,6 +26,7 @@
// This method is overridden for two reasons:
// 1. Avoid generating events for arguments.
// 2. Avoid calling skip expression for each argument (which doesn't work).
+ listener.handleNoArguments(token);
if (optional('(', token)) {
BeginGroupToken begin = token;
return begin.endGroup.next;
diff --git a/pkg/compiler/lib/src/resolution/constructors.dart b/pkg/compiler/lib/src/resolution/constructors.dart
index 1ccf768..d15f041 100644
--- a/pkg/compiler/lib/src/resolution/constructors.dart
+++ b/pkg/compiler/lib/src/resolution/constructors.dart
@@ -222,8 +222,8 @@
functionNode, calledConstructor, callStructure, className,
isImplicitSuperCall: true);
if (!result.isError) {
- registry.registerStaticUse(
- new StaticUse.constructorInvoke(calledConstructor, callStructure));
+ registry.registerStaticUse(new StaticUse.superConstructorInvoke(
+ calledConstructor, callStructure));
}
if (isConst && isValidAsConstant) {
diff --git a/pkg/compiler/lib/src/resolution/members.dart b/pkg/compiler/lib/src/resolution/members.dart
index 390b161..e508c83 100644
--- a/pkg/compiler/lib/src/resolution/members.dart
+++ b/pkg/compiler/lib/src/resolution/members.dart
@@ -1117,12 +1117,12 @@
if (notTypeNode != null) {
// `e is! T`.
Node typeNode = notTypeNode.receiver;
- type = resolveTypeAnnotation(typeNode);
+ type = resolveTypeAnnotation(typeNode, registerCheckedModeCheck: false);
sendStructure = new IsNotStructure(type);
} else {
// `e is T`.
Node typeNode = node.arguments.head;
- type = resolveTypeAnnotation(typeNode);
+ type = resolveTypeAnnotation(typeNode, registerCheckedModeCheck: false);
sendStructure = new IsStructure(type);
}
@@ -1144,7 +1144,8 @@
visitExpression(expression);
Node typeNode = node.arguments.head;
- DartType type = resolveTypeAnnotation(typeNode);
+ DartType type =
+ resolveTypeAnnotation(typeNode, registerCheckedModeCheck: false);
// GENERIC_METHODS: Method type variables are not reified so we must warn
// about the error which will occur at runtime.
@@ -3444,12 +3445,13 @@
registry.setSelector(node, setterSelector);
registry.setOperatorSelectorInComplexSendSet(node, operatorSelector);
- registry.registerDynamicUse(new DynamicUse(operatorSelector, null));
-
SendStructure sendStructure;
if (operator.kind == AssignmentOperatorKind.IF_NULL) {
+ registry.registerConstantLiteral(new NullConstantExpression());
+ registry.registerDynamicUse(new DynamicUse(Selectors.equals, null));
sendStructure = new SetIfNullStructure(semantics);
} else {
+ registry.registerDynamicUse(new DynamicUse(operatorSelector, null));
sendStructure = new CompoundStructure(semantics, operator);
}
registry.registerSendStructure(node, sendStructure);
@@ -3665,6 +3667,9 @@
// TODO(johnniwinther): Handle this (potentially) erroneous case.
isValidAsConstant = false;
}
+ if (type.typeArguments.any((DartType type) => !type.isDynamic)) {
+ registry.registerFeature(Feature.TYPE_VARIABLE_BOUNDS_CHECK);
+ }
redirectionTarget.computeType(resolution);
FunctionSignature targetSignature = redirectionTarget.functionSignature;
@@ -3882,11 +3887,17 @@
if (!isInvalid) {
// [constructor] might be the implementation element
// and only declaration elements may be registered.
- registry.registerStaticUse(new StaticUse.constructorInvoke(
- constructor.declaration, callStructure));
// TODO(johniwinther): Avoid registration of `type` in face of redirecting
// factory constructors.
- registry.registerTypeUse(new TypeUse.instantiation(type));
+ registry.registerStaticUse(node.isConst
+ ? new StaticUse.constConstructorInvoke(
+ constructor.declaration, callStructure, type)
+ : new StaticUse.typedConstructorInvoke(
+ constructor.declaration, callStructure, type));
+ InterfaceType interfaceType = type;
+ if (interfaceType.typeArguments.any((DartType type) => !type.isDynamic)) {
+ registry.registerFeature(Feature.TYPE_VARIABLE_BOUNDS_CHECK);
+ }
}
ResolutionResult resolutionResult = const NoneResult();
@@ -4594,6 +4605,15 @@
reporter.reportErrorMessage(
switchCase, MessageKind.INVALID_CASE_DEFAULT);
}
+ if (cases.isNotEmpty && switchCase.statements.isNotEmpty) {
+ Node last = switchCase.statements.last;
+ if (last.asBreakStatement() == null &&
+ last.asContinueStatement() == null &&
+ last.asThrow() == null &&
+ last.asReturn() == null) {
+ registry.registerFeature(Feature.FALL_THROUGH_ERROR);
+ }
+ }
}
addDeferredAction(enclosingElement, () {
@@ -4615,7 +4635,6 @@
});
// TODO(15575): We should warn if we can detect a fall through
// error.
- registry.registerFeature(Feature.FALL_THROUGH_ERROR);
return const NoneResult();
}
diff --git a/pkg/compiler/lib/src/resolution/resolution.dart b/pkg/compiler/lib/src/resolution/resolution.dart
index 13f248c..bdfffd8 100644
--- a/pkg/compiler/lib/src/resolution/resolution.dart
+++ b/pkg/compiler/lib/src/resolution/resolution.dart
@@ -430,16 +430,18 @@
}
DartType resolveTypeAnnotation(Element element, TypeAnnotation annotation) {
- DartType type = resolveReturnType(element, annotation);
+ DartType type = _resolveReturnType(element, annotation);
if (type.isVoid) {
reporter.reportErrorMessage(annotation, MessageKind.VOID_NOT_ALLOWED);
}
return type;
}
- DartType resolveReturnType(Element element, TypeAnnotation annotation) {
+ DartType _resolveReturnType(Element element, TypeAnnotation annotation) {
if (annotation == null) return const DynamicType();
DartType result = visitorFor(element).resolveTypeAnnotation(annotation);
+ assert(invariant(annotation, result != null,
+ message: "No type computed for $annotation."));
if (result == null) {
// TODO(karklose): warning.
return const DynamicType();
diff --git a/pkg/compiler/lib/src/resolution/type_resolver.dart b/pkg/compiler/lib/src/resolution/type_resolver.dart
index 274911d..bc9f2e5 100644
--- a/pkg/compiler/lib/src/resolution/type_resolver.dart
+++ b/pkg/compiler/lib/src/resolution/type_resolver.dart
@@ -222,7 +222,6 @@
node, "Unexpected element kind ${element.kind}.");
}
if (addTypeVariableBoundsCheck) {
- registry.registerFeature(Feature.TYPE_VARIABLE_BOUNDS_CHECK);
visitor.addDeferredAction(visitor.enclosingElement,
() => checkTypeVariableBounds(node, type));
}
diff --git a/pkg/compiler/lib/src/serialization/impact_serialization.dart b/pkg/compiler/lib/src/serialization/impact_serialization.dart
index e8ee514..c6ce258 100644
--- a/pkg/compiler/lib/src/serialization/impact_serialization.dart
+++ b/pkg/compiler/lib/src/serialization/impact_serialization.dart
@@ -78,6 +78,9 @@
object.setEnum(Key.KIND, staticUse.kind);
serializeElementReference(
element, Key.ELEMENT, Key.NAME, object, staticUse.element);
+ if (staticUse.type != null) {
+ object.setType(Key.TYPE, staticUse.type);
+ }
}
@override
@@ -131,7 +134,8 @@
StaticUseKind kind = object.getEnum(Key.KIND, StaticUseKind.values);
Element usedElement =
deserializeElementReference(element, Key.ELEMENT, Key.NAME, object);
- staticUses.add(new StaticUse.internal(usedElement, kind));
+ DartType type = object.getType(Key.TYPE, isOptional: true);
+ staticUses.add(new StaticUse.internal(usedElement, kind, type));
}
ListDecoder dynamicUseDecoder = objectDecoder.getList(Key.DYNAMIC_USES);
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
index fd89518..f58597b 100644
--- a/pkg/compiler/lib/src/ssa/builder.dart
+++ b/pkg/compiler/lib/src/ssa/builder.dart
@@ -377,7 +377,7 @@
// TODO(johnniwinther): Register this on the [registry]. Currently the
// [CodegenRegistry] calls the enqueuer, but [element] should _not_ be
// enqueued.
- backend.registerStaticUse(element, compiler.enqueuer.codegen);
+ backend.registerStaticUse(element, forResolution: false);
if (backend.isJsInterop(element) && !element.isFactoryConstructor) {
// We only inline factory JavaScript interop constructors.
@@ -677,14 +677,19 @@
// null check.
if (name == '==') {
if (!backend.operatorEqHandlesNullArgument(functionElement)) {
- handleIf(function, visitCondition: () {
- HParameterValue parameter = parameters.values.first;
- push(new HIdentity(parameter, graph.addConstantNull(compiler), null,
- backend.boolType));
- }, visitThen: () {
- closeAndGotoExit(new HReturn(graph.addConstantBool(false, compiler),
- sourceInformationBuilder.buildImplicitReturn(functionElement)));
- },
+ handleIf(
+ node: function,
+ visitCondition: () {
+ HParameterValue parameter = parameters.values.first;
+ push(new HIdentity(parameter, graph.addConstantNull(compiler),
+ null, backend.boolType));
+ },
+ visitThen: () {
+ closeAndGotoExit(new HReturn(
+ graph.addConstantBool(false, compiler),
+ sourceInformationBuilder
+ .buildImplicitReturn(functionElement)));
+ },
visitElse: null,
sourceInformation: sourceInformationBuilder.buildIf(function.body));
}
@@ -811,7 +816,7 @@
assert(resolvedAst != null);
localsHandler = new LocalsHandler(this, function, instanceType, compiler);
localsHandler.closureData =
- compiler.closureToClassMapper.computeClosureToClassMapping(resolvedAst);
+ compiler.closureToClassMapper.getClosureToClassMapping(resolvedAst);
returnLocal = new SyntheticLocal("result", function);
localsHandler.updateLocal(returnLocal, graph.addConstantNull(compiler));
@@ -985,8 +990,8 @@
ResolvedAst oldResolvedAst = resolvedAst;
resolvedAst = callee.resolvedAst;
ClosureClassMap oldClosureData = localsHandler.closureData;
- ClosureClassMap newClosureData = compiler.closureToClassMapper
- .computeClosureToClassMapping(resolvedAst);
+ ClosureClassMap newClosureData =
+ compiler.closureToClassMapper.getClosureToClassMapping(resolvedAst);
localsHandler.closureData = newClosureData;
if (resolvedAst.kind == ResolvedAstKind.PARSED) {
localsHandler.enterScope(resolvedAst.node, callee);
@@ -1158,8 +1163,7 @@
resolvedAst = fieldResolvedAst;
// In case the field initializer uses closures, run the
// closure to class mapper.
- compiler.closureToClassMapper
- .computeClosureToClassMapping(resolvedAst);
+ compiler.closureToClassMapper.getClosureToClassMapping(resolvedAst);
inlinedFrom(fieldResolvedAst, () => right.accept(this));
resolvedAst = savedResolvedAst;
fieldValues[member] = pop();
@@ -1317,8 +1321,8 @@
}
bodyCallInputs.add(newObject);
ast.Node node = constructorResolvedAst.node;
- ClosureClassMap parameterClosureData =
- compiler.closureToClassMapper.getMappingForNestedFunction(node);
+ ClosureClassMap parameterClosureData = compiler.closureToClassMapper
+ .getClosureToClassMapping(constructorResolvedAst);
FunctionSignature functionSignature = body.functionSignature;
// Provide the parameters to the generative constructor body.
@@ -1659,7 +1663,7 @@
pop();
}
- handleIf(node, visitCondition: buildCondition, visitThen: fail);
+ handleIf(node: node, visitCondition: buildCondition, visitThen: fail);
}
visitBlock(ast.Block node) {
@@ -1901,8 +1905,9 @@
}
visitFunctionExpression(ast.FunctionExpression node) {
- ClosureClassMap nestedClosureData =
- compiler.closureToClassMapper.getMappingForNestedFunction(node);
+ LocalFunctionElement methodElement = elements[node];
+ ClosureClassMap nestedClosureData = compiler.closureToClassMapper
+ .getClosureToClassMapping(methodElement.resolvedAst);
assert(nestedClosureData != null);
assert(nestedClosureData.closureClassElement != null);
ClosureClassElement closureClassElement =
@@ -1926,7 +1931,6 @@
push(new HCreate(closureClassElement, capturedVariables, type)
..sourceInformation = sourceInformationBuilder.buildCreate(node));
- Element methodElement = nestedClosureData.closureElement;
registry?.registerInstantiatedClosure(methodElement);
}
@@ -1954,24 +1958,14 @@
visitIf(ast.If node) {
assert(isReachable);
- handleIf(node,
+ handleIf(
+ node: node,
visitCondition: () => visit(node.condition),
visitThen: () => visit(node.thenPart),
visitElse: node.elsePart != null ? () => visit(node.elsePart) : null,
sourceInformation: sourceInformationBuilder.buildIf(node));
}
- void handleIf(ast.Node diagnosticNode,
- {void visitCondition(),
- void visitThen(),
- void visitElse(),
- SourceInformation sourceInformation}) {
- SsaBranchBuilder branchBuilder =
- new SsaBranchBuilder(this, compiler, diagnosticNode);
- branchBuilder.handleIf(visitCondition, visitThen, visitElse,
- sourceInformation: sourceInformation);
- }
-
@override
void visitIfNull(ast.Send node, ast.Node left, ast.Node right, _) {
SsaBranchBuilder brancher = new SsaBranchBuilder(this, compiler, node);
@@ -3743,7 +3737,7 @@
new Map<DartType, Set<DartType>>();
bool definitelyFails = false;
- addTypeVariableBoundCheck(GenericType instance, DartType typeArgument,
+ void addTypeVariableBoundCheck(GenericType instance, DartType typeArgument,
TypeVariableType typeVariable, DartType bound) {
if (definitelyFails) return;
@@ -6160,7 +6154,8 @@
nativeBehavior: native.NativeBehavior.PURE));
}
- handleIf(node,
+ handleIf(
+ node: node,
visitCondition: buildCondition,
visitThen: buildLoop,
visitElse: () => {});
@@ -6502,16 +6497,24 @@
isRethrow: true));
} else {
ast.CatchBlock newBlock = link.head;
- handleIf(node, visitCondition: () {
- pushCondition(newBlock);
- }, visitThen: visitThen, visitElse: visitElse);
+ handleIf(
+ node: node,
+ visitCondition: () {
+ pushCondition(newBlock);
+ },
+ visitThen: visitThen,
+ visitElse: visitElse);
}
}
ast.CatchBlock firstBlock = link.head;
- handleIf(node, visitCondition: () {
- pushCondition(firstBlock);
- }, visitThen: visitThen, visitElse: visitElse);
+ handleIf(
+ node: node,
+ visitCondition: () {
+ pushCondition(firstBlock);
+ },
+ visitThen: visitThen,
+ visitElse: visitElse);
if (!isAborted()) endCatchBlock = close(new HGoto());
rethrowableException = oldRethrowableException;
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index a309e39..4665ee8 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -108,7 +108,11 @@
void buildField(ir.Field field) {
openFunction();
- field.initializer.accept(this);
+ if (field.initializer != null) {
+ field.initializer.accept(this);
+ } else {
+ stack.add(graph.addConstantNull(compiler));
+ }
HInstruction value = pop();
closeAndGotoExit(new HReturn(value, null));
closeFunction();
@@ -412,11 +416,38 @@
@override
void visitIfStatement(ir.IfStatement ifStatement) {
- SsaBranchBuilder brancher = new SsaBranchBuilder(this, compiler);
- brancher.handleIf(
- () => ifStatement.condition.accept(this),
- () => ifStatement.then.accept(this),
- () => ifStatement.otherwise?.accept(this));
+ handleIf(
+ visitCondition: () => ifStatement.condition.accept(this),
+ visitThen: () => ifStatement.then.accept(this),
+ visitElse: () => ifStatement.otherwise?.accept(this));
+ }
+
+ @override
+ void visitAssertStatement(ir.AssertStatement assertStatement) {
+ if (!compiler.options.enableUserAssertions) return;
+ if (assertStatement.message == null) {
+ assertStatement.condition.accept(this);
+ _pushStaticInvocation(astAdapter.assertHelper, <HInstruction>[pop()],
+ astAdapter.assertHelperReturnType);
+ pop();
+ return;
+ }
+
+ // if (assertTest(condition)) assertThrow(message);
+ void buildCondition() {
+ assertStatement.condition.accept(this);
+ _pushStaticInvocation(astAdapter.assertTest, <HInstruction>[pop()],
+ astAdapter.assertTestReturnType);
+ }
+
+ void fail() {
+ assertStatement.message.accept(this);
+ _pushStaticInvocation(astAdapter.assertThrow, <HInstruction>[pop()],
+ astAdapter.assertThrowReturnType);
+ pop();
+ }
+
+ handleIf(visitCondition: buildCondition, visitThen: fail);
}
@override
diff --git a/pkg/compiler/lib/src/ssa/graph_builder.dart b/pkg/compiler/lib/src/ssa/graph_builder.dart
index a6ef442..22e6c30 100644
--- a/pkg/compiler/lib/src/ssa/graph_builder.dart
+++ b/pkg/compiler/lib/src/ssa/graph_builder.dart
@@ -4,12 +4,15 @@
import '../compiler.dart';
import '../elements/elements.dart';
+import '../io/source_information.dart';
import '../js_backend/js_backend.dart';
import '../resolution/tree_elements.dart';
+import '../tree/tree.dart' as ast;
import '../types/types.dart';
import 'jump_handler.dart';
import 'locals_handler.dart';
import 'nodes.dart';
+import 'ssa_branch_builder.dart';
/// Base class for objects that build up an SSA graph.
///
@@ -159,6 +162,17 @@
return result;
}
+ void handleIf(
+ {ast.Node node,
+ void visitCondition(),
+ void visitThen(),
+ void visitElse(),
+ SourceInformation sourceInformation}) {
+ SsaBranchBuilder branchBuilder = new SsaBranchBuilder(this, compiler, node);
+ branchBuilder.handleIf(visitCondition, visitThen, visitElse,
+ sourceInformation: sourceInformation);
+ }
+
HSubGraphBlockInformation wrapStatementGraph(SubGraph statements) {
if (statements == null) return null;
return new HSubGraphBlockInformation(statements);
diff --git a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
index 463c31c..63e3a26 100644
--- a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
+++ b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
@@ -34,55 +34,46 @@
return null;
}
+ void clearAllSideEffects(HInstruction instruction) {
+ instruction.sideEffects.clearAllSideEffects();
+ instruction.sideEffects.clearAllDependencies();
+ instruction.setUseGvn();
+ }
+
Operation operation(ConstantSystem constantSystem) => null;
static InvokeDynamicSpecializer lookupSpecializer(Selector selector) {
- if (selector.isIndex) {
- return const IndexSpecializer();
- } else if (selector.isIndexSet) {
- return const IndexAssignSpecializer();
- } else if (selector.isOperator) {
- if (selector.name == 'unary-') {
- return const UnaryNegateSpecializer();
- } else if (selector.name == '~') {
- return const BitNotSpecializer();
- } else if (selector.name == '+') {
- return const AddSpecializer();
- } else if (selector.name == '-') {
- return const SubtractSpecializer();
- } else if (selector.name == '*') {
- return const MultiplySpecializer();
- } else if (selector.name == '/') {
- return const DivideSpecializer();
- } else if (selector.name == '~/') {
- return const TruncatingDivideSpecializer();
- } else if (selector.name == '%') {
- return const ModuloSpecializer();
- } else if (selector.name == '>>') {
- return const ShiftRightSpecializer();
- } else if (selector.name == '<<') {
- return const ShiftLeftSpecializer();
- } else if (selector.name == '&') {
- return const BitAndSpecializer();
- } else if (selector.name == '|') {
- return const BitOrSpecializer();
- } else if (selector.name == '^') {
- return const BitXorSpecializer();
- } else if (selector.name == '==') {
- return const EqualsSpecializer();
- } else if (selector.name == '<') {
- return const LessSpecializer();
- } else if (selector.name == '<=') {
- return const LessEqualSpecializer();
- } else if (selector.name == '>') {
- return const GreaterSpecializer();
- } else if (selector.name == '>=') {
- return const GreaterEqualSpecializer();
- }
- } else if (selector.isCall) {
- if (selector.argumentCount == 1 && selector.namedArguments.length == 0) {
- if (selector.name == 'codeUnitAt') {
- return const CodeUnitAtSpecializer();
+ if (selector.isIndex) return const IndexSpecializer();
+ if (selector.isIndexSet) return const IndexAssignSpecializer();
+ String name = selector.name;
+ if (selector.isOperator) {
+ if (name == 'unary-') return const UnaryNegateSpecializer();
+ if (name == '~') return const BitNotSpecializer();
+ if (name == '+') return const AddSpecializer();
+ if (name == '-') return const SubtractSpecializer();
+ if (name == '*') return const MultiplySpecializer();
+ if (name == '/') return const DivideSpecializer();
+ if (name == '~/') return const TruncatingDivideSpecializer();
+ if (name == '%') return const ModuloSpecializer();
+ if (name == '>>') return const ShiftRightSpecializer();
+ if (name == '<<') return const ShiftLeftSpecializer();
+ if (name == '&') return const BitAndSpecializer();
+ if (name == '|') return const BitOrSpecializer();
+ if (name == '^') return const BitXorSpecializer();
+ if (name == '==') return const EqualsSpecializer();
+ if (name == '<') return const LessSpecializer();
+ if (name == '<=') return const LessEqualSpecializer();
+ if (name == '>') return const GreaterSpecializer();
+ if (name == '>=') return const GreaterEqualSpecializer();
+ return const InvokeDynamicSpecializer();
+ }
+ if (selector.isCall) {
+ if (selector.namedArguments.length == 0) {
+ int argumentCount = selector.argumentCount;
+ if (argumentCount == 0) {
+ if (name == 'round') return const RoundSpecializer();
+ } else if (argumentCount == 1) {
+ if (name == 'codeUnitAt') return const CodeUnitAtSpecializer();
}
}
}
@@ -219,12 +210,6 @@
return null;
}
- void clearAllSideEffects(HInstruction instruction) {
- instruction.sideEffects.clearAllSideEffects();
- instruction.sideEffects.clearAllDependencies();
- instruction.setUseGvn();
- }
-
bool inputsArePositiveIntegers(HInstruction instruction, Compiler compiler) {
HInstruction left = instruction.inputs[1];
HInstruction right = instruction.inputs[2];
@@ -756,6 +741,32 @@
HInvokeDynamic instruction, Compiler compiler) {
// TODO(sra): Implement a builtin HCodeUnitAt instruction and the same index
// bounds checking optimizations as for HIndex.
+ HInstruction receiver = instruction.getDartReceiver(compiler);
+ if (receiver.isStringOrNull(compiler)) {
+ // Even if there is no builtin equivalent instruction, we know
+ // String.codeUnitAt does not have any side effect (other than throwing),
+ // and that it can be GVN'ed.
+ clearAllSideEffects(instruction);
+ }
+ return null;
+ }
+}
+
+class RoundSpecializer extends InvokeDynamicSpecializer {
+ const RoundSpecializer();
+
+ UnaryOperation operation(ConstantSystem constantSystem) {
+ return constantSystem.round;
+ }
+
+ HInstruction tryConvertToBuiltin(
+ HInvokeDynamic instruction, Compiler compiler) {
+ HInstruction receiver = instruction.getDartReceiver(compiler);
+ if (receiver.isNumberOrNull(compiler)) {
+ // Even if there is no builtin equivalent instruction, we know the
+ // instruction does not have any side effect, and that it can be GVN'ed.
+ clearAllSideEffects(instruction);
+ }
return null;
}
}
diff --git a/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart b/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart
index 86aee00..0b54193 100644
--- a/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart
+++ b/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart
@@ -255,6 +255,23 @@
TypeMaskFactory.inferredReturnTypeForElement(
_backend.helpers.checkConcurrentModificationError, _compiler);
+ ir.Procedure get assertHelper =>
+ kernel.functions[_backend.helpers.assertHelper];
+
+ TypeMask get assertHelperReturnType => TypeMaskFactory
+ .inferredReturnTypeForElement(_backend.helpers.assertHelper, _compiler);
+
+ ir.Procedure get assertTest => kernel.functions[_backend.helpers.assertTest];
+
+ TypeMask get assertTestReturnType => TypeMaskFactory
+ .inferredReturnTypeForElement(_backend.helpers.assertTest, _compiler);
+
+ ir.Procedure get assertThrow =>
+ kernel.functions[_backend.helpers.assertThrow];
+
+ TypeMask get assertThrowReturnType => TypeMaskFactory
+ .inferredReturnTypeForElement(_backend.helpers.assertThrow, _compiler);
+
DartType getDartType(ir.DartType type) {
return type.accept(_typeConverter);
}
diff --git a/pkg/compiler/lib/src/ssa/kernel_impact.dart b/pkg/compiler/lib/src/ssa/kernel_impact.dart
index a2f9279..0c31e97 100644
--- a/pkg/compiler/lib/src/ssa/kernel_impact.dart
+++ b/pkg/compiler/lib/src/ssa/kernel_impact.dart
@@ -15,6 +15,7 @@
import '../kernel/kernel_debug.dart';
import '../kernel/kernel_visitor.dart';
import '../resolution/registry.dart' show ResolutionWorldImpactBuilder;
+import '../universe/call_structure.dart';
import '../universe/feature.dart';
import '../universe/selector.dart';
import '../universe/use.dart';
@@ -24,27 +25,38 @@
/// Computes the [ResolutionImpact] for [resolvedAst] through kernel.
ResolutionImpact build(Compiler compiler, ResolvedAst resolvedAst) {
- AstElement element = resolvedAst.element.implementation;
+ AstElement element = resolvedAst.element;
JavaScriptBackend backend = compiler.backend;
Kernel kernel = backend.kernelTask.kernel;
KernelImpactBuilder builder =
new KernelImpactBuilder(resolvedAst, compiler, kernel);
- if (element.isFunction) {
+ if (element.isFunction ||
+ element.isGetter ||
+ element.isSetter ||
+ element.isFactoryConstructor) {
ir.Procedure function = kernel.functions[element];
if (function == null) {
- print("FOUND NULL FUNCTION: $element");
+ throw "FOUND NULL FUNCTION: $element";
} else {
return builder.buildProcedure(function);
}
- } else {
+ } else if (element.isGenerativeConstructor) {
+ ir.Constructor constructor = kernel.functions[element];
+ if (constructor == null) {
+ throw "FOUND NULL CONSTRUCTOR: $element";
+ } else {
+ return builder.buildConstructor(constructor);
+ }
+ } else if (element.isField) {
ir.Field field = kernel.fields[element];
if (field == null) {
- print("FOUND NULL FUNCTION: $element");
+ throw "FOUND NULL FIELD: $element";
} else {
return builder.buildField(field);
}
+ } else {
+ throw new UnsupportedError("Unsupported element: $element");
}
- return null;
}
class KernelImpactBuilder extends ir.Visitor {
@@ -72,33 +84,61 @@
return type;
}
- /// Add a checked-mode type use of return type and parameters of [node].
- void checkFunctionTypes(ir.FunctionNode node) {
- checkType(node.returnType);
- node.positionalParameters.forEach((v) => checkType(v.type));
- node.namedParameters.forEach((v) => checkType(v.type));
+ /// Add checked-mode type use for the parameter type and constant for the
+ /// default value of [parameter].
+ void handleParameter(ir.VariableDeclaration parameter) {
+ checkType(parameter.type);
+ visitNode(parameter.initializer);
+ }
+
+ /// Add checked-mode type use for parameter and return types, and add
+ /// constants for default values.
+ void handleSignature(ir.FunctionNode node, {bool checkReturnType: true}) {
+ if (checkReturnType) {
+ checkType(node.returnType);
+ }
+ node.positionalParameters.forEach(handleParameter);
+ node.namedParameters.forEach(handleParameter);
}
ResolutionImpact buildField(ir.Field field) {
checkType(field.type);
if (field.initializer != null) {
visitNode(field.initializer);
+ if (!field.isConst) {
+ impactBuilder.registerFeature(Feature.LAZY_FIELD);
+ }
} else {
impactBuilder.registerFeature(Feature.FIELD_WITHOUT_INITIALIZER);
}
return impactBuilder;
}
+ ResolutionImpact buildConstructor(ir.Constructor constructor) {
+ handleSignature(constructor.function, checkReturnType: false);
+ visitNodes(constructor.initializers);
+ visitNode(constructor.function.body);
+ return impactBuilder;
+ }
+
ResolutionImpact buildProcedure(ir.Procedure procedure) {
- if (procedure.kind == ir.ProcedureKind.Method ||
- procedure.kind == ir.ProcedureKind.Operator) {
- checkFunctionTypes(procedure.function);
- visitNode(procedure.function.body);
- } else {
- compiler.reporter.internalError(
- resolvedAst.element,
- "Unable to compute resolution impact for this kind of Kernel "
- "procedure: ${procedure.kind}");
+ handleSignature(procedure.function);
+ visitNode(procedure.function.body);
+ switch (procedure.function.asyncMarker) {
+ case ir.AsyncMarker.Sync:
+ break;
+ case ir.AsyncMarker.SyncStar:
+ impactBuilder.registerFeature(Feature.SYNC_STAR);
+ break;
+ case ir.AsyncMarker.Async:
+ impactBuilder.registerFeature(Feature.ASYNC);
+ break;
+ case ir.AsyncMarker.AsyncStar:
+ impactBuilder.registerFeature(Feature.ASYNC_STAR);
+ break;
+ case ir.AsyncMarker.SyncYielding:
+ compiler.reporter.internalError(resolvedAst.element,
+ "Unexpected async marker: ${procedure.function.asyncMarker}");
}
return impactBuilder;
}
@@ -196,12 +236,39 @@
}
@override
- void visitStaticInvocation(ir.StaticInvocation invocation) {
- _visitArguments(invocation.arguments);
- Element target = astAdapter.getElement(invocation.target).declaration;
+ void visitConstructorInvocation(ir.ConstructorInvocation node) {
+ handleNew(node, node.target, isConst: node.isConst);
+ }
+
+ void handleNew(ir.InvocationExpression node, ir.Member target,
+ {bool isConst: false}) {
+ _visitArguments(node.arguments);
+ Element element = astAdapter.getElement(target).declaration;
+ ClassElement cls = astAdapter.getElement(target.enclosingClass);
+ List<DartType> typeArguments =
+ astAdapter.getDartTypes(node.arguments.types);
+ InterfaceType type = new InterfaceType(cls, typeArguments);
+ CallStructure callStructure = astAdapter.getCallStructure(node.arguments);
+ impactBuilder.registerStaticUse(isConst
+ ? new StaticUse.constConstructorInvoke(element, callStructure, type)
+ : new StaticUse.typedConstructorInvoke(element, callStructure, type));
+ if (typeArguments.any((DartType type) => !type.isDynamic)) {
+ impactBuilder.registerFeature(Feature.TYPE_VARIABLE_BOUNDS_CHECK);
+ }
+ }
+
+ @override
+ void visitSuperInitializer(ir.SuperInitializer node) {
+ Element target = astAdapter.getElement(node.target).declaration;
+ _visitArguments(node.arguments);
+ impactBuilder.registerStaticUse(new StaticUse.superConstructorInvoke(
+ target, astAdapter.getCallStructure(node.arguments)));
+ }
+
+ @override
+ void visitStaticInvocation(ir.StaticInvocation node) {
+ Element target = astAdapter.getElement(node.target).declaration;
if (target.isFactoryConstructor) {
- impactBuilder.registerStaticUse(new StaticUse.constructorInvoke(
- target, astAdapter.getCallStructure(invocation.arguments)));
// TODO(johnniwinther): We should not mark the type as instantiated but
// rather follow the type arguments directly.
//
@@ -224,18 +291,11 @@
// to B. Currently, we only do this soundly if we register A<int> and
// A<String> as instantiated. We should instead register that A.T is
// instantiated as int and String.
- ClassElement cls =
- astAdapter.getElement(invocation.target.enclosingClass);
- List<DartType> typeArguments =
- astAdapter.getDartTypes(invocation.arguments.types);
- impactBuilder.registerTypeUse(
- new TypeUse.instantiation(new InterfaceType(cls, typeArguments)));
- if (typeArguments.any((DartType type) => !type.isDynamic)) {
- impactBuilder.registerFeature(Feature.TYPE_VARIABLE_BOUNDS_CHECK);
- }
+ handleNew(node, node.target);
} else {
+ _visitArguments(node.arguments);
impactBuilder.registerStaticUse(new StaticUse.staticInvoke(
- target, astAdapter.getCallStructure(invocation.arguments)));
+ target, astAdapter.getCallStructure(node.arguments)));
}
}
@@ -251,6 +311,13 @@
}
@override
+ void visitStaticSet(ir.StaticSet node) {
+ visitNode(node.value);
+ Element element = astAdapter.getElement(node.target).declaration;
+ impactBuilder.registerStaticUse(new StaticUse.staticSet(element));
+ }
+
+ @override
void visitMethodInvocation(ir.MethodInvocation invocation) {
var receiver = invocation.receiver;
if (receiver is ir.VariableGet &&
@@ -299,7 +366,7 @@
void visitFunctionDeclaration(ir.FunctionDeclaration node) {
impactBuilder
.registerStaticUse(new StaticUse.closure(astAdapter.getElement(node)));
- checkFunctionTypes(node.function);
+ handleSignature(node.function);
visitNode(node.function.body);
}
@@ -307,7 +374,7 @@
void visitFunctionExpression(ir.FunctionExpression node) {
impactBuilder
.registerStaticUse(new StaticUse.closure(astAdapter.getElement(node)));
- checkFunctionTypes(node.function);
+ handleSignature(node.function);
visitNode(node.function.body);
}
@@ -321,6 +388,66 @@
}
}
+ @override
+ void visitIsExpression(ir.IsExpression node) {
+ impactBuilder.registerTypeUse(
+ new TypeUse.isCheck(astAdapter.getDartType(node.type)));
+ }
+
+ @override
+ void visitAsExpression(ir.AsExpression node) {
+ impactBuilder
+ .registerTypeUse(new TypeUse.asCast(astAdapter.getDartType(node.type)));
+ }
+
+ @override
+ void visitThrow(ir.Throw node) {
+ impactBuilder.registerFeature(Feature.THROW_EXPRESSION);
+ visitNode(node.expression);
+ }
+
+ @override
+ void visitForInStatement(ir.ForInStatement node) {
+ visitNode(node.variable);
+ visitNode(node.iterable);
+ visitNode(node.body);
+ if (node.isAsync) {
+ impactBuilder.registerFeature(Feature.ASYNC_FOR_IN);
+ } else {
+ impactBuilder.registerFeature(Feature.SYNC_FOR_IN);
+ impactBuilder
+ .registerDynamicUse(new DynamicUse(Selectors.iterator, null));
+ }
+ impactBuilder.registerDynamicUse(new DynamicUse(Selectors.current, null));
+ impactBuilder.registerDynamicUse(new DynamicUse(Selectors.moveNext, null));
+ }
+
+ @override
+ void visitTryCatch(ir.TryCatch node) {
+ visitNode(node.body);
+ visitNodes(node.catches);
+ }
+
+ @override
+ void visitCatch(ir.Catch node) {
+ impactBuilder.registerFeature(Feature.CATCH_STATEMENT);
+ visitNode(node.exception);
+ if (node.stackTrace != null) {
+ impactBuilder.registerFeature(Feature.STACK_TRACE_IN_CATCH);
+ }
+ if (node.guard is! ir.DynamicType) {
+ impactBuilder.registerTypeUse(
+ new TypeUse.catchType(astAdapter.getDartType(node.guard)));
+ }
+ visitNode(node.body);
+ }
+
+ @override
+ void visitTryFinally(ir.TryFinally node) {
+ visitNode(node.body);
+ visitNode(node.finalizer);
+ }
+
// TODO(johnniwinther): Make this throw and visit child nodes explicitly
// instead to ensure that we don't visit unwanted parts of the ir.
@override
diff --git a/pkg/compiler/lib/src/ssa/locals_handler.dart b/pkg/compiler/lib/src/ssa/locals_handler.dart
index dc2babe..0eca03a 100644
--- a/pkg/compiler/lib/src/ssa/locals_handler.dart
+++ b/pkg/compiler/lib/src/ssa/locals_handler.dart
@@ -186,7 +186,7 @@
void startFunction(AstElement element, ast.Node node) {
assert(invariant(element, element.isImplementation));
closureData = _compiler.closureToClassMapper
- .computeClosureToClassMapping(element.resolvedAst);
+ .getClosureToClassMapping(element.resolvedAst);
if (element is FunctionElement) {
FunctionElement functionElement = element;
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index ddeaf26..1b06943 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -873,6 +873,8 @@
static const int TYPE_INFO_READ_VARIABLE_TYPECODE = 39;
static const int TYPE_INFO_EXPRESSION_TYPECODE = 40;
+ static const int FOREIGN_CODE_TYPECODE = 41;
+
HInstruction(this.inputs, this.instructionType)
: id = idCounter++,
usedBy = <HInstruction>[] {
@@ -1901,6 +1903,9 @@
assert(this.throwBehavior != null);
if (effects != null) sideEffects.add(effects);
+ if (nativeBehavior != null && nativeBehavior.useGvn) {
+ setUseGvn();
+ }
}
HForeignCode.statement(js.Template codeTemplate, List<HInstruction> inputs,
@@ -1913,15 +1918,27 @@
accept(HVisitor visitor) => visitor.visitForeignCode(this);
bool isJsStatement() => isStatement;
- bool canThrow() =>
- canBeNull() ? throwBehavior.canThrow : throwBehavior.onNonNull.canThrow;
+ bool canThrow() {
+ if (inputs.length > 0) {
+ return inputs.first.canBeNull()
+ ? throwBehavior.canThrow
+ : throwBehavior.onNonNull.canThrow;
+ }
+ return throwBehavior.canThrow;
+ }
bool onlyThrowsNSM() => throwBehavior.isOnlyNullNSMGuard;
bool get isAllocation =>
nativeBehavior != null && nativeBehavior.isAllocation && !canBeNull();
- String toString() => 'HForeignCode("${codeTemplate.source}",$inputs)';
+ int typeCode() => HInstruction.FOREIGN_CODE_TYPECODE;
+ bool typeEquals(other) => other is HForeignCode;
+ bool dataEquals(HForeignCode other) {
+ return codeTemplate.source == other.codeTemplate.source;
+ }
+
+ String toString() => 'HForeignCode("${codeTemplate.source}", $inputs)';
}
abstract class HInvokeBinary extends HInstruction {
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index 9aa2d98..e8c546a 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -952,7 +952,9 @@
HInstruction visitInvokeStatic(HInvokeStatic node) {
propagateConstantValueToUses(node);
- if (node.element == backend.helpers.checkConcurrentModificationError) {
+ Element element = node.element;
+
+ if (element == backend.helpers.checkConcurrentModificationError) {
if (node.inputs.length == 2) {
HInstruction firstArgument = node.inputs[0];
if (firstArgument is HConstant) {
@@ -960,6 +962,21 @@
if (constant.constant.isTrue) return constant;
}
}
+ } else if (element == backend.helpers.checkInt) {
+ if (node.inputs.length == 1) {
+ HInstruction argument = node.inputs[0];
+ if (argument.isInteger(compiler)) return argument;
+ }
+ } else if (element == backend.helpers.checkNum) {
+ if (node.inputs.length == 1) {
+ HInstruction argument = node.inputs[0];
+ if (argument.isNumber(compiler)) return argument;
+ }
+ } else if (element == backend.helpers.checkString) {
+ if (node.inputs.length == 1) {
+ HInstruction argument = node.inputs[0];
+ if (argument.isString(compiler)) return argument;
+ }
}
return node;
}
@@ -2604,7 +2621,33 @@
MemorySet intersectionFor(
MemorySet other, HBasicBlock block, int predecessorIndex) {
MemorySet result = new MemorySet(compiler);
- if (other == null) return result;
+ if (other == null) {
+ // This is the first visit to a loop header ([other] is `null` because we
+ // have not visited the back edge). Copy the nonEscapingReceivers that are
+ // guaranteed to survive the loop because they are not escaped before
+ // method exit.
+ // TODO(sra): We should do a proper dataflow to find the maximal
+ // nonEscapingReceivers (a variant of Available-Expressions), which must
+ // converge before we edit the program in [findCommonInstruction].
+ for (HInstruction instruction in nonEscapingReceivers) {
+ bool isNonEscapingUse(HInstruction use) {
+ if (use is HReturn) return true; // Escapes, but so does control.
+ if (use is HFieldGet) return true;
+ if (use is HFieldSet &&
+ use.receiver.nonCheck() == instruction &&
+ use.value.nonCheck() != instruction) {
+ return true;
+ }
+ if (use is HTypeInfoReadVariable) return true;
+ return false;
+ }
+
+ if (instruction.usedBy.every(isNonEscapingUse)) {
+ result.nonEscapingReceivers.add(instruction);
+ }
+ }
+ return result;
+ }
fieldValues.forEach((element, values) {
var otherValues = other.fieldValues[element];
diff --git a/pkg/compiler/lib/src/types/flat_type_mask.dart b/pkg/compiler/lib/src/types/flat_type_mask.dart
index 5a3ef8e..ce6cd55 100644
--- a/pkg/compiler/lib/src/types/flat_type_mask.dart
+++ b/pkg/compiler/lib/src/types/flat_type_mask.dart
@@ -14,17 +14,15 @@
static const int SUBCLASS = 2;
static const int SUBTYPE = 3;
- final ClassElement base;
+ final Entity base;
final int flags;
- FlatTypeMask(ClassElement base, int kind, bool isNullable)
+ FlatTypeMask(Entity base, int kind, bool isNullable)
: this.internal(base, (kind << 1) | (isNullable ? 1 : 0));
- FlatTypeMask.exact(ClassElement base) : this.internal(base, (EXACT << 1) | 1);
- FlatTypeMask.subclass(ClassElement base)
- : this.internal(base, (SUBCLASS << 1) | 1);
- FlatTypeMask.subtype(ClassElement base)
- : this.internal(base, (SUBTYPE << 1) | 1);
+ FlatTypeMask.exact(Entity base) : this.internal(base, (EXACT << 1) | 1);
+ FlatTypeMask.subclass(Entity base) : this.internal(base, (SUBCLASS << 1) | 1);
+ FlatTypeMask.subtype(Entity base) : this.internal(base, (SUBTYPE << 1) | 1);
const FlatTypeMask.nonNullEmpty()
: base = null,
@@ -33,23 +31,22 @@
: base = null,
flags = 1;
- FlatTypeMask.nonNullExact(ClassElement base)
- : this.internal(base, EXACT << 1);
- FlatTypeMask.nonNullSubclass(ClassElement base)
+ FlatTypeMask.nonNullExact(Entity base) : this.internal(base, EXACT << 1);
+ FlatTypeMask.nonNullSubclass(Entity base)
: this.internal(base, SUBCLASS << 1);
- FlatTypeMask.nonNullSubtype(ClassElement base)
- : this.internal(base, SUBTYPE << 1);
+ FlatTypeMask.nonNullSubtype(Entity base) : this.internal(base, SUBTYPE << 1);
+
+ bool _validateBase(ClassElement element) => element.isDeclaration;
FlatTypeMask.internal(this.base, this.flags) {
- assert(base == null || base.isDeclaration);
+ assert(base == null || _validateBase(base));
}
/**
* Ensures that the generated mask is normalized, i.e., a call to
* [TypeMask.assertIsNormalized] with the factory's result returns `true`.
*/
- factory FlatTypeMask.normalized(
- ClassElement base, int flags, ClosedWorld world) {
+ factory FlatTypeMask.normalized(Entity base, int flags, ClosedWorld world) {
if ((flags >> 1) == EMPTY || ((flags >> 1) == EXACT)) {
return new FlatTypeMask.internal(base, flags);
}
@@ -61,14 +58,8 @@
if (((flags >> 1) == SUBCLASS) && !world.hasAnyStrictSubclass(base)) {
flags = (flags & 0x1) | (EXACT << 1);
}
- Map<ClassElement, TypeMask> cachedMasks =
- world.canonicalizedTypeMasks[flags];
- if (cachedMasks == null) {
- world.canonicalizedTypeMasks[flags] =
- cachedMasks = <ClassElement, TypeMask>{};
- }
- return cachedMasks.putIfAbsent(
- base, () => new FlatTypeMask.internal(base, flags));
+ return world.getCachedMask(
+ base, flags, () => new FlatTypeMask.internal(base, flags));
}
bool get isEmpty => isEmptyOrNull && !isNullable;
@@ -98,23 +89,23 @@
return isNullable ? new FlatTypeMask.internal(base, flags & ~1) : this;
}
- bool contains(ClassElement type, ClosedWorld closedWorld) {
- assert(type.isDeclaration);
+ bool contains(Entity other, ClosedWorld closedWorld) {
+ assert(_validateBase(other));
if (isEmptyOrNull) {
return false;
- } else if (identical(base, type)) {
+ } else if (identical(base, other)) {
return true;
} else if (isExact) {
return false;
} else if (isSubclass) {
- return closedWorld.isSubclassOf(type, base);
+ return closedWorld.isSubclassOf(other, base);
} else {
assert(isSubtype);
- return closedWorld.isSubtypeOf(type, base);
+ return closedWorld.isSubtypeOf(other, base);
}
}
- bool isSingleImplementationOf(ClassElement cls, ClosedWorld closedWorld) {
+ bool isSingleImplementationOf(Entity cls, ClosedWorld closedWorld) {
// Special case basic types so that, for example, JSString is the
// single implementation of String.
// The general optimization is to realize there is only one class that
@@ -154,7 +145,7 @@
if (other is! FlatTypeMask) return other.containsMask(this, closedWorld);
// The other must be flat, so compare base and flags.
FlatTypeMask flatOther = other;
- ClassElement otherBase = flatOther.base;
+ Entity otherBase = flatOther.base;
// If other is exact, it only contains its base.
// TODO(herhut): Get rid of isSingleImplementationOf.
if (flatOther.isExact) {
@@ -214,23 +205,21 @@
base == backendClasses.stringImplementation;
}
- bool containsOnly(ClassElement cls) {
- assert(cls.isDeclaration);
+ bool containsOnly(Entity cls) {
+ assert(_validateBase(cls));
return base == cls;
}
- bool satisfies(ClassElement cls, ClosedWorld closedWorld) {
- assert(cls.isDeclaration);
+ bool satisfies(Entity cls, ClosedWorld closedWorld) {
+ assert(_validateBase(cls));
if (isEmptyOrNull) return false;
if (closedWorld.isSubtypeOf(base, cls)) return true;
return false;
}
- /**
- * Returns the [ClassElement] if this type represents a single class,
- * otherwise returns `null`. This method is conservative.
- */
- ClassElement singleClass(ClosedWorld closedWorld) {
+ /// Returns the [Entity] if this type represents a single class, otherwise
+ /// returns `null`. This method is conservative.
+ Entity singleClass(ClosedWorld closedWorld) {
if (isEmptyOrNull) return null;
if (isNullable) return null; // It is Null and some other class.
if (isExact) {
@@ -479,6 +468,7 @@
if (isSubclass && other.isSubclass) return intersectionEmpty(other);
assert(isSubtype || other.isSubtype);
int kind = (isSubclass || other.isSubclass) ? SUBCLASS : SUBTYPE;
+ // TODO(johnniwinther): Move this computation to [ClosedWorld].
// Compute the set of classes that are contained in both type masks.
Set<ClassElement> common = commonContainedClasses(this, other, closedWorld);
if (common == null || common.isEmpty) return intersectionEmpty(other);
@@ -504,7 +494,7 @@
// result will only be nullable if both masks are nullable. We have
// to normalize here, as we generate types based on new base classes.
int combined = (kind << 1) | (flags & other.flags & 1);
- Iterable<TypeMask> masks = candidates.map((ClassElement cls) {
+ Iterable<TypeMask> masks = candidates.map((Entity cls) {
return new FlatTypeMask.normalized(cls, combined, closedWorld);
});
return UnionTypeMask.unionOf(masks, closedWorld);
@@ -517,27 +507,6 @@
}
/**
- * Returns whether [element] will be the one used at runtime when being
- * invoked on an instance of [cls]. [selector] is used to ensure library
- * privacy is taken into account.
- */
- static bool hasElementIn(
- ClassElement cls, Selector selector, Element element) {
- // Use [:implementation:] of [element]
- // because our function set only stores declarations.
- Element result = findMatchIn(cls, selector);
- return result == null
- ? false
- : result.implementation == element.implementation;
- }
-
- static Element findMatchIn(ClassElement cls, Selector selector) {
- // Use the [:implementation] of [cls] in case the found [element]
- // is in the patch class.
- return cls.implementation.lookupByName(selector.memberName);
- }
-
- /**
* Returns whether [element] is a potential target when being
* invoked on this type mask. [selector] is used to ensure library
* privacy is taken into account.
@@ -547,7 +516,8 @@
assert(element.name == selector.name);
if (isEmpty) return false;
if (isNull) {
- return hasElementIn(backendClasses.nullImplementation, selector, element);
+ return closedWorld.hasElementIn(
+ backendClasses.nullImplementation, selector, element);
}
// TODO(kasperl): Can't we just avoid creating typed selectors
@@ -563,14 +533,14 @@
if (other == backendClasses.nullImplementation) {
return isNullable;
} else if (isExact) {
- return hasElementIn(self, selector, element);
+ return closedWorld.hasElementIn(self, selector, element);
} else if (isSubclass) {
- return hasElementIn(self, selector, element) ||
+ return closedWorld.hasElementIn(self, selector, element) ||
other.isSubclassOf(self) ||
closedWorld.hasAnySubclassThatMixes(self, other);
} else {
assert(isSubtype);
- bool result = hasElementIn(self, selector, element) ||
+ bool result = closedWorld.hasElementIn(self, selector, element) ||
other.implementsInterface(self) ||
closedWorld.hasAnySubclassThatImplements(other, base) ||
closedWorld.hasAnySubclassOfMixinUseThatImplements(other, base);
@@ -579,108 +549,28 @@
// can be hit from any of the mixin applications.
Iterable<ClassElement> mixinUses = closedWorld.mixinUsesOf(self);
return mixinUses.any((mixinApplication) =>
- hasElementIn(mixinApplication, selector, element) ||
+ closedWorld.hasElementIn(mixinApplication, selector, element) ||
other.isSubclassOf(mixinApplication) ||
closedWorld.hasAnySubclassThatMixes(mixinApplication, other));
}
}
- /**
- * Returns whether a [selector] call on an instance of [cls]
- * will hit a method at runtime, and not go through [noSuchMethod].
- */
- static bool hasConcreteMatch(
- ClassElement cls, Selector selector, ClosedWorld world) {
- assert(invariant(cls, world.isInstantiated(cls),
- message: '$cls has not been instantiated.'));
- Element element = findMatchIn(cls, selector);
- if (element == null) return false;
-
- if (element.isAbstract) {
- ClassElement enclosingClass = element.enclosingClass;
- return hasConcreteMatch(enclosingClass.superclass, selector, world);
- }
- return selector.appliesUntyped(element);
- }
-
bool needsNoSuchMethodHandling(Selector selector, ClosedWorld closedWorld) {
// A call on an empty type mask is either dead code, or a call on
// `null`.
if (isEmptyOrNull) return false;
// A call on an exact mask for an abstract class is dead code.
- if (isExact && base.isAbstract) return false;
- // If the receiver is guaranteed to have a member that
- // matches what we're looking for, there's no need to
- // introduce a noSuchMethod handler. It will never be called.
- //
- // As an example, consider this class hierarchy:
- //
- // A <-- noSuchMethod
- // / \
- // C B <-- foo
- //
- // If we know we're calling foo on an object of type B we
- // don't have to worry about the noSuchMethod method in A
- // because objects of type B implement foo. On the other hand,
- // if we end up calling foo on something of type C we have to
- // add a handler for it.
+ // TODO(johnniwinther): A type mask cannot be abstract. Remove the need
+ // for this noise (currently used for super-calls in inference and mirror
+ // usage).
+ if (isExact && closedWorld.isAbstract(base)) return false;
- // If the holders of all user-defined noSuchMethod
- // implementations that might be applicable to the receiver
- // type have a matching member for the current name and
- // selector, we avoid introducing a noSuchMethod handler.
- //
- // As an example, consider this class hierarchy:
- //
- // A <-- foo
- // / \
- // noSuchMethod --> B C <-- bar
- // | |
- // C D <-- noSuchMethod
- //
- // When calling foo on an object of type A, we know that the
- // implementations of noSuchMethod are in the classes B and D
- // that also (indirectly) implement foo, so we do not need a
- // handler for it.
- //
- // If we're calling bar on an object of type D, we don't need
- // the handler either because all objects of type D implement
- // bar through inheritance.
- //
- // If we're calling bar on an object of type A we do need the
- // handler because we may have to call B.noSuchMethod since B
- // does not implement bar.
-
- /// Returns `true` if [cls] is an instantiated class that does not have
- /// a concrete method matching [selector].
- bool needsNoSuchMethod(ClassElement cls) {
- // We can skip uninstantiated subclasses.
- // TODO(johnniwinther): Put filtering into the (Class)World.
- if (!closedWorld.isInstantiated(cls)) {
- return false;
- }
- // We can just skip abstract classes because we know no
- // instance of them will be created at runtime, and
- // therefore there is no instance that will require
- // [noSuchMethod] handling.
- return !cls.isAbstract && !hasConcreteMatch(cls, selector, closedWorld);
- }
-
- bool baseNeedsNoSuchMethod = needsNoSuchMethod(base);
- if (isExact || baseNeedsNoSuchMethod) {
- return baseNeedsNoSuchMethod;
- }
-
- Iterable<ClassElement> subclassesToCheck;
- if (isSubtype) {
- subclassesToCheck = closedWorld.strictSubtypesOf(base);
- } else {
- assert(isSubclass);
- subclassesToCheck = closedWorld.strictSubclassesOf(base);
- }
-
- return subclassesToCheck != null &&
- subclassesToCheck.any(needsNoSuchMethod);
+ return closedWorld.needsNoSuchMethod(
+ base,
+ selector,
+ isExact
+ ? ClassQuery.EXACT
+ : (isSubclass ? ClassQuery.SUBCLASS : ClassQuery.SUBTYPE));
}
Element locateSingleElement(Selector selector, Compiler compiler) {
@@ -689,7 +579,7 @@
compiler.closedWorld.allFunctions.filter(selector, this);
if (targets.length != 1) return null;
Element result = targets.first;
- ClassElement enclosing = result.enclosingClass;
+ ClassElement enclosing = result.enclosingClass.declaration;
// 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
@@ -703,7 +593,7 @@
//}
return null;
} else {
- if (base.isSubclassOf(enclosing)) return result;
+ if (closedWorld.isSubclassOf(base, enclosing)) return result;
if (closedWorld.isSubclassOfMixinUseOf(base, enclosing)) return result;
}
return null;
diff --git a/pkg/compiler/lib/src/types/forwarding_type_mask.dart b/pkg/compiler/lib/src/types/forwarding_type_mask.dart
index cdf4f16..f285a59 100644
--- a/pkg/compiler/lib/src/types/forwarding_type_mask.dart
+++ b/pkg/compiler/lib/src/types/forwarding_type_mask.dart
@@ -54,23 +54,23 @@
return forwardTo.containsOnlyString(closedWorld);
}
- bool containsOnly(ClassElement element) {
- return forwardTo.containsOnly(element);
+ bool containsOnly(Entity cls) {
+ return forwardTo.containsOnly(cls);
}
- bool satisfies(ClassElement cls, ClosedWorld closedWorld) {
+ bool satisfies(Entity cls, ClosedWorld closedWorld) {
return forwardTo.satisfies(cls, closedWorld);
}
- bool contains(ClassElement type, ClosedWorld closedWorld) {
- return forwardTo.contains(type, closedWorld);
+ bool contains(Entity cls, ClosedWorld closedWorld) {
+ return forwardTo.contains(cls, closedWorld);
}
bool containsAll(ClosedWorld closedWorld) {
return forwardTo.containsAll(closedWorld);
}
- ClassElement singleClass(ClosedWorld closedWorld) {
+ Entity singleClass(ClosedWorld closedWorld) {
return forwardTo.singleClass(closedWorld);
}
diff --git a/pkg/compiler/lib/src/types/masks.dart b/pkg/compiler/lib/src/types/masks.dart
index 9f59ad5..8577558 100644
--- a/pkg/compiler/lib/src/types/masks.dart
+++ b/pkg/compiler/lib/src/types/masks.dart
@@ -12,13 +12,13 @@
import '../inferrer/type_graph_inferrer.dart' show TypeGraphInferrer;
import '../tree/tree.dart';
import '../universe/selector.dart' show Selector;
-import '../universe/universe.dart'
+import '../universe/world_builder.dart'
show
ReceiverConstraint,
UniverseSelectorConstraints,
SelectorConstraintsStrategy;
import '../util/util.dart';
-import '../world.dart' show ClosedWorld;
+import '../world.dart' show ClassQuery, ClosedWorld;
import 'abstract_value_domain.dart' show AbstractValue;
part 'container_type_mask.dart';
diff --git a/pkg/compiler/lib/src/types/type_mask.dart b/pkg/compiler/lib/src/types/type_mask.dart
index cd92ed9..a3ba10d 100644
--- a/pkg/compiler/lib/src/types/type_mask.dart
+++ b/pkg/compiler/lib/src/types/type_mask.dart
@@ -77,30 +77,30 @@
*/
abstract class TypeMask implements ReceiverConstraint, AbstractValue {
factory TypeMask(
- ClassElement base, int kind, bool isNullable, ClosedWorld closedWorld) {
+ Entity base, int kind, bool isNullable, ClosedWorld closedWorld) {
return new FlatTypeMask.normalized(
base, (kind << 1) | (isNullable ? 1 : 0), closedWorld);
}
const factory TypeMask.empty() = FlatTypeMask.empty;
- factory TypeMask.exact(ClassElement base, ClosedWorld closedWorld) {
+ factory TypeMask.exact(Entity base, ClosedWorld closedWorld) {
assert(invariant(base, closedWorld.isInstantiated(base),
message: () => "Cannot create exact type mask for uninstantiated "
"class $base.\n${closedWorld.dump(base)}"));
return new FlatTypeMask.exact(base);
}
- factory TypeMask.exactOrEmpty(ClassElement base, ClosedWorld closedWorld) {
+ factory TypeMask.exactOrEmpty(Entity base, ClosedWorld closedWorld) {
if (closedWorld.isInstantiated(base)) return new FlatTypeMask.exact(base);
return const TypeMask.empty();
}
- factory TypeMask.subclass(ClassElement base, ClosedWorld closedWorld) {
+ factory TypeMask.subclass(Entity base, ClosedWorld closedWorld) {
assert(invariant(base, closedWorld.isInstantiated(base),
message: () => "Cannot create subclass type mask for uninstantiated "
"class $base.\n${closedWorld.dump(base)}"));
- ClassElement topmost = closedWorld.getLubOfInstantiatedSubclasses(base);
+ Entity topmost = closedWorld.getLubOfInstantiatedSubclasses(base);
if (topmost == null) {
return new TypeMask.empty();
} else if (closedWorld.hasAnyStrictSubclass(topmost)) {
@@ -110,8 +110,8 @@
}
}
- factory TypeMask.subtype(ClassElement base, ClosedWorld closedWorld) {
- ClassElement topmost = closedWorld.getLubOfInstantiatedSubtypes(base);
+ factory TypeMask.subtype(Entity base, ClosedWorld closedWorld) {
+ Entity topmost = closedWorld.getLubOfInstantiatedSubtypes(base);
if (topmost == null) {
return new TypeMask.empty();
}
@@ -127,26 +127,25 @@
const factory TypeMask.nonNullEmpty() = FlatTypeMask.nonNullEmpty;
- factory TypeMask.nonNullExact(ClassElement base, ClosedWorld closedWorld) {
+ factory TypeMask.nonNullExact(Entity base, ClosedWorld closedWorld) {
assert(invariant(base, closedWorld.isInstantiated(base),
message: () => "Cannot create exact type mask for uninstantiated "
"class $base.\n${closedWorld.dump(base)}"));
return new FlatTypeMask.nonNullExact(base);
}
- factory TypeMask.nonNullExactOrEmpty(
- ClassElement base, ClosedWorld closedWorld) {
+ factory TypeMask.nonNullExactOrEmpty(Entity base, ClosedWorld closedWorld) {
if (closedWorld.isInstantiated(base)) {
return new FlatTypeMask.nonNullExact(base);
}
return const TypeMask.nonNullEmpty();
}
- factory TypeMask.nonNullSubclass(ClassElement base, ClosedWorld closedWorld) {
+ factory TypeMask.nonNullSubclass(Entity base, ClosedWorld closedWorld) {
assert(invariant(base, closedWorld.isInstantiated(base),
message: () => "Cannot create subclass type mask for uninstantiated "
"class $base.\n${closedWorld.dump(base)}"));
- ClassElement topmost = closedWorld.getLubOfInstantiatedSubclasses(base);
+ Entity topmost = closedWorld.getLubOfInstantiatedSubclasses(base);
if (topmost == null) {
return new TypeMask.nonNullEmpty();
} else if (closedWorld.hasAnyStrictSubclass(topmost)) {
@@ -156,8 +155,8 @@
}
}
- factory TypeMask.nonNullSubtype(ClassElement base, ClosedWorld closedWorld) {
- ClassElement topmost = closedWorld.getLubOfInstantiatedSubtypes(base);
+ factory TypeMask.nonNullSubtype(Entity base, ClosedWorld closedWorld) {
+ Entity topmost = closedWorld.getLubOfInstantiatedSubtypes(base);
if (topmost == null) {
return new TypeMask.nonNullEmpty();
}
@@ -287,7 +286,7 @@
bool containsOnlyNum(ClosedWorld closedWorld);
bool containsOnlyBool(ClosedWorld closedWorld);
bool containsOnlyString(ClosedWorld closedWorld);
- bool containsOnly(ClassElement element);
+ bool containsOnly(Entity cls);
/**
* Compares two [TypeMask] objects for structural equality.
@@ -316,23 +315,21 @@
/**
* Returns whether this type mask is an instance of [cls].
*/
- bool satisfies(ClassElement cls, ClosedWorld closedWorld);
+ bool satisfies(Entity cls, ClosedWorld closedWorld);
/**
- * Returns whether or not this type mask contains the given type.
+ * Returns whether or not this type mask contains the given class [cls].
*/
- bool contains(ClassElement type, ClosedWorld closedWorld);
+ bool contains(Entity cls, ClosedWorld closedWorld);
/**
* Returns whether or not this type mask contains all types.
*/
bool containsAll(ClosedWorld closedWorld);
- /**
- * Returns the [ClassElement] if this type represents a single class,
- * otherwise returns `null`. This method is conservative.
- */
- ClassElement singleClass(ClosedWorld closedWorld);
+ /// Returns the [Entity] if this type represents a single class, otherwise
+ /// returns `null`. This method is conservative.
+ Entity singleClass(ClosedWorld closedWorld);
/**
* Returns a type mask representing the union of [this] and [other].
diff --git a/pkg/compiler/lib/src/types/union_type_mask.dart b/pkg/compiler/lib/src/types/union_type_mask.dart
index 8e4aa39..8ba9a6a 100644
--- a/pkg/compiler/lib/src/types/union_type_mask.dart
+++ b/pkg/compiler/lib/src/types/union_type_mask.dart
@@ -94,15 +94,14 @@
bool useSubclass = masks.every((e) => !e.isSubtype);
bool isNullable = masks.any((e) => e.isNullable);
- List<ClassElement> masksBases = masks.map((mask) => mask.base).toList();
- Iterable<ClassElement> candidates =
- closedWorld.commonSupertypesOf(masksBases);
+ List masksBases = masks.map((mask) => mask.base).toList();
+ Iterable<Entity> candidates = closedWorld.commonSupertypesOf(masksBases);
// Compute the best candidate and its kind.
- ClassElement bestElement;
+ Entity bestElement;
int bestKind;
int bestSize;
- for (ClassElement candidate in candidates) {
+ for (Entity candidate in candidates) {
bool isInstantiatedStrictSubclass(cls) =>
cls != candidate &&
closedWorld.isDirectlyInstantiated(cls) &&
@@ -231,14 +230,14 @@
// Check we cover the base class.
if (!contains(flat.base, closedWorld)) return false;
// Check for other members.
- Iterable<ClassElement> members;
+ Iterable<Entity> members;
if (flat.isSubclass) {
members = closedWorld.strictSubclassesOf(flat.base);
} else {
assert(flat.isSubtype);
members = closedWorld.strictSubtypesOf(flat.base);
}
- return members.every((ClassElement cls) => this.contains(cls, closedWorld));
+ return members.every((Entity cls) => this.contains(cls, closedWorld));
}
bool isInMask(TypeMask other, ClosedWorld closedWorld) {
@@ -306,23 +305,23 @@
return disjointMasks.every((mask) => mask.containsOnlyString(closedWorld));
}
- bool containsOnly(ClassElement element) {
+ bool containsOnly(Entity element) {
return disjointMasks.every((mask) => mask.containsOnly(element));
}
- bool satisfies(ClassElement cls, ClosedWorld closedWorld) {
+ bool satisfies(Entity cls, ClosedWorld closedWorld) {
return disjointMasks.every((mask) => mask.satisfies(cls, closedWorld));
}
- bool contains(ClassElement type, ClosedWorld closedWorld) {
- return disjointMasks.any((e) => e.contains(type, closedWorld));
+ bool contains(Entity cls, ClosedWorld closedWorld) {
+ return disjointMasks.any((e) => e.contains(cls, closedWorld));
}
bool containsAll(ClosedWorld closedWorld) {
return disjointMasks.any((mask) => mask.containsAll(closedWorld));
}
- ClassElement singleClass(ClosedWorld closedWorld) => null;
+ Entity singleClass(ClosedWorld closedWorld) => null;
bool needsNoSuchMethodHandling(Selector selector, ClosedWorld closedWorld) {
return disjointMasks
diff --git a/pkg/compiler/lib/src/universe/function_set.dart b/pkg/compiler/lib/src/universe/function_set.dart
index c05c7f9..ac25450 100644
--- a/pkg/compiler/lib/src/universe/function_set.dart
+++ b/pkg/compiler/lib/src/universe/function_set.dart
@@ -11,7 +11,7 @@
import '../util/util.dart' show Hashing, Setlet;
import '../world.dart' show ClosedWorld;
import 'selector.dart' show Selector;
-import 'universe.dart' show ReceiverConstraint;
+import 'world_builder.dart' show ReceiverConstraint;
// TODO(kasperl): This actually holds getters and setters just fine
// too and stricly they aren't functions. Maybe this needs a better
diff --git a/pkg/compiler/lib/src/universe/universe.dart b/pkg/compiler/lib/src/universe/universe.dart
deleted file mode 100644
index 03fc3c1..0000000
--- a/pkg/compiler/lib/src/universe/universe.dart
+++ /dev/null
@@ -1,665 +0,0 @@
-// Copyright (c) 2012, 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 universe;
-
-import 'dart:collection';
-
-import '../common.dart';
-import '../compiler.dart' show Compiler;
-import '../dart_types.dart';
-import '../elements/elements.dart';
-import '../util/util.dart';
-import '../world.dart' show World, ClosedWorld, OpenWorld;
-import 'selector.dart' show Selector;
-import 'use.dart' show DynamicUse, DynamicUseKind, StaticUse, StaticUseKind;
-
-/// The known constraint on receiver for a dynamic call site.
-///
-/// This can for instance be used to constrain this dynamic call to `foo` to
-/// 'receivers of the exact instance `Bar`':
-///
-/// class Bar {
-/// void foo() {}
-/// }
-/// main() => new Bar().foo();
-///
-abstract class ReceiverConstraint {
- /// Returns whether [element] is a potential target when being
- /// invoked on a receiver with this constraint. [selector] is used to ensure
- /// library privacy is taken into account.
- bool canHit(Element element, Selector selector, World world);
-
- /// Returns whether this [TypeMask] applied to [selector] can hit a
- /// [noSuchMethod].
- bool needsNoSuchMethodHandling(Selector selector, World world);
-}
-
-/// The combined constraints on receivers all the dynamic call sites of the same
-/// selector.
-///
-/// For instance for these calls
-///
-/// class A {
-/// foo(a, b) {}
-/// }
-/// class B {
-/// foo(a, b) {}
-/// }
-/// class C {
-/// foo(a, b) {}
-/// }
-/// new A().foo(a, b);
-/// new B().foo(0, 42);
-///
-/// the selector constraints for dynamic calls to 'foo' with two positional
-/// arguments could be 'receiver of exact instance `A` or `B`'.
-abstract class SelectorConstraints {
- /// Returns `true` if [selector] applies to [element] under these constraints
- /// given the closed [world].
- ///
- /// Consider for instance in this world:
- ///
- /// class A {
- /// foo(a, b) {}
- /// }
- /// class B {
- /// foo(a, b) {}
- /// }
- /// new A().foo(a, b);
- ///
- /// Ideally the selector constraints for calls `foo` with two positional
- /// arguments apply to `A.foo` but `B.foo`.
- bool applies(Element element, Selector selector, World world);
-
- /// Returns `true` if at least one of the receivers matching these constraints
- /// in the closed [world] have no implementation matching [selector].
- ///
- /// For instance for this code snippet
- ///
- /// class A {}
- /// class B { foo() {} }
- /// m(b) => (b ? new A() : new B()).foo();
- ///
- /// the potential receiver `new A()` has no implementation of `foo` and thus
- /// needs to handle the call through its `noSuchMethod` handler.
- bool needsNoSuchMethodHandling(Selector selector, World world);
-}
-
-/// A mutable [SelectorConstraints] used in [Universe].
-abstract class UniverseSelectorConstraints extends SelectorConstraints {
- /// Adds [constraint] to these selector constraints. Return `true` if the set
- /// of potential receivers expanded due to the new constraint.
- bool addReceiverConstraint(ReceiverConstraint constraint);
-}
-
-/// Strategy for computing the constraints on potential receivers of dynamic
-/// call sites.
-abstract class SelectorConstraintsStrategy {
- /// Create a [UniverseSelectorConstraints] to represent the global receiver
- /// constraints for dynamic call sites with [selector].
- UniverseSelectorConstraints createSelectorConstraints(Selector selector);
-}
-
-/// The [Universe] is an auxiliary class used in the process of computing the
-/// [ClosedWorld]. The concepts here and in [ClosedWorld] are very similar -- in
-/// the same way that the "universe expands" you can think of this as a mutable
-/// world that is expanding as we visit and discover parts of the program.
-// TODO(sigmund): rename to "growing/expanding/mutable world"?
-// TODO(johnniwinther): Move common implementation to a [UniverseBase] when
-// universes and worlds have been unified.
-abstract class Universe {
- /// All directly instantiated classes, that is, classes with a generative
- /// constructor that has been called directly and not only through a
- /// super-call.
- // TODO(johnniwinther): Improve semantic precision.
- Iterable<ClassElement> get directlyInstantiatedClasses;
-
- /// All types that are checked either through is, as or checked mode checks.
- Iterable<DartType> get isChecks;
-
- /// Registers that [type] is checked in this universe. The unaliased type is
- /// returned.
- DartType registerIsCheck(DartType type, Compiler compiler);
-
- /// All directly instantiated types, that is, the types of the directly
- /// instantiated classes.
- // TODO(johnniwinther): Improve semantic precision.
- Iterable<DartType> get instantiatedTypes;
-
- /// Returns `true` if [member] is invoked as a setter.
- bool hasInvokedSetter(Element member, World world);
-}
-
-abstract class ResolutionUniverse implements Universe {
- /// Set of (live) local functions (closures) whose signatures reference type
- /// variables.
- ///
- /// A live function is one whose enclosing member function has been enqueued.
- Set<Element> get closuresWithFreeTypeVariables;
-
- /// Set of (live) `call` methods whose signatures reference type variables.
- ///
- /// A live `call` method is one whose enclosing class has been instantiated.
- Iterable<Element> get callMethodsWithFreeTypeVariables;
-
- /// Set of all closures in the program. Used by the mirror tracking system
- /// to find all live closure instances.
- Iterable<LocalFunctionElement> get allClosures;
-
- /// Set of methods in instantiated classes that are potentially closurized.
- Iterable<Element> get closurizedMembers;
-
- /// Returns `true` if [cls] is considered to be implemented by an
- /// instantiated class, either directly, through subclasses or through
- /// subtypes. The latter case only contains spurious information from
- /// instantiations through factory constructors and mixins.
- bool isImplemented(ClassElement cls);
-
- /// Set of all fields that are statically known to be written to.
- Iterable<Element> get fieldSetters;
-}
-
-class ResolutionUniverseImpl implements ResolutionUniverse {
- /// The set of all directly instantiated classes, that is, classes with a
- /// generative constructor that has been called directly and not only through
- /// a super-call.
- ///
- /// Invariant: Elements are declaration elements.
- // TODO(johnniwinther): [_directlyInstantiatedClasses] and
- // [_instantiatedTypes] sets should be merged.
- final Set<ClassElement> _directlyInstantiatedClasses =
- new Set<ClassElement>();
-
- /// The set of all directly instantiated types, that is, the types of the
- /// directly instantiated classes.
- ///
- /// See [_directlyInstantiatedClasses].
- final Set<DartType> _instantiatedTypes = new Set<DartType>();
-
- /// Classes implemented by directly instantiated classes.
- final Set<ClassElement> _implementedClasses = new Set<ClassElement>();
-
- /// The set of all referenced static fields.
- ///
- /// Invariant: Elements are declaration elements.
- final Set<FieldElement> allReferencedStaticFields = new Set<FieldElement>();
-
- /**
- * Documentation wanted -- johnniwinther
- *
- * Invariant: Elements are declaration elements.
- */
- final Set<FunctionElement> methodsNeedingSuperGetter =
- new Set<FunctionElement>();
- final Map<String, Map<Selector, SelectorConstraints>> _invokedNames =
- <String, Map<Selector, SelectorConstraints>>{};
- final Map<String, Map<Selector, SelectorConstraints>> _invokedGetters =
- <String, Map<Selector, SelectorConstraints>>{};
- final Map<String, Map<Selector, SelectorConstraints>> _invokedSetters =
- <String, Map<Selector, SelectorConstraints>>{};
-
- /// Fields set.
- final Set<Element> fieldSetters = new Set<Element>();
- final Set<DartType> isChecks = new Set<DartType>();
-
- /**
- * Set of (live) [:call:] methods whose signatures reference type variables.
- *
- * A live [:call:] method is one whose enclosing class has been instantiated.
- */
- final Set<Element> callMethodsWithFreeTypeVariables = new Set<Element>();
-
- /**
- * Set of (live) local functions (closures) whose signatures reference type
- * variables.
- *
- * A live function is one whose enclosing member function has been enqueued.
- */
- final Set<Element> closuresWithFreeTypeVariables = new Set<Element>();
-
- /**
- * Set of all closures in the program. Used by the mirror tracking system
- * to find all live closure instances.
- */
- final Set<LocalFunctionElement> allClosures = new Set<LocalFunctionElement>();
-
- /**
- * Set of methods in instantiated classes that are potentially
- * closurized.
- */
- final Set<Element> closurizedMembers = new Set<Element>();
-
- final SelectorConstraintsStrategy selectorConstraintsStrategy;
-
- ResolutionUniverseImpl(this.selectorConstraintsStrategy);
-
- /// All directly instantiated classes, that is, classes with a generative
- /// constructor that has been called directly and not only through a
- /// super-call.
- // TODO(johnniwinther): Improve semantic precision.
- Iterable<ClassElement> get directlyInstantiatedClasses {
- return _directlyInstantiatedClasses;
- }
-
- /// All directly instantiated types, that is, the types of the directly
- /// instantiated classes.
- ///
- /// See [directlyInstantiatedClasses].
- // TODO(johnniwinther): Improve semantic precision.
- Iterable<DartType> get instantiatedTypes => _instantiatedTypes;
-
- /// Returns `true` if [cls] is considered to be implemented by an
- /// instantiated class, either directly, through subclasses or through
- /// subtypes. The latter case only contains spurious information from
- /// instantiations through factory constructors and mixins.
- // TODO(johnniwinther): Improve semantic precision.
- bool isImplemented(ClassElement cls) {
- return _implementedClasses.contains(cls.declaration);
- }
-
- /// Register [type] as (directly) instantiated.
- ///
- /// If [byMirrors] is `true`, the instantiation is through mirrors.
- // TODO(johnniwinther): Fully enforce the separation between exact, through
- // subclass and through subtype instantiated types/classes.
- // TODO(johnniwinther): Support unknown type arguments for generic types.
- void registerTypeInstantiation(InterfaceType type,
- {bool byMirrors: false,
- bool isNative: false,
- void onImplemented(ClassElement cls)}) {
- _instantiatedTypes.add(type);
- ClassElement cls = type.element;
- if (!cls.isAbstract
- // We can't use the closed-world assumption with native abstract
- // classes; a native abstract class may have non-abstract subclasses
- // not declared to the program. Instances of these classes are
- // indistinguishable from the abstract class.
- ||
- isNative
- // Likewise, if this registration comes from the mirror system,
- // all bets are off.
- // TODO(herhut): Track classes required by mirrors seperately.
- ||
- byMirrors) {
- _directlyInstantiatedClasses.add(cls);
- }
-
- // TODO(johnniwinther): Replace this by separate more specific mappings that
- // include the type arguments.
- if (_implementedClasses.add(cls)) {
- onImplemented(cls);
- cls.allSupertypes.forEach((InterfaceType supertype) {
- if (_implementedClasses.add(supertype.element)) {
- onImplemented(supertype.element);
- }
- });
- }
- }
-
- bool _hasMatchingSelector(Map<Selector, SelectorConstraints> selectors,
- Element member, OpenWorld world) {
- if (selectors == null) return false;
- for (Selector selector in selectors.keys) {
- if (selector.appliesUnnamed(member)) {
- SelectorConstraints masks = selectors[selector];
- if (masks.applies(member, selector, world)) {
- return true;
- }
- }
- }
- return false;
- }
-
- bool hasInvocation(Element member, OpenWorld world) {
- return _hasMatchingSelector(_invokedNames[member.name], member, world);
- }
-
- bool hasInvokedGetter(Element member, OpenWorld world) {
- return _hasMatchingSelector(_invokedGetters[member.name], member, world) ||
- member.isFunction && methodsNeedingSuperGetter.contains(member);
- }
-
- bool hasInvokedSetter(Element member, OpenWorld world) {
- return _hasMatchingSelector(_invokedSetters[member.name], member, world);
- }
-
- bool registerDynamicUse(DynamicUse dynamicUse) {
- switch (dynamicUse.kind) {
- case DynamicUseKind.INVOKE:
- return _registerNewSelector(dynamicUse, _invokedNames);
- case DynamicUseKind.GET:
- return _registerNewSelector(dynamicUse, _invokedGetters);
- case DynamicUseKind.SET:
- return _registerNewSelector(dynamicUse, _invokedSetters);
- }
- }
-
- bool _registerNewSelector(DynamicUse dynamicUse,
- Map<String, Map<Selector, SelectorConstraints>> selectorMap) {
- Selector selector = dynamicUse.selector;
- String name = selector.name;
- ReceiverConstraint mask = dynamicUse.mask;
- Map<Selector, SelectorConstraints> selectors = selectorMap.putIfAbsent(
- name, () => new Maplet<Selector, SelectorConstraints>());
- UniverseSelectorConstraints constraints =
- selectors.putIfAbsent(selector, () {
- return selectorConstraintsStrategy.createSelectorConstraints(selector);
- });
- return constraints.addReceiverConstraint(mask);
- }
-
- DartType registerIsCheck(DartType type, Compiler compiler) {
- type.computeUnaliased(compiler.resolution);
- type = type.unaliased;
- // Even in checked mode, type annotations for return type and argument
- // types do not imply type checks, so there should never be a check
- // against the type variable of a typedef.
- isChecks.add(type);
- return type;
- }
-
- void registerStaticUse(StaticUse staticUse) {
- Element element = staticUse.element;
- if (Elements.isStaticOrTopLevel(element) && element.isField) {
- allReferencedStaticFields.add(element);
- }
- switch (staticUse.kind) {
- case StaticUseKind.SUPER_FIELD_SET:
- case StaticUseKind.FIELD_SET:
- fieldSetters.add(element);
- break;
- case StaticUseKind.SUPER_TEAR_OFF:
- methodsNeedingSuperGetter.add(element);
- break;
- case StaticUseKind.GENERAL:
- case StaticUseKind.STATIC_TEAR_OFF:
- case StaticUseKind.FIELD_GET:
- break;
- case StaticUseKind.CLOSURE:
- allClosures.add(element);
- break;
- }
- }
-
- void forgetElement(Element element, Compiler compiler) {
- allClosures.remove(element);
- slowDirectlyNestedClosures(element).forEach(compiler.forgetElement);
- closurizedMembers.remove(element);
- fieldSetters.remove(element);
- _directlyInstantiatedClasses.remove(element);
- if (element is ClassElement) {
- assert(invariant(element, element.thisType.isRaw,
- message: 'Generic classes not supported (${element.thisType}).'));
- _instantiatedTypes..remove(element.rawType)..remove(element.thisType);
- }
- }
-
- // TODO(ahe): Replace this method with something that is O(1), for example,
- // by using a map.
- List<LocalFunctionElement> slowDirectlyNestedClosures(Element element) {
- // Return new list to guard against concurrent modifications.
- return new List<LocalFunctionElement>.from(
- allClosures.where((LocalFunctionElement closure) {
- return closure.executableContext == element;
- }));
- }
-}
-
-/// Universe specific to codegen.
-///
-/// This adds additional access to liveness of selectors and elements.
-abstract class CodegenUniverse implements Universe {
- void forEachInvokedName(
- f(String name, Map<Selector, SelectorConstraints> selectors));
-
- void forEachInvokedGetter(
- f(String name, Map<Selector, SelectorConstraints> selectors));
-
- void forEachInvokedSetter(
- f(String name, Map<Selector, SelectorConstraints> selectors));
-
- bool hasInvokedGetter(Element member, ClosedWorld world);
-
- Map<Selector, SelectorConstraints> invocationsByName(String name);
-
- Map<Selector, SelectorConstraints> getterInvocationsByName(String name);
-
- Map<Selector, SelectorConstraints> setterInvocationsByName(String name);
-
- Iterable<FunctionElement> get staticFunctionsNeedingGetter;
- Iterable<FunctionElement> get methodsNeedingSuperGetter;
-
- /// The set of all referenced static fields.
- ///
- /// Invariant: Elements are declaration elements.
- Iterable<FieldElement> get allReferencedStaticFields;
-}
-
-class CodegenUniverseImpl implements CodegenUniverse {
- /// The set of all directly instantiated classes, that is, classes with a
- /// generative constructor that has been called directly and not only through
- /// a super-call.
- ///
- /// Invariant: Elements are declaration elements.
- // TODO(johnniwinther): [_directlyInstantiatedClasses] and
- // [_instantiatedTypes] sets should be merged.
- final Set<ClassElement> _directlyInstantiatedClasses =
- new Set<ClassElement>();
-
- /// The set of all directly instantiated types, that is, the types of the
- /// directly instantiated classes.
- ///
- /// See [_directlyInstantiatedClasses].
- final Set<DartType> _instantiatedTypes = new Set<DartType>();
-
- /// Classes implemented by directly instantiated classes.
- final Set<ClassElement> _implementedClasses = new Set<ClassElement>();
-
- /// The set of all referenced static fields.
- ///
- /// Invariant: Elements are declaration elements.
- final Set<FieldElement> allReferencedStaticFields = new Set<FieldElement>();
-
- /**
- * Documentation wanted -- johnniwinther
- *
- * Invariant: Elements are declaration elements.
- */
- final Set<FunctionElement> staticFunctionsNeedingGetter =
- new Set<FunctionElement>();
- final Set<FunctionElement> methodsNeedingSuperGetter =
- new Set<FunctionElement>();
- final Map<String, Map<Selector, SelectorConstraints>> _invokedNames =
- <String, Map<Selector, SelectorConstraints>>{};
- final Map<String, Map<Selector, SelectorConstraints>> _invokedGetters =
- <String, Map<Selector, SelectorConstraints>>{};
- final Map<String, Map<Selector, SelectorConstraints>> _invokedSetters =
- <String, Map<Selector, SelectorConstraints>>{};
-
- final Set<DartType> isChecks = new Set<DartType>();
-
- final SelectorConstraintsStrategy selectorConstraintsStrategy;
-
- CodegenUniverseImpl(this.selectorConstraintsStrategy);
-
- /// All directly instantiated classes, that is, classes with a generative
- /// constructor that has been called directly and not only through a
- /// super-call.
- // TODO(johnniwinther): Improve semantic precision.
- Iterable<ClassElement> get directlyInstantiatedClasses {
- return _directlyInstantiatedClasses;
- }
-
- /// All directly instantiated types, that is, the types of the directly
- /// instantiated classes.
- ///
- /// See [directlyInstantiatedClasses].
- // TODO(johnniwinther): Improve semantic precision.
- Iterable<DartType> get instantiatedTypes => _instantiatedTypes;
-
- /// Register [type] as (directly) instantiated.
- ///
- /// If [byMirrors] is `true`, the instantiation is through mirrors.
- // TODO(johnniwinther): Fully enforce the separation between exact, through
- // subclass and through subtype instantiated types/classes.
- // TODO(johnniwinther): Support unknown type arguments for generic types.
- void registerTypeInstantiation(InterfaceType type,
- {bool byMirrors: false,
- bool isNative: false,
- void onImplemented(ClassElement cls)}) {
- _instantiatedTypes.add(type);
- ClassElement cls = type.element;
- if (!cls.isAbstract
- // We can't use the closed-world assumption with native abstract
- // classes; a native abstract class may have non-abstract subclasses
- // not declared to the program. Instances of these classes are
- // indistinguishable from the abstract class.
- ||
- isNative
- // Likewise, if this registration comes from the mirror system,
- // all bets are off.
- // TODO(herhut): Track classes required by mirrors seperately.
- ||
- byMirrors) {
- _directlyInstantiatedClasses.add(cls);
- }
-
- // TODO(johnniwinther): Replace this by separate more specific mappings that
- // include the type arguments.
- if (_implementedClasses.add(cls)) {
- onImplemented(cls);
- cls.allSupertypes.forEach((InterfaceType supertype) {
- if (_implementedClasses.add(supertype.element)) {
- onImplemented(supertype.element);
- }
- });
- }
- }
-
- bool _hasMatchingSelector(Map<Selector, SelectorConstraints> selectors,
- Element member, ClosedWorld world) {
- if (selectors == null) return false;
- for (Selector selector in selectors.keys) {
- if (selector.appliesUnnamed(member)) {
- SelectorConstraints masks = selectors[selector];
- if (masks.applies(member, selector, world)) {
- return true;
- }
- }
- }
- return false;
- }
-
- bool hasInvocation(Element member, ClosedWorld world) {
- return _hasMatchingSelector(_invokedNames[member.name], member, world);
- }
-
- bool hasInvokedGetter(Element member, ClosedWorld world) {
- return _hasMatchingSelector(_invokedGetters[member.name], member, world) ||
- member.isFunction && methodsNeedingSuperGetter.contains(member);
- }
-
- bool hasInvokedSetter(Element member, ClosedWorld world) {
- return _hasMatchingSelector(_invokedSetters[member.name], member, world);
- }
-
- bool registerDynamicUse(DynamicUse dynamicUse) {
- switch (dynamicUse.kind) {
- case DynamicUseKind.INVOKE:
- return _registerNewSelector(dynamicUse, _invokedNames);
- case DynamicUseKind.GET:
- return _registerNewSelector(dynamicUse, _invokedGetters);
- case DynamicUseKind.SET:
- return _registerNewSelector(dynamicUse, _invokedSetters);
- }
- }
-
- bool _registerNewSelector(DynamicUse dynamicUse,
- Map<String, Map<Selector, SelectorConstraints>> selectorMap) {
- Selector selector = dynamicUse.selector;
- String name = selector.name;
- ReceiverConstraint mask = dynamicUse.mask;
- Map<Selector, SelectorConstraints> selectors = selectorMap.putIfAbsent(
- name, () => new Maplet<Selector, SelectorConstraints>());
- UniverseSelectorConstraints constraints =
- selectors.putIfAbsent(selector, () {
- return selectorConstraintsStrategy.createSelectorConstraints(selector);
- });
- return constraints.addReceiverConstraint(mask);
- }
-
- Map<Selector, SelectorConstraints> _asUnmodifiable(
- Map<Selector, SelectorConstraints> map) {
- if (map == null) return null;
- return new UnmodifiableMapView(map);
- }
-
- Map<Selector, SelectorConstraints> invocationsByName(String name) {
- return _asUnmodifiable(_invokedNames[name]);
- }
-
- Map<Selector, SelectorConstraints> getterInvocationsByName(String name) {
- return _asUnmodifiable(_invokedGetters[name]);
- }
-
- Map<Selector, SelectorConstraints> setterInvocationsByName(String name) {
- return _asUnmodifiable(_invokedSetters[name]);
- }
-
- void forEachInvokedName(
- f(String name, Map<Selector, SelectorConstraints> selectors)) {
- _invokedNames.forEach(f);
- }
-
- void forEachInvokedGetter(
- f(String name, Map<Selector, SelectorConstraints> selectors)) {
- _invokedGetters.forEach(f);
- }
-
- void forEachInvokedSetter(
- f(String name, Map<Selector, SelectorConstraints> selectors)) {
- _invokedSetters.forEach(f);
- }
-
- DartType registerIsCheck(DartType type, Compiler compiler) {
- type.computeUnaliased(compiler.resolution);
- type = type.unaliased;
- // Even in checked mode, type annotations for return type and argument
- // types do not imply type checks, so there should never be a check
- // against the type variable of a typedef.
- isChecks.add(type);
- return type;
- }
-
- void registerStaticUse(StaticUse staticUse) {
- Element element = staticUse.element;
- if (Elements.isStaticOrTopLevel(element) && element.isField) {
- allReferencedStaticFields.add(element);
- }
- switch (staticUse.kind) {
- case StaticUseKind.STATIC_TEAR_OFF:
- staticFunctionsNeedingGetter.add(element);
- break;
- case StaticUseKind.SUPER_TEAR_OFF:
- methodsNeedingSuperGetter.add(element);
- break;
- case StaticUseKind.SUPER_FIELD_SET:
- case StaticUseKind.FIELD_SET:
- case StaticUseKind.GENERAL:
- case StaticUseKind.CLOSURE:
- case StaticUseKind.FIELD_GET:
- break;
- }
- }
-
- void forgetElement(Element element, Compiler compiler) {
- _directlyInstantiatedClasses.remove(element);
- if (element is ClassElement) {
- assert(invariant(element, element.thisType.isRaw,
- message: 'Generic classes not supported (${element.thisType}).'));
- _instantiatedTypes..remove(element.rawType)..remove(element.thisType);
- }
- }
-}
diff --git a/pkg/compiler/lib/src/universe/use.dart b/pkg/compiler/lib/src/universe/use.dart
index 543e2bd..fad9d90 100644
--- a/pkg/compiler/lib/src/universe/use.dart
+++ b/pkg/compiler/lib/src/universe/use.dart
@@ -24,7 +24,7 @@
import '../world.dart' show World;
import 'call_structure.dart' show CallStructure;
import 'selector.dart' show Selector;
-import 'universe.dart' show ReceiverConstraint;
+import 'world_builder.dart' show ReceiverConstraint;
enum DynamicUseKind { INVOKE, GET, SET, }
@@ -71,6 +71,8 @@
FIELD_GET,
FIELD_SET,
CLOSURE,
+ CONSTRUCTOR_INVOKE,
+ CONST_CONSTRUCTOR_INVOKE,
}
/// Statically known use of an [Element].
@@ -80,11 +82,14 @@
final Element element;
final StaticUseKind kind;
final int hashCode;
+ final DartType type;
- StaticUse.internal(Element element, StaticUseKind kind)
+ StaticUse.internal(Element element, StaticUseKind kind,
+ [DartType type = null])
: this.element = element,
this.kind = kind,
- this.hashCode = Hashing.objectHash(element, Hashing.objectHash(kind)) {
+ this.type = type,
+ this.hashCode = Hashing.objectsHash(element, kind, type) {
assert(invariant(element, element.isDeclaration,
message: "Static use element $element must be "
"the declaration element."));
@@ -209,6 +214,28 @@
return new StaticUse.internal(element, StaticUseKind.GENERAL);
}
+ /// Constructor invocation of [element] with the given [callStructure] on
+ /// [type].
+ factory StaticUse.typedConstructorInvoke(
+ ConstructorElement element, CallStructure callStructure, DartType type) {
+ assert(invariant(element, type != null,
+ message: "No type provided for constructor invocation."));
+ // TODO(johnniwinther): Use the [callStructure].
+ return new StaticUse.internal(
+ element, StaticUseKind.CONSTRUCTOR_INVOKE, type);
+ }
+
+ /// Constant constructor invocation of [element] with the given
+ /// [callStructure] on [type].
+ factory StaticUse.constConstructorInvoke(
+ ConstructorElement element, CallStructure callStructure, DartType type) {
+ assert(invariant(element, type != null,
+ message: "No type provided for constructor invocation."));
+ // TODO(johnniwinther): Use the [callStructure].
+ return new StaticUse.internal(
+ element, StaticUseKind.CONST_CONSTRUCTOR_INVOKE, type);
+ }
+
/// Constructor redirection to [element].
factory StaticUse.constructorRedirect(ConstructorElement element) {
return new StaticUse.internal(element, StaticUseKind.GENERAL);
@@ -253,10 +280,10 @@
bool operator ==(other) {
if (identical(this, other)) return true;
if (other is! StaticUse) return false;
- return element == other.element && kind == other.kind;
+ return element == other.element && kind == other.kind && type == other.type;
}
- String toString() => 'StaticUse($element,$kind)';
+ String toString() => 'StaticUse($element,$kind,$type)';
}
enum TypeUseKind {
diff --git a/pkg/compiler/lib/src/universe/world_builder.dart b/pkg/compiler/lib/src/universe/world_builder.dart
new file mode 100644
index 0000000..b697325
--- /dev/null
+++ b/pkg/compiler/lib/src/universe/world_builder.dart
@@ -0,0 +1,666 @@
+// Copyright (c) 2012, 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 universe;
+
+import 'dart:collection';
+
+import '../common.dart';
+import '../compiler.dart' show Compiler;
+import '../dart_types.dart';
+import '../elements/elements.dart';
+import '../util/util.dart';
+import '../world.dart' show World, ClosedWorld, OpenWorld;
+import 'selector.dart' show Selector;
+import 'use.dart' show DynamicUse, DynamicUseKind, StaticUse, StaticUseKind;
+
+/// The known constraint on receiver for a dynamic call site.
+///
+/// This can for instance be used to constrain this dynamic call to `foo` to
+/// 'receivers of the exact instance `Bar`':
+///
+/// class Bar {
+/// void foo() {}
+/// }
+/// main() => new Bar().foo();
+///
+abstract class ReceiverConstraint {
+ /// Returns whether [element] is a potential target when being
+ /// invoked on a receiver with this constraint. [selector] is used to ensure
+ /// library privacy is taken into account.
+ bool canHit(Element element, Selector selector, World world);
+
+ /// Returns whether this [TypeMask] applied to [selector] can hit a
+ /// [noSuchMethod].
+ bool needsNoSuchMethodHandling(Selector selector, World world);
+}
+
+/// The combined constraints on receivers all the dynamic call sites of the same
+/// selector.
+///
+/// For instance for these calls
+///
+/// class A {
+/// foo(a, b) {}
+/// }
+/// class B {
+/// foo(a, b) {}
+/// }
+/// class C {
+/// foo(a, b) {}
+/// }
+/// new A().foo(a, b);
+/// new B().foo(0, 42);
+///
+/// the selector constraints for dynamic calls to 'foo' with two positional
+/// arguments could be 'receiver of exact instance `A` or `B`'.
+abstract class SelectorConstraints {
+ /// Returns `true` if [selector] applies to [element] under these constraints
+ /// given the closed [world].
+ ///
+ /// Consider for instance in this world:
+ ///
+ /// class A {
+ /// foo(a, b) {}
+ /// }
+ /// class B {
+ /// foo(a, b) {}
+ /// }
+ /// new A().foo(a, b);
+ ///
+ /// Ideally the selector constraints for calls `foo` with two positional
+ /// arguments apply to `A.foo` but `B.foo`.
+ bool applies(Element element, Selector selector, World world);
+
+ /// Returns `true` if at least one of the receivers matching these constraints
+ /// in the closed [world] have no implementation matching [selector].
+ ///
+ /// For instance for this code snippet
+ ///
+ /// class A {}
+ /// class B { foo() {} }
+ /// m(b) => (b ? new A() : new B()).foo();
+ ///
+ /// the potential receiver `new A()` has no implementation of `foo` and thus
+ /// needs to handle the call through its `noSuchMethod` handler.
+ bool needsNoSuchMethodHandling(Selector selector, World world);
+}
+
+/// A mutable [SelectorConstraints] used in [WorldBuilder].
+abstract class UniverseSelectorConstraints extends SelectorConstraints {
+ /// Adds [constraint] to these selector constraints. Return `true` if the set
+ /// of potential receivers expanded due to the new constraint.
+ bool addReceiverConstraint(ReceiverConstraint constraint);
+}
+
+/// Strategy for computing the constraints on potential receivers of dynamic
+/// call sites.
+abstract class SelectorConstraintsStrategy {
+ /// Create a [UniverseSelectorConstraints] to represent the global receiver
+ /// constraints for dynamic call sites with [selector].
+ UniverseSelectorConstraints createSelectorConstraints(Selector selector);
+}
+
+/// The [WorldBuilder] is an auxiliary class used in the process of computing
+/// the [ClosedWorld].
+// TODO(johnniwinther): Move common implementation to a [WorldBuilderBase] when
+// universes and worlds have been unified.
+abstract class WorldBuilder {
+ /// All directly instantiated classes, that is, classes with a generative
+ /// constructor that has been called directly and not only through a
+ /// super-call.
+ // TODO(johnniwinther): Improve semantic precision.
+ Iterable<ClassElement> get directlyInstantiatedClasses;
+
+ /// All types that are checked either through is, as or checked mode checks.
+ Iterable<DartType> get isChecks;
+
+ /// Registers that [type] is checked in this universe. The unaliased type is
+ /// returned.
+ DartType registerIsCheck(DartType type, Compiler compiler);
+
+ /// All directly instantiated types, that is, the types of the directly
+ /// instantiated classes.
+ // TODO(johnniwinther): Improve semantic precision.
+ Iterable<DartType> get instantiatedTypes;
+
+ /// Returns `true` if [member] is invoked as a setter.
+ bool hasInvokedSetter(Element member, World world);
+}
+
+abstract class ResolutionWorldBuilder implements WorldBuilder {
+ /// Set of (live) local functions (closures) whose signatures reference type
+ /// variables.
+ ///
+ /// A live function is one whose enclosing member function has been enqueued.
+ Set<Element> get closuresWithFreeTypeVariables;
+
+ /// Set of (live) `call` methods whose signatures reference type variables.
+ ///
+ /// A live `call` method is one whose enclosing class has been instantiated.
+ Iterable<Element> get callMethodsWithFreeTypeVariables;
+
+ /// Set of all closures in the program. Used by the mirror tracking system
+ /// to find all live closure instances.
+ Iterable<LocalFunctionElement> get allClosures;
+
+ /// Set of methods in instantiated classes that are potentially closurized.
+ Iterable<Element> get closurizedMembers;
+
+ /// Returns `true` if [cls] is considered to be implemented by an
+ /// instantiated class, either directly, through subclasses or through
+ /// subtypes. The latter case only contains spurious information from
+ /// instantiations through factory constructors and mixins.
+ bool isImplemented(ClassElement cls);
+
+ /// Set of all fields that are statically known to be written to.
+ Iterable<Element> get fieldSetters;
+}
+
+class ResolutionWorldBuilderImpl implements ResolutionWorldBuilder {
+ /// The set of all directly instantiated classes, that is, classes with a
+ /// generative constructor that has been called directly and not only through
+ /// a super-call.
+ ///
+ /// Invariant: Elements are declaration elements.
+ // TODO(johnniwinther): [_directlyInstantiatedClasses] and
+ // [_instantiatedTypes] sets should be merged.
+ final Set<ClassElement> _directlyInstantiatedClasses =
+ new Set<ClassElement>();
+
+ /// The set of all directly instantiated types, that is, the types of the
+ /// directly instantiated classes.
+ ///
+ /// See [_directlyInstantiatedClasses].
+ final Set<DartType> _instantiatedTypes = new Set<DartType>();
+
+ /// Classes implemented by directly instantiated classes.
+ final Set<ClassElement> _implementedClasses = new Set<ClassElement>();
+
+ /// The set of all referenced static fields.
+ ///
+ /// Invariant: Elements are declaration elements.
+ final Set<FieldElement> allReferencedStaticFields = new Set<FieldElement>();
+
+ /**
+ * Documentation wanted -- johnniwinther
+ *
+ * Invariant: Elements are declaration elements.
+ */
+ final Set<FunctionElement> methodsNeedingSuperGetter =
+ new Set<FunctionElement>();
+ final Map<String, Map<Selector, SelectorConstraints>> _invokedNames =
+ <String, Map<Selector, SelectorConstraints>>{};
+ final Map<String, Map<Selector, SelectorConstraints>> _invokedGetters =
+ <String, Map<Selector, SelectorConstraints>>{};
+ final Map<String, Map<Selector, SelectorConstraints>> _invokedSetters =
+ <String, Map<Selector, SelectorConstraints>>{};
+
+ /// Fields set.
+ final Set<Element> fieldSetters = new Set<Element>();
+ final Set<DartType> isChecks = new Set<DartType>();
+
+ /**
+ * Set of (live) [:call:] methods whose signatures reference type variables.
+ *
+ * A live [:call:] method is one whose enclosing class has been instantiated.
+ */
+ final Set<Element> callMethodsWithFreeTypeVariables = new Set<Element>();
+
+ /**
+ * Set of (live) local functions (closures) whose signatures reference type
+ * variables.
+ *
+ * A live function is one whose enclosing member function has been enqueued.
+ */
+ final Set<Element> closuresWithFreeTypeVariables = new Set<Element>();
+
+ /**
+ * Set of all closures in the program. Used by the mirror tracking system
+ * to find all live closure instances.
+ */
+ final Set<LocalFunctionElement> allClosures = new Set<LocalFunctionElement>();
+
+ /**
+ * Set of methods in instantiated classes that are potentially
+ * closurized.
+ */
+ final Set<Element> closurizedMembers = new Set<Element>();
+
+ final SelectorConstraintsStrategy selectorConstraintsStrategy;
+
+ ResolutionWorldBuilderImpl(this.selectorConstraintsStrategy);
+
+ /// All directly instantiated classes, that is, classes with a generative
+ /// constructor that has been called directly and not only through a
+ /// super-call.
+ // TODO(johnniwinther): Improve semantic precision.
+ Iterable<ClassElement> get directlyInstantiatedClasses {
+ return _directlyInstantiatedClasses;
+ }
+
+ /// All directly instantiated types, that is, the types of the directly
+ /// instantiated classes.
+ ///
+ /// See [directlyInstantiatedClasses].
+ // TODO(johnniwinther): Improve semantic precision.
+ Iterable<DartType> get instantiatedTypes => _instantiatedTypes;
+
+ /// Returns `true` if [cls] is considered to be implemented by an
+ /// instantiated class, either directly, through subclasses or through
+ /// subtypes. The latter case only contains spurious information from
+ /// instantiations through factory constructors and mixins.
+ // TODO(johnniwinther): Improve semantic precision.
+ bool isImplemented(ClassElement cls) {
+ return _implementedClasses.contains(cls.declaration);
+ }
+
+ /// Register [type] as (directly) instantiated.
+ ///
+ /// If [byMirrors] is `true`, the instantiation is through mirrors.
+ // TODO(johnniwinther): Fully enforce the separation between exact, through
+ // subclass and through subtype instantiated types/classes.
+ // TODO(johnniwinther): Support unknown type arguments for generic types.
+ void registerTypeInstantiation(InterfaceType type,
+ {bool byMirrors: false,
+ bool isNative: false,
+ void onImplemented(ClassElement cls)}) {
+ _instantiatedTypes.add(type);
+ ClassElement cls = type.element;
+ if (!cls.isAbstract
+ // We can't use the closed-world assumption with native abstract
+ // classes; a native abstract class may have non-abstract subclasses
+ // not declared to the program. Instances of these classes are
+ // indistinguishable from the abstract class.
+ ||
+ isNative
+ // Likewise, if this registration comes from the mirror system,
+ // all bets are off.
+ // TODO(herhut): Track classes required by mirrors seperately.
+ ||
+ byMirrors) {
+ _directlyInstantiatedClasses.add(cls);
+ }
+
+ // TODO(johnniwinther): Replace this by separate more specific mappings that
+ // include the type arguments.
+ if (_implementedClasses.add(cls)) {
+ onImplemented(cls);
+ cls.allSupertypes.forEach((InterfaceType supertype) {
+ if (_implementedClasses.add(supertype.element)) {
+ onImplemented(supertype.element);
+ }
+ });
+ }
+ }
+
+ bool _hasMatchingSelector(Map<Selector, SelectorConstraints> selectors,
+ Element member, OpenWorld world) {
+ if (selectors == null) return false;
+ for (Selector selector in selectors.keys) {
+ if (selector.appliesUnnamed(member)) {
+ SelectorConstraints masks = selectors[selector];
+ if (masks.applies(member, selector, world)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ bool hasInvocation(Element member, OpenWorld world) {
+ return _hasMatchingSelector(_invokedNames[member.name], member, world);
+ }
+
+ bool hasInvokedGetter(Element member, OpenWorld world) {
+ return _hasMatchingSelector(_invokedGetters[member.name], member, world) ||
+ member.isFunction && methodsNeedingSuperGetter.contains(member);
+ }
+
+ bool hasInvokedSetter(Element member, OpenWorld world) {
+ return _hasMatchingSelector(_invokedSetters[member.name], member, world);
+ }
+
+ bool registerDynamicUse(DynamicUse dynamicUse) {
+ switch (dynamicUse.kind) {
+ case DynamicUseKind.INVOKE:
+ return _registerNewSelector(dynamicUse, _invokedNames);
+ case DynamicUseKind.GET:
+ return _registerNewSelector(dynamicUse, _invokedGetters);
+ case DynamicUseKind.SET:
+ return _registerNewSelector(dynamicUse, _invokedSetters);
+ }
+ }
+
+ bool _registerNewSelector(DynamicUse dynamicUse,
+ Map<String, Map<Selector, SelectorConstraints>> selectorMap) {
+ Selector selector = dynamicUse.selector;
+ String name = selector.name;
+ ReceiverConstraint mask = dynamicUse.mask;
+ Map<Selector, SelectorConstraints> selectors = selectorMap.putIfAbsent(
+ name, () => new Maplet<Selector, SelectorConstraints>());
+ UniverseSelectorConstraints constraints =
+ selectors.putIfAbsent(selector, () {
+ return selectorConstraintsStrategy.createSelectorConstraints(selector);
+ });
+ return constraints.addReceiverConstraint(mask);
+ }
+
+ DartType registerIsCheck(DartType type, Compiler compiler) {
+ type.computeUnaliased(compiler.resolution);
+ type = type.unaliased;
+ // Even in checked mode, type annotations for return type and argument
+ // types do not imply type checks, so there should never be a check
+ // against the type variable of a typedef.
+ isChecks.add(type);
+ return type;
+ }
+
+ void registerStaticUse(StaticUse staticUse) {
+ Element element = staticUse.element;
+ if (Elements.isStaticOrTopLevel(element) && element.isField) {
+ allReferencedStaticFields.add(element);
+ }
+ switch (staticUse.kind) {
+ case StaticUseKind.SUPER_FIELD_SET:
+ case StaticUseKind.FIELD_SET:
+ fieldSetters.add(element);
+ break;
+ case StaticUseKind.SUPER_TEAR_OFF:
+ methodsNeedingSuperGetter.add(element);
+ break;
+ case StaticUseKind.GENERAL:
+ case StaticUseKind.STATIC_TEAR_OFF:
+ case StaticUseKind.FIELD_GET:
+ case StaticUseKind.CONSTRUCTOR_INVOKE:
+ case StaticUseKind.CONST_CONSTRUCTOR_INVOKE:
+ break;
+ case StaticUseKind.CLOSURE:
+ allClosures.add(element);
+ break;
+ }
+ }
+
+ void forgetElement(Element element, Compiler compiler) {
+ allClosures.remove(element);
+ slowDirectlyNestedClosures(element).forEach(compiler.forgetElement);
+ closurizedMembers.remove(element);
+ fieldSetters.remove(element);
+ _directlyInstantiatedClasses.remove(element);
+ if (element is ClassElement) {
+ assert(invariant(element, element.thisType.isRaw,
+ message: 'Generic classes not supported (${element.thisType}).'));
+ _instantiatedTypes..remove(element.rawType)..remove(element.thisType);
+ }
+ }
+
+ // TODO(ahe): Replace this method with something that is O(1), for example,
+ // by using a map.
+ List<LocalFunctionElement> slowDirectlyNestedClosures(Element element) {
+ // Return new list to guard against concurrent modifications.
+ return new List<LocalFunctionElement>.from(
+ allClosures.where((LocalFunctionElement closure) {
+ return closure.executableContext == element;
+ }));
+ }
+}
+
+/// World builder specific to codegen.
+///
+/// This adds additional access to liveness of selectors and elements.
+abstract class CodegenWorldBuilder implements WorldBuilder {
+ void forEachInvokedName(
+ f(String name, Map<Selector, SelectorConstraints> selectors));
+
+ void forEachInvokedGetter(
+ f(String name, Map<Selector, SelectorConstraints> selectors));
+
+ void forEachInvokedSetter(
+ f(String name, Map<Selector, SelectorConstraints> selectors));
+
+ bool hasInvokedGetter(Element member, ClosedWorld world);
+
+ Map<Selector, SelectorConstraints> invocationsByName(String name);
+
+ Map<Selector, SelectorConstraints> getterInvocationsByName(String name);
+
+ Map<Selector, SelectorConstraints> setterInvocationsByName(String name);
+
+ Iterable<FunctionElement> get staticFunctionsNeedingGetter;
+ Iterable<FunctionElement> get methodsNeedingSuperGetter;
+
+ /// The set of all referenced static fields.
+ ///
+ /// Invariant: Elements are declaration elements.
+ Iterable<FieldElement> get allReferencedStaticFields;
+}
+
+class CodegenWorldBuilderImpl implements CodegenWorldBuilder {
+ /// The set of all directly instantiated classes, that is, classes with a
+ /// generative constructor that has been called directly and not only through
+ /// a super-call.
+ ///
+ /// Invariant: Elements are declaration elements.
+ // TODO(johnniwinther): [_directlyInstantiatedClasses] and
+ // [_instantiatedTypes] sets should be merged.
+ final Set<ClassElement> _directlyInstantiatedClasses =
+ new Set<ClassElement>();
+
+ /// The set of all directly instantiated types, that is, the types of the
+ /// directly instantiated classes.
+ ///
+ /// See [_directlyInstantiatedClasses].
+ final Set<DartType> _instantiatedTypes = new Set<DartType>();
+
+ /// Classes implemented by directly instantiated classes.
+ final Set<ClassElement> _implementedClasses = new Set<ClassElement>();
+
+ /// The set of all referenced static fields.
+ ///
+ /// Invariant: Elements are declaration elements.
+ final Set<FieldElement> allReferencedStaticFields = new Set<FieldElement>();
+
+ /**
+ * Documentation wanted -- johnniwinther
+ *
+ * Invariant: Elements are declaration elements.
+ */
+ final Set<FunctionElement> staticFunctionsNeedingGetter =
+ new Set<FunctionElement>();
+ final Set<FunctionElement> methodsNeedingSuperGetter =
+ new Set<FunctionElement>();
+ final Map<String, Map<Selector, SelectorConstraints>> _invokedNames =
+ <String, Map<Selector, SelectorConstraints>>{};
+ final Map<String, Map<Selector, SelectorConstraints>> _invokedGetters =
+ <String, Map<Selector, SelectorConstraints>>{};
+ final Map<String, Map<Selector, SelectorConstraints>> _invokedSetters =
+ <String, Map<Selector, SelectorConstraints>>{};
+
+ final Set<DartType> isChecks = new Set<DartType>();
+
+ final SelectorConstraintsStrategy selectorConstraintsStrategy;
+
+ CodegenWorldBuilderImpl(this.selectorConstraintsStrategy);
+
+ /// All directly instantiated classes, that is, classes with a generative
+ /// constructor that has been called directly and not only through a
+ /// super-call.
+ // TODO(johnniwinther): Improve semantic precision.
+ Iterable<ClassElement> get directlyInstantiatedClasses {
+ return _directlyInstantiatedClasses;
+ }
+
+ /// All directly instantiated types, that is, the types of the directly
+ /// instantiated classes.
+ ///
+ /// See [directlyInstantiatedClasses].
+ // TODO(johnniwinther): Improve semantic precision.
+ Iterable<DartType> get instantiatedTypes => _instantiatedTypes;
+
+ /// Register [type] as (directly) instantiated.
+ ///
+ /// If [byMirrors] is `true`, the instantiation is through mirrors.
+ // TODO(johnniwinther): Fully enforce the separation between exact, through
+ // subclass and through subtype instantiated types/classes.
+ // TODO(johnniwinther): Support unknown type arguments for generic types.
+ void registerTypeInstantiation(InterfaceType type,
+ {bool byMirrors: false,
+ bool isNative: false,
+ void onImplemented(ClassElement cls)}) {
+ _instantiatedTypes.add(type);
+ ClassElement cls = type.element;
+ if (!cls.isAbstract
+ // We can't use the closed-world assumption with native abstract
+ // classes; a native abstract class may have non-abstract subclasses
+ // not declared to the program. Instances of these classes are
+ // indistinguishable from the abstract class.
+ ||
+ isNative
+ // Likewise, if this registration comes from the mirror system,
+ // all bets are off.
+ // TODO(herhut): Track classes required by mirrors seperately.
+ ||
+ byMirrors) {
+ _directlyInstantiatedClasses.add(cls);
+ }
+
+ // TODO(johnniwinther): Replace this by separate more specific mappings that
+ // include the type arguments.
+ if (_implementedClasses.add(cls)) {
+ onImplemented(cls);
+ cls.allSupertypes.forEach((InterfaceType supertype) {
+ if (_implementedClasses.add(supertype.element)) {
+ onImplemented(supertype.element);
+ }
+ });
+ }
+ }
+
+ bool _hasMatchingSelector(Map<Selector, SelectorConstraints> selectors,
+ Element member, ClosedWorld world) {
+ if (selectors == null) return false;
+ for (Selector selector in selectors.keys) {
+ if (selector.appliesUnnamed(member)) {
+ SelectorConstraints masks = selectors[selector];
+ if (masks.applies(member, selector, world)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ bool hasInvocation(Element member, ClosedWorld world) {
+ return _hasMatchingSelector(_invokedNames[member.name], member, world);
+ }
+
+ bool hasInvokedGetter(Element member, ClosedWorld world) {
+ return _hasMatchingSelector(_invokedGetters[member.name], member, world) ||
+ member.isFunction && methodsNeedingSuperGetter.contains(member);
+ }
+
+ bool hasInvokedSetter(Element member, ClosedWorld world) {
+ return _hasMatchingSelector(_invokedSetters[member.name], member, world);
+ }
+
+ bool registerDynamicUse(DynamicUse dynamicUse) {
+ switch (dynamicUse.kind) {
+ case DynamicUseKind.INVOKE:
+ return _registerNewSelector(dynamicUse, _invokedNames);
+ case DynamicUseKind.GET:
+ return _registerNewSelector(dynamicUse, _invokedGetters);
+ case DynamicUseKind.SET:
+ return _registerNewSelector(dynamicUse, _invokedSetters);
+ }
+ }
+
+ bool _registerNewSelector(DynamicUse dynamicUse,
+ Map<String, Map<Selector, SelectorConstraints>> selectorMap) {
+ Selector selector = dynamicUse.selector;
+ String name = selector.name;
+ ReceiverConstraint mask = dynamicUse.mask;
+ Map<Selector, SelectorConstraints> selectors = selectorMap.putIfAbsent(
+ name, () => new Maplet<Selector, SelectorConstraints>());
+ UniverseSelectorConstraints constraints =
+ selectors.putIfAbsent(selector, () {
+ return selectorConstraintsStrategy.createSelectorConstraints(selector);
+ });
+ return constraints.addReceiverConstraint(mask);
+ }
+
+ Map<Selector, SelectorConstraints> _asUnmodifiable(
+ Map<Selector, SelectorConstraints> map) {
+ if (map == null) return null;
+ return new UnmodifiableMapView(map);
+ }
+
+ Map<Selector, SelectorConstraints> invocationsByName(String name) {
+ return _asUnmodifiable(_invokedNames[name]);
+ }
+
+ Map<Selector, SelectorConstraints> getterInvocationsByName(String name) {
+ return _asUnmodifiable(_invokedGetters[name]);
+ }
+
+ Map<Selector, SelectorConstraints> setterInvocationsByName(String name) {
+ return _asUnmodifiable(_invokedSetters[name]);
+ }
+
+ void forEachInvokedName(
+ f(String name, Map<Selector, SelectorConstraints> selectors)) {
+ _invokedNames.forEach(f);
+ }
+
+ void forEachInvokedGetter(
+ f(String name, Map<Selector, SelectorConstraints> selectors)) {
+ _invokedGetters.forEach(f);
+ }
+
+ void forEachInvokedSetter(
+ f(String name, Map<Selector, SelectorConstraints> selectors)) {
+ _invokedSetters.forEach(f);
+ }
+
+ DartType registerIsCheck(DartType type, Compiler compiler) {
+ type.computeUnaliased(compiler.resolution);
+ type = type.unaliased;
+ // Even in checked mode, type annotations for return type and argument
+ // types do not imply type checks, so there should never be a check
+ // against the type variable of a typedef.
+ isChecks.add(type);
+ return type;
+ }
+
+ void registerStaticUse(StaticUse staticUse) {
+ Element element = staticUse.element;
+ if (Elements.isStaticOrTopLevel(element) && element.isField) {
+ allReferencedStaticFields.add(element);
+ }
+ switch (staticUse.kind) {
+ case StaticUseKind.STATIC_TEAR_OFF:
+ staticFunctionsNeedingGetter.add(element);
+ break;
+ case StaticUseKind.SUPER_TEAR_OFF:
+ methodsNeedingSuperGetter.add(element);
+ break;
+ case StaticUseKind.SUPER_FIELD_SET:
+ case StaticUseKind.FIELD_SET:
+ case StaticUseKind.GENERAL:
+ case StaticUseKind.CLOSURE:
+ case StaticUseKind.FIELD_GET:
+ case StaticUseKind.CONSTRUCTOR_INVOKE:
+ case StaticUseKind.CONST_CONSTRUCTOR_INVOKE:
+ break;
+ }
+ }
+
+ void forgetElement(Element element, Compiler compiler) {
+ _directlyInstantiatedClasses.remove(element);
+ if (element is ClassElement) {
+ assert(invariant(element, element.thisType.isRaw,
+ message: 'Generic classes not supported (${element.thisType}).'));
+ _instantiatedTypes..remove(element.rawType)..remove(element.thisType);
+ }
+ }
+}
diff --git a/pkg/compiler/lib/src/util/util.dart b/pkg/compiler/lib/src/util/util.dart
index 397bd6c..dbcc7d3 100644
--- a/pkg/compiler/lib/src/util/util.dart
+++ b/pkg/compiler/lib/src/util/util.dart
@@ -42,6 +42,14 @@
return mixHashCodeBits(existing, object.hashCode);
}
+ /// Mix the bits of `.hashCode` all non-null objects.
+ static int objectsHash(Object obj1, [Object obj2, Object obj3]) {
+ int hash = 0;
+ if (obj3 != null) hash = objectHash(obj3, hash);
+ if (obj2 != null) hash = objectHash(obj2, hash);
+ return objectHash(obj1, hash);
+ }
+
/// Mix the bits of the element hash codes of [list] with [existing].
static int listHash(List list, [int existing = 0]) {
int h = existing;
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
index 40e73a5..8c69bae 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -55,6 +55,10 @@
/// subclass.
bool isIndirectlyInstantiated(ClassElement cls);
+ /// Returns `true` if [cls] is abstract and thus can only be instantiated
+ /// through subclasses.
+ bool isAbstract(ClassElement cls);
+
/// Returns `true` if [cls] is implemented by an instantiated class.
bool isImplemented(ClassElement cls);
@@ -156,6 +160,52 @@
/// Returns `true` if any subclass of [superclass] implements [type].
bool hasAnySubclassThatImplements(ClassElement superclass, ClassElement type);
+ /// Returns `true` if a call of [selector] on [cls] and/or subclasses/subtypes
+ /// need noSuchMethod handling.
+ ///
+ /// If the receiver is guaranteed to have a member that matches what we're
+ /// looking for, there's no need to introduce a noSuchMethod handler. It will
+ /// never be called.
+ ///
+ /// As an example, consider this class hierarchy:
+ ///
+ /// A <-- noSuchMethod
+ /// / \
+ /// C B <-- foo
+ ///
+ /// If we know we're calling foo on an object of type B we don't have to worry
+ /// about the noSuchMethod method in A because objects of type B implement
+ /// foo. On the other hand, if we end up calling foo on something of type C we
+ /// have to add a handler for it.
+ ///
+ /// If the holders of all user-defined noSuchMethod implementations that might
+ /// be applicable to the receiver type have a matching member for the current
+ /// name and selector, we avoid introducing a noSuchMethod handler.
+ ///
+ /// As an example, consider this class hierarchy:
+ ///
+ /// A <-- foo
+ /// / \
+ /// noSuchMethod --> B C <-- bar
+ /// | |
+ /// C D <-- noSuchMethod
+ ///
+ /// When calling foo on an object of type A, we know that the implementations
+ /// of noSuchMethod are in the classes B and D that also (indirectly)
+ /// implement foo, so we do not need a handler for it.
+ ///
+ /// If we're calling bar on an object of type D, we don't need the handler
+ /// either because all objects of type D implement bar through inheritance.
+ ///
+ /// If we're calling bar on an object of type A we do need the handler because
+ /// we may have to call B.noSuchMethod since B does not implement bar.
+ bool needsNoSuchMethod(ClassElement cls, Selector selector, ClassQuery query);
+
+ /// Returns whether [element] will be the one used at runtime when being
+ /// invoked on an instance of [cls]. [selector] is used to ensure library
+ /// privacy is taken into account.
+ bool hasElementIn(ClassElement cls, Selector selector, Element element);
+
/// Returns [ClassHierarchyNode] for [cls] used to model the class hierarchies
/// of known classes.
///
@@ -170,9 +220,10 @@
/// methods defined in [ClosedWorld].
ClassSet getClassSet(ClassElement cls);
- // TODO(johnniwinther): Find a better strategy for caching these.
- @deprecated
- List<Map<ClassElement, TypeMask>> get canonicalizedTypeMasks;
+ /// Return the cached mask for [base] with the given flags, or
+ /// calls [createMask] to create the mask and cache it.
+ // TODO(johnniwinther): Find a better strategy for caching these?
+ TypeMask getCachedMask(ClassElement base, int flags, TypeMask createMask());
/// Returns the [FunctionSet] containing all live functions in the closed
/// world.
@@ -274,9 +325,15 @@
class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld {
bool _closed = false;
+ TypeMask getCachedMask(ClassElement base, int flags, TypeMask createMask()) {
+ Map<ClassElement, TypeMask> cachedMasks =
+ _canonicalizedTypeMasks[flags] ??= <ClassElement, TypeMask>{};
+ return cachedMasks.putIfAbsent(base, createMask);
+ }
+
/// Cache of [FlatTypeMask]s grouped by the 8 possible values of the
/// `FlatTypeMask.flags` property.
- List<Map<ClassElement, TypeMask>> canonicalizedTypeMasks =
+ final List<Map<ClassElement, TypeMask>> _canonicalizedTypeMasks =
new List<Map<ClassElement, TypeMask>>.filled(8, null);
bool checkInvariants(ClassElement cls, {bool mustBeInstantiated: true}) {
@@ -342,6 +399,9 @@
return node != null && node.isIndirectlyInstantiated;
}
+ @override
+ bool isAbstract(ClassElement cls) => cls.isAbstract;
+
/// Returns `true` if [cls] is implemented by an instantiated class.
bool isImplemented(ClassElement cls) {
assert(isClosed);
@@ -622,14 +682,14 @@
/// Returns `true` if [cls] or any superclass mixes in [mixin].
bool isSubclassOfMixinUseOf(ClassElement cls, ClassElement mixin) {
assert(isClosed);
+ assert(cls.isDeclaration);
+ assert(mixin.isDeclaration);
if (isUsedAsMixin(mixin)) {
- ClassElement current = cls.declaration;
- mixin = mixin.declaration;
+ ClassElement current = cls;
while (current != null) {
- current = current.declaration;
if (current.isMixinApplication) {
MixinApplicationElement application = current;
- if (application.mixin.declaration == mixin) return true;
+ if (application.mixin == mixin) return true;
}
current = current.superclass;
}
@@ -641,8 +701,8 @@
/// of a mixin application of [y].
bool everySubtypeIsSubclassOfOrMixinUseOf(ClassElement x, ClassElement y) {
assert(isClosed);
- x = x.declaration;
- y = y.declaration;
+ assert(x.isDeclaration);
+ assert(y.isDeclaration);
Map<ClassElement, bool> secondMap =
_subtypeCoveredByCache[x] ??= <ClassElement, bool>{};
return secondMap[y] ??= subtypesOf(x).every((ClassElement cls) =>
@@ -658,6 +718,72 @@
return subclasses.contains(type);
}
+ @override
+ bool hasElementIn(ClassElement cls, Selector selector, Element element) {
+ // Use [:implementation:] of [element]
+ // because our function set only stores declarations.
+ Element result = findMatchIn(cls, selector);
+ return result == null
+ ? false
+ : result.implementation == element.implementation;
+ }
+
+ Element findMatchIn(ClassElement cls, Selector selector) {
+ // Use the [:implementation] of [cls] in case the found [element]
+ // is in the patch class.
+ var result = cls.implementation.lookupByName(selector.memberName);
+ return result;
+ }
+
+ /// Returns whether a [selector] call on an instance of [cls]
+ /// will hit a method at runtime, and not go through [noSuchMethod].
+ bool hasConcreteMatch(ClassElement cls, Selector selector) {
+ assert(invariant(cls, isInstantiated(cls),
+ message: '$cls has not been instantiated.'));
+ Element element = findMatchIn(cls, selector);
+ if (element == null) return false;
+
+ if (element.isAbstract) {
+ ClassElement enclosingClass = element.enclosingClass;
+ return hasConcreteMatch(enclosingClass.superclass, selector);
+ }
+ return selector.appliesUntyped(element);
+ }
+
+ @override
+ bool needsNoSuchMethod(
+ ClassElement base, Selector selector, ClassQuery query) {
+ /// Returns `true` if [cls] is an instantiated class that does not have
+ /// a concrete method matching [selector].
+ bool needsNoSuchMethod(ClassElement cls) {
+ // We can skip uninstantiated subclasses.
+ if (!isInstantiated(cls)) {
+ return false;
+ }
+ // We can just skip abstract classes because we know no
+ // instance of them will be created at runtime, and
+ // therefore there is no instance that will require
+ // [noSuchMethod] handling.
+ return !cls.isAbstract && !hasConcreteMatch(cls, selector);
+ }
+
+ bool baseNeedsNoSuchMethod = needsNoSuchMethod(base);
+ if (query == ClassQuery.EXACT || baseNeedsNoSuchMethod) {
+ return baseNeedsNoSuchMethod;
+ }
+
+ Iterable<ClassElement> subclassesToCheck;
+ if (query == ClassQuery.SUBTYPE) {
+ subclassesToCheck = strictSubtypesOf(base);
+ } else {
+ assert(query == ClassQuery.SUBCLASS);
+ subclassesToCheck = strictSubclassesOf(base);
+ }
+
+ return subclassesToCheck != null &&
+ subclassesToCheck.any(needsNoSuchMethod);
+ }
+
final Compiler _compiler;
BackendClasses get backendClasses => _backend.backendClasses;
JavaScriptBackend get _backend => _compiler.backend;
@@ -1011,3 +1137,16 @@
return getMightBePassedToApply(element);
}
}
+
+/// Enum values defining subset of classes included in queries.
+enum ClassQuery {
+ /// Only the class itself is included.
+ EXACT,
+
+ /// The class and all subclasses (transitively) are included.
+ SUBCLASS,
+
+ /// The class and all classes that implement or subclass it (transitively)
+ /// are included.
+ SUBTYPE,
+}
diff --git a/pkg/compiler/pubspec.yaml b/pkg/compiler/pubspec.yaml
index a3e6070..19bd26e 100644
--- a/pkg/compiler/pubspec.yaml
+++ b/pkg/compiler/pubspec.yaml
@@ -15,7 +15,7 @@
path: ../../third_party/pkg/kernel
sdk_library_metadata:
path: ../../sdk/lib/_internal/sdk_library_metadata
- dart2js_info: ^0.2.4
+ dart2js_info: ^0.3.0
lookup_map:
path: ../lookup_map
diff --git a/pkg/compiler/tool/perf.dart b/pkg/compiler/tool/perf.dart
new file mode 100644
index 0000000..51f98d6
--- /dev/null
+++ b/pkg/compiler/tool/perf.dart
@@ -0,0 +1,319 @@
+// 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.
+
+/// An entrypoint used to run portions of dart2js and measure its performance.
+library compiler.tool.perf;
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:compiler/compiler_new.dart';
+import 'package:compiler/src/common.dart';
+import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
+import 'package:compiler/src/diagnostics/messages.dart'
+ show Message, MessageTemplate;
+import 'package:compiler/src/io/source_file.dart';
+import 'package:compiler/src/options.dart' show ParserOptions;
+import 'package:compiler/src/options.dart';
+import 'package:compiler/src/parser/element_listener.dart' show ScannerOptions;
+import 'package:compiler/src/parser/listener.dart';
+import 'package:compiler/src/parser/node_listener.dart' show NodeListener;
+import 'package:compiler/src/parser/parser.dart' show Parser;
+import 'package:compiler/src/parser/partial_parser.dart';
+import 'package:compiler/src/platform_configuration.dart' as platform;
+import 'package:compiler/src/scanner/scanner.dart';
+import 'package:compiler/src/source_file_provider.dart';
+import 'package:compiler/src/tokens/token.dart' show Token;
+import 'package:package_config/discovery.dart' show findPackages;
+import 'package:package_config/packages.dart' show Packages;
+import 'package:package_config/src/util.dart' show checkValidPackageUri;
+
+/// Cumulative total number of chars scanned.
+int scanTotalChars = 0;
+
+/// Cumulative time spent scanning.
+Stopwatch scanTimer = new Stopwatch();
+
+/// Helper class used to load source files using dart2js's internal APIs.
+_Loader loader;
+
+main(List<String> args) async {
+ // TODO(sigmund): provide sdk folder as well.
+ if (args.length < 2) {
+ print('usage: perf.dart <bench-id> <entry.dart>');
+ exit(1);
+ }
+ var totalTimer = new Stopwatch()..start();
+
+ var bench = args[0];
+ var entryUri = Uri.base.resolve(args[1]);
+
+ await setup(entryUri);
+
+ if (bench == 'scan') {
+ Set<SourceFile> files = await scanReachableFiles(entryUri);
+ // TODO(sigmund): consider replacing the warmup with instrumented snapshots.
+ for (int i = 0; i < 10; i++) scanFiles(files);
+ } else if (bench == 'parse') {
+ Set<SourceFile> files = await scanReachableFiles(entryUri);
+ // TODO(sigmund): consider replacing the warmup with instrumented snapshots.
+ for (int i = 0; i < 10; i++) parseFiles(files);
+ } else {
+ print('unsupported bench-id: $bench. Please specify "scan" or "parse"');
+ // TODO(sigmund): implement the remaining benchmarks.
+ exit(1);
+ }
+
+ totalTimer.stop();
+ report("total", totalTimer.elapsedMicroseconds);
+}
+
+Future setup(Uri entryUri) async {
+ var inputProvider = new CompilerSourceFileProvider();
+ var sdkLibraries = await platform.load(_platformConfigUri, inputProvider);
+ var packages = await findPackages(entryUri);
+ loader = new _Loader(inputProvider, sdkLibraries, packages);
+}
+
+/// Load and scans all files we need to process: files reachable from the
+/// entrypoint and all core libraries automatically included by the VM.
+Future<Set<SourceFile>> scanReachableFiles(Uri entryUri) async {
+ var files = new Set<SourceFile>();
+ var loadTimer = new Stopwatch()..start();
+ var entrypoints = [
+ entryUri,
+ Uri.parse("dart:async"),
+ Uri.parse("dart:collection"),
+ Uri.parse("dart:convert"),
+ Uri.parse("dart:core"),
+ Uri.parse("dart:developer"),
+ Uri.parse("dart:_internal"),
+ Uri.parse("dart:io"),
+ Uri.parse("dart:isolate"),
+ Uri.parse("dart:math"),
+ Uri.parse("dart:mirrors"),
+ Uri.parse("dart:typed_data"),
+ ];
+ for (var entry in entrypoints) {
+ await collectSources(await loader.loadFile(entry), files);
+ }
+ loadTimer.stop();
+
+ print('input size: ${scanTotalChars} chars');
+ var loadTime = loadTimer.elapsedMicroseconds - scanTimer.elapsedMicroseconds;
+ report("load", loadTime);
+ report("scan", scanTimer.elapsedMicroseconds);
+ return files;
+}
+
+/// Scans every file in [files] and reports the time spent doing so.
+void scanFiles(Set<SourceFile> files) {
+ // The code below will record again how many chars are scanned and how long it
+ // takes to scan them, even though we already did so in [scanReachableFiles].
+ // Recording and reporting this twice is unnecessary, but we do so for now to
+ // validate that the results are consistent.
+ scanTimer = new Stopwatch();
+ var old = scanTotalChars;
+ scanTotalChars = 0;
+ for (var source in files) {
+ tokenize(source);
+ }
+
+ // Report size and scanning time again. See discussion above.
+ if (old != scanTotalChars) print('input size changed? ${old} chars');
+ report("scan", scanTimer.elapsedMicroseconds);
+}
+
+/// Parses every file in [files] and reports the time spent doing so.
+void parseFiles(Set<SourceFile> files) {
+ // The code below will record again how many chars are scanned and how long it
+ // takes to scan them, even though we already did so in [scanReachableFiles].
+ // Recording and reporting this twice is unnecessary, but we do so for now to
+ // validate that the results are consistent.
+ scanTimer = new Stopwatch();
+ var old = scanTotalChars;
+ scanTotalChars = 0;
+ var parseTimer = new Stopwatch()..start();
+ for (var source in files) {
+ parseFull(source);
+ }
+ parseTimer.stop();
+
+ // Report size and scanning time again. See discussion above.
+ if (old != scanTotalChars) print('input size changed? ${old} chars');
+ report("scan", scanTimer.elapsedMicroseconds);
+
+ report(
+ "parse", parseTimer.elapsedMicroseconds - scanTimer.elapsedMicroseconds);
+}
+
+/// Add to [files] all sources reachable from [start].
+Future collectSources(SourceFile start, Set<SourceFile> files) async {
+ if (!files.add(start)) return;
+ for (var directive in parseDirectives(start)) {
+ var next = await loader.loadFile(start.uri.resolve(directive));
+ await collectSources(next, files);
+ }
+}
+
+/// Uses the diet-parser to parse only directives in [source], returns the
+/// URIs seen in import/export/part directives in the file.
+Set<String> parseDirectives(SourceFile source) {
+ var tokens = tokenize(source);
+ var listener = new DirectiveListener();
+ new PartialParser(listener, const _ParserOptions()).parseUnit(tokens);
+ return listener.targets;
+}
+
+/// Parse the full body of [source].
+parseFull(SourceFile source) {
+ var tokens = tokenize(source);
+ NodeListener listener = new NodeListener(
+ const ScannerOptions(canUseNative: true), new FakeReporter(), null);
+ Parser parser = new Parser(listener, const _ParserOptions());
+ parser.parseUnit(tokens);
+ return listener.popNode();
+}
+
+/// Scan [source] and return the first token produced by the scanner.
+Token tokenize(SourceFile source) {
+ scanTimer.start();
+ scanTotalChars += source.length;
+ var token = new Scanner(source).tokenize();
+ scanTimer.stop();
+ return token;
+}
+
+/// Report that metric [name] took [time] micro-seconds to process
+/// [scanTotalChars] characters.
+void report(String name, int time) {
+ var sb = new StringBuffer();
+ sb.write('$name: $time us, ${time ~/ 1000} ms');
+ sb.write(', ${scanTotalChars * 1000 ~/ time} chars/ms');
+ print('$sb');
+}
+
+/// Listener that parses out just the uri in imports, exports, and part
+/// directives.
+class DirectiveListener extends Listener {
+ Set<String> targets = new Set<String>();
+
+ bool inDirective = false;
+ void enterDirective() {
+ inDirective = true;
+ }
+
+ void exitDirective() {
+ inDirective = false;
+ }
+
+ void beginImport(Token importKeyword) => enterDirective();
+ void beginExport(Token token) => enterDirective();
+ void beginPart(Token token) => enterDirective();
+
+ void beginLiteralString(Token token) {
+ if (inDirective) {
+ var quotedString = token.value;
+ targets.add(quotedString.substring(1, quotedString.length - 1));
+ }
+ }
+
+ void endExport(Token exportKeyword, Token semicolon) => exitDirective();
+ void endImport(Token importKeyword, Token deferredKeyword, Token asKeyword,
+ Token semicolon) =>
+ exitDirective();
+ void endPart(Token partKeyword, Token semicolon) => exitDirective();
+}
+
+Uri _libraryRoot = Platform.script.resolve('../../../sdk/');
+Uri _platformConfigUri = _libraryRoot.resolve("lib/dart_server.platform");
+
+class FakeReporter extends DiagnosticReporter {
+ final hasReportedError = false;
+ final options = new FakeReporterOptions();
+
+ withCurrentElement(e, f) => f();
+ log(m) => print(m);
+ internalError(_, m) => print(m);
+ spanFromSpannable(_) => null;
+
+ void reportError(DiagnosticMessage message,
+ [List<DiagnosticMessage> infos = const <DiagnosticMessage>[]]) {
+ print('error: ${message.message}');
+ }
+
+ void reportWarning(DiagnosticMessage message,
+ [List<DiagnosticMessage> infos = const <DiagnosticMessage>[]]) {
+ print('warning: ${message.message}');
+ }
+
+ void reportHint(DiagnosticMessage message,
+ [List<DiagnosticMessage> infos = const <DiagnosticMessage>[]]) {
+ print('hint: ${message.message}');
+ }
+
+ void reportInfo(_, __, [Map arguments = const {}]) {}
+
+ DiagnosticMessage createMessage(_, MessageKind kind,
+ [Map arguments = const {}]) {
+ MessageTemplate template = MessageTemplate.TEMPLATES[kind];
+ Message message = template.message(arguments, false);
+ return new DiagnosticMessage(null, null, message);
+ }
+}
+
+class FakeReporterOptions {
+ bool get suppressHints => false;
+ bool get hidePackageWarnings => false;
+}
+
+class _Loader {
+ CompilerInput inputProvider;
+
+ /// Maps dart-URIs to a known location in the sdk.
+ Map<String, Uri> sdkLibraries;
+ Map<Uri, SourceFile> _cache = {};
+ Packages packages;
+
+ _Loader(this.inputProvider, this.sdkLibraries, this.packages);
+
+ Future<SourceFile> loadFile(Uri uri) async {
+ if (!uri.isAbsolute) throw 'Relative uri $uri provided to readScript.';
+ Uri resourceUri = _translateUri(uri);
+ if (resourceUri == null || resourceUri.scheme == 'dart-ext') {
+ throw '$uri not resolved or unsupported.';
+ }
+ var file = _cache[resourceUri];
+ if (file != null) return _cache[resourceUri];
+ return _cache[resourceUri] = await _readFile(resourceUri);
+ }
+
+ Future<SourceFile> _readFile(Uri uri) async {
+ var data = await inputProvider.readFromUri(uri);
+ if (data is List<int>) return new Utf8BytesSourceFile(uri, data);
+ if (data is String) return new StringSourceFile.fromUri(uri, data);
+ // TODO(sigmund): properly handle errors, just report, return null, wrap
+ // above and continue...
+ throw "Expected a 'String' or a 'List<int>' from the input "
+ "provider, but got: ${data.runtimeType}.";
+ }
+
+ Uri _translateUri(Uri uri) {
+ if (uri.scheme == 'dart') return sdkLibraries[uri.path];
+ if (uri.scheme == 'package') return _translatePackageUri(uri);
+ return uri;
+ }
+
+ Uri _translatePackageUri(Uri uri) {
+ checkValidPackageUri(uri);
+ return packages.resolve(uri, notFound: (_) {
+ print('$uri not found');
+ });
+ }
+}
+
+class _ParserOptions implements ParserOptions {
+ const _ParserOptions();
+ bool get enableGenericMethodSyntax => true;
+}
diff --git a/pkg/compiler/tool/perf_test.dart b/pkg/compiler/tool/perf_test.dart
new file mode 100644
index 0000000..20b6478
--- /dev/null
+++ b/pkg/compiler/tool/perf_test.dart
@@ -0,0 +1,11 @@
+// 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.
+
+/// The only purpose of this file is to enable analyzer tests on `perf.dart`,
+/// the code here just has a dummy import to the rest of the code.
+library compiler.tool.perf_test;
+
+import 'perf.dart' as m;
+
+main() => print('done ${m.scanTotalChars}');
diff --git a/pkg/dev_compiler/karma.conf.js b/pkg/dev_compiler/karma.conf.js
index 3fbe32e..dab62fc 100644
--- a/pkg/dev_compiler/karma.conf.js
+++ b/pkg/dev_compiler/karma.conf.js
@@ -62,12 +62,12 @@
// start these browsers
// available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
customLaunchers: {
- chrome_travis: {
+ ChromeTravis: {
base: 'Chrome',
flags: [ '--no-sandbox' ]
},
- chrome_canary_travis: {
+ ChromeCanaryTravis: {
base: 'ChromeCanary',
flags: [ '--no-sandbox' ]
},
@@ -81,7 +81,7 @@
};
if (process.env.TRAVIS) {
- configuration.browsers = ['chrome_canary_travis'];
+ configuration.browsers = ['ChromeTravis'];
configuration.autoWatch = false;
// Enable this for more logging on Travis. It is too much for Travis to
// automatically display, but still results in a downloadable raw log.
diff --git a/pkg/dev_compiler/lib/js/amd/dart_sdk.js b/pkg/dev_compiler/lib/js/amd/dart_sdk.js
index e4a67c2..b7dc69b 100644
--- a/pkg/dev_compiler/lib/js/amd/dart_sdk.js
+++ b/pkg/dev_compiler/lib/js/amd/dart_sdk.js
@@ -48,12 +48,14 @@
let ListOfNameValuePair = () => (ListOfNameValuePair = dart.constFn(core.List$(_debugger.NameValuePair)))();
let JSArrayOfString = () => (JSArrayOfString = dart.constFn(_interceptors.JSArray$(core.String)))();
let JSArrayOfJsonMLFormatter = () => (JSArrayOfJsonMLFormatter = dart.constFn(_interceptors.JSArray$(_debugger.JsonMLFormatter)))();
+ let JSIndexable = () => (JSIndexable = dart.constFn(_interceptors.JSIndexable$()))();
let JSArray = () => (JSArray = dart.constFn(_interceptors.JSArray$()))();
let JSMutableArray = () => (JSMutableArray = dart.constFn(_interceptors.JSMutableArray$()))();
let JSFixedArray = () => (JSFixedArray = dart.constFn(_interceptors.JSFixedArray$()))();
let JSExtendableArray = () => (JSExtendableArray = dart.constFn(_interceptors.JSExtendableArray$()))();
let JSUnmodifiableArray = () => (JSUnmodifiableArray = dart.constFn(_interceptors.JSUnmodifiableArray$()))();
let ArrayIterator = () => (ArrayIterator = dart.constFn(_interceptors.ArrayIterator$()))();
+ let JSIndexableOfString = () => (JSIndexableOfString = dart.constFn(_interceptors.JSIndexable$(core.String)))();
let MatchToString = () => (MatchToString = dart.constFn(dart.functionType(core.String, [core.Match])))();
let StringToString = () => (StringToString = dart.constFn(dart.functionType(core.String, [core.String])))();
let ComparableOfnum = () => (ComparableOfnum = dart.constFn(core.Comparable$(core.num)))();
@@ -142,6 +144,7 @@
let ListOfClassMirror = () => (ListOfClassMirror = dart.constFn(core.List$(mirrors.ClassMirror)))();
let ListOfTypeVariableMirror = () => (ListOfTypeVariableMirror = dart.constFn(core.List$(mirrors.TypeVariableMirror)))();
let MapOfSymbol$MethodMirror = () => (MapOfSymbol$MethodMirror = dart.constFn(core.Map$(core.Symbol, mirrors.MethodMirror)))();
+ let JSArrayOfType = () => (JSArrayOfType = dart.constFn(_interceptors.JSArray$(core.Type)))();
let ListOfParameterMirror = () => (ListOfParameterMirror = dart.constFn(core.List$(mirrors.ParameterMirror)))();
let ListOfFloat32x4 = () => (ListOfFloat32x4 = dart.constFn(core.List$(typed_data.Float32x4)))();
let ListOfInt32x4 = () => (ListOfInt32x4 = dart.constFn(core.List$(typed_data.Int32x4)))();
@@ -616,6 +619,7 @@
let dynamicToMap = () => (dynamicToMap = dart.constFn(dart.definiteFunctionType(core.Map, [dart.dynamic])))();
let TypeAndInvocationTodynamic = () => (TypeAndInvocationTodynamic = dart.constFn(dart.definiteFunctionType(dart.dynamic, [core.Type, core.Invocation])))();
let SymbolAnddynamicTovoid = () => (SymbolAnddynamicTovoid = dart.constFn(dart.definiteFunctionType(dart.void, [core.Symbol, dart.dynamic])))();
+ let MapOfSymbol$dynamicTodynamic = () => (MapOfSymbol$dynamicTodynamic = dart.constFn(dart.definiteFunctionType(dart.dynamic, [MapOfSymbol$dynamic()])))();
let StringAnddynamicTovoid = () => (StringAnddynamicTovoid = dart.constFn(dart.definiteFunctionType(dart.void, [core.String, dart.dynamic])))();
let dynamicToTypeMirror = () => (dynamicToTypeMirror = dart.constFn(dart.definiteFunctionType(mirrors.TypeMirror, [dart.dynamic])))();
let dynamicAnddynamicAnddynamicTovoid = () => (dynamicAnddynamicAnddynamicTovoid = dart.constFn(dart.definiteFunctionType(dart.void, [dart.dynamic, dart.dynamic, dart.dynamic])))();
@@ -3555,8 +3559,12 @@
constructors: () => ({new: dart.definiteFunctionType(_interceptors.JSBool, [])})
});
dart.registerExtension(dart.global.Boolean, _interceptors.JSBool);
- _interceptors.JSIndexable = class JSIndexable extends core.Object {};
- _interceptors.JSMutableIndexable = class JSMutableIndexable extends _interceptors.JSIndexable {};
+ _interceptors.JSIndexable$ = dart.generic(E => {
+ class JSIndexable extends core.Object {}
+ dart.addTypeTests(JSIndexable);
+ return JSIndexable;
+ });
+ _interceptors.JSIndexable = JSIndexable();
_interceptors.JSObject = class JSObject extends core.Object {};
_interceptors.JavaScriptObject = class JavaScriptObject extends _interceptors.Interceptor {
new() {
@@ -3619,6 +3627,7 @@
let SetOfE = () => (SetOfE = dart.constFn(core.Set$(E)))();
let ArrayIteratorOfE = () => (ArrayIteratorOfE = dart.constFn(_interceptors.ArrayIterator$(E)))();
let ListMapViewOfE = () => (ListMapViewOfE = dart.constFn(_internal.ListMapView$(E)))();
+ let JSIndexableOfE = () => (JSIndexableOfE = dart.constFn(_interceptors.JSIndexable$(E)))();
let ETobool = () => (ETobool = dart.constFn(dart.functionType(core.bool, [E])))();
let ETovoid = () => (ETovoid = dart.constFn(dart.functionType(dart.void, [E])))();
let EAndEToint = () => (EAndEToint = dart.constFn(dart.functionType(core.int, [E, E])))();
@@ -4176,7 +4185,7 @@
}
dart.setExtensionBaseClass(JSArray, dart.global.Array);
dart.addTypeTests(JSArray);
- JSArray[dart.implements] = () => [ListOfE(), _interceptors.JSIndexable];
+ JSArray[dart.implements] = () => [ListOfE(), JSIndexableOfE()];
dart.setSignature(JSArray, {
constructors: () => ({
new: dart.definiteFunctionType(_interceptors.JSArray$(E), []),
@@ -4261,7 +4270,6 @@
super.new();
}
}
- JSMutableArray[dart.implements] = () => [_interceptors.JSMutableIndexable];
return JSMutableArray;
});
_interceptors.JSMutableArray = JSMutableArray();
@@ -5337,7 +5345,7 @@
return this[index];
}
};
- _interceptors.JSString[dart.implements] = () => [core.String, _interceptors.JSIndexable];
+ _interceptors.JSString[dart.implements] = () => [core.String, JSIndexableOfString()];
dart.setSignature(_interceptors.JSString, {
constructors: () => ({new: dart.definiteFunctionType(_interceptors.JSString, [])}),
getters: () => ({
@@ -11557,7 +11565,7 @@
constructors: () => ({new: dart.definiteFunctionType(_js_helper.JSName, [core.String])}),
fields: () => ({name: core.String})
});
- _js_helper.JavaScriptIndexingBehavior = class JavaScriptIndexingBehavior extends _interceptors.JSMutableIndexable {};
+ _js_helper.JavaScriptIndexingBehavior = class JavaScriptIndexingBehavior extends core.Object {};
_js_helper.TypeErrorImplementation = class TypeErrorImplementation extends core.Error {
new(value, actualType, expectedType) {
this.message = dart.str`Type '${actualType}' is not a subtype ` + dart.str`of type '${expectedType}'`;
@@ -13083,58 +13091,66 @@
return _Lazy;
});
_js_mirrors._Lazy = _Lazy();
+ _js_mirrors._getNameForESSymbol = function(member) {
+ let str = dart.toString(member);
+ dart.assert(dart.test(str[dartx.startsWith]('Symbol(')) && dart.test(str[dartx.endsWith](')')));
+ return str[dartx.substring](7, dart.notNull(str[dartx.length]) - 1);
+ };
+ dart.lazyFn(_js_mirrors._getNameForESSymbol, () => dynamicToString());
+ _js_mirrors._toDartMap = function(data) {
+ if (data == null) return dart.map();
+ let map = _js_mirrors._dart.map(data);
+ let privateMembers = Object.getOwnPropertySymbols(data);
+ for (let member of core.Iterable._check(privateMembers)) {
+ let name = _js_mirrors._getNameForESSymbol(member);
+ map[dartx.set](name, data[member]);
+ }
+ return map;
+ };
+ dart.lazyFn(_js_mirrors._toDartMap, () => dynamicToMap());
_js_mirrors._getConstructors = function(obj) {
let sig = _js_mirrors._dart.getConstructorSig(obj);
- if (sig == null) return dart.map();
- return _js_mirrors._dart.map(sig);
+ return _js_mirrors._toDartMap(sig);
};
dart.lazyFn(_js_mirrors._getConstructors, () => dynamicToMap());
_js_mirrors._getFields = function(obj) {
let sig = _js_mirrors._dart.getFieldSig(obj);
- if (sig == null) return dart.map();
- return _js_mirrors._dart.map(sig);
+ return _js_mirrors._toDartMap(sig);
};
dart.lazyFn(_js_mirrors._getFields, () => dynamicToMap());
_js_mirrors._getMethods = function(obj) {
let sig = _js_mirrors._dart.getMethodSig(obj);
- if (sig == null) return dart.map();
- return _js_mirrors._dart.map(sig);
+ return _js_mirrors._toDartMap(sig);
};
dart.lazyFn(_js_mirrors._getMethods, () => dynamicToMap());
_js_mirrors._getGetters = function(obj) {
let sig = _js_mirrors._dart.getGetterSig(obj);
- if (sig == null) return dart.map();
- return _js_mirrors._dart.map(sig);
+ return _js_mirrors._toDartMap(sig);
};
dart.lazyFn(_js_mirrors._getGetters, () => dynamicToMap());
_js_mirrors._getSetters = function(obj) {
let sig = _js_mirrors._dart.getSetterSig(obj);
- if (sig == null) return dart.map();
- return _js_mirrors._dart.map(sig);
+ return _js_mirrors._toDartMap(sig);
};
dart.lazyFn(_js_mirrors._getSetters, () => dynamicToMap());
_js_mirrors._getStaticFields = function(obj) {
let sig = _js_mirrors._dart.getStaticFieldSig(obj);
- if (sig == null) return dart.map();
- return _js_mirrors._dart.map(sig);
+ return _js_mirrors._toDartMap(sig);
};
dart.lazyFn(_js_mirrors._getStaticFields, () => dynamicToMap());
_js_mirrors._getStatics = function(obj) {
let sig = _js_mirrors._dart.getStaticSig(obj);
- if (sig == null) return dart.map();
- return _js_mirrors._dart.map(sig);
+ return _js_mirrors._toDartMap(sig);
};
dart.lazyFn(_js_mirrors._getStatics, () => dynamicToMap());
_js_mirrors._getStaticGetters = function(obj) {
let sig = _js_mirrors._dart.getStaticGetterSig(obj);
- if (sig == null) return dart.map();
- return _js_mirrors._dart.map(sig);
+ return _js_mirrors._toDartMap(sig);
};
dart.lazyFn(_js_mirrors._getStaticGetters, () => dynamicToMap());
_js_mirrors._getStaticSetters = function(obj) {
let sig = _js_mirrors._dart.getStaticSetterSig(obj);
- if (sig == null) return dart.map();
- return _js_mirrors._dart.map(sig);
+ return _js_mirrors._toDartMap(sig);
};
dart.lazyFn(_js_mirrors._getStaticSetters, () => dynamicToMap());
_js_mirrors._unwrap = function(obj) {
@@ -13146,9 +13162,17 @@
};
dart.fn(_js_mirrors._wrap, dynamicTodynamic$());
_js_mirrors._unimplemented = function(t, i) {
- dart.throw(new core.UnimplementedError(dart.str`${t}.${i.memberName} unimplemented`));
+ dart.throw(new core.UnimplementedError(dart.str`${t}.${_js_mirrors.getName(i.memberName)} unimplemented`));
};
dart.fn(_js_mirrors._unimplemented, TypeAndInvocationTodynamic());
+ _js_mirrors._toJsMap = function(map) {
+ let obj = {};
+ map[dartx.forEach](dart.fn((key, value) => {
+ obj[_js_mirrors.getName(key)] = value;
+ }, SymbolAnddynamicTovoid()));
+ return obj;
+ };
+ dart.lazyFn(_js_mirrors._toJsMap, () => MapOfSymbol$dynamicTodynamic());
_js_mirrors.JsMirror = class JsMirror extends core.Object {
noSuchMethod(i) {
_js_mirrors._unimplemented(this.runtimeType, i);
@@ -13242,7 +13266,7 @@
}
};
_js_mirrors.JsObjectMirror[dart.implements] = () => [mirrors.ObjectMirror];
- const _toJsMap = Symbol('_toJsMap');
+ const _getAccessor = Symbol('_getAccessor');
_js_mirrors.JsInstanceMirror = class JsInstanceMirror extends _js_mirrors.JsObjectMirror {
get hasReflectee() {
return true;
@@ -13260,32 +13284,41 @@
get hashCode() {
return (dart.notNull(core.identityHashCode(this.reflectee)) ^ 909522486) >>> 0;
}
- getField(symbol) {
+ [_getAccessor](reflectee, symbol, args, namedArgs) {
+ if (args === void 0) args = null;
+ if (namedArgs === void 0) namedArgs = null;
let name = _js_mirrors.getName(symbol);
- let field = _js_mirrors._dload(this.reflectee, name);
+ if (!dart.test(name[dartx.startsWith]('_'))) return name;
+ let privateMembers = Object.getOwnPropertySymbols(reflectee);
+ dart.dsend(privateMembers, 'addAll', Object.getOwnPropertySymbols(reflectee.__proto__));
+ for (let member of core.Iterable._check(privateMembers)) {
+ let privateName = _js_mirrors._getNameForESSymbol(member);
+ if (name == privateName) return member;
+ }
+ return new core.NoSuchMethodError(reflectee, symbol, args, namedArgs);
+ }
+ getField(symbol) {
+ let name = this[_getAccessor](this.reflectee, symbol);
+ let field = _js_mirrors._dload(this.reflectee, core.String._check(name));
return _js_mirrors.reflect(field);
}
setField(symbol, value) {
- let name = _js_mirrors.getName(symbol);
- _js_mirrors._dput(this.reflectee, name, value);
+ let name = this[_getAccessor](this.reflectee, symbol);
+ _js_mirrors._dput(this.reflectee, core.String._check(name), value);
return _js_mirrors.reflect(value);
}
invoke(symbol, args, namedArgs) {
if (namedArgs === void 0) namedArgs = null;
- let name = _js_mirrors.getName(symbol);
+ let name = this[_getAccessor](this.reflectee, symbol, args, namedArgs);
if (namedArgs != null) {
args = core.List.from(args);
- args[dartx.add](this[_toJsMap](namedArgs));
+ args[dartx.add](_js_mirrors._toJsMap(namedArgs));
}
- let result = _js_mirrors._dsend(this.reflectee, name, args);
+ let result = _js_mirrors._dsend(this.reflectee, core.String._check(name), args);
return _js_mirrors.reflect(result);
}
- [_toJsMap](map) {
- let obj = {};
- map[dartx.forEach](dart.fn((key, value) => {
- obj[_js_mirrors.getName(key)] = value;
- }, SymbolAnddynamicTovoid()));
- return obj;
+ toString() {
+ return dart.str`InstanceMirror on '${this.reflectee}'`;
}
delegate(...args) {
return this.noSuchMethod(new dart.InvocationImpl('delegate', args, {isMethod: true}));
@@ -13302,10 +13335,10 @@
}),
methods: () => ({
'==': dart.definiteFunctionType(core.bool, [core.Object]),
+ [_getAccessor]: dart.definiteFunctionType(dart.dynamic, [dart.dynamic, core.Symbol], [core.List, MapOfSymbol$dynamic()]),
getField: dart.definiteFunctionType(mirrors.InstanceMirror, [core.Symbol]),
setField: dart.definiteFunctionType(mirrors.InstanceMirror, [core.Symbol, core.Object]),
- invoke: dart.definiteFunctionType(mirrors.InstanceMirror, [core.Symbol, core.List], [MapOfSymbol$dynamic()]),
- [_toJsMap]: dart.definiteFunctionType(dart.dynamic, [MapOfSymbol$dynamic()])
+ invoke: dart.definiteFunctionType(mirrors.InstanceMirror, [core.Symbol, core.List], [MapOfSymbol$dynamic()])
})
});
_js_mirrors.JsClosureMirror = class JsClosureMirror extends _js_mirrors.JsInstanceMirror {
@@ -13316,7 +13349,7 @@
if (namedArgs === void 0) namedArgs = null;
if (namedArgs != null) {
args = core.List.from(args);
- args[dartx.add](this[_toJsMap](namedArgs));
+ args[dartx.add](_js_mirrors._toJsMap(namedArgs));
}
let result = _js_mirrors._dcall(this.reflectee, args);
return _js_mirrors.reflect(result);
@@ -13344,7 +13377,8 @@
_js_mirrors.JsClassMirror = class JsClassMirror extends _js_mirrors.JsMirror {
get metadata() {
if (this[_metadata$] == null) {
- let fn = _js_mirrors._unwrap(this[_cls])[dart.metadata];
+ let unwrapped = _js_mirrors._unwrap(this[_cls]);
+ let fn = Object.hasOwnProperty.call(unwrapped, dart.metadata) ? unwrapped[dart.metadata] : null;
this[_metadata$] = fn == null ? const$0 || (const$0 = dart.constList([], mirrors.InstanceMirror)) : ListOfInstanceMirror().unmodifiable(core.Iterable._check(dart.dsend(dart.dcall(fn), 'map', dart.fn(i => _js_mirrors.reflect(i), dynamicToInstanceMirror()))));
}
return this[_metadata$];
@@ -13441,6 +13475,25 @@
let instance = name == 'new' || name == '' ? new (_js_mirrors._unwrap(this[_cls]))(...args) : new (_js_mirrors._unwrap(this[_cls]))[name](...args);
return _js_mirrors.reflect(instance);
}
+ getField(symbol) {
+ let name = _js_mirrors.getName(symbol);
+ return _js_mirrors.reflect(_js_mirrors._unwrap(this[_cls])[name]);
+ }
+ setField(symbol, value) {
+ let name = _js_mirrors.getName(symbol);
+ _js_mirrors._unwrap(this[_cls])[name] = value;
+ return _js_mirrors.reflect(value);
+ }
+ invoke(symbol, args, namedArgs) {
+ if (namedArgs === void 0) namedArgs = null;
+ let name = _js_mirrors.getName(symbol);
+ if (namedArgs != null) {
+ args = core.List.from(args);
+ args[dartx.add](_js_mirrors._toJsMap(namedArgs));
+ }
+ let result = _js_mirrors._unwrap(this[_cls])[name](...args);
+ return _js_mirrors.reflect(result);
+ }
get superinterfaces() {
let interfaceThunk = _js_mirrors._unwrap(this[_cls])[dart.implements];
if (interfaceThunk == null) {
@@ -13475,6 +13528,9 @@
return mirrors.ClassMirror._check(_js_mirrors.reflectType(core.Type._check(_js_mirrors._wrap(_js_mirrors._unwrap(this[_cls]).__proto__))));
}
}
+ toString() {
+ return dart.str`ClassMirror on '${this[_cls]}'`;
+ }
get qualifiedName() {
return core.Symbol._check(this.noSuchMethod(new dart.InvocationImpl('qualifiedName', [], {isGetter: true})));
}
@@ -13499,15 +13555,6 @@
get typeVariables() {
return ListOfTypeVariableMirror()._check(this.noSuchMethod(new dart.InvocationImpl('typeVariables', [], {isGetter: true})));
}
- invoke(...args) {
- return mirrors.InstanceMirror._check(this.noSuchMethod(new dart.InvocationImpl('invoke', args, {isMethod: true})));
- }
- getField(...args) {
- return mirrors.InstanceMirror._check(this.noSuchMethod(new dart.InvocationImpl('getField', args, {isMethod: true})));
- }
- setField(...args) {
- return mirrors.InstanceMirror._check(this.noSuchMethod(new dart.InvocationImpl('setField', args, {isMethod: true})));
- }
isSubclassOf(...args) {
return core.bool._check(this.noSuchMethod(new dart.InvocationImpl('isSubclassOf', args, {isMethod: true})));
}
@@ -13545,7 +13592,12 @@
originalDeclaration: dart.definiteFunctionType(mirrors.TypeMirror, []),
superclass: dart.definiteFunctionType(mirrors.ClassMirror, [])
}),
- methods: () => ({newInstance: dart.definiteFunctionType(mirrors.InstanceMirror, [core.Symbol, core.List], [MapOfSymbol$dynamic()])})
+ methods: () => ({
+ newInstance: dart.definiteFunctionType(mirrors.InstanceMirror, [core.Symbol, core.List], [MapOfSymbol$dynamic()]),
+ getField: dart.definiteFunctionType(mirrors.InstanceMirror, [core.Symbol]),
+ setField: dart.definiteFunctionType(mirrors.InstanceMirror, [core.Symbol, core.Object]),
+ invoke: dart.definiteFunctionType(mirrors.InstanceMirror, [core.Symbol, core.List], [MapOfSymbol$dynamic()])
+ })
});
const _name$ = Symbol('_name');
_js_mirrors.JsVariableMirror = class JsVariableMirror extends _js_mirrors.JsMirror {
@@ -13559,6 +13611,9 @@
this.isStatic = false;
this.isFinal = false;
}
+ toString() {
+ return dart.str`VariableMirror on '${this[_name$]}'`;
+ }
get qualifiedName() {
return core.Symbol._check(this.noSuchMethod(new dart.InvocationImpl('qualifiedName', [], {isGetter: true})));
}
@@ -13595,6 +13650,9 @@
_(name, t, annotations) {
super._(name, t, annotations);
}
+ toString() {
+ return dart.str`ParameterMirror on '${this[_name$]}'`;
+ }
get qualifiedName() {
return core.Symbol._check(this.noSuchMethod(new dart.InvocationImpl('qualifiedName', [], {isGetter: true})));
}
@@ -13688,12 +13746,15 @@
this[_metadata$] = const$3 || (const$3 = dart.constList([], mirrors.InstanceMirror));
return;
}
- if (core.List.is(ftype)) {
+ if (!core.Function.is(ftype) && core.List.is(ftype)) {
this[_metadata$] = ListOfInstanceMirror().unmodifiable(core.Iterable._check(dart.dsend(dart.dsend(ftype, 'skip', 1), 'map', dart.fn(a => _js_mirrors.reflect(a), dynamicToInstanceMirror()))));
ftype = dart.dindex(ftype, 0);
} else {
this[_metadata$] = const$4 || (const$4 = dart.constList([], mirrors.InstanceMirror));
}
+ if (typeof ftype == "function") {
+ ftype = ftype.apply(null, JSArrayOfType().of([dart.dynamic, dart.dynamic, dart.dynamic]));
+ }
let args = core.List._check(dart.dload(ftype, 'args'));
let opts = core.List._check(dart.dload(ftype, 'optionals'));
let params = ListOfParameterMirror().new(dart.notNull(args[dartx.length]) + dart.notNull(opts[dartx.length]));
@@ -13711,6 +13772,9 @@
}
this[_params] = ListOfParameterMirror().unmodifiable(params);
}
+ toString() {
+ return dart.str`MethodMirror on '${this[_name$]}'`;
+ }
get qualifiedName() {
return core.Symbol._check(this.noSuchMethod(new dart.InvocationImpl('qualifiedName', [], {isGetter: true})));
}
@@ -36958,40 +37022,13 @@
math.SQRT2 = 1.4142135623730951;
math.min = function(T) {
return (a, b) => {
- if (!(typeof a == 'number')) dart.throw(new core.ArgumentError(a));
- if (!(typeof b == 'number')) dart.throw(new core.ArgumentError(b));
- if (dart.notNull(a) > dart.notNull(b)) return b;
- if (dart.notNull(a) < dart.notNull(b)) return a;
- if (typeof b == 'number') {
- if (typeof a == 'number') {
- if (a == 0.0) {
- return (dart.notNull(a) + dart.notNull(b)) * dart.notNull(a) * dart.notNull(b);
- }
- }
- if (a == 0 && dart.test(b[dartx.isNegative]) || dart.test(b[dartx.isNaN])) return b;
- return a;
- }
- return a;
+ return Math.min(_js_helper.checkNum(a), _js_helper.checkNum(b));
};
};
dart.fn(math.min, TAndTToT());
math.max = function(T) {
return (a, b) => {
- if (!(typeof a == 'number')) dart.throw(new core.ArgumentError(a));
- if (!(typeof b == 'number')) dart.throw(new core.ArgumentError(b));
- if (dart.notNull(a) > dart.notNull(b)) return a;
- if (dart.notNull(a) < dart.notNull(b)) return b;
- if (typeof b == 'number') {
- if (typeof a == 'number') {
- if (a == 0.0) {
- return dart.notNull(a) + dart.notNull(b);
- }
- }
- if (dart.test(b[dartx.isNaN])) return b;
- return a;
- }
- if (b == 0 && dart.test(a[dartx.isNegative])) return b;
- return a;
+ return Math.max(_js_helper.checkNum(a), _js_helper.checkNum(b));
};
};
dart.fn(math.max, TAndTToT$());
@@ -37408,7 +37445,8 @@
}
['=='](other) {
if (!RectangleOfnum().is(other)) return false;
- return dart.equals(this[dartx.left], dart.dload(other, 'left')) && dart.equals(this[dartx.top], dart.dload(other, 'top')) && dart.equals(this[dartx.right], dart.dload(other, 'right')) && dart.equals(this[dartx.bottom], dart.dload(other, 'bottom'));
+ let otherRect = RectangleOfnum().as(other);
+ return this[dartx.left] == otherRect[dartx.left] && this[dartx.top] == otherRect[dartx.top] && this[dartx.right] == otherRect[dartx.right] && this[dartx.bottom] == otherRect[dartx.bottom];
}
get hashCode() {
return math._JenkinsSmiHash.hash4(dart.hashCode(this[dartx.left]), dart.hashCode(this[dartx.top]), dart.hashCode(this[dartx.right]), dart.hashCode(this[dartx.bottom]));
diff --git a/pkg/dev_compiler/lib/js/common/dart_sdk.js b/pkg/dev_compiler/lib/js/common/dart_sdk.js
index 8b9f7f9..cbb4987 100644
--- a/pkg/dev_compiler/lib/js/common/dart_sdk.js
+++ b/pkg/dev_compiler/lib/js/common/dart_sdk.js
@@ -48,12 +48,14 @@
let ListOfNameValuePair = () => (ListOfNameValuePair = dart.constFn(core.List$(_debugger.NameValuePair)))();
let JSArrayOfString = () => (JSArrayOfString = dart.constFn(_interceptors.JSArray$(core.String)))();
let JSArrayOfJsonMLFormatter = () => (JSArrayOfJsonMLFormatter = dart.constFn(_interceptors.JSArray$(_debugger.JsonMLFormatter)))();
+ let JSIndexable = () => (JSIndexable = dart.constFn(_interceptors.JSIndexable$()))();
let JSArray = () => (JSArray = dart.constFn(_interceptors.JSArray$()))();
let JSMutableArray = () => (JSMutableArray = dart.constFn(_interceptors.JSMutableArray$()))();
let JSFixedArray = () => (JSFixedArray = dart.constFn(_interceptors.JSFixedArray$()))();
let JSExtendableArray = () => (JSExtendableArray = dart.constFn(_interceptors.JSExtendableArray$()))();
let JSUnmodifiableArray = () => (JSUnmodifiableArray = dart.constFn(_interceptors.JSUnmodifiableArray$()))();
let ArrayIterator = () => (ArrayIterator = dart.constFn(_interceptors.ArrayIterator$()))();
+ let JSIndexableOfString = () => (JSIndexableOfString = dart.constFn(_interceptors.JSIndexable$(core.String)))();
let MatchToString = () => (MatchToString = dart.constFn(dart.functionType(core.String, [core.Match])))();
let StringToString = () => (StringToString = dart.constFn(dart.functionType(core.String, [core.String])))();
let ComparableOfnum = () => (ComparableOfnum = dart.constFn(core.Comparable$(core.num)))();
@@ -142,6 +144,7 @@
let ListOfClassMirror = () => (ListOfClassMirror = dart.constFn(core.List$(mirrors.ClassMirror)))();
let ListOfTypeVariableMirror = () => (ListOfTypeVariableMirror = dart.constFn(core.List$(mirrors.TypeVariableMirror)))();
let MapOfSymbol$MethodMirror = () => (MapOfSymbol$MethodMirror = dart.constFn(core.Map$(core.Symbol, mirrors.MethodMirror)))();
+ let JSArrayOfType = () => (JSArrayOfType = dart.constFn(_interceptors.JSArray$(core.Type)))();
let ListOfParameterMirror = () => (ListOfParameterMirror = dart.constFn(core.List$(mirrors.ParameterMirror)))();
let ListOfFloat32x4 = () => (ListOfFloat32x4 = dart.constFn(core.List$(typed_data.Float32x4)))();
let ListOfInt32x4 = () => (ListOfInt32x4 = dart.constFn(core.List$(typed_data.Int32x4)))();
@@ -616,6 +619,7 @@
let dynamicToMap = () => (dynamicToMap = dart.constFn(dart.definiteFunctionType(core.Map, [dart.dynamic])))();
let TypeAndInvocationTodynamic = () => (TypeAndInvocationTodynamic = dart.constFn(dart.definiteFunctionType(dart.dynamic, [core.Type, core.Invocation])))();
let SymbolAnddynamicTovoid = () => (SymbolAnddynamicTovoid = dart.constFn(dart.definiteFunctionType(dart.void, [core.Symbol, dart.dynamic])))();
+ let MapOfSymbol$dynamicTodynamic = () => (MapOfSymbol$dynamicTodynamic = dart.constFn(dart.definiteFunctionType(dart.dynamic, [MapOfSymbol$dynamic()])))();
let StringAnddynamicTovoid = () => (StringAnddynamicTovoid = dart.constFn(dart.definiteFunctionType(dart.void, [core.String, dart.dynamic])))();
let dynamicToTypeMirror = () => (dynamicToTypeMirror = dart.constFn(dart.definiteFunctionType(mirrors.TypeMirror, [dart.dynamic])))();
let dynamicAnddynamicAnddynamicTovoid = () => (dynamicAnddynamicAnddynamicTovoid = dart.constFn(dart.definiteFunctionType(dart.void, [dart.dynamic, dart.dynamic, dart.dynamic])))();
@@ -3555,8 +3559,12 @@
constructors: () => ({new: dart.definiteFunctionType(_interceptors.JSBool, [])})
});
dart.registerExtension(dart.global.Boolean, _interceptors.JSBool);
- _interceptors.JSIndexable = class JSIndexable extends core.Object {};
- _interceptors.JSMutableIndexable = class JSMutableIndexable extends _interceptors.JSIndexable {};
+ _interceptors.JSIndexable$ = dart.generic(E => {
+ class JSIndexable extends core.Object {}
+ dart.addTypeTests(JSIndexable);
+ return JSIndexable;
+ });
+ _interceptors.JSIndexable = JSIndexable();
_interceptors.JSObject = class JSObject extends core.Object {};
_interceptors.JavaScriptObject = class JavaScriptObject extends _interceptors.Interceptor {
new() {
@@ -3619,6 +3627,7 @@
let SetOfE = () => (SetOfE = dart.constFn(core.Set$(E)))();
let ArrayIteratorOfE = () => (ArrayIteratorOfE = dart.constFn(_interceptors.ArrayIterator$(E)))();
let ListMapViewOfE = () => (ListMapViewOfE = dart.constFn(_internal.ListMapView$(E)))();
+ let JSIndexableOfE = () => (JSIndexableOfE = dart.constFn(_interceptors.JSIndexable$(E)))();
let ETobool = () => (ETobool = dart.constFn(dart.functionType(core.bool, [E])))();
let ETovoid = () => (ETovoid = dart.constFn(dart.functionType(dart.void, [E])))();
let EAndEToint = () => (EAndEToint = dart.constFn(dart.functionType(core.int, [E, E])))();
@@ -4176,7 +4185,7 @@
}
dart.setExtensionBaseClass(JSArray, dart.global.Array);
dart.addTypeTests(JSArray);
- JSArray[dart.implements] = () => [ListOfE(), _interceptors.JSIndexable];
+ JSArray[dart.implements] = () => [ListOfE(), JSIndexableOfE()];
dart.setSignature(JSArray, {
constructors: () => ({
new: dart.definiteFunctionType(_interceptors.JSArray$(E), []),
@@ -4261,7 +4270,6 @@
super.new();
}
}
- JSMutableArray[dart.implements] = () => [_interceptors.JSMutableIndexable];
return JSMutableArray;
});
_interceptors.JSMutableArray = JSMutableArray();
@@ -5337,7 +5345,7 @@
return this[index];
}
};
- _interceptors.JSString[dart.implements] = () => [core.String, _interceptors.JSIndexable];
+ _interceptors.JSString[dart.implements] = () => [core.String, JSIndexableOfString()];
dart.setSignature(_interceptors.JSString, {
constructors: () => ({new: dart.definiteFunctionType(_interceptors.JSString, [])}),
getters: () => ({
@@ -11557,7 +11565,7 @@
constructors: () => ({new: dart.definiteFunctionType(_js_helper.JSName, [core.String])}),
fields: () => ({name: core.String})
});
- _js_helper.JavaScriptIndexingBehavior = class JavaScriptIndexingBehavior extends _interceptors.JSMutableIndexable {};
+ _js_helper.JavaScriptIndexingBehavior = class JavaScriptIndexingBehavior extends core.Object {};
_js_helper.TypeErrorImplementation = class TypeErrorImplementation extends core.Error {
new(value, actualType, expectedType) {
this.message = dart.str`Type '${actualType}' is not a subtype ` + dart.str`of type '${expectedType}'`;
@@ -13083,58 +13091,66 @@
return _Lazy;
});
_js_mirrors._Lazy = _Lazy();
+ _js_mirrors._getNameForESSymbol = function(member) {
+ let str = dart.toString(member);
+ dart.assert(dart.test(str[dartx.startsWith]('Symbol(')) && dart.test(str[dartx.endsWith](')')));
+ return str[dartx.substring](7, dart.notNull(str[dartx.length]) - 1);
+ };
+ dart.lazyFn(_js_mirrors._getNameForESSymbol, () => dynamicToString());
+ _js_mirrors._toDartMap = function(data) {
+ if (data == null) return dart.map();
+ let map = _js_mirrors._dart.map(data);
+ let privateMembers = Object.getOwnPropertySymbols(data);
+ for (let member of core.Iterable._check(privateMembers)) {
+ let name = _js_mirrors._getNameForESSymbol(member);
+ map[dartx.set](name, data[member]);
+ }
+ return map;
+ };
+ dart.lazyFn(_js_mirrors._toDartMap, () => dynamicToMap());
_js_mirrors._getConstructors = function(obj) {
let sig = _js_mirrors._dart.getConstructorSig(obj);
- if (sig == null) return dart.map();
- return _js_mirrors._dart.map(sig);
+ return _js_mirrors._toDartMap(sig);
};
dart.lazyFn(_js_mirrors._getConstructors, () => dynamicToMap());
_js_mirrors._getFields = function(obj) {
let sig = _js_mirrors._dart.getFieldSig(obj);
- if (sig == null) return dart.map();
- return _js_mirrors._dart.map(sig);
+ return _js_mirrors._toDartMap(sig);
};
dart.lazyFn(_js_mirrors._getFields, () => dynamicToMap());
_js_mirrors._getMethods = function(obj) {
let sig = _js_mirrors._dart.getMethodSig(obj);
- if (sig == null) return dart.map();
- return _js_mirrors._dart.map(sig);
+ return _js_mirrors._toDartMap(sig);
};
dart.lazyFn(_js_mirrors._getMethods, () => dynamicToMap());
_js_mirrors._getGetters = function(obj) {
let sig = _js_mirrors._dart.getGetterSig(obj);
- if (sig == null) return dart.map();
- return _js_mirrors._dart.map(sig);
+ return _js_mirrors._toDartMap(sig);
};
dart.lazyFn(_js_mirrors._getGetters, () => dynamicToMap());
_js_mirrors._getSetters = function(obj) {
let sig = _js_mirrors._dart.getSetterSig(obj);
- if (sig == null) return dart.map();
- return _js_mirrors._dart.map(sig);
+ return _js_mirrors._toDartMap(sig);
};
dart.lazyFn(_js_mirrors._getSetters, () => dynamicToMap());
_js_mirrors._getStaticFields = function(obj) {
let sig = _js_mirrors._dart.getStaticFieldSig(obj);
- if (sig == null) return dart.map();
- return _js_mirrors._dart.map(sig);
+ return _js_mirrors._toDartMap(sig);
};
dart.lazyFn(_js_mirrors._getStaticFields, () => dynamicToMap());
_js_mirrors._getStatics = function(obj) {
let sig = _js_mirrors._dart.getStaticSig(obj);
- if (sig == null) return dart.map();
- return _js_mirrors._dart.map(sig);
+ return _js_mirrors._toDartMap(sig);
};
dart.lazyFn(_js_mirrors._getStatics, () => dynamicToMap());
_js_mirrors._getStaticGetters = function(obj) {
let sig = _js_mirrors._dart.getStaticGetterSig(obj);
- if (sig == null) return dart.map();
- return _js_mirrors._dart.map(sig);
+ return _js_mirrors._toDartMap(sig);
};
dart.lazyFn(_js_mirrors._getStaticGetters, () => dynamicToMap());
_js_mirrors._getStaticSetters = function(obj) {
let sig = _js_mirrors._dart.getStaticSetterSig(obj);
- if (sig == null) return dart.map();
- return _js_mirrors._dart.map(sig);
+ return _js_mirrors._toDartMap(sig);
};
dart.lazyFn(_js_mirrors._getStaticSetters, () => dynamicToMap());
_js_mirrors._unwrap = function(obj) {
@@ -13146,9 +13162,17 @@
};
dart.fn(_js_mirrors._wrap, dynamicTodynamic$());
_js_mirrors._unimplemented = function(t, i) {
- dart.throw(new core.UnimplementedError(dart.str`${t}.${i.memberName} unimplemented`));
+ dart.throw(new core.UnimplementedError(dart.str`${t}.${_js_mirrors.getName(i.memberName)} unimplemented`));
};
dart.fn(_js_mirrors._unimplemented, TypeAndInvocationTodynamic());
+ _js_mirrors._toJsMap = function(map) {
+ let obj = {};
+ map[dartx.forEach](dart.fn((key, value) => {
+ obj[_js_mirrors.getName(key)] = value;
+ }, SymbolAnddynamicTovoid()));
+ return obj;
+ };
+ dart.lazyFn(_js_mirrors._toJsMap, () => MapOfSymbol$dynamicTodynamic());
_js_mirrors.JsMirror = class JsMirror extends core.Object {
noSuchMethod(i) {
_js_mirrors._unimplemented(this.runtimeType, i);
@@ -13242,7 +13266,7 @@
}
};
_js_mirrors.JsObjectMirror[dart.implements] = () => [mirrors.ObjectMirror];
- const _toJsMap = Symbol('_toJsMap');
+ const _getAccessor = Symbol('_getAccessor');
_js_mirrors.JsInstanceMirror = class JsInstanceMirror extends _js_mirrors.JsObjectMirror {
get hasReflectee() {
return true;
@@ -13260,32 +13284,41 @@
get hashCode() {
return (dart.notNull(core.identityHashCode(this.reflectee)) ^ 909522486) >>> 0;
}
- getField(symbol) {
+ [_getAccessor](reflectee, symbol, args, namedArgs) {
+ if (args === void 0) args = null;
+ if (namedArgs === void 0) namedArgs = null;
let name = _js_mirrors.getName(symbol);
- let field = _js_mirrors._dload(this.reflectee, name);
+ if (!dart.test(name[dartx.startsWith]('_'))) return name;
+ let privateMembers = Object.getOwnPropertySymbols(reflectee);
+ dart.dsend(privateMembers, 'addAll', Object.getOwnPropertySymbols(reflectee.__proto__));
+ for (let member of core.Iterable._check(privateMembers)) {
+ let privateName = _js_mirrors._getNameForESSymbol(member);
+ if (name == privateName) return member;
+ }
+ return new core.NoSuchMethodError(reflectee, symbol, args, namedArgs);
+ }
+ getField(symbol) {
+ let name = this[_getAccessor](this.reflectee, symbol);
+ let field = _js_mirrors._dload(this.reflectee, core.String._check(name));
return _js_mirrors.reflect(field);
}
setField(symbol, value) {
- let name = _js_mirrors.getName(symbol);
- _js_mirrors._dput(this.reflectee, name, value);
+ let name = this[_getAccessor](this.reflectee, symbol);
+ _js_mirrors._dput(this.reflectee, core.String._check(name), value);
return _js_mirrors.reflect(value);
}
invoke(symbol, args, namedArgs) {
if (namedArgs === void 0) namedArgs = null;
- let name = _js_mirrors.getName(symbol);
+ let name = this[_getAccessor](this.reflectee, symbol, args, namedArgs);
if (namedArgs != null) {
args = core.List.from(args);
- args[dartx.add](this[_toJsMap](namedArgs));
+ args[dartx.add](_js_mirrors._toJsMap(namedArgs));
}
- let result = _js_mirrors._dsend(this.reflectee, name, args);
+ let result = _js_mirrors._dsend(this.reflectee, core.String._check(name), args);
return _js_mirrors.reflect(result);
}
- [_toJsMap](map) {
- let obj = {};
- map[dartx.forEach](dart.fn((key, value) => {
- obj[_js_mirrors.getName(key)] = value;
- }, SymbolAnddynamicTovoid()));
- return obj;
+ toString() {
+ return dart.str`InstanceMirror on '${this.reflectee}'`;
}
delegate(...args) {
return this.noSuchMethod(new dart.InvocationImpl('delegate', args, {isMethod: true}));
@@ -13302,10 +13335,10 @@
}),
methods: () => ({
'==': dart.definiteFunctionType(core.bool, [core.Object]),
+ [_getAccessor]: dart.definiteFunctionType(dart.dynamic, [dart.dynamic, core.Symbol], [core.List, MapOfSymbol$dynamic()]),
getField: dart.definiteFunctionType(mirrors.InstanceMirror, [core.Symbol]),
setField: dart.definiteFunctionType(mirrors.InstanceMirror, [core.Symbol, core.Object]),
- invoke: dart.definiteFunctionType(mirrors.InstanceMirror, [core.Symbol, core.List], [MapOfSymbol$dynamic()]),
- [_toJsMap]: dart.definiteFunctionType(dart.dynamic, [MapOfSymbol$dynamic()])
+ invoke: dart.definiteFunctionType(mirrors.InstanceMirror, [core.Symbol, core.List], [MapOfSymbol$dynamic()])
})
});
_js_mirrors.JsClosureMirror = class JsClosureMirror extends _js_mirrors.JsInstanceMirror {
@@ -13316,7 +13349,7 @@
if (namedArgs === void 0) namedArgs = null;
if (namedArgs != null) {
args = core.List.from(args);
- args[dartx.add](this[_toJsMap](namedArgs));
+ args[dartx.add](_js_mirrors._toJsMap(namedArgs));
}
let result = _js_mirrors._dcall(this.reflectee, args);
return _js_mirrors.reflect(result);
@@ -13344,7 +13377,8 @@
_js_mirrors.JsClassMirror = class JsClassMirror extends _js_mirrors.JsMirror {
get metadata() {
if (this[_metadata$] == null) {
- let fn = _js_mirrors._unwrap(this[_cls])[dart.metadata];
+ let unwrapped = _js_mirrors._unwrap(this[_cls]);
+ let fn = Object.hasOwnProperty.call(unwrapped, dart.metadata) ? unwrapped[dart.metadata] : null;
this[_metadata$] = fn == null ? const$0 || (const$0 = dart.constList([], mirrors.InstanceMirror)) : ListOfInstanceMirror().unmodifiable(core.Iterable._check(dart.dsend(dart.dcall(fn), 'map', dart.fn(i => _js_mirrors.reflect(i), dynamicToInstanceMirror()))));
}
return this[_metadata$];
@@ -13441,6 +13475,25 @@
let instance = name == 'new' || name == '' ? new (_js_mirrors._unwrap(this[_cls]))(...args) : new (_js_mirrors._unwrap(this[_cls]))[name](...args);
return _js_mirrors.reflect(instance);
}
+ getField(symbol) {
+ let name = _js_mirrors.getName(symbol);
+ return _js_mirrors.reflect(_js_mirrors._unwrap(this[_cls])[name]);
+ }
+ setField(symbol, value) {
+ let name = _js_mirrors.getName(symbol);
+ _js_mirrors._unwrap(this[_cls])[name] = value;
+ return _js_mirrors.reflect(value);
+ }
+ invoke(symbol, args, namedArgs) {
+ if (namedArgs === void 0) namedArgs = null;
+ let name = _js_mirrors.getName(symbol);
+ if (namedArgs != null) {
+ args = core.List.from(args);
+ args[dartx.add](_js_mirrors._toJsMap(namedArgs));
+ }
+ let result = _js_mirrors._unwrap(this[_cls])[name](...args);
+ return _js_mirrors.reflect(result);
+ }
get superinterfaces() {
let interfaceThunk = _js_mirrors._unwrap(this[_cls])[dart.implements];
if (interfaceThunk == null) {
@@ -13475,6 +13528,9 @@
return mirrors.ClassMirror._check(_js_mirrors.reflectType(core.Type._check(_js_mirrors._wrap(_js_mirrors._unwrap(this[_cls]).__proto__))));
}
}
+ toString() {
+ return dart.str`ClassMirror on '${this[_cls]}'`;
+ }
get qualifiedName() {
return core.Symbol._check(this.noSuchMethod(new dart.InvocationImpl('qualifiedName', [], {isGetter: true})));
}
@@ -13499,15 +13555,6 @@
get typeVariables() {
return ListOfTypeVariableMirror()._check(this.noSuchMethod(new dart.InvocationImpl('typeVariables', [], {isGetter: true})));
}
- invoke(...args) {
- return mirrors.InstanceMirror._check(this.noSuchMethod(new dart.InvocationImpl('invoke', args, {isMethod: true})));
- }
- getField(...args) {
- return mirrors.InstanceMirror._check(this.noSuchMethod(new dart.InvocationImpl('getField', args, {isMethod: true})));
- }
- setField(...args) {
- return mirrors.InstanceMirror._check(this.noSuchMethod(new dart.InvocationImpl('setField', args, {isMethod: true})));
- }
isSubclassOf(...args) {
return core.bool._check(this.noSuchMethod(new dart.InvocationImpl('isSubclassOf', args, {isMethod: true})));
}
@@ -13545,7 +13592,12 @@
originalDeclaration: dart.definiteFunctionType(mirrors.TypeMirror, []),
superclass: dart.definiteFunctionType(mirrors.ClassMirror, [])
}),
- methods: () => ({newInstance: dart.definiteFunctionType(mirrors.InstanceMirror, [core.Symbol, core.List], [MapOfSymbol$dynamic()])})
+ methods: () => ({
+ newInstance: dart.definiteFunctionType(mirrors.InstanceMirror, [core.Symbol, core.List], [MapOfSymbol$dynamic()]),
+ getField: dart.definiteFunctionType(mirrors.InstanceMirror, [core.Symbol]),
+ setField: dart.definiteFunctionType(mirrors.InstanceMirror, [core.Symbol, core.Object]),
+ invoke: dart.definiteFunctionType(mirrors.InstanceMirror, [core.Symbol, core.List], [MapOfSymbol$dynamic()])
+ })
});
const _name$ = Symbol('_name');
_js_mirrors.JsVariableMirror = class JsVariableMirror extends _js_mirrors.JsMirror {
@@ -13559,6 +13611,9 @@
this.isStatic = false;
this.isFinal = false;
}
+ toString() {
+ return dart.str`VariableMirror on '${this[_name$]}'`;
+ }
get qualifiedName() {
return core.Symbol._check(this.noSuchMethod(new dart.InvocationImpl('qualifiedName', [], {isGetter: true})));
}
@@ -13595,6 +13650,9 @@
_(name, t, annotations) {
super._(name, t, annotations);
}
+ toString() {
+ return dart.str`ParameterMirror on '${this[_name$]}'`;
+ }
get qualifiedName() {
return core.Symbol._check(this.noSuchMethod(new dart.InvocationImpl('qualifiedName', [], {isGetter: true})));
}
@@ -13688,12 +13746,15 @@
this[_metadata$] = const$3 || (const$3 = dart.constList([], mirrors.InstanceMirror));
return;
}
- if (core.List.is(ftype)) {
+ if (!core.Function.is(ftype) && core.List.is(ftype)) {
this[_metadata$] = ListOfInstanceMirror().unmodifiable(core.Iterable._check(dart.dsend(dart.dsend(ftype, 'skip', 1), 'map', dart.fn(a => _js_mirrors.reflect(a), dynamicToInstanceMirror()))));
ftype = dart.dindex(ftype, 0);
} else {
this[_metadata$] = const$4 || (const$4 = dart.constList([], mirrors.InstanceMirror));
}
+ if (typeof ftype == "function") {
+ ftype = ftype.apply(null, JSArrayOfType().of([dart.dynamic, dart.dynamic, dart.dynamic]));
+ }
let args = core.List._check(dart.dload(ftype, 'args'));
let opts = core.List._check(dart.dload(ftype, 'optionals'));
let params = ListOfParameterMirror().new(dart.notNull(args[dartx.length]) + dart.notNull(opts[dartx.length]));
@@ -13711,6 +13772,9 @@
}
this[_params] = ListOfParameterMirror().unmodifiable(params);
}
+ toString() {
+ return dart.str`MethodMirror on '${this[_name$]}'`;
+ }
get qualifiedName() {
return core.Symbol._check(this.noSuchMethod(new dart.InvocationImpl('qualifiedName', [], {isGetter: true})));
}
@@ -36958,40 +37022,13 @@
math.SQRT2 = 1.4142135623730951;
math.min = function(T) {
return (a, b) => {
- if (!(typeof a == 'number')) dart.throw(new core.ArgumentError(a));
- if (!(typeof b == 'number')) dart.throw(new core.ArgumentError(b));
- if (dart.notNull(a) > dart.notNull(b)) return b;
- if (dart.notNull(a) < dart.notNull(b)) return a;
- if (typeof b == 'number') {
- if (typeof a == 'number') {
- if (a == 0.0) {
- return (dart.notNull(a) + dart.notNull(b)) * dart.notNull(a) * dart.notNull(b);
- }
- }
- if (a == 0 && dart.test(b[dartx.isNegative]) || dart.test(b[dartx.isNaN])) return b;
- return a;
- }
- return a;
+ return Math.min(_js_helper.checkNum(a), _js_helper.checkNum(b));
};
};
dart.fn(math.min, TAndTToT());
math.max = function(T) {
return (a, b) => {
- if (!(typeof a == 'number')) dart.throw(new core.ArgumentError(a));
- if (!(typeof b == 'number')) dart.throw(new core.ArgumentError(b));
- if (dart.notNull(a) > dart.notNull(b)) return a;
- if (dart.notNull(a) < dart.notNull(b)) return b;
- if (typeof b == 'number') {
- if (typeof a == 'number') {
- if (a == 0.0) {
- return dart.notNull(a) + dart.notNull(b);
- }
- }
- if (dart.test(b[dartx.isNaN])) return b;
- return a;
- }
- if (b == 0 && dart.test(a[dartx.isNegative])) return b;
- return a;
+ return Math.max(_js_helper.checkNum(a), _js_helper.checkNum(b));
};
};
dart.fn(math.max, TAndTToT$());
@@ -37408,7 +37445,8 @@
}
['=='](other) {
if (!RectangleOfnum().is(other)) return false;
- return dart.equals(this[dartx.left], dart.dload(other, 'left')) && dart.equals(this[dartx.top], dart.dload(other, 'top')) && dart.equals(this[dartx.right], dart.dload(other, 'right')) && dart.equals(this[dartx.bottom], dart.dload(other, 'bottom'));
+ let otherRect = RectangleOfnum().as(other);
+ return this[dartx.left] == otherRect[dartx.left] && this[dartx.top] == otherRect[dartx.top] && this[dartx.right] == otherRect[dartx.right] && this[dartx.bottom] == otherRect[dartx.bottom];
}
get hashCode() {
return math._JenkinsSmiHash.hash4(dart.hashCode(this[dartx.left]), dart.hashCode(this[dartx.top]), dart.hashCode(this[dartx.right]), dart.hashCode(this[dartx.bottom]));
diff --git a/pkg/dev_compiler/lib/js/es6/dart_sdk.js b/pkg/dev_compiler/lib/js/es6/dart_sdk.js
index c99499b..5114d4a 100644
--- a/pkg/dev_compiler/lib/js/es6/dart_sdk.js
+++ b/pkg/dev_compiler/lib/js/es6/dart_sdk.js
@@ -46,12 +46,14 @@
let ListOfNameValuePair = () => (ListOfNameValuePair = dart.constFn(core.List$(_debugger.NameValuePair)))();
let JSArrayOfString = () => (JSArrayOfString = dart.constFn(_interceptors.JSArray$(core.String)))();
let JSArrayOfJsonMLFormatter = () => (JSArrayOfJsonMLFormatter = dart.constFn(_interceptors.JSArray$(_debugger.JsonMLFormatter)))();
+let JSIndexable = () => (JSIndexable = dart.constFn(_interceptors.JSIndexable$()))();
let JSArray = () => (JSArray = dart.constFn(_interceptors.JSArray$()))();
let JSMutableArray = () => (JSMutableArray = dart.constFn(_interceptors.JSMutableArray$()))();
let JSFixedArray = () => (JSFixedArray = dart.constFn(_interceptors.JSFixedArray$()))();
let JSExtendableArray = () => (JSExtendableArray = dart.constFn(_interceptors.JSExtendableArray$()))();
let JSUnmodifiableArray = () => (JSUnmodifiableArray = dart.constFn(_interceptors.JSUnmodifiableArray$()))();
let ArrayIterator = () => (ArrayIterator = dart.constFn(_interceptors.ArrayIterator$()))();
+let JSIndexableOfString = () => (JSIndexableOfString = dart.constFn(_interceptors.JSIndexable$(core.String)))();
let MatchToString = () => (MatchToString = dart.constFn(dart.functionType(core.String, [core.Match])))();
let StringToString = () => (StringToString = dart.constFn(dart.functionType(core.String, [core.String])))();
let ComparableOfnum = () => (ComparableOfnum = dart.constFn(core.Comparable$(core.num)))();
@@ -140,6 +142,7 @@
let ListOfClassMirror = () => (ListOfClassMirror = dart.constFn(core.List$(mirrors.ClassMirror)))();
let ListOfTypeVariableMirror = () => (ListOfTypeVariableMirror = dart.constFn(core.List$(mirrors.TypeVariableMirror)))();
let MapOfSymbol$MethodMirror = () => (MapOfSymbol$MethodMirror = dart.constFn(core.Map$(core.Symbol, mirrors.MethodMirror)))();
+let JSArrayOfType = () => (JSArrayOfType = dart.constFn(_interceptors.JSArray$(core.Type)))();
let ListOfParameterMirror = () => (ListOfParameterMirror = dart.constFn(core.List$(mirrors.ParameterMirror)))();
let ListOfFloat32x4 = () => (ListOfFloat32x4 = dart.constFn(core.List$(typed_data.Float32x4)))();
let ListOfInt32x4 = () => (ListOfInt32x4 = dart.constFn(core.List$(typed_data.Int32x4)))();
@@ -614,6 +617,7 @@
let dynamicToMap = () => (dynamicToMap = dart.constFn(dart.definiteFunctionType(core.Map, [dart.dynamic])))();
let TypeAndInvocationTodynamic = () => (TypeAndInvocationTodynamic = dart.constFn(dart.definiteFunctionType(dart.dynamic, [core.Type, core.Invocation])))();
let SymbolAnddynamicTovoid = () => (SymbolAnddynamicTovoid = dart.constFn(dart.definiteFunctionType(dart.void, [core.Symbol, dart.dynamic])))();
+let MapOfSymbol$dynamicTodynamic = () => (MapOfSymbol$dynamicTodynamic = dart.constFn(dart.definiteFunctionType(dart.dynamic, [MapOfSymbol$dynamic()])))();
let StringAnddynamicTovoid = () => (StringAnddynamicTovoid = dart.constFn(dart.definiteFunctionType(dart.void, [core.String, dart.dynamic])))();
let dynamicToTypeMirror = () => (dynamicToTypeMirror = dart.constFn(dart.definiteFunctionType(mirrors.TypeMirror, [dart.dynamic])))();
let dynamicAnddynamicAnddynamicTovoid = () => (dynamicAnddynamicAnddynamicTovoid = dart.constFn(dart.definiteFunctionType(dart.void, [dart.dynamic, dart.dynamic, dart.dynamic])))();
@@ -3553,8 +3557,12 @@
constructors: () => ({new: dart.definiteFunctionType(_interceptors.JSBool, [])})
});
dart.registerExtension(dart.global.Boolean, _interceptors.JSBool);
-_interceptors.JSIndexable = class JSIndexable extends core.Object {};
-_interceptors.JSMutableIndexable = class JSMutableIndexable extends _interceptors.JSIndexable {};
+_interceptors.JSIndexable$ = dart.generic(E => {
+ class JSIndexable extends core.Object {}
+ dart.addTypeTests(JSIndexable);
+ return JSIndexable;
+});
+_interceptors.JSIndexable = JSIndexable();
_interceptors.JSObject = class JSObject extends core.Object {};
_interceptors.JavaScriptObject = class JavaScriptObject extends _interceptors.Interceptor {
new() {
@@ -3617,6 +3625,7 @@
let SetOfE = () => (SetOfE = dart.constFn(core.Set$(E)))();
let ArrayIteratorOfE = () => (ArrayIteratorOfE = dart.constFn(_interceptors.ArrayIterator$(E)))();
let ListMapViewOfE = () => (ListMapViewOfE = dart.constFn(_internal.ListMapView$(E)))();
+ let JSIndexableOfE = () => (JSIndexableOfE = dart.constFn(_interceptors.JSIndexable$(E)))();
let ETobool = () => (ETobool = dart.constFn(dart.functionType(core.bool, [E])))();
let ETovoid = () => (ETovoid = dart.constFn(dart.functionType(dart.void, [E])))();
let EAndEToint = () => (EAndEToint = dart.constFn(dart.functionType(core.int, [E, E])))();
@@ -4174,7 +4183,7 @@
}
dart.setExtensionBaseClass(JSArray, dart.global.Array);
dart.addTypeTests(JSArray);
- JSArray[dart.implements] = () => [ListOfE(), _interceptors.JSIndexable];
+ JSArray[dart.implements] = () => [ListOfE(), JSIndexableOfE()];
dart.setSignature(JSArray, {
constructors: () => ({
new: dart.definiteFunctionType(_interceptors.JSArray$(E), []),
@@ -4259,7 +4268,6 @@
super.new();
}
}
- JSMutableArray[dart.implements] = () => [_interceptors.JSMutableIndexable];
return JSMutableArray;
});
_interceptors.JSMutableArray = JSMutableArray();
@@ -5335,7 +5343,7 @@
return this[index];
}
};
-_interceptors.JSString[dart.implements] = () => [core.String, _interceptors.JSIndexable];
+_interceptors.JSString[dart.implements] = () => [core.String, JSIndexableOfString()];
dart.setSignature(_interceptors.JSString, {
constructors: () => ({new: dart.definiteFunctionType(_interceptors.JSString, [])}),
getters: () => ({
@@ -11555,7 +11563,7 @@
constructors: () => ({new: dart.definiteFunctionType(_js_helper.JSName, [core.String])}),
fields: () => ({name: core.String})
});
-_js_helper.JavaScriptIndexingBehavior = class JavaScriptIndexingBehavior extends _interceptors.JSMutableIndexable {};
+_js_helper.JavaScriptIndexingBehavior = class JavaScriptIndexingBehavior extends core.Object {};
_js_helper.TypeErrorImplementation = class TypeErrorImplementation extends core.Error {
new(value, actualType, expectedType) {
this.message = dart.str`Type '${actualType}' is not a subtype ` + dart.str`of type '${expectedType}'`;
@@ -13081,58 +13089,66 @@
return _Lazy;
});
_js_mirrors._Lazy = _Lazy();
+_js_mirrors._getNameForESSymbol = function(member) {
+ let str = dart.toString(member);
+ dart.assert(dart.test(str[dartx.startsWith]('Symbol(')) && dart.test(str[dartx.endsWith](')')));
+ return str[dartx.substring](7, dart.notNull(str[dartx.length]) - 1);
+};
+dart.lazyFn(_js_mirrors._getNameForESSymbol, () => dynamicToString());
+_js_mirrors._toDartMap = function(data) {
+ if (data == null) return dart.map();
+ let map = _js_mirrors._dart.map(data);
+ let privateMembers = Object.getOwnPropertySymbols(data);
+ for (let member of core.Iterable._check(privateMembers)) {
+ let name = _js_mirrors._getNameForESSymbol(member);
+ map[dartx.set](name, data[member]);
+ }
+ return map;
+};
+dart.lazyFn(_js_mirrors._toDartMap, () => dynamicToMap());
_js_mirrors._getConstructors = function(obj) {
let sig = _js_mirrors._dart.getConstructorSig(obj);
- if (sig == null) return dart.map();
- return _js_mirrors._dart.map(sig);
+ return _js_mirrors._toDartMap(sig);
};
dart.lazyFn(_js_mirrors._getConstructors, () => dynamicToMap());
_js_mirrors._getFields = function(obj) {
let sig = _js_mirrors._dart.getFieldSig(obj);
- if (sig == null) return dart.map();
- return _js_mirrors._dart.map(sig);
+ return _js_mirrors._toDartMap(sig);
};
dart.lazyFn(_js_mirrors._getFields, () => dynamicToMap());
_js_mirrors._getMethods = function(obj) {
let sig = _js_mirrors._dart.getMethodSig(obj);
- if (sig == null) return dart.map();
- return _js_mirrors._dart.map(sig);
+ return _js_mirrors._toDartMap(sig);
};
dart.lazyFn(_js_mirrors._getMethods, () => dynamicToMap());
_js_mirrors._getGetters = function(obj) {
let sig = _js_mirrors._dart.getGetterSig(obj);
- if (sig == null) return dart.map();
- return _js_mirrors._dart.map(sig);
+ return _js_mirrors._toDartMap(sig);
};
dart.lazyFn(_js_mirrors._getGetters, () => dynamicToMap());
_js_mirrors._getSetters = function(obj) {
let sig = _js_mirrors._dart.getSetterSig(obj);
- if (sig == null) return dart.map();
- return _js_mirrors._dart.map(sig);
+ return _js_mirrors._toDartMap(sig);
};
dart.lazyFn(_js_mirrors._getSetters, () => dynamicToMap());
_js_mirrors._getStaticFields = function(obj) {
let sig = _js_mirrors._dart.getStaticFieldSig(obj);
- if (sig == null) return dart.map();
- return _js_mirrors._dart.map(sig);
+ return _js_mirrors._toDartMap(sig);
};
dart.lazyFn(_js_mirrors._getStaticFields, () => dynamicToMap());
_js_mirrors._getStatics = function(obj) {
let sig = _js_mirrors._dart.getStaticSig(obj);
- if (sig == null) return dart.map();
- return _js_mirrors._dart.map(sig);
+ return _js_mirrors._toDartMap(sig);
};
dart.lazyFn(_js_mirrors._getStatics, () => dynamicToMap());
_js_mirrors._getStaticGetters = function(obj) {
let sig = _js_mirrors._dart.getStaticGetterSig(obj);
- if (sig == null) return dart.map();
- return _js_mirrors._dart.map(sig);
+ return _js_mirrors._toDartMap(sig);
};
dart.lazyFn(_js_mirrors._getStaticGetters, () => dynamicToMap());
_js_mirrors._getStaticSetters = function(obj) {
let sig = _js_mirrors._dart.getStaticSetterSig(obj);
- if (sig == null) return dart.map();
- return _js_mirrors._dart.map(sig);
+ return _js_mirrors._toDartMap(sig);
};
dart.lazyFn(_js_mirrors._getStaticSetters, () => dynamicToMap());
_js_mirrors._unwrap = function(obj) {
@@ -13144,9 +13160,17 @@
};
dart.fn(_js_mirrors._wrap, dynamicTodynamic());
_js_mirrors._unimplemented = function(t, i) {
- dart.throw(new core.UnimplementedError(dart.str`${t}.${i.memberName} unimplemented`));
+ dart.throw(new core.UnimplementedError(dart.str`${t}.${_js_mirrors.getName(i.memberName)} unimplemented`));
};
dart.fn(_js_mirrors._unimplemented, TypeAndInvocationTodynamic());
+_js_mirrors._toJsMap = function(map) {
+ let obj = {};
+ map[dartx.forEach](dart.fn((key, value) => {
+ obj[_js_mirrors.getName(key)] = value;
+ }, SymbolAnddynamicTovoid()));
+ return obj;
+};
+dart.lazyFn(_js_mirrors._toJsMap, () => MapOfSymbol$dynamicTodynamic());
_js_mirrors.JsMirror = class JsMirror extends core.Object {
noSuchMethod(i) {
_js_mirrors._unimplemented(this.runtimeType, i);
@@ -13240,7 +13264,7 @@
}
};
_js_mirrors.JsObjectMirror[dart.implements] = () => [mirrors.ObjectMirror];
-const _toJsMap = Symbol('_toJsMap');
+const _getAccessor = Symbol('_getAccessor');
_js_mirrors.JsInstanceMirror = class JsInstanceMirror extends _js_mirrors.JsObjectMirror {
get hasReflectee() {
return true;
@@ -13258,32 +13282,41 @@
get hashCode() {
return (dart.notNull(core.identityHashCode(this.reflectee)) ^ 909522486) >>> 0;
}
- getField(symbol) {
+ [_getAccessor](reflectee, symbol, args, namedArgs) {
+ if (args === void 0) args = null;
+ if (namedArgs === void 0) namedArgs = null;
let name = _js_mirrors.getName(symbol);
- let field = _js_mirrors._dload(this.reflectee, name);
+ if (!dart.test(name[dartx.startsWith]('_'))) return name;
+ let privateMembers = Object.getOwnPropertySymbols(reflectee);
+ dart.dsend(privateMembers, 'addAll', Object.getOwnPropertySymbols(reflectee.__proto__));
+ for (let member of core.Iterable._check(privateMembers)) {
+ let privateName = _js_mirrors._getNameForESSymbol(member);
+ if (name == privateName) return member;
+ }
+ return new core.NoSuchMethodError(reflectee, symbol, args, namedArgs);
+ }
+ getField(symbol) {
+ let name = this[_getAccessor](this.reflectee, symbol);
+ let field = _js_mirrors._dload(this.reflectee, core.String._check(name));
return _js_mirrors.reflect(field);
}
setField(symbol, value) {
- let name = _js_mirrors.getName(symbol);
- _js_mirrors._dput(this.reflectee, name, value);
+ let name = this[_getAccessor](this.reflectee, symbol);
+ _js_mirrors._dput(this.reflectee, core.String._check(name), value);
return _js_mirrors.reflect(value);
}
invoke(symbol, args, namedArgs) {
if (namedArgs === void 0) namedArgs = null;
- let name = _js_mirrors.getName(symbol);
+ let name = this[_getAccessor](this.reflectee, symbol, args, namedArgs);
if (namedArgs != null) {
args = core.List.from(args);
- args[dartx.add](this[_toJsMap](namedArgs));
+ args[dartx.add](_js_mirrors._toJsMap(namedArgs));
}
- let result = _js_mirrors._dsend(this.reflectee, name, args);
+ let result = _js_mirrors._dsend(this.reflectee, core.String._check(name), args);
return _js_mirrors.reflect(result);
}
- [_toJsMap](map) {
- let obj = {};
- map[dartx.forEach](dart.fn((key, value) => {
- obj[_js_mirrors.getName(key)] = value;
- }, SymbolAnddynamicTovoid()));
- return obj;
+ toString() {
+ return dart.str`InstanceMirror on '${this.reflectee}'`;
}
delegate(...args) {
return this.noSuchMethod(new dart.InvocationImpl('delegate', args, {isMethod: true}));
@@ -13300,10 +13333,10 @@
}),
methods: () => ({
'==': dart.definiteFunctionType(core.bool, [core.Object]),
+ [_getAccessor]: dart.definiteFunctionType(dart.dynamic, [dart.dynamic, core.Symbol], [core.List, MapOfSymbol$dynamic()]),
getField: dart.definiteFunctionType(mirrors.InstanceMirror, [core.Symbol]),
setField: dart.definiteFunctionType(mirrors.InstanceMirror, [core.Symbol, core.Object]),
- invoke: dart.definiteFunctionType(mirrors.InstanceMirror, [core.Symbol, core.List], [MapOfSymbol$dynamic()]),
- [_toJsMap]: dart.definiteFunctionType(dart.dynamic, [MapOfSymbol$dynamic()])
+ invoke: dart.definiteFunctionType(mirrors.InstanceMirror, [core.Symbol, core.List], [MapOfSymbol$dynamic()])
})
});
_js_mirrors.JsClosureMirror = class JsClosureMirror extends _js_mirrors.JsInstanceMirror {
@@ -13314,7 +13347,7 @@
if (namedArgs === void 0) namedArgs = null;
if (namedArgs != null) {
args = core.List.from(args);
- args[dartx.add](this[_toJsMap](namedArgs));
+ args[dartx.add](_js_mirrors._toJsMap(namedArgs));
}
let result = _js_mirrors._dcall(this.reflectee, args);
return _js_mirrors.reflect(result);
@@ -13342,7 +13375,8 @@
_js_mirrors.JsClassMirror = class JsClassMirror extends _js_mirrors.JsMirror {
get metadata() {
if (this[_metadata] == null) {
- let fn = _js_mirrors._unwrap(this[_cls])[dart.metadata];
+ let unwrapped = _js_mirrors._unwrap(this[_cls]);
+ let fn = Object.hasOwnProperty.call(unwrapped, dart.metadata) ? unwrapped[dart.metadata] : null;
this[_metadata] = fn == null ? const || (const = dart.constList([], mirrors.InstanceMirror)) : ListOfInstanceMirror().unmodifiable(core.Iterable._check(dart.dsend(dart.dcall(fn), 'map', dart.fn(i => _js_mirrors.reflect(i), dynamicToInstanceMirror()))));
}
return this[_metadata];
@@ -13439,6 +13473,25 @@
let instance = name == 'new' || name == '' ? new (_js_mirrors._unwrap(this[_cls]))(...args) : new (_js_mirrors._unwrap(this[_cls]))[name](...args);
return _js_mirrors.reflect(instance);
}
+ getField(symbol) {
+ let name = _js_mirrors.getName(symbol);
+ return _js_mirrors.reflect(_js_mirrors._unwrap(this[_cls])[name]);
+ }
+ setField(symbol, value) {
+ let name = _js_mirrors.getName(symbol);
+ _js_mirrors._unwrap(this[_cls])[name] = value;
+ return _js_mirrors.reflect(value);
+ }
+ invoke(symbol, args, namedArgs) {
+ if (namedArgs === void 0) namedArgs = null;
+ let name = _js_mirrors.getName(symbol);
+ if (namedArgs != null) {
+ args = core.List.from(args);
+ args[dartx.add](_js_mirrors._toJsMap(namedArgs));
+ }
+ let result = _js_mirrors._unwrap(this[_cls])[name](...args);
+ return _js_mirrors.reflect(result);
+ }
get superinterfaces() {
let interfaceThunk = _js_mirrors._unwrap(this[_cls])[dart.implements];
if (interfaceThunk == null) {
@@ -13473,6 +13526,9 @@
return mirrors.ClassMirror._check(_js_mirrors.reflectType(core.Type._check(_js_mirrors._wrap(_js_mirrors._unwrap(this[_cls]).__proto__))));
}
}
+ toString() {
+ return dart.str`ClassMirror on '${this[_cls]}'`;
+ }
get qualifiedName() {
return core.Symbol._check(this.noSuchMethod(new dart.InvocationImpl('qualifiedName', [], {isGetter: true})));
}
@@ -13497,15 +13553,6 @@
get typeVariables() {
return ListOfTypeVariableMirror()._check(this.noSuchMethod(new dart.InvocationImpl('typeVariables', [], {isGetter: true})));
}
- invoke(...args) {
- return mirrors.InstanceMirror._check(this.noSuchMethod(new dart.InvocationImpl('invoke', args, {isMethod: true})));
- }
- getField(...args) {
- return mirrors.InstanceMirror._check(this.noSuchMethod(new dart.InvocationImpl('getField', args, {isMethod: true})));
- }
- setField(...args) {
- return mirrors.InstanceMirror._check(this.noSuchMethod(new dart.InvocationImpl('setField', args, {isMethod: true})));
- }
isSubclassOf(...args) {
return core.bool._check(this.noSuchMethod(new dart.InvocationImpl('isSubclassOf', args, {isMethod: true})));
}
@@ -13543,7 +13590,12 @@
originalDeclaration: dart.definiteFunctionType(mirrors.TypeMirror, []),
superclass: dart.definiteFunctionType(mirrors.ClassMirror, [])
}),
- methods: () => ({newInstance: dart.definiteFunctionType(mirrors.InstanceMirror, [core.Symbol, core.List], [MapOfSymbol$dynamic()])})
+ methods: () => ({
+ newInstance: dart.definiteFunctionType(mirrors.InstanceMirror, [core.Symbol, core.List], [MapOfSymbol$dynamic()]),
+ getField: dart.definiteFunctionType(mirrors.InstanceMirror, [core.Symbol]),
+ setField: dart.definiteFunctionType(mirrors.InstanceMirror, [core.Symbol, core.Object]),
+ invoke: dart.definiteFunctionType(mirrors.InstanceMirror, [core.Symbol, core.List], [MapOfSymbol$dynamic()])
+ })
});
const _name = Symbol('_name');
_js_mirrors.JsVariableMirror = class JsVariableMirror extends _js_mirrors.JsMirror {
@@ -13557,6 +13609,9 @@
this.isStatic = false;
this.isFinal = false;
}
+ toString() {
+ return dart.str`VariableMirror on '${this[_name]}'`;
+ }
get qualifiedName() {
return core.Symbol._check(this.noSuchMethod(new dart.InvocationImpl('qualifiedName', [], {isGetter: true})));
}
@@ -13593,6 +13648,9 @@
_(name, t, annotations) {
super._(name, t, annotations);
}
+ toString() {
+ return dart.str`ParameterMirror on '${this[_name]}'`;
+ }
get qualifiedName() {
return core.Symbol._check(this.noSuchMethod(new dart.InvocationImpl('qualifiedName', [], {isGetter: true})));
}
@@ -13686,12 +13744,15 @@
this[_metadata] = const || (const = dart.constList([], mirrors.InstanceMirror));
return;
}
- if (core.List.is(ftype)) {
+ if (!core.Function.is(ftype) && core.List.is(ftype)) {
this[_metadata] = ListOfInstanceMirror().unmodifiable(core.Iterable._check(dart.dsend(dart.dsend(ftype, 'skip', 1), 'map', dart.fn(a => _js_mirrors.reflect(a), dynamicToInstanceMirror()))));
ftype = dart.dindex(ftype, 0);
} else {
this[_metadata] = const || (const = dart.constList([], mirrors.InstanceMirror));
}
+ if (typeof ftype == "function") {
+ ftype = ftype.apply(null, JSArrayOfType().of([dart.dynamic, dart.dynamic, dart.dynamic]));
+ }
let args = core.List._check(dart.dload(ftype, 'args'));
let opts = core.List._check(dart.dload(ftype, 'optionals'));
let params = ListOfParameterMirror().new(dart.notNull(args[dartx.length]) + dart.notNull(opts[dartx.length]));
@@ -13709,6 +13770,9 @@
}
this[_params] = ListOfParameterMirror().unmodifiable(params);
}
+ toString() {
+ return dart.str`MethodMirror on '${this[_name]}'`;
+ }
get qualifiedName() {
return core.Symbol._check(this.noSuchMethod(new dart.InvocationImpl('qualifiedName', [], {isGetter: true})));
}
@@ -36956,40 +37020,13 @@
math.SQRT2 = 1.4142135623730951;
math.min = function(T) {
return (a, b) => {
- if (!(typeof a == 'number')) dart.throw(new core.ArgumentError(a));
- if (!(typeof b == 'number')) dart.throw(new core.ArgumentError(b));
- if (dart.notNull(a) > dart.notNull(b)) return b;
- if (dart.notNull(a) < dart.notNull(b)) return a;
- if (typeof b == 'number') {
- if (typeof a == 'number') {
- if (a == 0.0) {
- return (dart.notNull(a) + dart.notNull(b)) * dart.notNull(a) * dart.notNull(b);
- }
- }
- if (a == 0 && dart.test(b[dartx.isNegative]) || dart.test(b[dartx.isNaN])) return b;
- return a;
- }
- return a;
+ return Math.min(_js_helper.checkNum(a), _js_helper.checkNum(b));
};
};
dart.fn(math.min, TAndTToT());
math.max = function(T) {
return (a, b) => {
- if (!(typeof a == 'number')) dart.throw(new core.ArgumentError(a));
- if (!(typeof b == 'number')) dart.throw(new core.ArgumentError(b));
- if (dart.notNull(a) > dart.notNull(b)) return a;
- if (dart.notNull(a) < dart.notNull(b)) return b;
- if (typeof b == 'number') {
- if (typeof a == 'number') {
- if (a == 0.0) {
- return dart.notNull(a) + dart.notNull(b);
- }
- }
- if (dart.test(b[dartx.isNaN])) return b;
- return a;
- }
- if (b == 0 && dart.test(a[dartx.isNegative])) return b;
- return a;
+ return Math.max(_js_helper.checkNum(a), _js_helper.checkNum(b));
};
};
dart.fn(math.max, TAndTToT());
@@ -37406,7 +37443,8 @@
}
['=='](other) {
if (!RectangleOfnum().is(other)) return false;
- return dart.equals(this[dartx.left], dart.dload(other, 'left')) && dart.equals(this[dartx.top], dart.dload(other, 'top')) && dart.equals(this[dartx.right], dart.dload(other, 'right')) && dart.equals(this[dartx.bottom], dart.dload(other, 'bottom'));
+ let otherRect = RectangleOfnum().as(other);
+ return this[dartx.left] == otherRect[dartx.left] && this[dartx.top] == otherRect[dartx.top] && this[dartx.right] == otherRect[dartx.right] && this[dartx.bottom] == otherRect[dartx.bottom];
}
get hashCode() {
return math._JenkinsSmiHash.hash4(dart.hashCode(this[dartx.left]), dart.hashCode(this[dartx.top]), dart.hashCode(this[dartx.right]), dart.hashCode(this[dartx.bottom]));
diff --git a/pkg/dev_compiler/lib/js/legacy/dart_sdk.js b/pkg/dev_compiler/lib/js/legacy/dart_sdk.js
index 4c981ff..283ffe5 100644
--- a/pkg/dev_compiler/lib/js/legacy/dart_sdk.js
+++ b/pkg/dev_compiler/lib/js/legacy/dart_sdk.js
@@ -49,12 +49,14 @@
let ListOfNameValuePair = () => (ListOfNameValuePair = dart.constFn(core.List$(_debugger.NameValuePair)))();
let JSArrayOfString = () => (JSArrayOfString = dart.constFn(_interceptors.JSArray$(core.String)))();
let JSArrayOfJsonMLFormatter = () => (JSArrayOfJsonMLFormatter = dart.constFn(_interceptors.JSArray$(_debugger.JsonMLFormatter)))();
+ let JSIndexable = () => (JSIndexable = dart.constFn(_interceptors.JSIndexable$()))();
let JSArray = () => (JSArray = dart.constFn(_interceptors.JSArray$()))();
let JSMutableArray = () => (JSMutableArray = dart.constFn(_interceptors.JSMutableArray$()))();
let JSFixedArray = () => (JSFixedArray = dart.constFn(_interceptors.JSFixedArray$()))();
let JSExtendableArray = () => (JSExtendableArray = dart.constFn(_interceptors.JSExtendableArray$()))();
let JSUnmodifiableArray = () => (JSUnmodifiableArray = dart.constFn(_interceptors.JSUnmodifiableArray$()))();
let ArrayIterator = () => (ArrayIterator = dart.constFn(_interceptors.ArrayIterator$()))();
+ let JSIndexableOfString = () => (JSIndexableOfString = dart.constFn(_interceptors.JSIndexable$(core.String)))();
let MatchToString = () => (MatchToString = dart.constFn(dart.functionType(core.String, [core.Match])))();
let StringToString = () => (StringToString = dart.constFn(dart.functionType(core.String, [core.String])))();
let ComparableOfnum = () => (ComparableOfnum = dart.constFn(core.Comparable$(core.num)))();
@@ -143,6 +145,7 @@
let ListOfClassMirror = () => (ListOfClassMirror = dart.constFn(core.List$(mirrors.ClassMirror)))();
let ListOfTypeVariableMirror = () => (ListOfTypeVariableMirror = dart.constFn(core.List$(mirrors.TypeVariableMirror)))();
let MapOfSymbol$MethodMirror = () => (MapOfSymbol$MethodMirror = dart.constFn(core.Map$(core.Symbol, mirrors.MethodMirror)))();
+ let JSArrayOfType = () => (JSArrayOfType = dart.constFn(_interceptors.JSArray$(core.Type)))();
let ListOfParameterMirror = () => (ListOfParameterMirror = dart.constFn(core.List$(mirrors.ParameterMirror)))();
let ListOfFloat32x4 = () => (ListOfFloat32x4 = dart.constFn(core.List$(typed_data.Float32x4)))();
let ListOfInt32x4 = () => (ListOfInt32x4 = dart.constFn(core.List$(typed_data.Int32x4)))();
@@ -617,6 +620,7 @@
let dynamicToMap = () => (dynamicToMap = dart.constFn(dart.definiteFunctionType(core.Map, [dart.dynamic])))();
let TypeAndInvocationTodynamic = () => (TypeAndInvocationTodynamic = dart.constFn(dart.definiteFunctionType(dart.dynamic, [core.Type, core.Invocation])))();
let SymbolAnddynamicTovoid = () => (SymbolAnddynamicTovoid = dart.constFn(dart.definiteFunctionType(dart.void, [core.Symbol, dart.dynamic])))();
+ let MapOfSymbol$dynamicTodynamic = () => (MapOfSymbol$dynamicTodynamic = dart.constFn(dart.definiteFunctionType(dart.dynamic, [MapOfSymbol$dynamic()])))();
let StringAnddynamicTovoid = () => (StringAnddynamicTovoid = dart.constFn(dart.definiteFunctionType(dart.void, [core.String, dart.dynamic])))();
let dynamicToTypeMirror = () => (dynamicToTypeMirror = dart.constFn(dart.definiteFunctionType(mirrors.TypeMirror, [dart.dynamic])))();
let dynamicAnddynamicAnddynamicTovoid = () => (dynamicAnddynamicAnddynamicTovoid = dart.constFn(dart.definiteFunctionType(dart.void, [dart.dynamic, dart.dynamic, dart.dynamic])))();
@@ -3556,8 +3560,12 @@
constructors: () => ({new: dart.definiteFunctionType(_interceptors.JSBool, [])})
});
dart.registerExtension(dart.global.Boolean, _interceptors.JSBool);
- _interceptors.JSIndexable = class JSIndexable extends core.Object {};
- _interceptors.JSMutableIndexable = class JSMutableIndexable extends _interceptors.JSIndexable {};
+ _interceptors.JSIndexable$ = dart.generic(E => {
+ class JSIndexable extends core.Object {}
+ dart.addTypeTests(JSIndexable);
+ return JSIndexable;
+ });
+ _interceptors.JSIndexable = JSIndexable();
_interceptors.JSObject = class JSObject extends core.Object {};
_interceptors.JavaScriptObject = class JavaScriptObject extends _interceptors.Interceptor {
new() {
@@ -3620,6 +3628,7 @@
let SetOfE = () => (SetOfE = dart.constFn(core.Set$(E)))();
let ArrayIteratorOfE = () => (ArrayIteratorOfE = dart.constFn(_interceptors.ArrayIterator$(E)))();
let ListMapViewOfE = () => (ListMapViewOfE = dart.constFn(_internal.ListMapView$(E)))();
+ let JSIndexableOfE = () => (JSIndexableOfE = dart.constFn(_interceptors.JSIndexable$(E)))();
let ETobool = () => (ETobool = dart.constFn(dart.functionType(core.bool, [E])))();
let ETovoid = () => (ETovoid = dart.constFn(dart.functionType(dart.void, [E])))();
let EAndEToint = () => (EAndEToint = dart.constFn(dart.functionType(core.int, [E, E])))();
@@ -4177,7 +4186,7 @@
}
dart.setExtensionBaseClass(JSArray, dart.global.Array);
dart.addTypeTests(JSArray);
- JSArray[dart.implements] = () => [ListOfE(), _interceptors.JSIndexable];
+ JSArray[dart.implements] = () => [ListOfE(), JSIndexableOfE()];
dart.setSignature(JSArray, {
constructors: () => ({
new: dart.definiteFunctionType(_interceptors.JSArray$(E), []),
@@ -4262,7 +4271,6 @@
super.new();
}
}
- JSMutableArray[dart.implements] = () => [_interceptors.JSMutableIndexable];
return JSMutableArray;
});
_interceptors.JSMutableArray = JSMutableArray();
@@ -5338,7 +5346,7 @@
return this[index];
}
};
- _interceptors.JSString[dart.implements] = () => [core.String, _interceptors.JSIndexable];
+ _interceptors.JSString[dart.implements] = () => [core.String, JSIndexableOfString()];
dart.setSignature(_interceptors.JSString, {
constructors: () => ({new: dart.definiteFunctionType(_interceptors.JSString, [])}),
getters: () => ({
@@ -11558,7 +11566,7 @@
constructors: () => ({new: dart.definiteFunctionType(_js_helper.JSName, [core.String])}),
fields: () => ({name: core.String})
});
- _js_helper.JavaScriptIndexingBehavior = class JavaScriptIndexingBehavior extends _interceptors.JSMutableIndexable {};
+ _js_helper.JavaScriptIndexingBehavior = class JavaScriptIndexingBehavior extends core.Object {};
_js_helper.TypeErrorImplementation = class TypeErrorImplementation extends core.Error {
new(value, actualType, expectedType) {
this.message = dart.str`Type '${actualType}' is not a subtype ` + dart.str`of type '${expectedType}'`;
@@ -13084,58 +13092,66 @@
return _Lazy;
});
_js_mirrors._Lazy = _Lazy();
+ _js_mirrors._getNameForESSymbol = function(member) {
+ let str = dart.toString(member);
+ dart.assert(dart.test(str[dartx.startsWith]('Symbol(')) && dart.test(str[dartx.endsWith](')')));
+ return str[dartx.substring](7, dart.notNull(str[dartx.length]) - 1);
+ };
+ dart.lazyFn(_js_mirrors._getNameForESSymbol, () => dynamicToString());
+ _js_mirrors._toDartMap = function(data) {
+ if (data == null) return dart.map();
+ let map = _js_mirrors._dart.map(data);
+ let privateMembers = Object.getOwnPropertySymbols(data);
+ for (let member of core.Iterable._check(privateMembers)) {
+ let name = _js_mirrors._getNameForESSymbol(member);
+ map[dartx.set](name, data[member]);
+ }
+ return map;
+ };
+ dart.lazyFn(_js_mirrors._toDartMap, () => dynamicToMap());
_js_mirrors._getConstructors = function(obj) {
let sig = _js_mirrors._dart.getConstructorSig(obj);
- if (sig == null) return dart.map();
- return _js_mirrors._dart.map(sig);
+ return _js_mirrors._toDartMap(sig);
};
dart.lazyFn(_js_mirrors._getConstructors, () => dynamicToMap());
_js_mirrors._getFields = function(obj) {
let sig = _js_mirrors._dart.getFieldSig(obj);
- if (sig == null) return dart.map();
- return _js_mirrors._dart.map(sig);
+ return _js_mirrors._toDartMap(sig);
};
dart.lazyFn(_js_mirrors._getFields, () => dynamicToMap());
_js_mirrors._getMethods = function(obj) {
let sig = _js_mirrors._dart.getMethodSig(obj);
- if (sig == null) return dart.map();
- return _js_mirrors._dart.map(sig);
+ return _js_mirrors._toDartMap(sig);
};
dart.lazyFn(_js_mirrors._getMethods, () => dynamicToMap());
_js_mirrors._getGetters = function(obj) {
let sig = _js_mirrors._dart.getGetterSig(obj);
- if (sig == null) return dart.map();
- return _js_mirrors._dart.map(sig);
+ return _js_mirrors._toDartMap(sig);
};
dart.lazyFn(_js_mirrors._getGetters, () => dynamicToMap());
_js_mirrors._getSetters = function(obj) {
let sig = _js_mirrors._dart.getSetterSig(obj);
- if (sig == null) return dart.map();
- return _js_mirrors._dart.map(sig);
+ return _js_mirrors._toDartMap(sig);
};
dart.lazyFn(_js_mirrors._getSetters, () => dynamicToMap());
_js_mirrors._getStaticFields = function(obj) {
let sig = _js_mirrors._dart.getStaticFieldSig(obj);
- if (sig == null) return dart.map();
- return _js_mirrors._dart.map(sig);
+ return _js_mirrors._toDartMap(sig);
};
dart.lazyFn(_js_mirrors._getStaticFields, () => dynamicToMap());
_js_mirrors._getStatics = function(obj) {
let sig = _js_mirrors._dart.getStaticSig(obj);
- if (sig == null) return dart.map();
- return _js_mirrors._dart.map(sig);
+ return _js_mirrors._toDartMap(sig);
};
dart.lazyFn(_js_mirrors._getStatics, () => dynamicToMap());
_js_mirrors._getStaticGetters = function(obj) {
let sig = _js_mirrors._dart.getStaticGetterSig(obj);
- if (sig == null) return dart.map();
- return _js_mirrors._dart.map(sig);
+ return _js_mirrors._toDartMap(sig);
};
dart.lazyFn(_js_mirrors._getStaticGetters, () => dynamicToMap());
_js_mirrors._getStaticSetters = function(obj) {
let sig = _js_mirrors._dart.getStaticSetterSig(obj);
- if (sig == null) return dart.map();
- return _js_mirrors._dart.map(sig);
+ return _js_mirrors._toDartMap(sig);
};
dart.lazyFn(_js_mirrors._getStaticSetters, () => dynamicToMap());
_js_mirrors._unwrap = function(obj) {
@@ -13147,9 +13163,17 @@
};
dart.fn(_js_mirrors._wrap, dynamicTodynamic$());
_js_mirrors._unimplemented = function(t, i) {
- dart.throw(new core.UnimplementedError(dart.str`${t}.${i.memberName} unimplemented`));
+ dart.throw(new core.UnimplementedError(dart.str`${t}.${_js_mirrors.getName(i.memberName)} unimplemented`));
};
dart.fn(_js_mirrors._unimplemented, TypeAndInvocationTodynamic());
+ _js_mirrors._toJsMap = function(map) {
+ let obj = {};
+ map[dartx.forEach](dart.fn((key, value) => {
+ obj[_js_mirrors.getName(key)] = value;
+ }, SymbolAnddynamicTovoid()));
+ return obj;
+ };
+ dart.lazyFn(_js_mirrors._toJsMap, () => MapOfSymbol$dynamicTodynamic());
_js_mirrors.JsMirror = class JsMirror extends core.Object {
noSuchMethod(i) {
_js_mirrors._unimplemented(this.runtimeType, i);
@@ -13243,7 +13267,7 @@
}
};
_js_mirrors.JsObjectMirror[dart.implements] = () => [mirrors.ObjectMirror];
- const _toJsMap = Symbol('_toJsMap');
+ const _getAccessor = Symbol('_getAccessor');
_js_mirrors.JsInstanceMirror = class JsInstanceMirror extends _js_mirrors.JsObjectMirror {
get hasReflectee() {
return true;
@@ -13261,32 +13285,41 @@
get hashCode() {
return (dart.notNull(core.identityHashCode(this.reflectee)) ^ 909522486) >>> 0;
}
- getField(symbol) {
+ [_getAccessor](reflectee, symbol, args, namedArgs) {
+ if (args === void 0) args = null;
+ if (namedArgs === void 0) namedArgs = null;
let name = _js_mirrors.getName(symbol);
- let field = _js_mirrors._dload(this.reflectee, name);
+ if (!dart.test(name[dartx.startsWith]('_'))) return name;
+ let privateMembers = Object.getOwnPropertySymbols(reflectee);
+ dart.dsend(privateMembers, 'addAll', Object.getOwnPropertySymbols(reflectee.__proto__));
+ for (let member of core.Iterable._check(privateMembers)) {
+ let privateName = _js_mirrors._getNameForESSymbol(member);
+ if (name == privateName) return member;
+ }
+ return new core.NoSuchMethodError(reflectee, symbol, args, namedArgs);
+ }
+ getField(symbol) {
+ let name = this[_getAccessor](this.reflectee, symbol);
+ let field = _js_mirrors._dload(this.reflectee, core.String._check(name));
return _js_mirrors.reflect(field);
}
setField(symbol, value) {
- let name = _js_mirrors.getName(symbol);
- _js_mirrors._dput(this.reflectee, name, value);
+ let name = this[_getAccessor](this.reflectee, symbol);
+ _js_mirrors._dput(this.reflectee, core.String._check(name), value);
return _js_mirrors.reflect(value);
}
invoke(symbol, args, namedArgs) {
if (namedArgs === void 0) namedArgs = null;
- let name = _js_mirrors.getName(symbol);
+ let name = this[_getAccessor](this.reflectee, symbol, args, namedArgs);
if (namedArgs != null) {
args = core.List.from(args);
- args[dartx.add](this[_toJsMap](namedArgs));
+ args[dartx.add](_js_mirrors._toJsMap(namedArgs));
}
- let result = _js_mirrors._dsend(this.reflectee, name, args);
+ let result = _js_mirrors._dsend(this.reflectee, core.String._check(name), args);
return _js_mirrors.reflect(result);
}
- [_toJsMap](map) {
- let obj = {};
- map[dartx.forEach](dart.fn((key, value) => {
- obj[_js_mirrors.getName(key)] = value;
- }, SymbolAnddynamicTovoid()));
- return obj;
+ toString() {
+ return dart.str`InstanceMirror on '${this.reflectee}'`;
}
delegate(...args) {
return this.noSuchMethod(new dart.InvocationImpl('delegate', args, {isMethod: true}));
@@ -13303,10 +13336,10 @@
}),
methods: () => ({
'==': dart.definiteFunctionType(core.bool, [core.Object]),
+ [_getAccessor]: dart.definiteFunctionType(dart.dynamic, [dart.dynamic, core.Symbol], [core.List, MapOfSymbol$dynamic()]),
getField: dart.definiteFunctionType(mirrors.InstanceMirror, [core.Symbol]),
setField: dart.definiteFunctionType(mirrors.InstanceMirror, [core.Symbol, core.Object]),
- invoke: dart.definiteFunctionType(mirrors.InstanceMirror, [core.Symbol, core.List], [MapOfSymbol$dynamic()]),
- [_toJsMap]: dart.definiteFunctionType(dart.dynamic, [MapOfSymbol$dynamic()])
+ invoke: dart.definiteFunctionType(mirrors.InstanceMirror, [core.Symbol, core.List], [MapOfSymbol$dynamic()])
})
});
_js_mirrors.JsClosureMirror = class JsClosureMirror extends _js_mirrors.JsInstanceMirror {
@@ -13317,7 +13350,7 @@
if (namedArgs === void 0) namedArgs = null;
if (namedArgs != null) {
args = core.List.from(args);
- args[dartx.add](this[_toJsMap](namedArgs));
+ args[dartx.add](_js_mirrors._toJsMap(namedArgs));
}
let result = _js_mirrors._dcall(this.reflectee, args);
return _js_mirrors.reflect(result);
@@ -13345,7 +13378,8 @@
_js_mirrors.JsClassMirror = class JsClassMirror extends _js_mirrors.JsMirror {
get metadata() {
if (this[_metadata$] == null) {
- let fn = _js_mirrors._unwrap(this[_cls])[dart.metadata];
+ let unwrapped = _js_mirrors._unwrap(this[_cls]);
+ let fn = Object.hasOwnProperty.call(unwrapped, dart.metadata) ? unwrapped[dart.metadata] : null;
this[_metadata$] = fn == null ? const$0 || (const$0 = dart.constList([], mirrors.InstanceMirror)) : ListOfInstanceMirror().unmodifiable(core.Iterable._check(dart.dsend(dart.dcall(fn), 'map', dart.fn(i => _js_mirrors.reflect(i), dynamicToInstanceMirror()))));
}
return this[_metadata$];
@@ -13442,6 +13476,25 @@
let instance = name == 'new' || name == '' ? new (_js_mirrors._unwrap(this[_cls]))(...args) : new (_js_mirrors._unwrap(this[_cls]))[name](...args);
return _js_mirrors.reflect(instance);
}
+ getField(symbol) {
+ let name = _js_mirrors.getName(symbol);
+ return _js_mirrors.reflect(_js_mirrors._unwrap(this[_cls])[name]);
+ }
+ setField(symbol, value) {
+ let name = _js_mirrors.getName(symbol);
+ _js_mirrors._unwrap(this[_cls])[name] = value;
+ return _js_mirrors.reflect(value);
+ }
+ invoke(symbol, args, namedArgs) {
+ if (namedArgs === void 0) namedArgs = null;
+ let name = _js_mirrors.getName(symbol);
+ if (namedArgs != null) {
+ args = core.List.from(args);
+ args[dartx.add](_js_mirrors._toJsMap(namedArgs));
+ }
+ let result = _js_mirrors._unwrap(this[_cls])[name](...args);
+ return _js_mirrors.reflect(result);
+ }
get superinterfaces() {
let interfaceThunk = _js_mirrors._unwrap(this[_cls])[dart.implements];
if (interfaceThunk == null) {
@@ -13476,6 +13529,9 @@
return mirrors.ClassMirror._check(_js_mirrors.reflectType(core.Type._check(_js_mirrors._wrap(_js_mirrors._unwrap(this[_cls]).__proto__))));
}
}
+ toString() {
+ return dart.str`ClassMirror on '${this[_cls]}'`;
+ }
get qualifiedName() {
return core.Symbol._check(this.noSuchMethod(new dart.InvocationImpl('qualifiedName', [], {isGetter: true})));
}
@@ -13500,15 +13556,6 @@
get typeVariables() {
return ListOfTypeVariableMirror()._check(this.noSuchMethod(new dart.InvocationImpl('typeVariables', [], {isGetter: true})));
}
- invoke(...args) {
- return mirrors.InstanceMirror._check(this.noSuchMethod(new dart.InvocationImpl('invoke', args, {isMethod: true})));
- }
- getField(...args) {
- return mirrors.InstanceMirror._check(this.noSuchMethod(new dart.InvocationImpl('getField', args, {isMethod: true})));
- }
- setField(...args) {
- return mirrors.InstanceMirror._check(this.noSuchMethod(new dart.InvocationImpl('setField', args, {isMethod: true})));
- }
isSubclassOf(...args) {
return core.bool._check(this.noSuchMethod(new dart.InvocationImpl('isSubclassOf', args, {isMethod: true})));
}
@@ -13546,7 +13593,12 @@
originalDeclaration: dart.definiteFunctionType(mirrors.TypeMirror, []),
superclass: dart.definiteFunctionType(mirrors.ClassMirror, [])
}),
- methods: () => ({newInstance: dart.definiteFunctionType(mirrors.InstanceMirror, [core.Symbol, core.List], [MapOfSymbol$dynamic()])})
+ methods: () => ({
+ newInstance: dart.definiteFunctionType(mirrors.InstanceMirror, [core.Symbol, core.List], [MapOfSymbol$dynamic()]),
+ getField: dart.definiteFunctionType(mirrors.InstanceMirror, [core.Symbol]),
+ setField: dart.definiteFunctionType(mirrors.InstanceMirror, [core.Symbol, core.Object]),
+ invoke: dart.definiteFunctionType(mirrors.InstanceMirror, [core.Symbol, core.List], [MapOfSymbol$dynamic()])
+ })
});
const _name$ = Symbol('_name');
_js_mirrors.JsVariableMirror = class JsVariableMirror extends _js_mirrors.JsMirror {
@@ -13560,6 +13612,9 @@
this.isStatic = false;
this.isFinal = false;
}
+ toString() {
+ return dart.str`VariableMirror on '${this[_name$]}'`;
+ }
get qualifiedName() {
return core.Symbol._check(this.noSuchMethod(new dart.InvocationImpl('qualifiedName', [], {isGetter: true})));
}
@@ -13596,6 +13651,9 @@
_(name, t, annotations) {
super._(name, t, annotations);
}
+ toString() {
+ return dart.str`ParameterMirror on '${this[_name$]}'`;
+ }
get qualifiedName() {
return core.Symbol._check(this.noSuchMethod(new dart.InvocationImpl('qualifiedName', [], {isGetter: true})));
}
@@ -13689,12 +13747,15 @@
this[_metadata$] = const$3 || (const$3 = dart.constList([], mirrors.InstanceMirror));
return;
}
- if (core.List.is(ftype)) {
+ if (!core.Function.is(ftype) && core.List.is(ftype)) {
this[_metadata$] = ListOfInstanceMirror().unmodifiable(core.Iterable._check(dart.dsend(dart.dsend(ftype, 'skip', 1), 'map', dart.fn(a => _js_mirrors.reflect(a), dynamicToInstanceMirror()))));
ftype = dart.dindex(ftype, 0);
} else {
this[_metadata$] = const$4 || (const$4 = dart.constList([], mirrors.InstanceMirror));
}
+ if (typeof ftype == "function") {
+ ftype = ftype.apply(null, JSArrayOfType().of([dart.dynamic, dart.dynamic, dart.dynamic]));
+ }
let args = core.List._check(dart.dload(ftype, 'args'));
let opts = core.List._check(dart.dload(ftype, 'optionals'));
let params = ListOfParameterMirror().new(dart.notNull(args[dartx.length]) + dart.notNull(opts[dartx.length]));
@@ -13712,6 +13773,9 @@
}
this[_params] = ListOfParameterMirror().unmodifiable(params);
}
+ toString() {
+ return dart.str`MethodMirror on '${this[_name$]}'`;
+ }
get qualifiedName() {
return core.Symbol._check(this.noSuchMethod(new dart.InvocationImpl('qualifiedName', [], {isGetter: true})));
}
@@ -36959,40 +37023,13 @@
math.SQRT2 = 1.4142135623730951;
math.min = function(T) {
return (a, b) => {
- if (!(typeof a == 'number')) dart.throw(new core.ArgumentError(a));
- if (!(typeof b == 'number')) dart.throw(new core.ArgumentError(b));
- if (dart.notNull(a) > dart.notNull(b)) return b;
- if (dart.notNull(a) < dart.notNull(b)) return a;
- if (typeof b == 'number') {
- if (typeof a == 'number') {
- if (a == 0.0) {
- return (dart.notNull(a) + dart.notNull(b)) * dart.notNull(a) * dart.notNull(b);
- }
- }
- if (a == 0 && dart.test(b[dartx.isNegative]) || dart.test(b[dartx.isNaN])) return b;
- return a;
- }
- return a;
+ return Math.min(_js_helper.checkNum(a), _js_helper.checkNum(b));
};
};
dart.fn(math.min, TAndTToT());
math.max = function(T) {
return (a, b) => {
- if (!(typeof a == 'number')) dart.throw(new core.ArgumentError(a));
- if (!(typeof b == 'number')) dart.throw(new core.ArgumentError(b));
- if (dart.notNull(a) > dart.notNull(b)) return a;
- if (dart.notNull(a) < dart.notNull(b)) return b;
- if (typeof b == 'number') {
- if (typeof a == 'number') {
- if (a == 0.0) {
- return dart.notNull(a) + dart.notNull(b);
- }
- }
- if (dart.test(b[dartx.isNaN])) return b;
- return a;
- }
- if (b == 0 && dart.test(a[dartx.isNegative])) return b;
- return a;
+ return Math.max(_js_helper.checkNum(a), _js_helper.checkNum(b));
};
};
dart.fn(math.max, TAndTToT$());
@@ -37409,7 +37446,8 @@
}
['=='](other) {
if (!RectangleOfnum().is(other)) return false;
- return dart.equals(this[dartx.left], dart.dload(other, 'left')) && dart.equals(this[dartx.top], dart.dload(other, 'top')) && dart.equals(this[dartx.right], dart.dload(other, 'right')) && dart.equals(this[dartx.bottom], dart.dload(other, 'bottom'));
+ let otherRect = RectangleOfnum().as(other);
+ return this[dartx.left] == otherRect[dartx.left] && this[dartx.top] == otherRect[dartx.top] && this[dartx.right] == otherRect[dartx.right] && this[dartx.bottom] == otherRect[dartx.bottom];
}
get hashCode() {
return math._JenkinsSmiHash.hash4(dart.hashCode(this[dartx.left]), dart.hashCode(this[dartx.top]), dart.hashCode(this[dartx.right]), dart.hashCode(this[dartx.bottom]));
diff --git a/pkg/dev_compiler/lib/src/compiler/code_generator.dart b/pkg/dev_compiler/lib/src/compiler/code_generator.dart
index 1b306a7..a642fe4 100644
--- a/pkg/dev_compiler/lib/src/compiler/code_generator.dart
+++ b/pkg/dev_compiler/lib/src/compiler/code_generator.dart
@@ -31,7 +31,7 @@
import 'package:analyzer/src/summary/summary_sdk.dart';
import 'package:analyzer/src/task/strong/ast_properties.dart'
show isDynamicInvoke, setIsDynamicInvoke, getImplicitAssignmentCast;
-import 'package:path/path.dart' show separator;
+import 'package:path/path.dart' show separator, isWithin, fromUri;
import '../closure/closure_annotator.dart' show ClosureAnnotator;
import '../js_ast/js_ast.dart' as JS;
@@ -3872,6 +3872,7 @@
JS.Expression emitNew() {
JS.Expression ctor;
bool isFactory = false;
+ bool isNative = false;
if (element == null) {
// TODO(jmesserly): this only happens if we had a static error.
// Should we generate a throw instead?
@@ -3884,9 +3885,14 @@
} else {
ctor = _emitConstructorName(element, type, name);
isFactory = element.isFactory;
+ var classElem = element.enclosingElement;
+ isNative = _isJSNative(classElem);
}
var args = _visit(argumentList) as List<JS.Expression>;
- return isFactory ? new JS.Call(ctor, args) : new JS.New(ctor, args);
+ // Native factory constructors are JS constructors - use new here.
+ return isFactory && !isNative
+ ? new JS.Call(ctor, args)
+ : new JS.New(ctor, args);
}
if (element != null && _isObjectLiteral(element.enclosingElement)) {
@@ -3901,6 +3907,9 @@
findAnnotation(classElem, isJSAnonymousAnnotation) != null;
}
+ bool _isJSNative(ClassElement classElem) =>
+ findAnnotation(classElem, isPublicJSAnnotation) != null;
+
JS.Expression _emitObjectLiteral(ArgumentList argumentList) {
var args = _visit(argumentList) as List<JS.Expression>;
if (args.isEmpty) {
@@ -5443,16 +5452,17 @@
return uri.path;
}
// TODO(vsm): This is not necessarily unique if '__' appears in a file name.
- var separator = '__';
+ var customSeparator = '__';
String qualifiedPath;
if (uri.scheme == 'package') {
// Strip the package name.
// TODO(vsm): This is not unique if an escaped '/'appears in a filename.
// E.g., "foo/bar.dart" and "foo$47bar.dart" would collide.
- qualifiedPath = uri.pathSegments.skip(1).join(separator);
- } else if (uri.toFilePath().startsWith(libraryRoot)) {
- qualifiedPath =
- uri.path.substring(libraryRoot.length).replaceAll('/', separator);
+ qualifiedPath = uri.pathSegments.skip(1).join(customSeparator);
+ } else if (isWithin(libraryRoot, uri.toFilePath())) {
+ qualifiedPath = fromUri(uri)
+ .substring(libraryRoot.length)
+ .replaceAll(separator, customSeparator);
} else {
// We don't have a unique name.
throw 'Invalid library root. $libraryRoot does not contain ${uri
diff --git a/pkg/dev_compiler/lib/src/compiler/compiler.dart b/pkg/dev_compiler/lib/src/compiler/compiler.dart
index e789bca..1e57ada 100644
--- a/pkg/dev_compiler/lib/src/compiler/compiler.dart
+++ b/pkg/dev_compiler/lib/src/compiler/compiler.dart
@@ -111,10 +111,10 @@
var compilingSdk = false;
for (var sourcePath in unit.sources) {
var sourceUri = Uri.parse(sourcePath);
- if (sourceUri.scheme == '') {
- sourceUri = path.toUri(path.absolute(sourcePath));
- } else if (sourceUri.scheme == 'dart') {
+ if (sourceUri.scheme == 'dart') {
compilingSdk = true;
+ } else if (sourceUri.scheme != 'package') {
+ sourceUri = path.toUri(path.absolute(sourcePath));
}
Source source = context.sourceFactory.forUri2(sourceUri);
@@ -503,7 +503,7 @@
if (match != null) return match;
// Fall back to a relative path.
- return path.toUri(path.relative(path.fromUri(uri), from: dir)).toString();
+ return path.toUri(path.relative(uri, from: dir)).toString();
}
for (int i = 0; i < list.length; i++) {
diff --git a/pkg/dev_compiler/test-main.js b/pkg/dev_compiler/test-main.js
index fe330b7..fc04a7b 100644
--- a/pkg/dev_compiler/test-main.js
+++ b/pkg/dev_compiler/test-main.js
@@ -52,6 +52,7 @@
expect: 'gen/codegen_output/pkg/expect',
js: 'gen/codegen_output/pkg/js',
matcher: 'gen/codegen_output/pkg/matcher',
+ minitest: 'gen/codegen_output/pkg/minitest',
path: 'gen/codegen_output/pkg/path',
stack_trace: 'gen/codegen_output/pkg/stack_trace',
unittest: 'gen/codegen_output/pkg/unittest',
diff --git a/pkg/dev_compiler/test/browser/language_tests.js b/pkg/dev_compiler/test/browser/language_tests.js
index 5922544..25ea068 100644
--- a/pkg/dev_compiler/test/browser/language_tests.js
+++ b/pkg/dev_compiler/test/browser/language_tests.js
@@ -2,11 +2,12 @@
// 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.
-define(['dart_sdk', 'async_helper', 'unittest', 'require'],
- function(dart_sdk, async_helper, unittest, require) {
+define(['dart_sdk', 'async_helper', 'expect', 'unittest', 'require'],
+ function(dart_sdk, async_helper, expect, unittest, require) {
'use strict';
async_helper = async_helper.async_helper;
+ let minitest = expect.minitest;
dart_sdk._isolate_helper.startRootIsolate(function() {}, []);
let html_config = unittest.html_config;
@@ -25,6 +26,13 @@
const skip_fail = ['skip', 'fail'];
const skip_timeout = ['skip', 'timeout'];
+ // Tests marked with this are still using the deprecated unittest package
+ // because they rely on its support for futures and asynchronous tests, which
+ // expect and minitest do not handle.
+ // TODO(rnystrom): Move all of these away from using the async test API so
+ // they can stop using unittest.
+ const async_unittest = ['unittest', 'skip', 'fail'];
+
// The number of expected unittest errors should be zero but unfortunately
// there are a lot of broken html unittests.
let num_expected_unittest_fails = 3;
@@ -36,6 +44,7 @@
'assert_with_type_test_or_cast_test': skip_fail,
'assertion_test': skip_fail,
'async_await_test_none_multi': 'unittest',
+ 'async_await_test_02_multi': 'unittest',
'async_await_test_03_multi': skip_fail, // Flaky on travis (#634)
'async_star_await_pauses_test': skip_fail,
@@ -390,10 +399,6 @@
// newer SDKs.
'html_escape_test': ['skip'],
- // TODO(rnystrom): If this test is enabled, karma gets confused and
- // disconnects randomly.
- 'json_lib_test': skip_fail,
-
'json_utf8_chunk_test': skip_timeout,
'latin1_test': skip_timeout,
@@ -405,183 +410,122 @@
'utf85_test': skip_timeout,
},
- // TODO(jacobr): enable more of the html tests in unittest once they have
- // more hope of passing. Triage tests that can never run in this test
- // runner and track them separately.
'lib/html': {
- 'async_spawnuri_test': ['unittest', 'skip', 'fail'],
- 'async_test': ['unittest', 'skip', 'fail'],
- 'audiobuffersourcenode_test': ['unittest', 'skip', 'fail'],
- 'audiocontext_test': ['unittest', 'skip', 'fail'],
- 'audioelement_test': ['unittest', 'skip', 'fail'],
- 'b_element_test': ['unittest', 'skip', 'fail'],
- 'blob_constructor_test': ['unittest', 'skip', 'fail'],
- 'cache_test': ['unittest', 'skip', 'fail'],
- 'callbacks_test': ['unittest', 'skip', 'fail'],
- 'canvas_pixel_array_type_alias_test': ['unittest'],
- 'canvasrenderingcontext2d_test': ['unittest'],
+ 'async_spawnuri_test': async_unittest,
+ 'async_test': async_unittest,
+ 'audiobuffersourcenode_test': 'fail', // sdk#27578.
+ 'audiocontext_test': 'fail', // sdk#27578.
+ 'blob_constructor_test': 'fail', // sdk#27578.
+ 'cache_test': 'fail', // sdk#27578.
'canvas_test': ['unittest'],
- 'cdata_test': ['unittest', 'skip', 'fail'],
- 'client_rect_test': ['unittest', 'skip', 'fail'],
- 'cross_domain_iframe_test': ['unittest', 'skip', 'fail'],
- 'cross_frame_test': ['unittest', 'skip', 'fail'],
- 'crypto_test': ['unittest', 'skip', 'fail'],
- 'css_rule_list_test': ['unittest', 'skip', 'fail'],
- 'cssstyledeclaration_test': ['unittest', 'skip', 'fail'],
- 'css_test': ['unittest', 'skip', 'fail'],
- 'custom_element_method_clash_test': ['unittest', 'skip', 'fail'],
- 'custom_element_name_clash_test': ['unittest', 'skip', 'fail'],
- 'custom_elements_23127_test': ['unittest', 'skip', 'fail'],
- 'custom_elements_test': ['unittest', 'skip', 'fail'],
- 'custom_tags_test': ['unittest', 'skip', 'fail'],
- 'dart_object_local_storage_test': ['unittest', 'skip', 'fail'],
- 'datalistelement_test': ['unittest', 'skip', 'fail'],
- 'documentfragment_test': ['unittest', 'skip', 'fail'],
- 'document_test': ['unittest'],
- 'dom_constructors_test': ['unittest', 'skip', 'fail'],
- 'domparser_test': ['unittest', 'skip', 'fail'],
- 'element_add_test': ['unittest', 'skip', 'fail'],
- 'element_animate_test': ['unittest', 'skip', 'fail'],
- 'element_classes_svg_test': ['unittest', 'skip', 'fail'],
- 'element_classes_test': ['unittest', 'skip', 'fail'],
- 'element_constructor_1_test': ['unittest', 'skip', 'fail'],
- 'element_dimensions_test': ['unittest', 'skip', 'fail'],
- 'element_offset_test': ['unittest', 'skip', 'fail'],
- 'element_test': ['unittest', 'skip', 'fail'],
- 'element_types_constructors1_test': ['unittest', 'skip', 'fail'],
- 'element_types_constructors2_test': ['unittest', 'skip', 'fail'],
- 'element_types_constructors3_test': ['unittest', 'skip', 'fail'],
- 'element_types_constructors4_test': ['unittest', 'skip', 'fail'],
- 'element_types_constructors5_test': ['unittest', 'skip', 'fail'],
- 'element_types_constructors6_test': ['unittest', 'skip', 'fail'],
- 'element_types_test': ['unittest', 'skip', 'fail'],
- 'event_customevent_test': ['unittest', 'skip', 'fail'],
- 'events_test': ['unittest', 'skip', 'fail'],
- 'event_test': ['unittest', 'skip', 'fail'],
- 'exceptions_test': ['unittest', 'skip', 'fail'],
- 'fileapi_test': ['unittest', 'skip', 'fail'],
- 'filereader_test': ['unittest', 'skip', 'fail'],
- 'filteredelementlist_test': ['unittest', 'skip', 'fail'],
- 'fontface_loaded_test': ['unittest', 'skip', 'fail'],
- 'fontface_test': ['unittest', 'skip', 'fail'],
- 'form_data_test': ['unittest', 'skip', 'fail'],
- 'form_element_test': ['unittest', 'skip', 'fail'],
- 'geolocation_test': ['unittest', 'skip', 'fail'],
- 'hidden_dom_1_test': ['unittest', 'skip', 'fail'],
- 'hidden_dom_2_test': ['unittest', 'skip', 'fail'],
- 'history_test': ['unittest', 'skip', 'fail'],
- 'htmlcollection_test': ['unittest', 'skip', 'fail'],
- 'htmlelement_test': ['unittest', 'skip', 'fail'],
- 'htmloptionscollection_test': ['unittest', 'skip', 'fail'],
- 'indexeddb_1_test': ['unittest', 'skip', 'fail'],
- 'indexeddb_2_test': ['unittest', 'skip', 'fail'],
- 'indexeddb_3_test': ['unittest', 'skip', 'fail'],
- 'indexeddb_4_test': ['unittest', 'skip', 'fail'],
- 'indexeddb_5_test': ['unittest', 'skip', 'fail'],
- 'input_element_test': ['unittest', 'skip', 'fail'],
- 'instance_of_test': ['unittest', 'skip', 'fail'],
- 'interactive_test': ['unittest', 'skip', 'fail'],
- 'isolates_test': ['unittest', 'skip', 'fail'],
- 'js_function_getter_test': 'unittest',
- 'js_function_getter_trust_types_test': 'unittest',
- 'js_interop_1_test': 'unittest',
- 'js_test': 'unittest',
- 'js_util_test': 'unittest',
- 'js_typed_interop_anonymous2_exp_test': 'unittest',
- 'js_typed_interop_anonymous2_test': 'unittest',
- 'js_typed_interop_anonymous_exp_test': 'unittest',
- 'js_typed_interop_anonymous_test': 'unittest',
- 'js_typed_interop_anonymous_unreachable_exp_test': 'unittest',
- 'js_typed_interop_anonymous_unreachable_test': 'unittest',
- 'js_typed_interop_default_arg_test': 'unittest',
- 'js_typed_interop_side_cast_exp_test': 'unittest',
- 'js_typed_interop_side_cast_test': 'unittest',
- 'js_typed_interop_test': ['unittest', 'skip', 'fail'],
- 'keyboard_event_test': ['unittest', 'skip', 'fail'],
- 'localstorage_test': ['unittest', 'skip', 'fail'],
- 'location_test': ['unittest', 'skip', 'fail'],
- 'mediasource_test': ['unittest', 'skip', 'fail'],
- 'media_stream_test': ['unittest', 'skip', 'fail'],
- 'messageevent_test': ['unittest', 'skip', 'fail'],
- 'mirrors_js_typed_interop_test': ['unittest', 'skip', 'fail'],
- 'mouse_event_test': ['unittest', 'skip', 'fail'],
- 'mutationobserver_test': ['unittest', 'skip', 'fail'],
- 'native_gc_test': ['unittest', 'skip', 'fail'],
- 'navigator_test': ['unittest', 'skip', 'fail'],
- 'node_test': ['unittest', 'skip', 'fail'],
- 'node_validator_important_if_you_suppress_make_the_bug_critical_test': ['unittest', 'skip', 'fail'],
- 'non_instantiated_is_test': ['unittest', 'skip', 'fail'],
- 'notification_test': ['unittest', 'skip', 'fail'],
- 'performance_api_test': ['unittest', 'skip', 'fail'],
- 'postmessage_structured_test': ['unittest', 'skip', 'fail'],
- 'private_extension_member_test': ['unittest', 'skip', 'fail'],
- 'queryall_test': ['unittest', 'skip', 'fail'],
- 'query_test': ['unittest', 'skip', 'fail'],
- 'range_test': ['unittest', 'skip', 'fail'],
- 'request_animation_frame_test': ['unittest', 'skip', 'fail'],
- 'resource_http_test': ['unittest', 'skip', 'fail'],
- 'rtc_test': ['unittest', 'skip', 'fail'],
- 'selectelement_test': ['unittest', 'skip', 'fail'],
- 'serialized_script_value_test': ['unittest', 'skip', 'fail'],
- 'shadow_dom_test': ['unittest', 'skip', 'fail'],
- 'shadowroot_test': ['unittest', 'skip', 'fail'],
- 'speechrecognition_test': ['unittest', 'skip', 'fail'],
- 'storage_test': ['unittest', 'skip', 'fail'],
- 'streams_test': ['unittest', 'skip', 'fail'],
- 'svgelement_test': ['unittest', 'skip', 'fail'],
- 'svg_test': ['unittest', 'skip', 'fail'],
- 'table_test': ['unittest', 'skip', 'fail'],
- 'text_event_test': ['unittest', 'skip', 'fail'],
- 'touchevent_test': ['unittest', 'skip', 'fail'],
- 'track_element_constructor_test': ['unittest', 'skip', 'fail'],
- 'transferables_test': ['unittest', 'skip', 'fail'],
- 'transition_event_test': ['unittest', 'skip', 'fail'],
- 'trusted_html_tree_sanitizer_test': ['unittest', 'skip', 'fail'],
- 'typed_arrays_1_test': ['unittest', 'skip', 'fail'],
- 'typed_arrays_2_test': ['unittest', 'skip', 'fail'],
- 'typed_arrays_3_test': ['unittest', 'skip', 'fail'],
- 'typed_arrays_4_test': ['unittest', 'skip', 'fail'],
- 'typed_arrays_5_test': ['unittest', 'skip', 'fail'],
- 'typed_arrays_arraybuffer_test': ['unittest', 'skip', 'fail'],
- 'typed_arrays_dataview_test': ['unittest', 'skip', 'fail'],
- 'typed_arrays_range_checks_test': ['unittest', 'skip', 'fail'],
- 'typed_arrays_simd_test': ['unittest', 'skip', 'fail'],
- 'typing_test': ['unittest', 'skip', 'fail'],
- 'unknownelement_test': ['unittest', 'skip', 'fail'],
- 'uri_test': ['unittest', 'skip', 'fail'],
- 'url_test': ['unittest', 'skip', 'fail'],
- 'webgl_1_test': ['unittest', 'skip', 'fail'],
- 'websocket_test': ['unittest', 'skip', 'fail'],
- 'websql_test': ['unittest', 'skip', 'fail'],
- 'wheelevent_test': ['unittest', 'skip', 'fail'],
- 'window_eq_test': ['unittest', 'skip', 'fail'],
- 'window_mangling_test': ['unittest', 'skip', 'fail'],
- 'window_nosuchmethod_test': ['unittest', 'skip', 'fail'],
- 'window_test': ['unittest', 'skip', 'fail'],
- 'worker_api_test': ['unittest', 'skip', 'fail'],
- 'worker_test': ['unittest', 'skip', 'fail'],
- 'wrapping_collections_test': ['unittest', 'skip', 'fail'],
- 'xhr_cross_origin_test': ['unittest', 'skip', 'fail'],
- 'xhr_test': ['unittest', 'skip', 'fail'],
- 'xsltprocessor_test': ['unittest', 'skip', 'fail'],
+ 'canvasrenderingcontext2d_test': ['unittest'],
+ 'cross_domain_iframe_test': async_unittest,
+ 'crypto_test': 'fail', // sdk#27578.
+ 'cssstyledeclaration_test': async_unittest,
+ 'css_test': async_unittest,
- 'js_typed_interop_default_arg_test_none_multi': ['unittest', 'skip', 'fail'],
- 'js_typed_interop_default_arg_test_explicit_argument_multi': ['unittest', 'skip', 'fail'],
- 'js_typed_interop_default_arg_test_default_value_multi': ['unittest', 'skip', 'fail']
+ // This is failing with a range error, I'm guessing because it's looking
+ // for a stylesheet and the page has none.
+ 'css_rule_list_test': 'fail',
+ 'custom_element_method_clash_test': async_unittest,
+ 'custom_element_name_clash_test': async_unittest,
+ 'custom_elements_23127_test': async_unittest,
+ 'custom_elements_test': async_unittest,
+ 'datalistelement_test': 'fail', // sdk#27578.
+ 'dom_constructors_test': 'fail', // sdk#27578.
+ 'element_animate_test': async_unittest,
+ 'element_classes_test': 'fail', // sdk#27579.
+ 'element_classes_svg_test': 'fail', // sdk#27579.
+
+ // Failure: 'Expected 56 to be in the inclusive range [111, 160].'.
+ 'element_offset_test': 'fail',
+ 'element_test': async_unittest,
+ 'element_types_test': 'fail', // sdk#27578.
+ 'event_customevent_test': async_unittest,
+ 'events_test': async_unittest,
+
+ // Failure: "Failed to execute 'dispatchEvent' on 'EventTarget': parameter
+ // 1 is not of type 'Event'."
+ 'event_test': 'fail',
+ 'fileapi_test': async_unittest,
+ 'filereader_test': async_unittest,
+ 'fontface_loaded_test': async_unittest,
+
+ // Failed because it's expecting "Ahem" but getting null. Maybe sdk#27579?
+ 'fontface_test': 'fail',
+ 'form_data_test': async_unittest,
+ 'history_test': async_unittest,
+ 'indexeddb_1_test': async_unittest,
+ 'indexeddb_2_test': async_unittest,
+ 'indexeddb_3_test': async_unittest,
+ 'indexeddb_4_test': async_unittest,
+ 'indexeddb_5_test': async_unittest,
+ 'input_element_test': 'fail', // sdk#27578.
+ 'interactive_test': async_unittest,
+ 'isolates_test': async_unittest,
+
+ // Failing on "identical JS objects should have identical proxies".
+ 'js_test': 'fail',
+ 'js_interop_1_test': async_unittest,
+
+ // Failing because accessing "zSomeInvalidName" does not throw.
+ 'js_typed_interop_test': 'fail',
+
+ // The "typed literal" test fails because the object does not have "_c".
+ 'js_util_test': 'fail',
+ 'keyboard_event_test': async_unittest,
+
+ 'mediasource_test': 'fail', // sdk#27578.
+ 'media_stream_test': 'fail', // sdk#27578.
+ 'messageevent_test': 'fail', // sdk#27578.
+
+ // Should throw but does not.
+ 'mirrors_js_typed_interop_test': 'fail',
+
+ 'mutationobserver_test': async_unittest,
+ 'native_gc_test': async_unittest,
+ 'node_validator_important_if_you_suppress_make_the_bug_critical_test': 'fail', // sdk#27578.
+ 'notification_test': 'fail', // sdk#27578.
+ 'performance_api_test': 'fail', // sdk#27578.
+ 'postmessage_structured_test': async_unittest,
+ 'range_test': 'fail', // sdk#27578.
+ 'request_animation_frame_test': async_unittest,
+ 'resource_http_test': async_unittest,
+ 'rtc_test': 'fail', // sdk#27578.
+
+ // Expected 1, got null.
+ 'serialized_script_value_test': 'fail',
+ 'shadow_dom_test': 'fail', // sdk#27578.
+ 'shadowroot_test': 'fail', // sdk#27578.
+ 'speechrecognition_test': 'fail', // sdk#27578.
+ 'svgelement_test': 'fail', // sdk#27578.
+ 'touchevent_test': 'fail', // sdk#27578.
+ 'track_element_constructor_test': 'fail', // sdk#27578.
+ 'transferables_test': async_unittest,
+ 'transition_event_test': async_unittest,
+ 'url_test': async_unittest,
+ 'websocket_test': async_unittest,
+ 'websql_test': async_unittest,
+ 'wheelevent_test': async_unittest,
+ 'worker_api_test': async_unittest,
+ 'worker_test': async_unittest,
+
+ 'xhr_cross_origin_test': async_unittest,
+ 'xhr_test': async_unittest,
+ 'xsltprocessor_test': 'fail', // sdk#27578.
+
+ // Failing when it gets 3 instead of 42.
+ 'js_typed_interop_default_arg_test_default_value_multi': 'fail',
},
'lib/html/custom': {
- 'attribute_changed_callback_test': ['unittest', 'skip', 'fail'],
- 'constructor_calls_created_synchronously_test':
- ['unittest', 'skip', 'fail'],
- 'created_callback_test': ['unittest', 'skip', 'fail'],
- 'document_register_basic_test': ['unittest', 'skip', 'fail'],
- 'document_register_type_extensions_test': ['unittest', 'skip', 'fail'],
- 'element_upgrade_test': ['unittest', 'skip', 'fail'],
- 'entered_left_view_test': ['unittest', 'skip', 'fail'],
- 'js_custom_test': ['unittest', 'skip', 'fail'],
- 'mirrors_test': ['unittest', 'skip', 'fail'],
- 'regress_194523002_test': ['unittest', 'skip', 'fail'],
+ 'attribute_changed_callback_test': async_unittest,
+ 'constructor_calls_created_synchronously_test': async_unittest,
+ 'created_callback_test': async_unittest,
+ 'entered_left_view_test': async_unittest,
+ 'js_custom_test': async_unittest,
+ 'mirrors_test': async_unittest,
+ 'regress_194523002_test': async_unittest,
},
'lib/math': {
@@ -591,9 +535,8 @@
'math_test': skip_fail,
'math2_test': skip_fail,
'pi_test': skip_timeout,
- 'point_test': ['unittest', 'skip', 'fail'],
'random_big_test': skip_fail,
- 'rectangle_test': 'unittest',
+ 'rectangle_test': fail, // TODO(rnystrom): #27551
},
'lib/typed_data': {
@@ -645,8 +588,6 @@
'generics_special_types_test': fail,
'generics_substitution_test': fail,
'generics_test_none_multi': fail,
- 'get_field_static_test_00_multi': fail,
- 'get_field_static_test_none_multi': fail,
'globalized_closures2_test_00_multi': fail,
'globalized_closures2_test_none_multi': fail,
'globalized_closures_test_00_multi': fail,
@@ -726,7 +667,6 @@
'relation_subtype_test': fail,
'runtime_type_test': fail,
'set_field_with_final_test': fail,
- 'static_const_field_test': fail,
'superclass2_test': fail,
'symbol_validation_test_01_multi': fail,
'symbol_validation_test_none_multi': fail,
@@ -757,7 +697,6 @@
let languageTestPattern =
new RegExp('gen/codegen_output/(.*)/([^/]*_test[^/]*)');
- html_config.useHtmlConfiguration();
// We need to let Dart unittest control when tests are run not mocha.
// mocha.allowUncaught(true);
for (let testFile of allTestFiles) {
@@ -828,30 +767,49 @@
}
}
} else {
- if (negative) {
- assert.throws(mainLibrary.main);
- } else {
- mainLibrary.main();
+ try {
+ if (negative) {
+ assert.throws(mainLibrary.main);
+ } else {
+ mainLibrary.main();
+ }
+ } finally {
+ minitest.finishTests();
}
}
+ // If the test left any lingering detritus in the DOM, blow it away
+ // so it doesn't interfere with later tests.
+ document.body.innerHTML = '';
+ console.log("cleared");
+
if (!async_helper.asyncTestStarted) done();
});
}
}
- // TODO(jmesserly): unitttest tests are currently broken
- // https://github.com/dart-lang/dev_compiler/issues/631
- return;
-
let mochaOnError;
// We run these tests in a mocha test wrapper to avoid the confusing failure
// case of dart unittests being interleaved with mocha tests.
// In practice we are really just suppressing all mocha test behavior while
// Dart unittests run and then re-enabling it when the dart tests complete.
+ html_config.useHtmlConfiguration();
test('run all dart unittests', function(done) { // 'function' to allow `this.timeout`
if (unittest_tests.length == 0) return done();
+ // TODO(vsm): We're using an old deprecated version of unittest.
+ // We need to migrate all tests (in the SDK itself) off of
+ // unittest.
+
+ // All unittests need to be explicitly marked as such above. If
+ // not, the unittest framework will be run in a 'normal' test and
+ // left in an inconsistent state at this point triggering spurious
+ // failures. This check ensures we're not in such a state. If it fails,
+ // we've likely added a new unittest and need to categorize it as such.
+ if (unittest.src__test_environment.environment.testCases[dart_sdk.dartx.length] != 0) {
+ return done(new Error('Unittest framework in an invalid state'));
+ }
+
this.timeout(100000000);
this.enableTimeouts(false);
// Suppress mocha on-error handling because it will mess up unittests.
diff --git a/pkg/dev_compiler/test/codegen/expect.dart b/pkg/dev_compiler/test/codegen/expect.dart
deleted file mode 100644
index e7eb892..0000000
--- a/pkg/dev_compiler/test/codegen/expect.dart
+++ /dev/null
@@ -1,426 +0,0 @@
-// Copyright (c) 2012, 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.
-
-/**
- * This library contains an Expect class with static methods that can be used
- * for simple unit-tests.
- */
-library expect;
-
-/**
- * Expect is used for tests that do not want to make use of the
- * Dart unit test library - for example, the core language tests.
- * Third parties are discouraged from using this, and should use
- * the expect() function in the unit test library instead for
- * test assertions.
- */
-class Expect {
- /**
- * Return a slice of a string.
- *
- * The slice will contain at least the substring from [start] to the lower of
- * [end] and `start + length`.
- * If the result is no more than `length - 10` characters long,
- * context may be added by extending the range of the slice, by decreasing
- * [start] and increasing [end], up to at most length characters.
- * If the start or end of the slice are not matching the start or end of
- * the string, ellipses are added before or after the slice.
- * Control characters may be encoded as "\xhh" codes.
- */
- static String _truncateString(String string, int start, int end, int length) {
- if (end - start > length) {
- end = start + length;
- } else if (end - start < length) {
- int overflow = length - (end - start);
- if (overflow > 10) overflow = 10;
- // Add context.
- start = start - ((overflow + 1) ~/ 2);
- end = end + (overflow ~/ 2);
- if (start < 0) start = 0;
- if (end > string.length) end = string.length;
- }
- if (start == 0 && end == string.length) return string;
- StringBuffer buf = new StringBuffer();
- if (start > 0) buf.write("...");
- for (int i = start; i < end; i++) {
- int code = string.codeUnitAt(i);
- if (code < 0x20) {
- buf.write(r"\x");
- buf.write("0123456789abcdef"[code ~/ 16]);
- buf.write("0123456789abcdef"[code % 16]);
- } else {
- buf.writeCharCode(string.codeUnitAt(i));
- }
- }
- if (end < string.length) buf.write("...");
- return buf.toString();
- }
-
- /**
- * Find the difference between two strings.
- *
- * This finds the first point where two strings differ, and returns
- * a text describing the difference.
- *
- * For small strings (length less than 20) nothing is done, and null is
- * returned. Small strings can be compared visually, but for longer strings
- * only a slice containing the first difference will be shown.
- */
- static String _stringDifference(String expected, String actual) {
- if (expected.length < 20 && actual.length < 20) return null;
- for (int i = 0; i < expected.length && i < actual.length; i++) {
- if (expected.codeUnitAt(i) != actual.codeUnitAt(i)) {
- int start = i;
- i++;
- while (i < expected.length && i < actual.length) {
- if (expected.codeUnitAt(i) == actual.codeUnitAt(i)) break;
- i++;
- }
- int end = i;
- var truncExpected = _truncateString(expected, start, end, 20);
- var truncActual = _truncateString(actual, start, end, 20);
- return "at index $start: Expected <$truncExpected>, "
- "Found: <$truncActual>";
- }
- }
- return null;
- }
-
- /**
- * Checks whether the expected and actual values are equal (using `==`).
- */
- static void equals(var expected, var actual, [String reason = null]) {
- if (expected == actual) return;
- String msg = _getMessage(reason);
- if (expected is String && actual is String) {
- String stringDifference = _stringDifference(expected, actual);
- if (stringDifference != null) {
- _fail("Expect.equals($stringDifference$msg) fails.");
- }
- }
- _fail("Expect.equals(expected: <$expected>, actual: <$actual>$msg) fails.");
- }
-
- /**
- * Checks whether the actual value is a bool and its value is true.
- */
- static void isTrue(var actual, [String reason = null]) {
- if (_identical(actual, true)) return;
- String msg = _getMessage(reason);
- _fail("Expect.isTrue($actual$msg) fails.");
- }
-
- /**
- * Checks whether the actual value is a bool and its value is false.
- */
- static void isFalse(var actual, [String reason = null]) {
- if (_identical(actual, false)) return;
- String msg = _getMessage(reason);
- _fail("Expect.isFalse($actual$msg) fails.");
- }
-
- /**
- * Checks whether [actual] is null.
- */
- static void isNull(actual, [String reason = null]) {
- if (null == actual) return;
- String msg = _getMessage(reason);
- _fail("Expect.isNull(actual: <$actual>$msg) fails.");
- }
-
- /**
- * Checks whether [actual] is not null.
- */
- static void isNotNull(actual, [String reason = null]) {
- if (null != actual) return;
- String msg = _getMessage(reason);
- _fail("Expect.isNotNull(actual: <$actual>$msg) fails.");
- }
-
- /**
- * Checks whether the expected and actual values are identical
- * (using `identical`).
- */
- static void identical(var expected, var actual, [String reason = null]) {
- if (_identical(expected, actual)) return;
- String msg = _getMessage(reason);
- _fail("Expect.identical(expected: <$expected>, actual: <$actual>$msg) "
- "fails.");
- }
-
- // Unconditional failure.
- static void fail(String msg) {
- _fail("Expect.fail('$msg')");
- }
-
- /**
- * Failure if the difference between expected and actual is greater than the
- * given tolerance. If no tolerance is given, tolerance is assumed to be the
- * value 4 significant digits smaller than the value given for expected.
- */
- static void approxEquals(num expected,
- num actual,
- [num tolerance = null,
- String reason = null]) {
- if (tolerance == null) {
- tolerance = (expected / 1e4).abs();
- }
- // Note: use !( <= ) rather than > so we fail on NaNs
- if ((expected - actual).abs() <= tolerance) return;
-
- String msg = _getMessage(reason);
- _fail('Expect.approxEquals(expected:<$expected>, actual:<$actual>, '
- 'tolerance:<$tolerance>$msg) fails');
- }
-
- static void notEquals(unexpected, actual, [String reason = null]) {
- if (unexpected != actual) return;
- String msg = _getMessage(reason);
- _fail("Expect.notEquals(unexpected: <$unexpected>, actual:<$actual>$msg) "
- "fails.");
- }
-
- /**
- * Checks that all elements in [expected] and [actual] are equal `==`.
- * This is different than the typical check for identity equality `identical`
- * used by the standard list implementation. It should also produce nicer
- * error messages than just calling `Expect.equals(expected, actual)`.
- */
- static void listEquals(List expected, List actual, [String reason = null]) {
- String msg = _getMessage(reason);
- int n = (expected.length < actual.length) ? expected.length : actual.length;
- for (int i = 0; i < n; i++) {
- if (expected[i] != actual[i]) {
- _fail('Expect.listEquals(at index $i, '
- 'expected: <${expected[i]}>, actual: <${actual[i]}>$msg) fails');
- }
- }
- // We check on length at the end in order to provide better error
- // messages when an unexpected item is inserted in a list.
- if (expected.length != actual.length) {
- _fail('Expect.listEquals(list length, '
- 'expected: <${expected.length}>, actual: <${actual.length}>$msg) '
- 'fails: Next element <'
- '${expected.length > n ? expected[n] : actual[n]}>');
- }
- }
-
- /**
- * Checks that all [expected] and [actual] have the same set of keys (using
- * the semantics of [Map.containsKey] to determine what "same" means. For
- * each key, checks that the values in both maps are equal using `==`.
- */
- static void mapEquals(Map expected, Map actual, [String reason = null]) {
- String msg = _getMessage(reason);
-
- // Make sure all of the values are present in both and match.
- for (final key in expected.keys) {
- if (!actual.containsKey(key)) {
- _fail('Expect.mapEquals(missing expected key: <$key>$msg) fails');
- }
-
- Expect.equals(expected[key], actual[key]);
- }
-
- // Make sure the actual map doesn't have any extra keys.
- for (final key in actual.keys) {
- if (!expected.containsKey(key)) {
- _fail('Expect.mapEquals(unexpected key: <$key>$msg) fails');
- }
- }
- }
-
- /**
- * Specialized equality test for strings. When the strings don't match,
- * this method shows where the mismatch starts and ends.
- */
- static void stringEquals(String expected,
- String actual,
- [String reason = null]) {
- if (expected == actual) return;
-
- String msg = _getMessage(reason);
- String defaultMessage =
- 'Expect.stringEquals(expected: <$expected>", <$actual>$msg) fails';
-
- if ((expected == null) || (actual == null)) {
- _fail('$defaultMessage');
- }
-
- // Scan from the left until we find the mismatch.
- int left = 0;
- int right = 0;
- int eLen = expected.length;
- int aLen = actual.length;
-
- while (true) {
- if (left == eLen || left == aLen || expected[left] != actual[left]) {
- break;
- }
- left++;
- }
-
- // Scan from the right until we find the mismatch.
- int eRem = eLen - left; // Remaining length ignoring left match.
- int aRem = aLen - left;
- while (true) {
- if (right == eRem || right == aRem ||
- expected[eLen - right - 1] != actual[aLen - right - 1]) {
- break;
- }
- right++;
- }
-
- // First difference is at index `left`, last at `length - right - 1`
- // Make useful difference message.
- // Example:
- // Diff (1209..1209/1246):
- // ...,{"name":"[ ]FallThroug...
- // ...,{"name":"[ IndexError","kind":"class"},{"name":" ]FallThroug...
- // (colors would be great!)
-
- // Make snippets of up to ten characters before and after differences.
-
- String leftSnippet = expected.substring(left < 10 ? 0 : left - 10, left);
- int rightSnippetLength = right < 10 ? right : 10;
- String rightSnippet =
- expected.substring(eLen - right, eLen - right + rightSnippetLength);
-
- // Make snippets of the differences.
- String eSnippet = expected.substring(left, eLen - right);
- String aSnippet = actual.substring(left, aLen - right);
-
- // If snippets are long, elide the middle.
- if (eSnippet.length > 43) {
- eSnippet = eSnippet.substring(0, 20) + "..." +
- eSnippet.substring(eSnippet.length - 20);
- }
- if (aSnippet.length > 43) {
- aSnippet = aSnippet.substring(0, 20) + "..." +
- aSnippet.substring(aSnippet.length - 20);
- }
- // Add "..." before and after, unless the snippets reach the end.
- String leftLead = "...";
- String rightTail = "...";
- if (left <= 10) leftLead = "";
- if (right <= 10) rightTail = "";
-
- String diff = '\nDiff ($left..${eLen - right}/${aLen - right}):\n'
- '$leftLead$leftSnippet[ $eSnippet ]$rightSnippet$rightTail\n'
- '$leftLead$leftSnippet[ $aSnippet ]$rightSnippet$rightTail';
- _fail("$defaultMessage$diff");
- }
-
- /**
- * Checks that every element of [expected] is also in [actual], and that
- * every element of [actual] is also in [expected].
- */
- static void setEquals(Iterable expected,
- Iterable actual,
- [String reason = null]) {
- final missingSet = new Set.from(expected);
- missingSet.removeAll(actual);
- final extraSet = new Set.from(actual);
- extraSet.removeAll(expected);
-
- if (extraSet.isEmpty && missingSet.isEmpty) return;
- String msg = _getMessage(reason);
-
- StringBuffer sb = new StringBuffer("Expect.setEquals($msg) fails");
- // Report any missing items.
- if (!missingSet.isEmpty) {
- sb.write('\nExpected collection does not contain: ');
- }
-
- for (final val in missingSet) {
- sb.write('$val ');
- }
-
- // Report any extra items.
- if (!extraSet.isEmpty) {
- sb.write('\nExpected collection should not contain: ');
- }
-
- for (final val in extraSet) {
- sb.write('$val ');
- }
- _fail(sb.toString());
- }
-
- /**
- * Calls the function [f] and verifies that it throws an exception.
- * The optional [check] function can provide additional validation
- * that the correct exception is being thrown. For example, to check
- * the type of the exception you could write this:
- *
- * Expect.throws(myThrowingFunction, (e) => e is MyException);
- */
- static void throws(void f(),
- [_CheckExceptionFn check = null,
- String reason = null]) {
- String msg = reason == null ? "" : "($reason)";
- if (f is! _Nullary) {
- // Only throws from executing the funtion body should count as throwing.
- // The failure to even call `f` should throw outside the try/catch.
- _fail("Expect.throws$msg: Function f not callable with zero arguments");
- }
- try {
- f();
- } catch (e, s) {
- if (check != null) {
- if (!check(e)) {
- _fail("Expect.throws$msg: Unexpected '$e'\n$s");
- }
- }
- return;
- }
- _fail('Expect.throws$msg fails: Did not throw');
- }
-
- static String _getMessage(String reason)
- => (reason == null) ? "" : ", '$reason'";
-
- static void _fail(String message) {
- throw new ExpectException(message);
- }
-}
-
-bool _identical(a, b) => identical(a, b);
-
-typedef bool _CheckExceptionFn(exception);
-typedef _Nullary(); // Expect.throws argument must be this type.
-
-class ExpectException implements Exception {
- ExpectException(this.message);
- String toString() => message;
- String message;
-}
-
-/// Annotation class for testing of dart2js. Use this as metadata on method
-/// declarations to disable inlining of the annotated method.
-class NoInline {
- const NoInline();
-}
-
-/// Annotation class for testing of dart2js. Use this as metadata on method
-/// declarations to make the type inferrer trust the parameter and return types,
-/// effectively asserting the runtime values will (at least) be subtypes of the
-/// annotated types.
-///
-/// While the actually inferred type is guaranteed to be a subtype of the
-/// annotation, it often is more precise. In particular, if a method is only
-/// called with `null`, the inferrer will still infer null. To ensure that
-/// the annotated type is also the inferred type, additionally use
-/// [AssumeDynamic].
-class TrustTypeAnnotations {
- const TrustTypeAnnotations();
-}
-
-/// Annotation class for testing of dart2js. Use this as metadata on method
-/// declarations to disable closed world assumptions on parameters, effectively
-/// assuming that the runtime arguments could be any value. Note that the
-/// constraints due to [TrustTypeAnnotations] still apply.
-class AssumeDynamic {
- const AssumeDynamic();
-}
diff --git a/pkg/dev_compiler/test/codegen/lib/convert/json_lib_test.dart b/pkg/dev_compiler/test/codegen/lib/convert/json_lib_test.dart
index 1226f7b..0966eaf 100644
--- a/pkg/dev_compiler/test/codegen/lib/convert/json_lib_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/convert/json_lib_test.dart
@@ -2,162 +2,188 @@
// 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 json_tests;
-import 'package:unittest/unittest.dart';
+import 'package:expect/expect.dart';
import 'dart:convert';
main() {
- test('Parse', () {
- // Scalars.
- expect(JSON.decode(' 5 '), equals(5));
- expect(JSON.decode(' -42 '), equals(-42));
- expect(JSON.decode(' 3e0 '), equals(3));
- expect(JSON.decode(' 3.14 '), equals(3.14));
- expect(JSON.decode('true '), isTrue);
- expect(JSON.decode(' false'), isFalse);
- expect(JSON.decode(' null '), isNull);
- expect(JSON.decode('\n\rnull\t'), isNull);
- expect(JSON.decode(' "hi there\\" bob" '), equals('hi there" bob'));
- expect(JSON.decode(' "" '), isEmpty);
+ testParsing();
+ testStringify();
+ testStringifyErrors();
+}
- // Lists.
- expect(JSON.decode(' [] '), isEmpty);
- expect(JSON.decode('[ ]'), isEmpty);
- expect(JSON.decode(' [3, -4.5, true, "hi", false] '),
- equals([3, -4.5, true, 'hi', false]));
- // Nulls are tricky.
- expect(JSON.decode('[null]'), orderedEquals([null]));
- expect(JSON.decode(' [3, -4.5, null, true, "hi", false] '),
- equals([3, -4.5, null, true, 'hi', false]));
- expect(JSON.decode('[[null]]'), equals([[null]]));
- expect(JSON.decode(' [ [3], [], [null], ["hi", true]] '),
- equals([[3], [], [null], ['hi', true]]));
+void testParsing() {
+ // Scalars.
+ Expect.equals(5, JSON.decode(' 5 '));
+ Expect.equals(-42, JSON.decode(' -42 '));
+ Expect.equals(3, JSON.decode(' 3e0 '));
+ Expect.equals(3.14, JSON.decode(' 3.14 '));
+ Expect.isTrue(JSON.decode('true '));
+ Expect.isFalse(JSON.decode(' false'));
+ Expect.isNull(JSON.decode(' null '));
+ Expect.isNull(JSON.decode('\n\rnull\t'));
+ Expect.equals('hi there" bob', JSON.decode(' "hi there\\" bob" '));
+ Expect.equals('', JSON.decode(' "" '));
- // Maps.
- expect(JSON.decode(' {} '), isEmpty);
- expect(JSON.decode('{ }'), isEmpty);
+ // Lists.
+ Expect.deepEquals([], JSON.decode(' [] '));
+ Expect.deepEquals([], JSON.decode('[ ]'));
+ Expect.deepEquals([3, -4.5, true, 'hi', false],
+ JSON.decode(' [3, -4.5, true, "hi", false] '));
+ // Nulls are tricky.
+ Expect.deepEquals([null], JSON.decode('[null]'));
+ Expect.deepEquals([3, -4.5, null, true, 'hi', false],
+ JSON.decode(' [3, -4.5, null, true, "hi", false] '));
+ Expect.deepEquals([
+ [null]
+ ], JSON.decode('[[null]]'));
+ Expect.deepEquals([
+ [3],
+ [],
+ [null],
+ ['hi', true]
+ ], JSON.decode(' [ [3], [], [null], ["hi", true]] '));
- expect(JSON.decode(
- ' {"x":3, "y": -4.5, "z" : "hi","u" : true, "v": false } '),
- equals({"x":3, "y": -4.5, "z" : "hi", "u" : true, "v": false }));
+ // Maps.
+ Expect.deepEquals({}, JSON.decode(' {} '));
+ Expect.deepEquals({}, JSON.decode('{ }'));
- expect(JSON.decode(' {"x":3, "y": -4.5, "z" : "hi" } '),
- equals({"x":3, "y": -4.5, "z" : "hi" }));
+ Expect.deepEquals({"x": 3, "y": -4.5, "z": "hi", "u": true, "v": false},
+ JSON.decode(' {"x":3, "y": -4.5, "z" : "hi","u" : true, "v": false } '));
- expect(JSON.decode(' {"y": -4.5, "z" : "hi" ,"x":3 } '),
- equals({"y": -4.5, "z" : "hi" ,"x":3 }));
+ Expect.deepEquals({"x": 3, "y": -4.5, "z": "hi"},
+ JSON.decode(' {"x":3, "y": -4.5, "z" : "hi" } '));
- expect(JSON.decode('{ " hi bob " :3, "": 4.5}'),
- equals({ " hi bob " :3, "": 4.5}));
+ Expect.deepEquals({"y": -4.5, "z": "hi", "x": 3},
+ JSON.decode(' {"y": -4.5, "z" : "hi" ,"x":3 } '));
- expect(JSON.decode(' { "x" : { } } '), equals({ 'x' : {}}));
- expect(JSON.decode('{"x":{}}'), equals({ 'x' : {}}));
+ Expect.deepEquals(
+ {" hi bob ": 3, "": 4.5}, JSON.decode('{ " hi bob " :3, "": 4.5}'));
- // Nulls are tricky.
- expect(JSON.decode('{"w":null}'), equals({ 'w' : null}));
+ Expect.deepEquals({'x': {}}, JSON.decode(' { "x" : { } } '));
+ Expect.deepEquals({'x': {}}, JSON.decode('{"x":{}}'));
- expect(JSON.decode('{"x":{"w":null}}'), equals({"x":{"w":null}}));
+ // Nulls are tricky.
+ Expect.deepEquals({'w': null}, JSON.decode('{"w":null}'));
- expect(JSON.decode(' {"x":3, "y": -4.5, "z" : "hi",'
- '"w":null, "u" : true, "v": false } '),
- equals({"x":3, "y": -4.5, "z" : "hi",
- "w":null, "u" : true, "v": false }));
+ Expect.deepEquals({
+ "x": {"w": null}
+ }, JSON.decode('{"x":{"w":null}}'));
- expect(JSON.decode('{"x": {"a":3, "b": -4.5}, "y":[{}], '
- '"z":"hi","w":{"c":null,"d":true}, "v":null}'),
- equals({"x": {"a":3, "b": -4.5}, "y":[{}],
- "z":"hi","w":{"c":null,"d":true}, "v":null}));
+ Expect.deepEquals(
+ {"x": 3, "y": -4.5, "z": "hi", "w": null, "u": true, "v": false},
+ JSON.decode(' {"x":3, "y": -4.5, "z" : "hi",'
+ '"w":null, "u" : true, "v": false } '));
+
+ Expect.deepEquals(
+ {
+ "x": {"a": 3, "b": -4.5},
+ "y": [{}],
+ "z": "hi",
+ "w": {"c": null, "d": true},
+ "v": null
+ },
+ JSON.decode('{"x": {"a":3, "b": -4.5}, "y":[{}], '
+ '"z":"hi","w":{"c":null,"d":true}, "v":null}'));
+}
+
+void testStringify() {
+ // Scalars.
+ Expect.equals('5', JSON.encode(5));
+ Expect.equals('-42', JSON.encode(-42));
+ // Dart does not guarantee a formatting for doubles,
+ // so reparse and compare to the original.
+ validateRoundTrip(3.14);
+ Expect.equals('true', JSON.encode(true));
+ Expect.equals('false', JSON.encode(false));
+ Expect.equals('null', JSON.encode(null));
+ Expect.equals('" hi there\\" bob "', JSON.encode(' hi there" bob '));
+ Expect.equals('"hi\\\\there"', JSON.encode('hi\\there'));
+ Expect.equals('"hi\\nthere"', JSON.encode('hi\nthere'));
+ Expect.equals('"hi\\r\\nthere"', JSON.encode('hi\r\nthere'));
+ Expect.equals('""', JSON.encode(''));
+
+ // Lists.
+ Expect.equals('[]', JSON.encode([]));
+ Expect.equals('[]', JSON.encode(new List(0)));
+ Expect.equals('[null,null,null]', JSON.encode(new List(3)));
+ validateRoundTrip([3, -4.5, null, true, 'hi', false]);
+ Expect.equals(
+ '[[3],[],[null],["hi",true]]',
+ JSON.encode([
+ [3],
+ [],
+ [null],
+ ['hi', true]
+ ]));
+
+ // Maps.
+ Expect.equals('{}', JSON.encode({}));
+ Expect.equals('{}', JSON.encode(new Map()));
+ Expect.equals('{"x":{}}', JSON.encode({'x': {}}));
+ Expect.equals(
+ '{"x":{"a":3}}',
+ JSON.encode({
+ 'x': {'a': 3}
+ }));
+
+ // Dart does not guarantee an order on the keys
+ // of a map literal, so reparse and compare to the original Map.
+ validateRoundTrip(
+ {'x': 3, 'y': -4.5, 'z': 'hi', 'w': null, 'u': true, 'v': false});
+ validateRoundTrip({"x": 3, "y": -4.5, "z": 'hi'});
+ validateRoundTrip({' hi bob ': 3, '': 4.5});
+ validateRoundTrip({
+ 'x': {'a': 3, 'b': -4.5},
+ 'y': [{}],
+ 'z': 'hi',
+ 'w': {'c': null, 'd': true},
+ 'v': null
});
- test('stringify', () {
- // Scalars.
- expect(JSON.encode(5), equals('5'));
- expect(JSON.encode(-42), equals('-42'));
- // Dart does not guarantee a formatting for doubles,
- // so reparse and compare to the original.
- validateRoundTrip(3.14);
- expect(JSON.encode(true), equals('true'));
- expect(JSON.encode(false), equals('false'));
- expect(JSON.encode(null), equals('null'));
- expect(JSON.encode(' hi there" bob '), equals('" hi there\\" bob "'));
- expect(JSON.encode('hi\\there'), equals('"hi\\\\there"'));
- expect(JSON.encode('hi\nthere'), equals('"hi\\nthere"'));
- expect(JSON.encode('hi\r\nthere'), equals('"hi\\r\\nthere"'));
- expect(JSON.encode(''), equals('""'));
+ Expect.equals("4", JSON.encode(new ToJson(4)));
+ Expect.equals('[4,"a"]', JSON.encode(new ToJson([4, "a"])));
+ Expect.equals(
+ '[4,{"x":42}]',
+ JSON.encode(new ToJson([
+ 4,
+ new ToJson({"x": 42})
+ ])));
- // Lists.
- expect(JSON.encode([]), equals('[]'));
- expect(JSON.encode(new List(0)), equals('[]'));
- expect(JSON.encode(new List(3)), equals('[null,null,null]'));
- validateRoundTrip([3, -4.5, null, true, 'hi', false]);
- expect(JSON.encode([[3], [], [null], ['hi', true]]),
- equals('[[3],[],[null],["hi",true]]'));
+ expectThrowsJsonError(() => JSON.encode([new ToJson(new ToJson(4))]));
+ expectThrowsJsonError(() => JSON.encode([new Object()]));
+}
- // Maps.
- expect(JSON.encode({}), equals('{}'));
- expect(JSON.encode(new Map()), equals('{}'));
- expect(JSON.encode({'x':{}}), equals('{"x":{}}'));
- expect(JSON.encode({'x':{'a':3}}), equals('{"x":{"a":3}}'));
+void testStringifyErrors() {
+ // Throws if argument cannot be converted.
+ expectThrowsJsonError(() => JSON.encode(new TestClass()));
- // Dart does not guarantee an order on the keys
- // of a map literal, so reparse and compare to the original Map.
- validateRoundTrip(
- {'x':3, 'y':-4.5, 'z':'hi', 'w':null, 'u':true, 'v':false});
- validateRoundTrip({"x":3, "y":-4.5, "z":'hi'});
- validateRoundTrip({' hi bob ':3, '':4.5});
- validateRoundTrip(
- {'x':{'a':3, 'b':-4.5}, 'y':[{}], 'z':'hi', 'w':{'c':null, 'd':true},
- 'v':null});
+ // Throws if toJson throws.
+ expectThrowsJsonError(() => JSON.encode(new ToJsoner("bad", throws: true)));
- expect(JSON.encode(new ToJson(4)), "4");
- expect(JSON.encode(new ToJson([4, "a"])), '[4,"a"]');
- expect(JSON.encode(new ToJson([4, new ToJson({"x":42})])),
- '[4,{"x":42}]');
+ // Throws if toJson returns non-serializable value.
+ expectThrowsJsonError(() => JSON.encode(new ToJsoner(new TestClass())));
- expect(() {
- JSON.encode([new ToJson(new ToJson(4))]);
- }, throwsJsonError);
+ // Throws on cyclic values.
+ var a = [];
+ var b = a;
+ for (int i = 0; i < 50; i++) {
+ b = [b];
+ }
+ a.add(b);
+ expectThrowsJsonError(() => JSON.encode(a));
+}
- expect(() {
- JSON.encode([new Object()]);
- }, throwsJsonError);
-
- });
-
- test('stringify throws if argument cannot be converted', () {
- /**
- * Checks that we get an exception (rather than silently returning null) if
- * we try to stringify something that cannot be converted to json.
- */
- expect(() => JSON.encode(new TestClass()), throwsJsonError);
- });
-
- test('stringify throws if toJson throws', () {
- expect(() => JSON.encode(new ToJsoner("bad", throws: true)),
- throwsJsonError);
- });
-
- test('stringify throws if toJson returns non-serializable value', () {
- expect(() => JSON.encode(new ToJsoner(new TestClass())),
- throwsJsonError);
- });
-
- test('stringify throws on cyclic values', () {
- var a = [];
- var b = a;
- for (int i = 0; i < 50; i++) {
- b = [b];
- }
- a.add(b);
- expect(() => JSON.encode(a), throwsJsonError);
- });
+void expectThrowsJsonError(void f()) {
+ Expect.throws(f, (e) => e is JsonUnsupportedObjectError);
}
class TestClass {
int x;
String y;
- TestClass() : x = 3, y = 'joe' { }
+ TestClass()
+ : x = 3,
+ y = 'joe' {}
}
class ToJsoner {
@@ -176,13 +202,10 @@
toJson() => object;
}
-var throwsJsonError =
- throwsA(new isInstanceOf<JsonUnsupportedObjectError>());
-
/**
* Checks that the argument can be converted to a JSON string and
* back, and produce something equivalent to the argument.
*/
validateRoundTrip(expected) {
- expect(JSON.decode(JSON.encode(expected)), equals(expected));
+ Expect.deepEquals(expected, JSON.decode(JSON.encode(expected)));
}
diff --git a/pkg/dev_compiler/test/codegen/lib/html/audiobuffersourcenode_test.dart b/pkg/dev_compiler/test/codegen/lib/html/audiobuffersourcenode_test.dart
index c55c08c..9c98cf0 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/audiobuffersourcenode_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/audiobuffersourcenode_test.dart
@@ -1,21 +1,17 @@
-library AudioBufferSourceNodeTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
import 'dart:web_audio';
+import 'package:expect/minitest.dart';
+
main() {
-
- useHtmlIndividualConfiguration();
-
group('supported', () {
test('supported', () {
- expect(AudioContext.supported, true);
+ expect(AudioContext.supported, isTrue);
});
});
group('functional', () {
test('createBuffer', () {
- if(AudioContext.supported) {
+ if (AudioContext.supported) {
var ctx = new AudioContext();
AudioBufferSourceNode node = ctx.createBufferSource();
expect(node is AudioBufferSourceNode, isTrue);
diff --git a/pkg/dev_compiler/test/codegen/lib/html/audiocontext_test.dart b/pkg/dev_compiler/test/codegen/lib/html/audiocontext_test.dart
index 68c2af9..195130f 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/audiocontext_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/audiocontext_test.dart
@@ -1,15 +1,11 @@
-library AudioContextTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
+import 'dart:async';
import 'dart:html';
import 'dart:typed_data';
import 'dart:web_audio';
-import 'dart:async';
+
+import 'package:expect/minitest.dart';
main() {
-
- useHtmlIndividualConfiguration();
-
var isAudioContext =
predicate((x) => x is AudioContext, 'is an AudioContext');
@@ -24,16 +20,16 @@
if (AudioContext.supported) {
context = new AudioContext();
}
-
+
test('constructorTest', () {
- if(AudioContext.supported) {
+ if (AudioContext.supported) {
expect(context, isNotNull);
expect(context, isAudioContext);
}
});
test('audioRenames', () {
- if(AudioContext.supported) {
+ if (AudioContext.supported) {
GainNode gainNode = context.createGain();
gainNode.connectNode(context.destination);
expect(gainNode is GainNode, isTrue);
diff --git a/pkg/dev_compiler/test/codegen/lib/html/audioelement_test.dart b/pkg/dev_compiler/test/codegen/lib/html/audioelement_test.dart
index 9957ff7..9f47b9f 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/audioelement_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/audioelement_test.dart
@@ -1,11 +1,8 @@
-library AudioElementTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
-main() {
- useHtmlConfiguration();
+import 'package:expect/minitest.dart';
+main() {
test('constructorTest1', () {
var audio = new AudioElement();
expect(audio, isNotNull);
@@ -16,7 +13,7 @@
var audio = new AudioElement('IntentionallyMissingFileURL');
expect(audio, isNotNull);
expect(audio is AudioElement, isTrue);
- expect(audio.src, contains('IntentionallyMissingFileURL'));
+ expect(audio.src.contains('IntentionallyMissingFileURL'), isTrue);
});
test('canPlayTypeTest', () {
diff --git a/pkg/dev_compiler/test/codegen/lib/html/b_element_test.dart b/pkg/dev_compiler/test/codegen/lib/html/b_element_test.dart
index f208e6d..3dbb0e7 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/b_element_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/b_element_test.dart
@@ -1,13 +1,5 @@
-library BElementTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
main() {
- useHtmlConfiguration();
-
- test('create b', () {
- new Element.tag('b');
- });
+ new Element.tag('b');
}
-
diff --git a/pkg/dev_compiler/test/codegen/lib/html/blob_constructor_test.dart b/pkg/dev_compiler/test/codegen/lib/html/blob_constructor_test.dart
index 41461f5..b7f704c 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/blob_constructor_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/blob_constructor_test.dart
@@ -2,18 +2,15 @@
// 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 blob_test;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
import 'dart:typed_data';
-main() {
- useHtmlConfiguration();
+import 'package:expect/minitest.dart';
+main() {
test('basic', () {
var b = new Blob([]);
- expect(b.size, isZero);
+ expect(b.size, 0);
});
test('type1', () {
@@ -32,7 +29,7 @@
test('endings2', () {
// OPTIONALS var b = new Blob(['A\nB\n'], endings: 'native');
var b = new Blob(['A\nB\n'], null, 'native');
- expect(b.size, (x) => x == 4 || x == 6,
+ expect(b.size, predicate((x) => x == 4 || x == 6),
reason: "b.size should be 4 or 6");
});
@@ -45,7 +42,7 @@
test('fromBlob1', () {
var b1 = new Blob([]);
var b2 = new Blob([b1]);
- expect(b2.size, isZero);
+ expect(b2.size, 0);
});
test('fromBlob2', () {
diff --git a/pkg/dev_compiler/test/codegen/lib/html/cache_test.dart b/pkg/dev_compiler/test/codegen/lib/html/cache_test.dart
index d81770f..3b2e121 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/cache_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/cache_test.dart
@@ -1,14 +1,11 @@
-library CacheTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
import 'dart:html';
-main() {
- useHtmlIndividualConfiguration();
+import 'package:expect/minitest.dart';
+main() {
group('supported', () {
test('supported', () {
- expect(ApplicationCache.supported, true);
+ expect(ApplicationCache.supported, isTrue);
});
});
@@ -19,10 +16,8 @@
ApplicationCache appCache = window.applicationCache;
expect(cacheStatusToString(appCache.status), "UNCACHED");
}, expectation);
-
});
});
-
}
String cacheStatusToString(int status) {
diff --git a/pkg/dev_compiler/test/codegen/lib/html/callbacks_test.dart b/pkg/dev_compiler/test/codegen/lib/html/callbacks_test.dart
index c6e9498..7afeae5 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/callbacks_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/callbacks_test.dart
@@ -1,11 +1,5 @@
-library CallbacksTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
main() {
- useHtmlConfiguration();
- test('RequestAnimationFrameCallback', () {
- window.requestAnimationFrame((num time) => false);
- });
+ window.requestAnimationFrame((num time) => false);
}
diff --git a/pkg/dev_compiler/test/codegen/lib/html/canvas_pixel_array_type_alias_test.dart b/pkg/dev_compiler/test/codegen/lib/html/canvas_pixel_array_type_alias_test.dart
index 4dd6b40..1bb2006 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/canvas_pixel_array_type_alias_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/canvas_pixel_array_type_alias_test.dart
@@ -2,12 +2,11 @@
// 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 CanvasTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
import 'dart:html';
import 'dart:typed_data';
+import 'package:expect/minitest.dart';
+
// We have aliased the legacy type CanvasPixelArray with the new type
// Uint8ClampedArray by mapping the CanvasPixelArray type tag to
// Uint8ClampedArray. It is not a perfect match since CanvasPixelArray is
@@ -16,9 +15,6 @@
var inscrutable;
main() {
-
- useHtmlIndividualConfiguration();
-
inscrutable = (x) => x;
int width = 100;
@@ -39,7 +35,7 @@
expect(inscrutable(data) is List<int>, isTrue,
reason: 'canvas array type');
- expect(data, hasLength(40000));
+ expect(data.length, 40000);
checkPixel(data, 0, [0, 0, 0, 0]);
checkPixel(data, width * height - 1, [0, 0, 0, 0]);
diff --git a/pkg/dev_compiler/test/codegen/lib/html/cdata_test.dart b/pkg/dev_compiler/test/codegen/lib/html/cdata_test.dart
index 424d52f..60c311a 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/cdata_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/cdata_test.dart
@@ -2,15 +2,11 @@
// 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 cdata_test;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
+import 'package:expect/minitest.dart';
main() {
- useHtmlConfiguration();
-
test('remove', () {
var div = new Element.html('<div>content</div>');
var cdata = div.nodes[0];
diff --git a/pkg/dev_compiler/test/codegen/lib/html/client_rect_test.dart b/pkg/dev_compiler/test/codegen/lib/html/client_rect_test.dart
index b9c9bb54..526e011 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/client_rect_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/client_rect_test.dart
@@ -1,10 +1,8 @@
-library ClientRectTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
-main() {
+import 'package:expect/minitest.dart';
+main() {
var isRectList =
predicate((x) => x is List<Rectangle>, 'is a List<Rectangle>');
@@ -19,9 +17,7 @@
return element;
}
- useHtmlConfiguration();
-
- test("ClientRectList test", () {
+ test("ClientRectList test", () {
insertTestDiv();
var range = new Range();
var rects = range.getClientRects();
diff --git a/pkg/dev_compiler/test/codegen/lib/html/cross_frame_test.dart b/pkg/dev_compiler/test/codegen/lib/html/cross_frame_test.dart
index b5a37f6..bdb0d88 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/cross_frame_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/cross_frame_test.dart
@@ -1,11 +1,8 @@
-library CrossFrameTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
-main() {
- useHtmlConfiguration();
+import 'package:expect/minitest.dart';
+main() {
var isWindowBase = predicate((x) => x is WindowBase, 'is a WindowBase');
var isWindow = predicate((x) => x is Window, 'is a Window');
var isLocationBase = predicate((x) => x is LocationBase, 'is a LocationBase');
@@ -14,7 +11,7 @@
var isHistoryBase = predicate((x) => x is HistoryBase, 'is a HistoryBase');
var isHistory = predicate((x) => x is History, 'is a History');
- final iframe = new Element.tag('iframe');
+ final iframe = new IFrameElement();
document.body.append(iframe);
test('window', () {
diff --git a/pkg/dev_compiler/test/codegen/lib/html/crypto_test.dart b/pkg/dev_compiler/test/codegen/lib/html/crypto_test.dart
index 41666a5..9cb63ab 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/crypto_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/crypto_test.dart
@@ -2,15 +2,12 @@
// 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 crypto_test;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
import 'dart:html';
import 'dart:typed_data';
-main() {
- useHtmlIndividualConfiguration();
+import 'package:expect/minitest.dart';
+main() {
group('supported', () {
test('supported', () {
expect(Crypto.supported, true);
diff --git a/pkg/dev_compiler/test/codegen/lib/html/css_rule_list_test.dart b/pkg/dev_compiler/test/codegen/lib/html/css_rule_list_test.dart
index ade3833..481aca9 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/css_rule_list_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/css_rule_list_test.dart
@@ -1,17 +1,13 @@
-library CssRuleListTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
-main() {
+import 'package:expect/minitest.dart';
+main() {
var isCssRuleList =
predicate((x) => x is List<CssRule>, 'is a List<CssRule>');
- useHtmlConfiguration();
-
test("ClientRectList test", () {
- var sheet = document.styleSheets[0];
+ var sheet = document.styleSheets[0] as CssStyleSheet;
List<CssRule> rulesList = sheet.cssRules;
expect(rulesList, isCssRuleList);
});
diff --git a/pkg/dev_compiler/test/codegen/lib/html/custom/document_register_basic_test.dart b/pkg/dev_compiler/test/codegen/lib/html/custom/document_register_basic_test.dart
index cf11b63..33f07ba 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/custom/document_register_basic_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/custom/document_register_basic_test.dart
@@ -2,10 +2,10 @@
// 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 document_register_basic_test;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
import '../utils.dart';
class Foo extends HtmlElement {
@@ -45,8 +45,6 @@
}
main() {
- useHtmlConfiguration();
-
// Adapted from Blink's fast/dom/custom/document-register-basic test.
setUp(() => customElementsReady);
diff --git a/pkg/dev_compiler/test/codegen/lib/html/custom/document_register_type_extensions_test.dart b/pkg/dev_compiler/test/codegen/lib/html/custom/document_register_type_extensions_test.dart
index 67957b12..682e821 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/custom/document_register_type_extensions_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/custom/document_register_type_extensions_test.dart
@@ -2,10 +2,10 @@
// 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 document_register_type_extensions_test;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
import '../utils.dart';
class Foo extends HtmlElement {
diff --git a/pkg/dev_compiler/test/codegen/lib/html/custom/element_upgrade_test.dart b/pkg/dev_compiler/test/codegen/lib/html/custom/element_upgrade_test.dart
index c8e7376..a1f071b 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/custom/element_upgrade_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/custom/element_upgrade_test.dart
@@ -2,13 +2,12 @@
// 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 register_element_proxy_test;
-
import 'dart:async';
import 'dart:html';
import 'dart:js' as js;
-import 'package:unittest/html_config.dart';
-import 'package:unittest/unittest.dart';
+
+import 'package:expect/minitest.dart';
+
import '../utils.dart';
class FooElement extends HtmlElement {
@@ -28,8 +27,6 @@
}
main() {
- useHtmlConfiguration();
-
var registered = false;
var upgrader;
setUp(() => customElementsReady.then((_) {
diff --git a/pkg/dev_compiler/test/codegen/lib/html/custom_elements_23127_test.dart b/pkg/dev_compiler/test/codegen/lib/html/custom_elements_23127_test.dart
index 6386690..7b0f576 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/custom_elements_23127_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/custom_elements_23127_test.dart
@@ -56,25 +56,25 @@
class C1 extends B1 {
int z;
C1.created() : super.created();
- action() => z = 3;
+ action() { z = 3; }
}
class C1T extends B1T {
int z;
C1T.created() : super.created();
- action() => z = 3;
+ action() { z = 3; }
}
class C2 extends B2 {
int z;
C2.created() : super.created(20);
- action() => z = 3;
+ action() { z = 3; }
}
class C2T extends B2T {
int z;
C2T.created() : super.created(20);
- action() => z = 3;
+ action() { z = 3; }
}
diff --git a/pkg/dev_compiler/test/codegen/lib/html/custom_elements_test.dart b/pkg/dev_compiler/test/codegen/lib/html/custom_elements_test.dart
index 3ab5207..05fe5d2 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/custom_elements_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/custom_elements_test.dart
@@ -48,7 +48,7 @@
var tag = nextTag;
document.registerElement(tag, CustomType);
- var element = new Element.tag(tag);
+ var element = new Element.tag(tag) as CustomType;
expect(element, isNotNull);
expect(element is CustomType, isTrue);
expect(element.createdCalled, isTrue);
@@ -64,7 +64,7 @@
var newTag = nextTag;
document.registerElement(newTag, CustomType);
- var element = new Element.tag(newTag);
+ var element = new Element.tag(newTag) as CustomType;
expect(element, isNotNull);
expect(element is CustomType, isTrue);
});
@@ -138,7 +138,7 @@
treeSanitizer: new NullTreeSanitizer());
upgradeCustomElements(element);
document.body.nodes.add(element);
- var queried = query(tag);
+ var queried = query(tag) as CustomType;
expect(queried, isNotNull);
expect(queried is CustomType, isTrue);
@@ -153,7 +153,7 @@
treeSanitizer: new NullTreeSanitizer());
upgradeCustomElements(element);
document.body.nodes.add(element);
- var queried = query('#someid');
+ var queried = query('#someid') as CustomType;
expect(queried, isNotNull);
expect(queried is CustomType, isTrue);
@@ -180,7 +180,7 @@
var tag = nextTag;
document.registerElement(tag, CustomType);
- var element = new Element.tag(tag);
+ var element = new Element.tag(tag) as CustomType;
element.invokeMixinMethod();
expect(element.mixinMethodCalled, isTrue);
});
diff --git a/pkg/dev_compiler/test/codegen/lib/html/custom_tags_test.dart b/pkg/dev_compiler/test/codegen/lib/html/custom_tags_test.dart
index 5f5457b..5c91168 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/custom_tags_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/custom_tags_test.dart
@@ -2,15 +2,13 @@
// 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 custom_tags_test;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
import 'utils.dart';
main() {
- useHtmlConfiguration();
-
test('create via custom tag', () {
var element = new Element.tag('x-basic1')..id = 'basic1';
document.body.nodes.add(element);
diff --git a/pkg/dev_compiler/test/codegen/lib/html/dart_object_local_storage_test.dart b/pkg/dev_compiler/test/codegen/lib/html/dart_object_local_storage_test.dart
index 22add6a..502f08a 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/dart_object_local_storage_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/dart_object_local_storage_test.dart
@@ -1,16 +1,13 @@
-library DartObjectLocalStorageTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
+import 'package:expect/minitest.dart';
+
// TODO(vsm): Rename this to wrapper_caching_test or similar. It's
// basically a port of dom/dart_object_local_storage_test.dart. For
// wrapping implementation of dart:html (i.e., the dartium one), it is
// effectively testing dart_object_local_storage in the underlying dom
// object.
main() {
- useHtmlConfiguration();
-
BodyElement body = document.body;
Storage localStorage = window.localStorage;
Storage sessionStorage = window.sessionStorage;
diff --git a/pkg/dev_compiler/test/codegen/lib/html/datalistelement_test.dart b/pkg/dev_compiler/test/codegen/lib/html/datalistelement_test.dart
index 2fd9fa8..f831a45 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/datalistelement_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/datalistelement_test.dart
@@ -2,14 +2,11 @@
// 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 datalistelement_dataview_test;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
-main() {
- useHtmlConfiguration();
+import 'package:expect/minitest.dart';
+main() {
var isDataListElement =
predicate((x) => x is DataListElement, 'is a DataListElement');
@@ -46,15 +43,15 @@
test('list', () {
expect(() {
- var list = document.query('#browsers');
- var input = document.query('#input');
+ var list = document.query('#browsers') as DataListElement;
+ var input = document.query('#input') as InputElement;
expect(input.list, list);
}, expectation);
});
test('options', () {
expect(() {
- var options = document.query('#browsers').options;
+ var options = (document.query('#browsers') as DataListElement).options;
expect(options.length, 5);
}, expectation);
});
diff --git a/pkg/dev_compiler/test/codegen/lib/html/document_test.dart b/pkg/dev_compiler/test/codegen/lib/html/document_test.dart
index 2ed520f..b7d8f60 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/document_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/document_test.dart
@@ -1,11 +1,8 @@
-library DocumentTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
import 'dart:html';
-main() {
- useHtmlIndividualConfiguration();
+import 'package:expect/minitest.dart';
+main() {
var isElement = predicate((x) => x is Element, 'is an Element');
var isDivElement = predicate((x) => x is DivElement, 'is a DivElement');
var isAnchorElement =
@@ -59,7 +56,7 @@
var div = new Element.html('<div><div id="foo">bar</div></div>');
var doc = document.implementation.createHtmlDocument('');
var div2 = doc.importNode(div, true);
- expect(div2, isNot(equals(div)));
+ expect(div2, notEquals(div));
expect(div2.ownerDocument, doc);
doc.body.nodes.add(div2);
expect(doc.query('#foo').text, 'bar');
diff --git a/pkg/dev_compiler/test/codegen/lib/html/documentfragment_test.dart b/pkg/dev_compiler/test/codegen/lib/html/documentfragment_test.dart
index b09c04d..3b5249f 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/documentfragment_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/documentfragment_test.dart
@@ -2,15 +2,13 @@
// 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 DocumentFragmentTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
-import 'util.dart';
import 'dart:html';
-main() {
- useHtmlConfiguration();
+import 'package:expect/minitest.dart';
+import 'util.dart';
+
+main() {
var isAnchorElement =
predicate((x) => x is AnchorElement, 'is an AnchorElement');
@@ -42,7 +40,7 @@
expect(style.cssText, equals(''));
expect(style.getPropertyPriority('color'), equals(''));
expect(style.item(0), equals(''));
- expect(style.length, isZero);
+ expect(style.length, equals(0));
// TODO(jacobr): these checks throw UnimplementedErrors in dartium.
// expect(style.parentRule, isNull);
// expect(style.getPropertyCssValue('color'), isNull);
@@ -81,8 +79,8 @@
});
group('children', () {
- var fragment;
- var children;
+ DocumentFragment fragment;
+ List<Element> children;
init() {
fragment = new DocumentFragment();
@@ -102,36 +100,36 @@
test('filters out non-element nodes', () {
init();
expect(_nodeStrings(fragment.nodes),
- orderedEquals(["1", "A", "B", "2", "I", "3", "U"]));
+ equals(["1", "A", "B", "2", "I", "3", "U"]));
expect(_nodeStrings(children),
- orderedEquals(["A", "B", "I", "U"]));
+ equals(["A", "B", "I", "U"]));
});
test('only indexes children, not other nodes', () {
init();
children[1] = new Element.tag("BR");
expect(_nodeStrings(fragment.nodes),
- orderedEquals(["1", "A", "BR", "2", "I", "3", "U"]));
+ equals(["1", "A", "BR", "2", "I", "3", "U"]));
expect(_nodeStrings(children),
- orderedEquals(["A", "BR", "I", "U"]));
+ equals(["A", "BR", "I", "U"]));
});
test('adds to both children and nodes', () {
init();
children.add(new Element.tag("UL"));
expect(_nodeStrings(fragment.nodes),
- orderedEquals(["1", "A", "B", "2", "I", "3", "U", "UL"]));
+ equals(["1", "A", "B", "2", "I", "3", "U", "UL"]));
expect(_nodeStrings(children),
- orderedEquals(["A", "B", "I", "U", "UL"]));
+ equals(["A", "B", "I", "U", "UL"]));
});
test('removes only children, from both children and nodes', () {
init();
expect(children.removeLast().tagName, equals('U'));
expect(_nodeStrings(fragment.nodes),
- orderedEquals(["1", "A", "B", "2", "I", "3"]));
+ equals(["1", "A", "B", "2", "I", "3"]));
expect(_nodeStrings(children),
- orderedEquals(["A", "B", "I"]));
+ equals(["A", "B", "I"]));
expect(children.removeLast().tagName, "I");
expect(_nodeStrings(fragment.nodes),
diff --git a/pkg/dev_compiler/test/codegen/lib/html/dom_constructors_test.dart b/pkg/dev_compiler/test/codegen/lib/html/dom_constructors_test.dart
index a2bcf55..38c661a 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/dom_constructors_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/dom_constructors_test.dart
@@ -1,10 +1,8 @@
-library DOMConstructorsTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
+import 'package:expect/minitest.dart';
+
main() {
- useHtmlConfiguration();
test('FileReader', () {
FileReader fileReader = new FileReader();
expect(fileReader.readyState, equals(FileReader.EMPTY));
diff --git a/pkg/dev_compiler/test/codegen/lib/html/domparser_test.dart b/pkg/dev_compiler/test/codegen/lib/html/domparser_test.dart
index 61ecf86..51f8ce1 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/domparser_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/domparser_test.dart
@@ -1,17 +1,13 @@
-library DOMParserTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
+import 'package:expect/minitest.dart';
+
main() {
-
- useHtmlConfiguration();
-
var isDomParser = predicate((x) => x is DomParser, 'is a DomParser');
test('constructorTest', () {
- var ctx = new DomParser();
- expect(ctx, isNotNull);
- expect(ctx, isDomParser);
+ var ctx = new DomParser();
+ expect(ctx, isNotNull);
+ expect(ctx, isDomParser);
});
}
diff --git a/pkg/dev_compiler/test/codegen/lib/html/element_add_test.dart b/pkg/dev_compiler/test/codegen/lib/html/element_add_test.dart
index 2c2ea01..fc346d2 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/element_add_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/element_add_test.dart
@@ -2,15 +2,13 @@
// 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 ElementAddTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
-import 'util.dart';
import 'dart:html';
-main() {
- useHtmlConfiguration();
+import 'package:expect/minitest.dart';
+import 'util.dart';
+
+main() {
var isSpanElement = predicate((x) => x is SpanElement, 'is a SpanElemt');
var isDivElement = predicate((x) => x is DivElement, 'is a DivElement');
var isText = predicate((x) => x is Text, 'is a Text');
diff --git a/pkg/dev_compiler/test/codegen/lib/html/element_classes_svg_test.dart b/pkg/dev_compiler/test/codegen/lib/html/element_classes_svg_test.dart
index 0acd2a7..44d47f4 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/element_classes_svg_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/element_classes_svg_test.dart
@@ -2,13 +2,12 @@
// 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 ElementTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:collection';
import 'dart:html';
import 'dart:svg' as svg;
+import 'package:expect/minitest.dart';
+
// Test for `querySelectorAll(xxx).classes.op()` where the query returns mixed
// Html and Svg elements.
@@ -53,8 +52,6 @@
}
main() {
- useHtmlConfiguration();
-
Set<String> extractClasses(Element el) {
final match = new RegExp('class="([^"]+)"').firstMatch(el.outerHtml);
return new LinkedHashSet.from(match[1].split(' '));
@@ -82,8 +79,8 @@
expect(view(elements2), '[[foo, qux], [foo, qux], [foo, qux], [foo, qux]]');
for (Element e in elements2) {
- expect(e.classes, orderedEquals(['foo', 'qux']));
- expect(extractClasses(e), orderedEquals(['foo', 'qux']));
+ expect(e.classes, equals(['foo', 'qux']));
+ expect(extractClasses(e), equals(['foo', 'qux']));
}
elements.classes = [];
@@ -103,7 +100,6 @@
expect(elements.classes.contains('troll'), isFalse);
});
-
test('listAdd', () {
var elements = elementsSetup();
var added = elements.classes.add('lassie');
diff --git a/pkg/dev_compiler/test/codegen/lib/html/element_classes_test.dart b/pkg/dev_compiler/test/codegen/lib/html/element_classes_test.dart
index 2846d0d..0139471 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/element_classes_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/element_classes_test.dart
@@ -2,18 +2,17 @@
// 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 ElementTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:collection';
import 'dart:html';
+import 'package:expect/minitest.dart';
+
Element makeElement() => new Element.tag('div');
Element makeElementWithClasses() =>
new Element.html('<div class="foo bar baz"></div>');
-Set<String> makeClassSet() => makeElementWithClasses().classes;
+CssClassSet makeClassSet() => makeElementWithClasses().classes;
Element makeListElement() =>
new Element.html('<ul class="foo bar baz">'
@@ -47,43 +46,40 @@
}
main() {
- useHtmlConfiguration();
-
Set<String> extractClasses(Element el) {
final match = new RegExp('class="([^"]+)"').firstMatch(el.outerHtml);
return new LinkedHashSet.from(match[1].split(' '));
}
-
test('affects the "class" attribute', () {
final el = makeElementWithClasses();
el.classes.add('qux');
- expect(extractClasses(el), orderedEquals(['foo', 'bar', 'baz', 'qux']));
+ expect(extractClasses(el), equals(['foo', 'bar', 'baz', 'qux']));
});
test('is affected by the "class" attribute', () {
final el = makeElementWithClasses();
el.attributes['class'] = 'foo qux';
- expect(el.classes, orderedEquals(['foo', 'qux']));
+ expect(el.classes, equals(['foo', 'qux']));
});
test('classes=', () {
final el = makeElementWithClasses();
el.classes = ['foo', 'qux'];
- expect(el.classes, orderedEquals(['foo', 'qux']));
- expect(extractClasses(el), orderedEquals(['foo', 'qux']));
+ expect(el.classes, equals(['foo', 'qux']));
+ expect(extractClasses(el), equals(['foo', 'qux']));
});
test('toString', () {
expect(makeClassSet().toString().split(' '),
- orderedEquals(['foo', 'bar', 'baz']));
+ equals(['foo', 'bar', 'baz']));
expect(makeElement().classes.toString(), '');
});
test('forEach', () {
final classes = <String>[];
makeClassSet().forEach(classes.add);
- expect(classes, orderedEquals(['foo', 'bar', 'baz']));
+ expect(classes, equals(['foo', 'bar', 'baz']));
});
test('iterator', () {
@@ -91,17 +87,17 @@
for (var el in makeClassSet()) {
classes.add(el);
}
- expect(classes, orderedEquals(['foo', 'bar', 'baz']));
+ expect(classes, equals(['foo', 'bar', 'baz']));
});
test('map', () {
expect(makeClassSet().map((c) => c.toUpperCase()).toList(),
- orderedEquals(['FOO', 'BAR', 'BAZ']));
+ equals(['FOO', 'BAR', 'BAZ']));
});
test('where', () {
expect(makeClassSet().where((c) => c.contains('a')).toList(),
- orderedEquals(['bar', 'baz']));
+ equals(['bar', 'baz']));
});
test('every', () {
@@ -142,13 +138,13 @@
final classes = makeClassSet();
var added = classes.add('qux');
expect(added, isTrue);
- expect(classes, orderedEquals(['foo', 'bar', 'baz', 'qux']));
+ expect(classes, equals(['foo', 'bar', 'baz', 'qux']));
added = classes.add('qux');
expect(added, isFalse);
final list = new List.from(classes);
list.sort((a, b) => a.compareTo(b));
- expect(list, orderedEquals(['bar', 'baz', 'foo', 'qux']),
+ expect(list, equals(['bar', 'baz', 'foo', 'qux']),
reason: "The class set shouldn't have duplicate elements.");
});
@@ -161,9 +157,9 @@
test('remove', () {
final classes = makeClassSet();
classes.remove('bar');
- expect(classes, orderedEquals(['foo', 'baz']));
+ expect(classes, equals(['foo', 'baz']));
classes.remove('qux');
- expect(classes, orderedEquals(['foo', 'baz']));
+ expect(classes, equals(['foo', 'baz']));
});
test('remove-bad', () {
@@ -175,18 +171,18 @@
test('toggle', () {
final classes = makeClassSet();
classes.toggle('bar');
- expect(classes, orderedEquals(['foo', 'baz']));
+ expect(classes, equals(['foo', 'baz']));
classes.toggle('qux');
- expect(classes, orderedEquals(['foo', 'baz', 'qux']));
+ expect(classes, equals(['foo', 'baz', 'qux']));
classes.toggle('qux', true);
- expect(classes, orderedEquals(['foo', 'baz', 'qux']));
+ expect(classes, equals(['foo', 'baz', 'qux']));
classes.toggle('qux', false);
- expect(classes, orderedEquals(['foo', 'baz']));
+ expect(classes, equals(['foo', 'baz']));
classes.toggle('qux', false);
- expect(classes, orderedEquals(['foo', 'baz']));
+ expect(classes, equals(['foo', 'baz']));
classes.toggle('qux', true);
- expect(classes, orderedEquals(['foo', 'baz', 'qux']));
+ expect(classes, equals(['foo', 'baz', 'qux']));
});
test('toggle-bad', () {
@@ -202,43 +198,43 @@
test('addAll', () {
final classes = makeClassSet();
classes.addAll(['bar', 'qux', 'bip']);
- expect(classes, orderedEquals(['foo', 'bar', 'baz', 'qux', 'bip']));
+ expect(classes, equals(['foo', 'bar', 'baz', 'qux', 'bip']));
});
test('removeAll', () {
final classes = makeClassSet();
classes.removeAll(['bar', 'baz', 'qux']);
- expect(classes, orderedEquals(['foo']));
+ expect(classes, equals(['foo']));
});
test('toggleAll', () {
final classes = makeClassSet();
classes.toggleAll(['bar', 'foo']);
- expect(classes, orderedEquals(['baz']));
+ expect(classes, equals(['baz']));
classes.toggleAll(['qux', 'quux']);
- expect(classes, orderedEquals(['baz', 'qux', 'quux']));
+ expect(classes, equals(['baz', 'qux', 'quux']));
classes.toggleAll(['bar', 'foo'], true);
- expect(classes, orderedEquals(['baz', 'qux', 'quux', 'bar', 'foo']));
+ expect(classes, equals(['baz', 'qux', 'quux', 'bar', 'foo']));
classes.toggleAll(['baz', 'quux'], false);
- expect(classes, orderedEquals(['qux','bar', 'foo']));
+ expect(classes, equals(['qux','bar', 'foo']));
});
test('retainAll', () {
final classes = makeClassSet();
classes.retainAll(['bar', 'baz', 'qux']);
- expect(classes, orderedEquals(['bar', 'baz']));
+ expect(classes, equals(['bar', 'baz']));
});
test('removeWhere', () {
final classes = makeClassSet();
classes.removeWhere((s) => s.startsWith('b'));
- expect(classes, orderedEquals(['foo']));
+ expect(classes, equals(['foo']));
});
test('retainWhere', () {
final classes = makeClassSet();
classes.retainWhere((s) => s.startsWith('b'));
- expect(classes, orderedEquals(['bar', 'baz']));
+ expect(classes, equals(['bar', 'baz']));
});
test('containsAll', () {
@@ -264,11 +260,11 @@
test('order', () {
var classes = makeClassSet();
classes.add('aardvark');
- expect(classes, orderedEquals(['foo', 'bar', 'baz', 'aardvark']));
+ expect(classes, equals(['foo', 'bar', 'baz', 'aardvark']));
classes.toggle('baz');
- expect(classes, orderedEquals(['foo', 'bar', 'aardvark']));
+ expect(classes, equals(['foo', 'bar', 'aardvark']));
classes.toggle('baz');
- expect(classes, orderedEquals(['foo', 'bar', 'aardvark', 'baz']));
+ expect(classes, equals(['foo', 'bar', 'aardvark', 'baz']));
});
tearDown(listElementTearDown);
@@ -286,8 +282,8 @@
elements.classes = ['foo', 'qux'];
elements = document.queryAll('li');
for (Element e in elements) {
- expect(e.classes, orderedEquals(['foo', 'qux']));
- expect(extractClasses(e), orderedEquals(['foo', 'qux']));
+ expect(e.classes, equals(['foo', 'qux']));
+ expect(extractClasses(e), equals(['foo', 'qux']));
}
elements.classes = [];
diff --git a/pkg/dev_compiler/test/codegen/lib/html/element_constructor_1_test.dart b/pkg/dev_compiler/test/codegen/lib/html/element_constructor_1_test.dart
index b53e366..f97ce0f 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/element_constructor_1_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/element_constructor_1_test.dart
@@ -6,25 +6,22 @@
// Move constructors that fail on some configuration to their own
// element_constructor_foo_test.dart file.
-library ElementConstructorTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
-main() {
- useHtmlConfiguration();
+import 'package:expect/minitest.dart';
- var isAnchorElement =
+main() {
+ var isAnchorElement =
predicate((x) => x is AnchorElement, 'is an AnchorElement');
- var isAreaElement =
+ var isAreaElement =
predicate((x) => x is AreaElement, 'is an AreaElement');
var isDivElement = predicate((x) => x is DivElement, 'is a DivElement');
- var isCanvasElement =
+ var isCanvasElement =
predicate((x) => x is CanvasElement, 'is a CanvasElement');
var isParagraphElement =
predicate((x) => x is ParagraphElement, 'is a ParagraphElement');
var isSpanElement = predicate((x) => x is SpanElement, 'is a SpanElement');
- var isSelectElement =
+ var isSelectElement =
predicate((x) => x is SelectElement, 'is a SelectElement');
test('anchor1', () {
@@ -35,7 +32,7 @@
test('anchor2', () {
var e = new AnchorElement(href: '#blah');
expect(e, isAnchorElement);
- expect(e.href, endsWith('#blah'));
+ expect(e.href.endsWith('#blah'), isTrue);
});
test('area', () {
diff --git a/pkg/dev_compiler/test/codegen/lib/html/element_dimensions_test.dart b/pkg/dev_compiler/test/codegen/lib/html/element_dimensions_test.dart
index 413d302..2f11c40 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/element_dimensions_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/element_dimensions_test.dart
@@ -2,14 +2,11 @@
// 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 element_dimensions_test;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
-main() {
- useHtmlConfiguration();
+import 'package:expect/minitest.dart';
+main() {
var isElement = predicate((x) => x is Element, 'is an Element');
var isCanvasElement =
predicate((x) => x is CanvasElement, 'is a CanvasElement');
diff --git a/pkg/dev_compiler/test/codegen/lib/html/element_offset_test.dart b/pkg/dev_compiler/test/codegen/lib/html/element_offset_test.dart
index e7129d0..7e66523 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/element_offset_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/element_offset_test.dart
@@ -2,14 +2,12 @@
// 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 element_offset_test;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
import 'dart:async';
import 'dart:html';
+import 'package:expect/minitest.dart';
+
main() {
- useHtmlIndividualConfiguration();
void initPage() {
var level1 = new UListElement()
..classes.add('level-1')
diff --git a/pkg/dev_compiler/test/codegen/lib/html/element_types_constructors1_test.dart b/pkg/dev_compiler/test/codegen/lib/html/element_types_constructors1_test.dart
index 202556a..d867cba 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/element_types_constructors1_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/element_types_constructors1_test.dart
@@ -2,12 +2,10 @@
// 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 element_types_constructors1_test;
-
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
import 'dart:html';
+import 'package:expect/minitest.dart';
+
main() {
check(String name, bool fn(), [bool supported = true]) {
test(name, () {
diff --git a/pkg/dev_compiler/test/codegen/lib/html/element_types_constructors2_test.dart b/pkg/dev_compiler/test/codegen/lib/html/element_types_constructors2_test.dart
index 07a5fc4..9812ac7 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/element_types_constructors2_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/element_types_constructors2_test.dart
@@ -2,15 +2,11 @@
// 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 element_types_constructors2_test;
-
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
import 'dart:html';
-main() {
- useHtmlIndividualConfiguration();
+import 'package:expect/minitest.dart';
+main() {
check(String name, bool fn(), [bool supported = true]) {
test(name, () {
var expectation = supported ? returnsNormally : throws;
diff --git a/pkg/dev_compiler/test/codegen/lib/html/element_types_constructors3_test.dart b/pkg/dev_compiler/test/codegen/lib/html/element_types_constructors3_test.dart
index 54324a6..8c3957e 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/element_types_constructors3_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/element_types_constructors3_test.dart
@@ -2,15 +2,11 @@
// 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 element_types_constructors3_test;
-
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
import 'dart:html';
-main() {
- useHtmlIndividualConfiguration();
+import 'package:expect/minitest.dart';
+main() {
check(String name, bool fn(), [bool supported = true]) {
test(name, () {
var expectation = supported ? returnsNormally : throws;
diff --git a/pkg/dev_compiler/test/codegen/lib/html/element_types_constructors4_test.dart b/pkg/dev_compiler/test/codegen/lib/html/element_types_constructors4_test.dart
index 38223c9..f25660c 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/element_types_constructors4_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/element_types_constructors4_test.dart
@@ -2,15 +2,11 @@
// 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 element_types_constructors_test4;
-
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
import 'dart:html';
-main() {
- useHtmlIndividualConfiguration();
+import 'package:expect/minitest.dart';
+main() {
check(String name, bool fn(), [bool supported = true]) {
test(name, () {
var expectation = supported ? returnsNormally : throws;
diff --git a/pkg/dev_compiler/test/codegen/lib/html/element_types_constructors5_test.dart b/pkg/dev_compiler/test/codegen/lib/html/element_types_constructors5_test.dart
index e930ac1..3b66d81 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/element_types_constructors5_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/element_types_constructors5_test.dart
@@ -2,15 +2,11 @@
// 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 element_types_constructors5_test;
-
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
import 'dart:html';
-main() {
- useHtmlIndividualConfiguration();
+import 'package:expect/minitest.dart';
+main() {
check(String name, bool fn(), [bool supported = true]) {
test(name, () {
var expectation = supported ? returnsNormally : throws;
diff --git a/pkg/dev_compiler/test/codegen/lib/html/element_types_constructors6_test.dart b/pkg/dev_compiler/test/codegen/lib/html/element_types_constructors6_test.dart
index 6049ffc..57724b3 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/element_types_constructors6_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/element_types_constructors6_test.dart
@@ -2,15 +2,11 @@
// 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 element_types_constructors6_test;
-
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
import 'dart:html';
-main() {
- useHtmlIndividualConfiguration();
+import 'package:expect/minitest.dart';
+main() {
check(String name, bool fn(), [bool supported = true]) {
test(name, () {
var expectation = supported ? returnsNormally : throws;
diff --git a/pkg/dev_compiler/test/codegen/lib/html/element_types_test.dart b/pkg/dev_compiler/test/codegen/lib/html/element_types_test.dart
index ab06012..2f01a7d 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/element_types_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/element_types_test.dart
@@ -2,14 +2,11 @@
// 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 element_types;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
import 'dart:html';
-main() {
- useHtmlIndividualConfiguration();
+import 'package:expect/minitest.dart';
+main() {
group('supported_content', () {
test('supported', () {
expect(ContentElement.supported, true);
diff --git a/pkg/dev_compiler/test/codegen/lib/html/event_test.dart b/pkg/dev_compiler/test/codegen/lib/html/event_test.dart
index 14c92f1..82dc104 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/event_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/event_test.dart
@@ -2,14 +2,10 @@
// 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 EventTest;
-import "package:expect/expect.dart";
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
-// TODO(nweiz): Make this private to testEvents when Frog supports closures with
-// optional arguments.
+import 'package:expect/minitest.dart';
+
eventTest(String name, Event eventFn(), void validate(Event),
[String type = 'foo']) {
test(name, () {
@@ -25,8 +21,6 @@
}
main() {
- useHtmlConfiguration();
-
// Issue 1005.
// eventTest('AnimationEvent', () => new AnimationEvent('foo', 'color', 0.5),
// (ev) {
@@ -101,7 +95,7 @@
eventTest('MouseEvent',
() => new MouseEvent('foo', view: window, detail: 1, screenX: 2,
- screenY: 3, clientX: 4, clientY: 5, button: 6,
+ screenY: 3, clientX: 4, clientY: 5, button: 6,
ctrlKey: true, altKey: true, shiftKey: true,
metaKey: true, relatedTarget: document.body),
(ev) {
diff --git a/pkg/dev_compiler/test/codegen/lib/html/exceptions_test.dart b/pkg/dev_compiler/test/codegen/lib/html/exceptions_test.dart
index d7603b9..e07c328 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/exceptions_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/exceptions_test.dart
@@ -1,11 +1,8 @@
-library ExceptionsTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
-main() {
- useHtmlConfiguration();
+import 'package:expect/minitest.dart';
+main() {
test('EventException', () {
final event = new Event('Event');
// Intentionally do not initialize it!
diff --git a/pkg/dev_compiler/test/codegen/lib/html/filteredelementlist_test.dart b/pkg/dev_compiler/test/codegen/lib/html/filteredelementlist_test.dart
index b4110f7..eb5e364 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/filteredelementlist_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/filteredelementlist_test.dart
@@ -1,10 +1,8 @@
-library filteredelementlist_test;
-
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
import 'dart:html_common';
+import 'package:expect/minitest.dart';
+
main() {
var t1 = new Text('T1'),
t2 = new Text('T2'),
@@ -28,8 +26,6 @@
return testDiv;
}
- useHtmlConfiguration();
-
test('FilteredElementList.insert test', () {
var i = new DivElement();
@@ -95,8 +91,8 @@
test('FilteredElementList.insertAndRemove', () {
var emptyDiv = new DivElement();
var elementList = new FilteredElementList(emptyDiv);
- expect(() => elementList[0], throwsA(isRangeError));
- expect(() => elementList.insert(2, new BRElement()), throwsA(isRangeError));
+ expect(() => elementList[0], throwsRangeError);
+ expect(() => elementList.insert(2, new BRElement()), throwsRangeError);
var br = new BRElement();
elementList.insert(0, br);
expect(elementList.removeLast(), br);
@@ -106,6 +102,6 @@
elementList.add(br);
expect(elementList.remove(br2), isFalse);
expect(elementList[0], br);
- expect(() => elementList[1], throwsA(isRangeError));
+ expect(() => elementList[1], throwsRangeError);
});
}
diff --git a/pkg/dev_compiler/test/codegen/lib/html/fontface_test.dart b/pkg/dev_compiler/test/codegen/lib/html/fontface_test.dart
index 8247a8a..e7f9302 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/fontface_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/fontface_test.dart
@@ -2,16 +2,11 @@
// 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 fontface_test;
-
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
-
import 'dart:html';
-main() {
- useHtmlConfiguration();
+import 'package:expect/minitest.dart';
+main() {
test("Creation with parameters", () {
var font =
new FontFace('Ahem', 'url(Ahem.ttf)', {'variant': 'small-caps'});
diff --git a/pkg/dev_compiler/test/codegen/lib/html/form_element_test.dart b/pkg/dev_compiler/test/codegen/lib/html/form_element_test.dart
index b3b06c3..f1c9222 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/form_element_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/form_element_test.dart
@@ -2,15 +2,11 @@
// 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 FormElementTest;
-
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
-void main() {
- useHtmlConfiguration();
+import 'package:expect/minitest.dart';
+void main() {
var isFormElement = predicate((x) => x is FormElement, 'is a FormElement');
test('constructorTest1', () {
diff --git a/pkg/dev_compiler/test/codegen/lib/html/geolocation_test.dart b/pkg/dev_compiler/test/codegen/lib/html/geolocation_test.dart
index c49e531..889f874 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/geolocation_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/geolocation_test.dart
@@ -2,14 +2,11 @@
// 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 geolocation_test;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
-main() {
- useHtmlConfiguration();
+import 'package:expect/minitest.dart';
+main() {
// Actual tests require browser interaction. This just makes sure the API
// is present.
test('is not null', () {
diff --git a/pkg/dev_compiler/test/codegen/lib/html/hidden_dom_1_test.dart b/pkg/dev_compiler/test/codegen/lib/html/hidden_dom_1_test.dart
index 120136b5..a1c5dc3 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/hidden_dom_1_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/hidden_dom_1_test.dart
@@ -1,14 +1,11 @@
-library HiddenDom1Test;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
+import 'package:expect/minitest.dart';
+
// Test that the dart:html API does not leak native jsdom methods:
// onfocus setter.
main() {
- useHtmlConfiguration();
-
test('test1', () {
document.body.children.add(new Element.html(r'''
<div id='div1'>
@@ -17,7 +14,7 @@
Element e = document.query('#div1');
expect(e, isNotNull);
- checkNoSuchMethod(() { confuse(e).onfocus = null; });
+ expect(() { confuse(e).onfocus = null; }, throwsNoSuchMethodError);
});
}
@@ -28,18 +25,5 @@
confuse(x) => opaqueTrue() ? x : (opaqueTrue() ? new Object() : new Decoy());
-/** Returns [:true:], but in a way that confuses the compiler. */
+/** Returns `true`, but in a way that confuses the compiler. */
opaqueTrue() => true; // Expand as needed.
-
-checkNoSuchMethod(action()) {
- var ex = null;
- try {
- action();
- } catch (e) {
- ex = e;
- }
- if (ex == null)
- expect(false, isTrue, reason: 'Action should have thrown exception');
-
- expect(ex, isNoSuchMethodError);
-}
diff --git a/pkg/dev_compiler/test/codegen/lib/html/hidden_dom_2_test.dart b/pkg/dev_compiler/test/codegen/lib/html/hidden_dom_2_test.dart
index e8abc4e..5e638b1 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/hidden_dom_2_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/hidden_dom_2_test.dart
@@ -1,14 +1,11 @@
-library HiddenDom2Test;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
+import 'package:expect/minitest.dart';
+
// Test that the dart:html API does not leak native jsdom methods:
// appendChild operation.
main() {
- useHtmlConfiguration();
-
test('test1', () {
document.body.children.add(new Element.html(r'''
<div id='div1'>
@@ -18,7 +15,7 @@
Element e2 = new Element.html(r"<div id='xx'>XX</div>");
expect(e, isNotNull);
- checkNoSuchMethod(() { confuse(e).appendChild(e2); });
+ expect(() { confuse(e).appendChild(e2); }, throwsNoSuchMethodError);
});
}
@@ -29,20 +26,5 @@
confuse(x) => opaqueTrue() ? x : (opaqueTrue() ? new Object() : new Decoy());
-/** Returns [:true:], but in a way that confuses the compiler. */
+/** Returns `true`, but in a way that confuses the compiler. */
opaqueTrue() => true; // Expand as needed.
-
-checkNoSuchMethod(action()) {
- var ex = null;
- bool threw = false;
- try {
- action();
- } catch (e) {
- threw = true;
- ex = e;
- }
- if (!threw)
- expect(false, isTrue, reason: 'Action should have thrown exception');
-
- expect(ex, isNoSuchMethodError);
-}
diff --git a/pkg/dev_compiler/test/codegen/lib/html/htmlcollection_test.dart b/pkg/dev_compiler/test/codegen/lib/html/htmlcollection_test.dart
index 9781c3c9..4496106 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/htmlcollection_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/htmlcollection_test.dart
@@ -1,8 +1,10 @@
-library ElementListTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
+import 'package:expect/minitest.dart';
+
+bool isChecked(Element e) => (e as CheckboxInputElement).checked;
+bool isUnchecked(Element e) => !(e as CheckboxInputElement).checked;
+
// Test that List<Element> implements List<T>
main() {
Element insertTestDiv() {
@@ -32,15 +34,13 @@
return element;
}
- useHtmlConfiguration();
-
test('IsList', () {
Element root = insertTestDiv();
List<Element> eachChecked =
document.query('#allChecked').children;
- expect(eachChecked, isList);
+ expect(eachChecked is List, isTrue);
root.remove();
});
@@ -60,12 +60,12 @@
expect(someChecked.length, 4);
expect(noneChecked.length, 4);
- expect(eachChecked.every((x) => x.checked), isTrue);
- expect(eachChecked.every((x) => !x.checked), isFalse);
- expect(someChecked.every((x) => x.checked), isFalse);
- expect(someChecked.every((x) => !x.checked), isFalse);
- expect(noneChecked.every((x) => x.checked), isFalse);
- expect(noneChecked.every((x) => !x.checked), isTrue);
+ expect(eachChecked.every(isChecked), isTrue);
+ expect(eachChecked.every(isUnchecked), isFalse);
+ expect(someChecked.every(isChecked), isFalse);
+ expect(someChecked.every(isUnchecked), isFalse);
+ expect(noneChecked.every(isChecked), isFalse);
+ expect(noneChecked.every(isUnchecked), isTrue);
root.remove();
});
@@ -85,12 +85,12 @@
expect(someChecked.length, 4);
expect(noneChecked.length, 4);
- expect(eachChecked.any((x) => x.checked), isTrue);
- expect(eachChecked.any((x) => !x.checked), isFalse);
- expect(someChecked.any((x) => x.checked), isTrue);
- expect(someChecked.any((x) => !x.checked), isTrue);
- expect(noneChecked.any((x) => x.checked), isFalse);
- expect(noneChecked.any((x) => !x.checked), isTrue);
+ expect(eachChecked.any(isChecked), isTrue);
+ expect(eachChecked.any(isUnchecked), isFalse);
+ expect(someChecked.any(isChecked), isTrue);
+ expect(someChecked.any(isUnchecked), isTrue);
+ expect(noneChecked.any(isChecked), isFalse);
+ expect(noneChecked.any(isUnchecked), isTrue);
root.remove();
});
@@ -110,12 +110,12 @@
expect(someChecked.length, 4);
expect(noneChecked.length, 4);
- expect(eachChecked.where((x) => x.checked).length, 4);
- expect(eachChecked.where((x) => !x.checked).length, 0);
- expect(someChecked.where((x) => x.checked).length, 2);
- expect(someChecked.where((x) => !x.checked).length, 2);
- expect(noneChecked.where((x) => x.checked).length, 0);
- expect(noneChecked.where((x) => !x.checked).length, 4);
+ expect(eachChecked.where(isChecked).length, 4);
+ expect(eachChecked.where(isUnchecked).length, 0);
+ expect(someChecked.where(isChecked).length, 2);
+ expect(someChecked.where(isUnchecked).length, 2);
+ expect(noneChecked.where(isChecked).length, 0);
+ expect(noneChecked.where(isUnchecked).length, 4);
root.remove();
});
@@ -161,12 +161,12 @@
expect(someChecked.length, 4);
expect(noneChecked.length, 4);
- expect(countWithForEach(eachChecked, (x) => x.checked), 4);
- expect(countWithForEach(eachChecked, (x) => !x.checked), 0);
- expect(countWithForEach(someChecked, (x) => x.checked), 2);
- expect(countWithForEach(someChecked, (x) => !x.checked), 2);
- expect(countWithForEach(noneChecked, (x) => x.checked), 0);
- expect(countWithForEach(noneChecked, (x) => !x.checked), 4);
+ expect(countWithForEach(eachChecked, isChecked), 4);
+ expect(countWithForEach(eachChecked, isUnchecked), 0);
+ expect(countWithForEach(someChecked, isChecked), 2);
+ expect(countWithForEach(someChecked, isUnchecked), 2);
+ expect(countWithForEach(noneChecked, isChecked), 0);
+ expect(countWithForEach(noneChecked, isUnchecked), 4);
root.remove();
});
@@ -195,12 +195,12 @@
expect(someChecked.length, 4);
expect(noneChecked.length, 4);
- expect(countWithForLoop(eachChecked, (x) => x.checked), 4);
- expect(countWithForLoop(eachChecked, (x) => !x.checked), 0);
- expect(countWithForLoop(someChecked, (x) => x.checked), 2);
- expect(countWithForLoop(someChecked, (x) => !x.checked), 2);
- expect(countWithForLoop(noneChecked, (x) => x.checked), 0);
- expect(countWithForLoop(noneChecked, (x) => !x.checked), 4);
+ expect(countWithForLoop(eachChecked, isChecked), 4);
+ expect(countWithForLoop(eachChecked, isUnchecked), 0);
+ expect(countWithForLoop(someChecked, isChecked), 2);
+ expect(countWithForLoop(someChecked, isUnchecked), 2);
+ expect(countWithForLoop(noneChecked, isChecked), 0);
+ expect(countWithForLoop(noneChecked, isUnchecked), 4);
root.remove();
});
diff --git a/pkg/dev_compiler/test/codegen/lib/html/htmlelement_test.dart b/pkg/dev_compiler/test/codegen/lib/html/htmlelement_test.dart
index fd22c13..10b0070 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/htmlelement_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/htmlelement_test.dart
@@ -1,11 +1,10 @@
-library ElementTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
import 'utils.dart';
main() {
- useHtmlConfiguration();
test('InnerHTML', () {
Element element = new Element.tag('div');
element.id = 'test';
@@ -17,7 +16,7 @@
element.remove();
});
test('HTMLTable', () {
- Element table = new Element.tag('table');
+ TableElement table = new Element.tag('table');
TableRowElement row = new Element.tag('tr');
table.append(row);
diff --git a/pkg/dev_compiler/test/codegen/lib/html/htmloptionscollection_test.dart b/pkg/dev_compiler/test/codegen/lib/html/htmloptionscollection_test.dart
index cc5166a..3c1eaaa 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/htmloptionscollection_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/htmloptionscollection_test.dart
@@ -2,18 +2,15 @@
// 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 HTMLOptionsCollectionTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
-main() {
- useHtmlConfiguration();
+import 'package:expect/minitest.dart';
+main() {
test('indexedAccessTest', () {
// FIXME: we need some massaging to dart:html to enable HTMLOptionsCollection.add
// and hence programatic building of collection.
- final selectElement = new Element.html('''
+ SelectElement selectElement = new Element.html('''
<select>
<option value="0">Option0</option>
<option value="1">Option1</option>
@@ -29,7 +26,7 @@
expect(optionsCollection[1].text, equals('Option1'));
expect(optionsCollection[2].text, equals('Option2'));
- expect(() { optionsCollection[0] = 1; }, throws);
+ expect(() { (optionsCollection as dynamic)[0] = 1; }, throws);
// OPTIONALS optionsCollection[0] = new OptionElement(value: '42', data: 'Option42');
expect(() {
diff --git a/pkg/dev_compiler/test/codegen/lib/html/indexeddb_2_test.dart b/pkg/dev_compiler/test/codegen/lib/html/indexeddb_2_test.dart
index 7350559..f14a3df 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/indexeddb_2_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/indexeddb_2_test.dart
@@ -69,7 +69,7 @@
obj4['a'] = 100;
obj4['b'] = 's';
- var cyclic_list = [1, 2, 3];
+ var cyclic_list = <Object>[1, 2, 3];
cyclic_list[1] = cyclic_list;
go(name, data) => test(name,
diff --git a/pkg/dev_compiler/test/codegen/lib/html/input_element_test.dart b/pkg/dev_compiler/test/codegen/lib/html/input_element_test.dart
index 9509e02..c186399 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/input_element_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/input_element_test.dart
@@ -1,8 +1,7 @@
-library input_element_test;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
import 'dart:html';
+import 'package:expect/minitest.dart';
+
void check(InputElement element, String type, [bool supported = true]) {
expect(element is InputElement, true);
if (supported) {
@@ -13,8 +12,6 @@
}
main() {
- useHtmlIndividualConfiguration();
-
group('supported_search', () {
test('supported', () {
expect(SearchInputElement.supported, true);
diff --git a/pkg/dev_compiler/test/codegen/lib/html/instance_of_test.dart b/pkg/dev_compiler/test/codegen/lib/html/instance_of_test.dart
index da664db..4322afb 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/instance_of_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/instance_of_test.dart
@@ -1,8 +1,7 @@
-library InstanceOfTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
+import 'package:expect/minitest.dart';
+
main() {
CanvasElement canvas;
@@ -13,53 +12,61 @@
var isCanvasRenderingContext = predicate((x) => x is CanvasRenderingContext,
'is a CanvasRenderingContext');
+ var isNotCanvasRenderingContext = predicate((x) => x is! CanvasRenderingContext,
+ 'is not a CanvasRenderingContext');
var isCanvasRenderingContext2D =
predicate((x) => x is CanvasRenderingContext2D,
'is a CanvasRenderingContext2D');
+ var isNotCanvasRenderingContext2D =
+ predicate((x) => x is! CanvasRenderingContext2D,
+ 'is not a CanvasRenderingContext2D');
var isElement = predicate((x) => x is Element, 'is an Element');
+ var isNotElement = predicate((x) => x is! Element, 'is not an Element');
var isCanvasElement =
predicate((x) => x is CanvasElement, 'is a CanvasElement');
+ var isNotCanvasElement =
+ predicate((x) => x is! CanvasElement, 'is not a CanvasElement');
var isImageData = predicate((x) => x is ImageData, 'is an ImageData');
+ var isNotImageData = predicate((x) => x is! ImageData, 'is not an ImageData');
//var isUint8ClampedArray =
// predicate((x) => x is Uint8ClampedArray, 'is a Uint8ClampedArray');
var isIntList =
predicate((x) => x is List<int>, 'is a List<int>');
- useHtmlConfiguration();
test('Instanceof', () {
- expect(canvas, isNot(isCanvasRenderingContext));
- expect(canvas, isNot(isCanvasRenderingContext2D));
+ expect(canvas, isNotCanvasRenderingContext);
+ expect(canvas, isNotCanvasRenderingContext2D);
expect(canvas, isElement);
expect(canvas, isCanvasElement);
- expect(canvas, isNot(isImageData));
+ expect(canvas, isNotImageData);
// expect(canvas, isNot(isCanvasPixelArray));
CanvasRenderingContext2D context = canvas.getContext('2d');
expect(context, isCanvasRenderingContext);
expect(context, isCanvasRenderingContext2D);
- expect(context, isNot(isElement));
- expect(context, isNot(isCanvasElement));
- expect(context, isNot(isImageData));
+ expect(context, isNotElement);
+ expect(context, isNotCanvasElement);
+ expect(context, isNotImageData);
// expect(context, isNot(isCanvasPixelArray));
// FIXME(b/5286633): Interface injection type check workaround.
var image = context.createImageData(canvas.width as dynamic,
canvas.height as dynamic);
- expect(image, isNot(isCanvasRenderingContext));
- expect(image, isNot(isCanvasRenderingContext2D));
- expect(image, isNot(isElement));
- expect(image, isNot(isCanvasElement));
+ expect(image, isNotCanvasRenderingContext);
+ expect(image, isNotCanvasRenderingContext2D);
+ expect(image, isNotElement);
+ expect(image, isNotCanvasElement);
expect(image, isImageData);
// expect(image, isNot(isCanvasPixelArray));
// Include CanvasPixelArray since constructor and prototype are not
// available until one is created.
var bytes = image.data;
- expect(bytes, isNot(isCanvasRenderingContext));
- expect(bytes, isNot(isCanvasRenderingContext2D));
- expect(bytes, isNot(isElement));
- expect(bytes, isNot(isCanvasElement));
- expect(bytes, isNot(isImageData));
+ expect(bytes, isNotCanvasRenderingContext);
+ expect(bytes, isNotCanvasRenderingContext2D);
+ expect(bytes, isNotElement);
+ expect(bytes, isNotCanvasElement);
+ expect(bytes, isNotImageData);
expect(bytes, isIntList);
// FIXME: Ensure this is an SpanElement when we next update
diff --git a/pkg/dev_compiler/test/codegen/lib/html/js_function_getter_test.dart b/pkg/dev_compiler/test/codegen/lib/html/js_function_getter_test.dart
index c8a61b8..4001209 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/js_function_getter_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/js_function_getter_test.dart
@@ -8,9 +8,7 @@
import 'dart:html';
import 'package:js/js.dart';
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
-import 'package:unittest/html_individual_config.dart';
+import 'package:expect/minitest.dart';
_injectJs() {
document.body.append(new ScriptElement()
@@ -63,8 +61,6 @@
main() {
_injectJs();
- useHtmlIndividualConfiguration();
-
group('call getter as function', () {
test('member function', () {
expect(foo.bar.instanceMember(), equals(0));
diff --git a/pkg/dev_compiler/test/codegen/lib/html/js_test.dart b/pkg/dev_compiler/test/codegen/lib/html/js_test.dart
index ae9d9b3..675ddde 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/js_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/js_test.dart
@@ -2,16 +2,12 @@
// 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 jsTest;
-
-import 'dart:async';
import 'dart:html';
import 'dart:typed_data' show ByteBuffer, Int32List;
import 'dart:indexed_db' show IdbFactory, KeyRange;
import 'dart:js';
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
+import 'package:expect/minitest.dart';
_injectJs() {
final script = new ScriptElement();
@@ -230,7 +226,6 @@
main() {
_injectJs();
- useHtmlIndividualConfiguration();
group('identity', () {
@@ -274,7 +269,7 @@
var foo2 = new JsObject(context['Foo'], [2]);
context['foo1'] = foo1;
context['foo2'] = foo2;
- expect(foo1, isNot(equals(context['foo2'])));
+ expect(foo1, notEquals(context['foo2']));
expect(foo2, equals(context['foo2']));
context.deleteProperty('foo1');
context.deleteProperty('foo2');
@@ -325,7 +320,7 @@
var foo = new JsObject(context['Foo'], [42]);
expect(foo['a'], equals(42));
expect(foo.callMethod('bar'), equals(42));
- expect(() => foo.callMethod('baz'), throwsA(isNoSuchMethodError));
+ expect(() => foo.callMethod('baz'), throwsNoSuchMethodError);
});
test('new container.Foo()', () {
@@ -337,7 +332,7 @@
test('new Array()', () {
var a = new JsObject(context['Array']);
- expect(a, new isInstanceOf<JsArray>());
+ expect(a is JsArray, isTrue);
// Test that the object still behaves via the base JsObject interface.
// JsArray specific tests are below.
@@ -444,7 +439,7 @@
test('new JsObject can return a JsFunction', () {
var f = new JsObject(context['Function']);
- expect(f, new isInstanceOf<JsFunction>());
+ expect(f is JsFunction, isTrue);
});
test('JsFunction.apply on a function defined in JS', () {
@@ -458,7 +453,7 @@
test('JsObject.callMethod on a function defined in JS', () {
expect(context.callMethod('razzle'), equals(42));
- expect(() => context.callMethod('dazzle'), throwsA(isNoSuchMethodError));
+ expect(() => context.callMethod('dazzle'), throwsNoSuchMethodError);
});
test('callMethod with many arguments', () {
@@ -477,7 +472,7 @@
test('callMethod throws if name is not a String or num', () {
expect(() => context.callMethod(true),
- throwsA(new isInstanceOf<ArgumentError>()));
+ throwsArgumentError);
});
*/
});
@@ -506,7 +501,7 @@
expect(context.callMethod('isPropertyInstanceOf',
['a', context['Array']]), isTrue);
var a = context['a'];
- expect(a, new isInstanceOf<JsArray>());
+ expect(a is JsArray, isTrue);
expect(a, [1, 2, 3]);
context.deleteProperty('a');
});
@@ -516,8 +511,8 @@
expect(context.callMethod('isPropertyInstanceOf',
['a', context['Array']]), isTrue);
var a = context['a'];
- expect(a, new isInstanceOf<List>());
- expect(a, isNot(new isInstanceOf<JsArray>()));
+ expect(a is List, isTrue);
+ expect(a is JsArray, isFalse);
expect(a, [1, 2, 3]);
context.deleteProperty('a');
});
@@ -526,17 +521,17 @@
var array = new JsArray.from([1, 2]);
expect(array[0], 1);
expect(array[1], 2);
- expect(() => array[-1], throwsA(isRangeError));
- expect(() => array[2], throwsA(isRangeError));
+ expect(() => array[-1], throwsRangeError);
+ expect(() => array[2], throwsRangeError);
});
test('[]=', () {
- var array = new JsArray.from([1, 2]);
+ var array = new JsArray<Object>.from([1, 2]);
array[0] = 'd';
array[1] = 'e';
expect(array, ['d', 'e']);
- expect(() => array[-1] = 3, throwsA(isRangeError));
- expect(() => array[2] = 3, throwsA(isRangeError));
+ expect(() => array[-1] = 3, throwsRangeError);
+ expect(() => array[2] = 3, throwsRangeError);
});
test('length', () {
@@ -575,16 +570,16 @@
expect(array, ['a', 'b']);
array.insert(2, 'c');
expect(array, ['a', 'b', 'c']);
- expect(() => array.insert(4, 'e'), throwsA(isRangeError));
- expect(() => array.insert(-1, 'e'), throwsA(isRangeError));
+ expect(() => array.insert(4, 'e'), throwsRangeError);
+ expect(() => array.insert(-1, 'e'), throwsRangeError);
});
test('removeAt', () {
var array = new JsArray.from(['a', 'b', 'c']);
expect(array.removeAt(1), 'b');
expect(array, ['a', 'c']);
- expect(() => array.removeAt(2), throwsA(isRangeError));
- expect(() => array.removeAt(-1), throwsA(isRangeError));
+ expect(() => array.removeAt(2), throwsRangeError);
+ expect(() => array.removeAt(-1), throwsRangeError);
});
test('removeLast', () {
@@ -592,16 +587,16 @@
expect(array.removeLast(), 'c');
expect(array, ['a', 'b']);
array.length = 0;
- expect(() => array.removeLast(), throwsA(isRangeError));
+ expect(() => array.removeLast(), throwsRangeError);
});
test('removeRange', () {
var array = new JsArray.from(['a', 'b', 'c', 'd']);
array.removeRange(1, 3);
expect(array, ['a', 'd']);
- expect(() => array.removeRange(-1, 2), throwsA(isRangeError));
- expect(() => array.removeRange(0, 3), throwsA(isRangeError));
- expect(() => array.removeRange(2, 1), throwsA(isRangeError));
+ expect(() => array.removeRange(-1, 2), throwsRangeError);
+ expect(() => array.removeRange(0, 3), throwsRangeError);
+ expect(() => array.removeRange(2, 1), throwsRangeError);
});
test('setRange', () {
@@ -639,8 +634,7 @@
test('primitives and null throw ArgumentError', () {
for (var v in ['a', 1, 2.0, true, null]) {
- expect(() => new JsObject.fromBrowserObject(v),
- throwsA(new isInstanceOf<ArgumentError>()));
+ expect(() => new JsObject.fromBrowserObject(v), throwsArgumentError);
}
});
@@ -725,7 +719,7 @@
});
test('deep convert a complex object', () {
- final object = {
+ dynamic object = {
'a': [1, [2, 3]],
'b': {
'c': 3,
@@ -744,8 +738,7 @@
});
test('throws if object is not a Map or Iterable', () {
- expect(() => new JsObject.jsify('a'),
- throwsA(new isInstanceOf<ArgumentError>()));
+ expect(() => new JsObject.jsify('a'), throwsArgumentError);
});
});
@@ -793,7 +786,7 @@
test('deleteProperty throws if name is not a String or num', () {
var object = new JsObject.jsify({});
expect(() => object.deleteProperty(true),
- throwsA(new isInstanceOf<ArgumentError>()));
+ throwsArgumentError);
});
*/
@@ -808,7 +801,7 @@
test('hasProperty throws if name is not a String or num', () {
var object = new JsObject.jsify({});
expect(() => object.hasProperty(true),
- throwsA(new isInstanceOf<ArgumentError>()));
+ throwsArgumentError);
});
*/
@@ -829,9 +822,9 @@
test('[] and []= throw if name is not a String or num', () {
var object = new JsObject.jsify({});
expect(() => object[true],
- throwsA(new isInstanceOf<ArgumentError>()));
+ throwsArgumentError);
expect(() => object[true] = 1,
- throwsA(new isInstanceOf<ArgumentError>()));
+ throwsArgumentError);
});
*/
});
@@ -916,7 +909,7 @@
var list = context.callMethod('getNewInt32Array');
print(list);
expect(list is Int32List, isTrue);
- expect(list, orderedEquals([1, 2, 3, 4, 5, 6, 7, 8]));
+ expect(list, equals([1, 2, 3, 4, 5, 6, 7, 8]));
}
});
@@ -988,7 +981,7 @@
// is called, or if the other tests in this file are enabled
skipIE9_test('ImageData', () {
var canvas = new CanvasElement();
- var ctx = canvas.getContext('2d');
+ var ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
context['o'] = ctx.createImageData(1, 1);
var imageDataType = context['ImageData'];
expect(context.callMethod('isPropertyInstanceOf', ['o', imageDataType]),
diff --git a/pkg/dev_compiler/test/codegen/lib/html/js_typed_interop_anonymous2_exp_test.dart b/pkg/dev_compiler/test/codegen/lib/html/js_typed_interop_anonymous2_exp_test.dart
index d1db741..efd16aa 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/js_typed_interop_anonymous2_exp_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/js_typed_interop_anonymous2_exp_test.dart
@@ -13,8 +13,7 @@
import 'dart:js' as js;
import 'package:js/js.dart';
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
+import 'package:expect/minitest.dart';
@JS() @anonymous
class A {
@@ -42,8 +41,6 @@
}
main() {
- useHtmlConfiguration();
-
test('simple', () {
var b = new B();
var a = new A(b: b);
diff --git a/pkg/dev_compiler/test/codegen/lib/html/js_typed_interop_anonymous2_test.dart b/pkg/dev_compiler/test/codegen/lib/html/js_typed_interop_anonymous2_test.dart
index 449269e..058420a 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/js_typed_interop_anonymous2_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/js_typed_interop_anonymous2_test.dart
@@ -9,8 +9,7 @@
import 'dart:js' as js;
import 'package:js/js.dart';
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
+import 'package:expect/minitest.dart';
@JS() @anonymous
class A {
@@ -38,8 +37,6 @@
}
main() {
- useHtmlConfiguration();
-
test('simple', () {
var b = new B();
var a = new A(b: b);
diff --git a/pkg/dev_compiler/test/codegen/lib/html/js_typed_interop_anonymous_exp_test.dart b/pkg/dev_compiler/test/codegen/lib/html/js_typed_interop_anonymous_exp_test.dart
index 8fdd50f..12af29e 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/js_typed_interop_anonymous_exp_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/js_typed_interop_anonymous_exp_test.dart
@@ -13,8 +13,7 @@
import 'dart:js' as js;
import 'package:js/js.dart';
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
+import 'package:expect/minitest.dart';
@JS() @anonymous
class Literal {
@@ -26,8 +25,6 @@
}
main() {
- useHtmlConfiguration();
-
test('simple', () {
var l = new Literal(x: 3, y: "foo");
expect(l.x, equals(3));
diff --git a/pkg/dev_compiler/test/codegen/lib/html/js_typed_interop_anonymous_test.dart b/pkg/dev_compiler/test/codegen/lib/html/js_typed_interop_anonymous_test.dart
index c4836c8..de36b8e 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/js_typed_interop_anonymous_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/js_typed_interop_anonymous_test.dart
@@ -9,8 +9,7 @@
import 'dart:js' as js;
import 'package:js/js.dart';
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
+import 'package:expect/minitest.dart';
@JS() @anonymous
class Literal {
@@ -22,8 +21,6 @@
}
main() {
- useHtmlConfiguration();
-
test('simple', () {
var l = new Literal(x: 3, y: "foo");
expect(l.x, equals(3));
diff --git a/pkg/dev_compiler/test/codegen/lib/html/js_typed_interop_anonymous_unreachable_exp_test.dart b/pkg/dev_compiler/test/codegen/lib/html/js_typed_interop_anonymous_unreachable_exp_test.dart
index 7754012..1b9dc7d 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/js_typed_interop_anonymous_unreachable_exp_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/js_typed_interop_anonymous_unreachable_exp_test.dart
@@ -13,8 +13,7 @@
import 'dart:js' as js;
import 'package:js/js.dart';
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
+import 'package:expect/minitest.dart';
@JS() @anonymous
class Literal {
@@ -26,7 +25,6 @@
}
main() {
- useHtmlConfiguration();
test('nothing to do', () {
// This test is empty, but it is a regression for Issue# 24974: dartjs
// would crash trying to compile code that used @anonymous and that was
diff --git a/pkg/dev_compiler/test/codegen/lib/html/js_typed_interop_anonymous_unreachable_test.dart b/pkg/dev_compiler/test/codegen/lib/html/js_typed_interop_anonymous_unreachable_test.dart
index bbd97f0..6440c15 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/js_typed_interop_anonymous_unreachable_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/js_typed_interop_anonymous_unreachable_test.dart
@@ -9,8 +9,7 @@
import 'dart:js' as js;
import 'package:js/js.dart';
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
+import 'package:expect/minitest.dart';
@JS() @anonymous
class Literal {
@@ -22,7 +21,6 @@
}
main() {
- useHtmlConfiguration();
test('nothing to do', () {
// This test is empty, but it is a regression for Issue# 24974: dartjs
// would crash trying to compile code that used @anonymous and that was
diff --git a/pkg/dev_compiler/test/codegen/lib/html/js_typed_interop_default_arg_test.dart b/pkg/dev_compiler/test/codegen/lib/html/js_typed_interop_default_arg_test.dart
index 69a0756..963b0ba 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/js_typed_interop_default_arg_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/js_typed_interop_default_arg_test.dart
@@ -7,10 +7,8 @@
import 'dart:html';
-import 'package:expect/expect.dart' show NoInline;
import 'package:js/js.dart';
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
+import 'package:expect/minitest.dart';
_injectJs() {
document.body.append(new ScriptElement()
@@ -34,7 +32,6 @@
main() {
_injectJs();
- useHtmlConfiguration();
test('call directly from dart', () {
expect(Foo.get42(2), 2);
diff --git a/pkg/dev_compiler/test/codegen/lib/html/js_typed_interop_test.dart b/pkg/dev_compiler/test/codegen/lib/html/js_typed_interop_test.dart
index 431d533..cae4b6f 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/js_typed_interop_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/js_typed_interop_test.dart
@@ -8,9 +8,7 @@
import 'dart:html';
import 'package:js/js.dart';
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
-import 'package:unittest/html_individual_config.dart';
+import 'package:expect/minitest.dart';
_injectJs() {
document.body.append(new ScriptElement()
@@ -71,7 +69,7 @@
getA: function() { return this.a;}
};
- var selection = ["a", "b", "c", foo, bar];
+ var selection = ["a", "b", "c", foo, bar];
function returnNumArgs() { return arguments.length; };
function returnLastArg() { return arguments[arguments.length-1]; };
@@ -110,6 +108,14 @@
external get b;
}
+@JS('ClassWithConstructor')
+class ClassWithFactory {
+ external factory ClassWithFactory(aParam, bParam);
+ external getA();
+ external get a;
+ external get b;
+}
+
typedef num MultiplyWithDefault(num a, [num b]);
@JS()
@@ -194,8 +200,6 @@
main() {
_injectJs();
- useHtmlIndividualConfiguration();
-
group('object literal', () {
test('simple', () {
var l = new ExampleLiteral(x: 3, y: "foo");
@@ -223,6 +227,13 @@
expect(o.b, equals("bar"));
expect(o.getA(), equals("foo"));
});
+
+ test('external factory', () {
+ var o = new ClassWithFactory("foo", "bar");
+ expect(o.a, equals("foo"));
+ expect(o.b, equals("bar"));
+ expect(o.getA(), equals("foo"));
+ });
});
group('property', () {
@@ -259,7 +270,7 @@
Function multiplyByX = foo.multiplyByX;
// Tearing off a JS closure doesn't bind this.
// You will need to use the new method tearoff syntax to bind this.
- expect(multiplyByX(4), isNaN);
+ expect(multiplyByX(4), double.NAN);
MultiplyWithDefault multiplyWithDefault = foo.multiplyDefault2Function;
expect(multiplyWithDefault(6, 6), equals(36));
@@ -273,7 +284,7 @@
// Calling a JavaScript method with too few arguments is also fine and
// defaults to JavaScript behavior of setting all unspecified arguments
// to undefined resulting in multiplying undefined by 2 == NAN.
- expect(untypedFunction(), isNaN);
+ expect(untypedFunction(), double.NAN);
});
});
diff --git a/pkg/dev_compiler/test/codegen/lib/html/js_util_test.dart b/pkg/dev_compiler/test/codegen/lib/html/js_util_test.dart
index b0130b2..78ea380 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/js_util_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/js_util_test.dart
@@ -12,9 +12,7 @@
import 'package:js/js.dart';
import 'package:js/js_util.dart' as js_util;
-
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
+import 'package:expect/minitest.dart';
_injectJs() {
final script = new ScriptElement();
@@ -114,7 +112,6 @@
main() {
_injectJs();
- useHtmlIndividualConfiguration();
group('js_util.jsify()', () {
test('convert a List', () {
@@ -148,7 +145,7 @@
});
test('deep convert a complex object', () {
- final object = {
+ dynamic object = {
'a': [
1,
[2, 3]
@@ -175,8 +172,7 @@
});
test('throws if object is not a Map or Iterable', () {
- expect(() => js_util.jsify('a'),
- throwsA(new isInstanceOf<ArgumentError>()));
+ expect(() => js_util.jsify('a'), throwsArgumentError);
});
});
@@ -287,7 +283,7 @@
group('callMethod', () {
test('html object', () {
- var canvas = new Element.tag('canvas');
+ var canvas = new CanvasElement();
expect(
identical(canvas.getContext('2d'),
js_util.callMethod(canvas, 'getContext', ['2d'])),
diff --git a/pkg/dev_compiler/test/codegen/lib/html/localstorage_test.dart b/pkg/dev_compiler/test/codegen/lib/html/localstorage_test.dart
index 3e92b10..2ed126e 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/localstorage_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/localstorage_test.dart
@@ -2,49 +2,42 @@
// 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 LocalStorageTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
+import 'package:expect/minitest.dart';
+
main() {
- useHtmlConfiguration();
+ setUp(() {
+ window.localStorage['key1'] = 'val1';
+ window.localStorage['key2'] = 'val2';
+ window.localStorage['key3'] = 'val3';
+ });
- void testWithLocalStorage(String name, fn()) {
- test(name, () {
- window.localStorage['key1'] = 'val1';
- window.localStorage['key2'] = 'val2';
- window.localStorage['key3'] = 'val3';
+ tearDown(() {
+ window.localStorage.clear();
+ });
- try {
- fn();
- } finally {
- window.localStorage.clear();
- }
- });
- }
-
- testWithLocalStorage('containsValue', () {
+ test('containsValue', () {
expect(window.localStorage.containsValue('does not exist'), isFalse);
expect(window.localStorage.containsValue('key1'), isFalse);
expect(window.localStorage.containsValue('val1'), isTrue);
expect(window.localStorage.containsValue('val3'), isTrue);
});
- testWithLocalStorage('containsKey', () {
+ test('containsKey', () {
expect(window.localStorage.containsKey('does not exist'), isFalse);
expect(window.localStorage.containsKey('val1'), isFalse);
expect(window.localStorage.containsKey('key1'), isTrue);
expect(window.localStorage.containsKey('key3'), isTrue);
});
- testWithLocalStorage('[]', () {
+ test('[]', () {
expect(window.localStorage['does not exist'], isNull);
expect(window.localStorage['key1'], 'val1');
expect(window.localStorage['key3'], 'val3');
});
- testWithLocalStorage('[]=', () {
+ test('[]=', () {
expect(window.localStorage['key4'], isNull);
window.localStorage['key4'] = 'val4';
expect(window.localStorage['key4'], 'val4');
@@ -54,29 +47,32 @@
expect(window.localStorage['key3'], 'val3-new');
});
- testWithLocalStorage('putIfAbsent', () {
+ test('putIfAbsent', () {
expect(window.localStorage['key4'], isNull);
expect(window.localStorage.putIfAbsent('key4', () => 'val4'), 'val4');
expect(window.localStorage['key4'], 'val4');
expect(window.localStorage['key3'], 'val3');
expect(window.localStorage.putIfAbsent('key3',
- () => expect(false, isTrue, reason: 'should not be called')), 'val3');
+ () {
+ fail('should not be called');
+ return 'unused';
+ }), 'val3');
expect(window.localStorage['key3'], 'val3');
});
- testWithLocalStorage('remove', () {
+ test('remove', () {
expect(window.localStorage.remove('does not exist'), isNull);
expect(window.localStorage.remove('key3'), 'val3');
expect(window.localStorage, equals({'key1': 'val1', 'key2': 'val2'}));
});
- testWithLocalStorage('clear', () {
+ test('clear', () {
window.localStorage.clear();
expect(window.localStorage, equals({}));
});
- testWithLocalStorage('forEach', () {
+ test('forEach', () {
Map<String, String> results = {};
window.localStorage.forEach((k, v) {
results[k] = v;
@@ -84,23 +80,23 @@
expect(results, equals({'key1': 'val1', 'key2': 'val2', 'key3': 'val3'}));
});
- testWithLocalStorage('getKeys', () {
+ test('getKeys', () {
expect(window.localStorage.keys.toList(),
unorderedEquals(['key1', 'key2', 'key3']));
});
- testWithLocalStorage('getVals', () {
+ test('getVals', () {
expect(window.localStorage.values.toList(),
unorderedEquals(['val1', 'val2', 'val3']));
});
- testWithLocalStorage('length', () {
+ test('length', () {
expect(window.localStorage.length, 3);
window.localStorage.clear();
expect(window.localStorage.length, 0);
});
- testWithLocalStorage('isEmpty', () {
+ test('isEmpty', () {
expect(window.localStorage.isEmpty, isFalse);
window.localStorage.clear();
expect(window.localStorage.isEmpty, isTrue);
diff --git a/pkg/dev_compiler/test/codegen/lib/html/location_test.dart b/pkg/dev_compiler/test/codegen/lib/html/location_test.dart
index e274a2a0..703456d 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/location_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/location_test.dart
@@ -1,11 +1,8 @@
-library LocationTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
-main() {
- useHtmlConfiguration();
+import 'package:expect/minitest.dart';
+main() {
var isLocation = predicate((x) => x is Location, 'is a Location');
test('location hash', () {
diff --git a/pkg/dev_compiler/test/codegen/lib/html/media_stream_test.dart b/pkg/dev_compiler/test/codegen/lib/html/media_stream_test.dart
index 602c199..7dc5bde 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/media_stream_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/media_stream_test.dart
@@ -2,14 +2,11 @@
// 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 media_stream_test;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
import 'dart:html';
-main() {
- useHtmlIndividualConfiguration();
+import 'package:expect/minitest.dart';
+main() {
group('supported_media', () {
test('supported', () {
expect(MediaStream.supported, true);
diff --git a/pkg/dev_compiler/test/codegen/lib/html/mediasource_test.dart b/pkg/dev_compiler/test/codegen/lib/html/mediasource_test.dart
index 7db8af8..f24b72d 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/mediasource_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/mediasource_test.dart
@@ -1,14 +1,9 @@
-library mediasource_test;
-
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
import 'dart:html';
import 'dart:typed_data';
-import 'dart:async';
+
+import 'package:expect/minitest.dart';
main() {
- useHtmlIndividualConfiguration();
-
var isMediaSource = predicate((x) => x is MediaSource, 'is a MediaSource');
group('supported', () {
diff --git a/pkg/dev_compiler/test/codegen/lib/html/messageevent_test.dart b/pkg/dev_compiler/test/codegen/lib/html/messageevent_test.dart
index 86348fd..ae051f9 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/messageevent_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/messageevent_test.dart
@@ -1,11 +1,8 @@
-library SerializedScriptValueTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
-main() {
- useHtmlConfiguration();
+import 'package:expect/minitest.dart';
+main() {
test('new MessageEvent', () {
final event = new MessageEvent('type', cancelable: true, data: 'data',
origin: 'origin', lastEventId: 'lastEventId');
diff --git a/pkg/dev_compiler/test/codegen/lib/html/mirrors_js_typed_interop_test.dart b/pkg/dev_compiler/test/codegen/lib/html/mirrors_js_typed_interop_test.dart
index f4b30a6..e877295 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/mirrors_js_typed_interop_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/mirrors_js_typed_interop_test.dart
@@ -9,8 +9,7 @@
import 'dart:html';
import 'package:js/js.dart';
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
+import 'package:expect/minitest.dart';
_injectJs() {
document.body.append(new ScriptElement()
@@ -37,8 +36,6 @@
main() {
_injectJs();
- useHtmlConfiguration();
-
test('dynamic dispatch', () {
var f = foo;
expect(f.x, 3);
diff --git a/pkg/dev_compiler/test/codegen/lib/html/mouse_event_test.dart b/pkg/dev_compiler/test/codegen/lib/html/mouse_event_test.dart
index 38792c2..7d7b0d9 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/mouse_event_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/mouse_event_test.dart
@@ -2,14 +2,11 @@
// 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 mouse_event_test;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
-main() {
- useHtmlConfiguration();
+import 'package:expect/minitest.dart';
+main() {
test('relatedTarget', () {
var event = new MouseEvent('mouseout');
expect(event.relatedTarget, isNull);
diff --git a/pkg/dev_compiler/test/codegen/lib/html/navigator_test.dart b/pkg/dev_compiler/test/codegen/lib/html/navigator_test.dart
index 2bc5cc8..c0f2627 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/navigator_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/navigator_test.dart
@@ -1,12 +1,7 @@
-library NavigatorTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
-main() {
- useHtmlConfiguration();
+import 'package:expect/expect.dart';
- test('language never returns null', () {
- expect(window.navigator.language, isNotNull);
- });
+main() {
+ Expect.isNotNull(window.navigator.language);
}
diff --git a/pkg/dev_compiler/test/codegen/lib/html/node_test.dart b/pkg/dev_compiler/test/codegen/lib/html/node_test.dart
index 18f7f36..0e2b435 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/node_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/node_test.dart
@@ -2,14 +2,13 @@
// 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 NodeTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
import 'dart:html';
import 'dart:svg' as svg;
+import 'package:expect/minitest.dart';
+
Node makeNode() => new Element.tag('div');
-Node makeNodeWithChildren() =>
+Element makeNodeWithChildren() =>
new Element.html("<div>Foo<br/><!--baz--></div>");
void testUnsupported(String name, void f()) {
@@ -19,8 +18,6 @@
}
main() {
- useHtmlIndividualConfiguration();
-
var isText = predicate((x) => x is Text, 'is a Text');
var isComment = predicate((x) => x is Comment, 'is a Comment');
var isBRElement = predicate((x) => x is BRElement, 'is a BRElement');
diff --git a/pkg/dev_compiler/test/codegen/lib/html/node_validator_important_if_you_suppress_make_the_bug_critical_test.dart b/pkg/dev_compiler/test/codegen/lib/html/node_validator_important_if_you_suppress_make_the_bug_critical_test.dart
index 4d7d338..84821ff 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/node_validator_important_if_you_suppress_make_the_bug_critical_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/node_validator_important_if_you_suppress_make_the_bug_critical_test.dart
@@ -10,8 +10,9 @@
import 'dart:html';
import 'dart:svg' as svg;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
+
+import 'package:expect/minitest.dart';
+
import 'utils.dart';
void validateHtml(String html, String reference, NodeValidator validator) {
@@ -52,8 +53,6 @@
}
main() {
- useHtmlIndividualConfiguration();
-
group('DOM_sanitization', () {
var validator = new NodeValidatorBuilder.common();
@@ -126,7 +125,7 @@
'</template>';
var fragment = document.body.createFragment(html, validator: validator);
- var template = fragment.nodes.single;
+ var template = fragment.nodes.single as TemplateElement;
var expectedContent = document.body.createFragment(
'<div></div>'
@@ -149,8 +148,9 @@
var fragment = new DocumentFragment.html(html);
fragment.appendHtml('<div id="bad"><script></script></div>');
expect(fragment.childNodes.length, 1);
- expect(fragment.childNodes[0].id, "bad");
- expect(fragment.childNodes[0].childNodes.length, 0);
+ var child = fragment.childNodes[0] as Element;
+ expect(child.id, "bad");
+ expect(child.childNodes.length, 0);
});
testHtml("sanitizes embed",
@@ -500,7 +500,7 @@
'</svg>';
var fragment = new DocumentFragment.svg(svgText);
- var element = fragment.nodes.first;
+ var element = fragment.nodes.first as Element;
expect(element is svg.SvgSvgElement, isTrue);
expect(element.children[0] is svg.ImageElement, isTrue);
});
@@ -542,7 +542,7 @@
var fragment = document.body.createFragment(
"<form onmouseover='alert(2)'><input name='tagName'>",
validator: validator);
- var form = fragment.lastChild;
+ var form = fragment.lastChild as FormElement;
// If the tagName was clobbered, the sanitizer should have removed
// the whole thing and form is null.
// If the tagName was not clobbered, then there will be content,
@@ -557,7 +557,7 @@
var fragment = document.body.createFragment(
"<form><input name='tagName'>",
validator: validator);
- var form = fragment.lastChild;
+ var form = fragment.lastChild as FormElement;
// If the tagName was clobbered, the sanitizer should have removed
// the whole thing and form is null.
// If the tagName was not clobbered, then there will be content,
diff --git a/pkg/dev_compiler/test/codegen/lib/html/non_instantiated_is_test.dart b/pkg/dev_compiler/test/codegen/lib/html/non_instantiated_is_test.dart
index b226ea7..0865b07 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/non_instantiated_is_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/non_instantiated_is_test.dart
@@ -6,15 +6,11 @@
// checks of native classes that are not instantiated.
import 'dart:html';
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
+
+import 'package:expect/expect.dart';
var a = [new Object()];
main() {
- useHtmlConfiguration();
-
- test('is', () {
- expect(a[0] is Node, isFalse);
- });
+ Expect.isFalse(a[0] is Node);
}
diff --git a/pkg/dev_compiler/test/codegen/lib/html/notification_test.dart b/pkg/dev_compiler/test/codegen/lib/html/notification_test.dart
index 077ea54..283dc5b 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/notification_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/notification_test.dart
@@ -2,15 +2,11 @@
// 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 notification_test;
-
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
import 'dart:html';
-main() {
- useHtmlIndividualConfiguration();
+import 'package:expect/minitest.dart';
+main() {
group('supported_notification', () {
test('supported', () {
expect(Notification.supported, true);
diff --git a/pkg/dev_compiler/test/codegen/lib/html/performance_api_test.dart b/pkg/dev_compiler/test/codegen/lib/html/performance_api_test.dart
index f4f1d28..b66feeb 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/performance_api_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/performance_api_test.dart
@@ -1,11 +1,8 @@
-library PerformanceApiTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
import 'dart:html';
-main() {
- useHtmlIndividualConfiguration();
+import 'package:expect/minitest.dart';
+main() {
group('supported', () {
test('supported', () {
expect(Performance.supported, true);
diff --git a/pkg/dev_compiler/test/codegen/lib/html/private_extension_member_test.dart b/pkg/dev_compiler/test/codegen/lib/html/private_extension_member_test.dart
index 4512d9e..0425e95 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/private_extension_member_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/private_extension_member_test.dart
@@ -13,6 +13,6 @@
//
// The createFragment() method sets `_innerHtml` on the element, so we use it
// as a test case.
- Expect.equals("[object DocumentFragment]",
+ Expect.equals("Instance of 'DocumentFragment'",
new BRElement().createFragment("Hi").toString());
}
diff --git a/pkg/dev_compiler/test/codegen/lib/html/query_test.dart b/pkg/dev_compiler/test/codegen/lib/html/query_test.dart
index bffe0d9..f40aa26 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/query_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/query_test.dart
@@ -2,21 +2,18 @@
// 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 QueryTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
-main() {
- useHtmlConfiguration();
+import 'package:expect/minitest.dart';
+main() {
final div = new DivElement();
final canvas = new CanvasElement(width: 200, height: 200);
canvas.id = 'testcanvas';
final element =
new Element.html("<div><br/><img/><input/><img/></div>");
document.body.nodes.addAll([div, canvas, element]);
-
+
var isCanvasElement =
predicate((x) => x is CanvasElement, 'is a CanvasElement');
var isImageElement =
@@ -47,7 +44,7 @@
expect(l.length, 2);
expect(l[0], isImageElement);
expect(l[1], isImageElement);
- expect(l[0], isNot(equals(l[1])));
+ expect(l[0] == l[1], isFalse);
});
test('queryAll (None)', () {
diff --git a/pkg/dev_compiler/test/codegen/lib/html/queryall_test.dart b/pkg/dev_compiler/test/codegen/lib/html/queryall_test.dart
index be4e67b..c8c00f9 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/queryall_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/queryall_test.dart
@@ -2,14 +2,11 @@
// 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 NodeListTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
-main() {
- useHtmlConfiguration();
+import 'package:expect/minitest.dart';
+main() {
var isElement = predicate((x) => x is Element, 'is an Element');
var isCanvasElement =
predicate((x) => x is CanvasElement, 'is a CanvasElement');
@@ -45,7 +42,7 @@
});
test('queryAll-canvas', () {
- List<CanvasElement> all = queryAll('canvas');
+ var all = queryAll('canvas');
for (var e in all) {
expect(e, isCanvasElement);
}
@@ -61,7 +58,7 @@
test('queryAll-where', () {
List<Element> all = queryAll('*');
- Iterable<CanvasElement> canvases = all.where((e) => e is CanvasElement);
+ var canvases = all.where((e) => e is CanvasElement);
for (var e in canvases) {
expect(e is CanvasElement, isTrue);
}
diff --git a/pkg/dev_compiler/test/codegen/lib/html/range_test.dart b/pkg/dev_compiler/test/codegen/lib/html/range_test.dart
index 5c2028d..01739fd 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/range_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/range_test.dart
@@ -1,12 +1,8 @@
-library range_test;
-
import 'dart:html';
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
+
+import 'package:expect/minitest.dart';
main() {
- useHtmlIndividualConfiguration();
-
group('supported', () {
test('supports_createContextualFragment', () {
expect(Range.supportsCreateContextualFragment, isTrue);
diff --git a/pkg/dev_compiler/test/codegen/lib/html/rtc_test.dart b/pkg/dev_compiler/test/codegen/lib/html/rtc_test.dart
index e55e79f..8582b3a 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/rtc_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/rtc_test.dart
@@ -2,17 +2,14 @@
// 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 RealTimeCommunicationTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
import 'dart:html';
-main() {
- useHtmlIndividualConfiguration();
+import 'package:expect/minitest.dart';
+main() {
group('supported', () {
test('supported', () {
- expect(RtcPeerConnection.supported, true);
+ expect(RtcPeerConnection.supported, isTrue);
});
});
diff --git a/pkg/dev_compiler/test/codegen/lib/html/selectelement_test.dart b/pkg/dev_compiler/test/codegen/lib/html/selectelement_test.dart
index b56912c..94a9a29 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/selectelement_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/selectelement_test.dart
@@ -2,14 +2,11 @@
// 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 selectelement_test;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
-main() {
- useHtmlConfiguration();
+import 'package:expect/minitest.dart';
+main() {
test('selectedOptions', () {
var element = new SelectElement();
element.multiple = false;
@@ -64,14 +61,14 @@
'<optgroup>'
'<option>2</option>'
'</optgroup>'
- '</select>');
+ '</select>') as SelectElement;
expect(element.options.length, 2);
element.selectedIndex = 1;
var optGroup = element.children[1];
expect(optGroup is OptGroupElement, isTrue);
- expect(optGroup.children.single.selected, isTrue);
+ expect((optGroup.children.single as OptionElement).selected, isTrue);
expect(element.selectedOptions, optGroup.children);
});
}
diff --git a/pkg/dev_compiler/test/codegen/lib/html/serialized_script_value_test.dart b/pkg/dev_compiler/test/codegen/lib/html/serialized_script_value_test.dart
index 16c8b43..d4f5a9c 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/serialized_script_value_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/serialized_script_value_test.dart
@@ -1,21 +1,20 @@
-library SerializedScriptValueTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
import 'utils.dart';
-serializationTest(name, value) => test(name, () {
+serializationTest(name, value) {
+ test(name, () {
// To check how value is serialized and deserialized, we create a
// MessageEvent.
final event =
new MessageEvent('', data: value, origin: '', lastEventId: '');
verifyGraph(value, event.data);
-});
-
+ });
+}
main() {
- useHtmlConfiguration();
-
serializationTest('null', null);
serializationTest('int', 1);
serializationTest('double', 2.39);
diff --git a/pkg/dev_compiler/test/codegen/lib/html/shadow_dom_test.dart b/pkg/dev_compiler/test/codegen/lib/html/shadow_dom_test.dart
index 323d0e2..704e81a 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/shadow_dom_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/shadow_dom_test.dart
@@ -2,14 +2,11 @@
// 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 ShadowDOMTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
import 'dart:html';
-main() {
- useHtmlIndividualConfiguration();
+import 'package:expect/minitest.dart';
+main() {
group('supported', () {
test('supported', () {
expect(ShadowRoot.supported, true);
@@ -17,7 +14,6 @@
});
group('ShadowDOM_tests', () {
-
var div1, div2, shadowRoot, paragraph1, paragraph2;
init() {
diff --git a/pkg/dev_compiler/test/codegen/lib/html/shadowroot_test.dart b/pkg/dev_compiler/test/codegen/lib/html/shadowroot_test.dart
index c3ac8d9..4e9252d 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/shadowroot_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/shadowroot_test.dart
@@ -2,14 +2,11 @@
// 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 ShadowRootTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
-main() {
- useHtmlConfiguration();
+import 'package:expect/minitest.dart';
+main() {
var isShadowRoot =
predicate((x) => x is ShadowRoot, 'is a ShadowRoot');
diff --git a/pkg/dev_compiler/test/codegen/lib/html/speechrecognition_test.dart b/pkg/dev_compiler/test/codegen/lib/html/speechrecognition_test.dart
index 16fd9de..e85531c 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/speechrecognition_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/speechrecognition_test.dart
@@ -2,14 +2,11 @@
// 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 speech_recognition_test;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
import 'dart:html';
-main() {
- useHtmlIndividualConfiguration();
+import 'package:expect/minitest.dart';
+main() {
group('supported', () {
test('supported', () {
expect(SpeechRecognition.supported, true);
diff --git a/pkg/dev_compiler/test/codegen/lib/html/storage_test.dart b/pkg/dev_compiler/test/codegen/lib/html/storage_test.dart
index b68e9d4..c614ca9 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/storage_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/storage_test.dart
@@ -1,10 +1,8 @@
-library StorageTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
+import 'package:expect/minitest.dart';
+
main() {
- useHtmlConfiguration();
test('GetItem', () {
final value = window.localStorage['does not exist'];
expect(value, isNull);
diff --git a/pkg/dev_compiler/test/codegen/lib/html/streams_test.dart b/pkg/dev_compiler/test/codegen/lib/html/streams_test.dart
index edd77e7..2a43f4c 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/streams_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/streams_test.dart
@@ -1,9 +1,8 @@
-library streams_test;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:async';
import 'dart:html';
+import 'package:expect/minitest.dart';
+
class StreamHelper {
var _a;
StreamHelper() {
@@ -22,8 +21,6 @@
}
main() {
- useHtmlConfiguration();
-
test('simple', () {
var helper = new StreamHelper();
diff --git a/pkg/dev_compiler/test/codegen/lib/html/svg_test.dart b/pkg/dev_compiler/test/codegen/lib/html/svg_test.dart
index b24084a..0477852 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/svg_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/svg_test.dart
@@ -2,15 +2,12 @@
// 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 SVGTest;
import 'dart:html';
import 'dart:svg' as svg;
-import 'package:unittest/html_individual_config.dart';
-import 'package:unittest/unittest.dart';
+
+import 'package:expect/minitest.dart';
main() {
- useHtmlIndividualConfiguration();
-
group('svgPresence', () {
var isSvgElement = predicate((x) => x is svg.SvgElement, 'is a SvgElement');
@@ -42,8 +39,7 @@
</svg>
""");
- expect(logo, isSvgElement);
-
+ expect(logo, isSvgElement);
});
});
@@ -66,9 +62,13 @@
var isSvgElement = predicate((x) => x is svg.SvgElement, 'is a SvgElement');
var isSvgSvgElement =
predicate((x) => x is svg.SvgSvgElement, 'is a SvgSvgElement');
+ var isNotSvgSvgElement =
+ predicate((x) => x is! svg.SvgSvgElement, 'is not a SvgSvgElement');
var isNode = predicate((x) => x is Node, 'is a Node');
var isSvgNumber = predicate((x) => x is svg.Number, 'is a svg.Number');
+ var isNotSvgNumber = predicate((x) => x is! svg.Number, 'is not a svg.Number');
var isSvgRect = predicate((x) => x is svg.Rect, 'is a svg.Rect');
+ var isNotSvgRect = predicate((x) => x is! svg.Rect, 'is not a svg.Rect');
test('rect_isChecks', () {
var div = insertTestDiv();
@@ -80,9 +80,9 @@
expect(r, isNode);
// Interfaces not implemented.
- expect(r, isNot(isSvgNumber));
- expect(r, isNot(isSvgRect));
- expect(r, isNot(isSvgSvgElement));
+ expect(r, isNotSvgNumber);
+ expect(r, isNotSvgRect);
+ expect(r, isNotSvgSvgElement);
div.remove();
});
diff --git a/pkg/dev_compiler/test/codegen/lib/html/svgelement_test.dart b/pkg/dev_compiler/test/codegen/lib/html/svgelement_test.dart
index 1fa7259..bd66420 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/svgelement_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/svgelement_test.dart
@@ -2,16 +2,12 @@
// 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 SvgElementTest;
import 'dart:html';
import 'dart:svg' as svg;
-import 'package:expect/expect.dart';
-import 'package:unittest/html_individual_config.dart';
-import 'package:unittest/unittest.dart';
+
+import 'package:expect/minitest.dart';
main() {
- useHtmlIndividualConfiguration();
-
var isSvgSvgElement =
predicate((x) => x is svg.SvgSvgElement, 'is a SvgSvgElement');
@@ -47,12 +43,12 @@
"</svg>";
final el = new svg.SvgElement.svg(svgContent);
expect(el, isSvgSvgElement);
- expect(el.innerHtml, anyOf("<circle></circle><path></path>", '<circle '
+ expect(el.innerHtml, anyOf(["<circle></circle><path></path>", '<circle '
'xmlns="http://www.w3.org/2000/svg" /><path '
- 'xmlns="http://www.w3.org/2000/svg" />'));
- expect(el.outerHtml, anyOf(svgContent,
+ 'xmlns="http://www.w3.org/2000/svg" />']));
+ expect(el.outerHtml, anyOf([svgContent,
'<svg xmlns="http://www.w3.org/2000/svg" version="1.1">\n '
- '<circle />\n <path />\n</svg>'));
+ '<circle />\n <path />\n</svg>']));
});
test('has no parent', () =>
diff --git a/pkg/dev_compiler/test/codegen/lib/html/table_test.dart b/pkg/dev_compiler/test/codegen/lib/html/table_test.dart
index 7432e5d..fca7e3a 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/table_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/table_test.dart
@@ -2,14 +2,11 @@
// 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 TableTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
-main() {
- useHtmlConfiguration();
+import 'package:expect/minitest.dart';
+main() {
test('createTBody', () {
var table = new TableElement();
var head = table.createTHead();
diff --git a/pkg/dev_compiler/test/codegen/lib/html/text_event_test.dart b/pkg/dev_compiler/test/codegen/lib/html/text_event_test.dart
index 5be0651..038e153 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/text_event_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/text_event_test.dart
@@ -2,17 +2,13 @@
// 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 text_event_test;
-import "package:expect/expect.dart";
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
+import 'package:expect/minitest.dart';
+
import 'event_test.dart';
main() {
- useHtmlConfiguration();
-
eventTest('TextEvent', () => new TextEvent('foo', view: window, data: 'data'),
(ev) { expect(ev.data, 'data'); });
}
diff --git a/pkg/dev_compiler/test/codegen/lib/html/touchevent_test.dart b/pkg/dev_compiler/test/codegen/lib/html/touchevent_test.dart
index fba6e61..cd60245 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/touchevent_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/touchevent_test.dart
@@ -2,14 +2,11 @@
// 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 touch_event_test;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
import 'dart:html';
-main() {
- useHtmlIndividualConfiguration();
+import 'package:expect/minitest.dart';
+main() {
group('supported', () {
test('supported', () {
expect(TouchEvent.supported, true);
diff --git a/pkg/dev_compiler/test/codegen/lib/html/track_element_constructor_test.dart b/pkg/dev_compiler/test/codegen/lib/html/track_element_constructor_test.dart
index 883dabd..b2077ee 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/track_element_constructor_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/track_element_constructor_test.dart
@@ -11,19 +11,18 @@
import 'dart:html';
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
+import 'package:expect/minitest.dart';
void main() {
- useHtmlConfiguration();
test('', () {
if (!TrackElement.supported) return;
document.body.append(new TrackElement()..defaultValue = true);
- if (!document.query('track').defaultValue) {
+ var trackElement = document.query('track') as TrackElement;
+ if (!trackElement.defaultValue) {
throw 'Expected default value to be true';
}
- document.query('track').defaultValue = false;
- if (document.query('track').defaultValue) {
+ trackElement.defaultValue = false;
+ if (trackElement.defaultValue) {
throw 'Expected default value to be false';
}
});
diff --git a/pkg/dev_compiler/test/codegen/lib/html/trusted_html_tree_sanitizer_test.dart b/pkg/dev_compiler/test/codegen/lib/html/trusted_html_tree_sanitizer_test.dart
index c03e39d..3f9a534 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/trusted_html_tree_sanitizer_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/trusted_html_tree_sanitizer_test.dart
@@ -6,14 +6,13 @@
/// for prevent XSS or other attacks. If you suppress this, or parts of it
/// please make it a critical bug and bring it to the attention of the
/// dart:html maintainers.
-library trusted_html_tree_sanitizer_test;
-
+import 'dart:js' as js;
import 'dart:html';
import 'dart:svg' as svg;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
+
+import 'package:expect/minitest.dart';
+
import 'utils.dart';
-import 'dart:js' as js;
var oldAdoptNode;
var jsDocument;
@@ -33,8 +32,6 @@
}
main() {
- useHtmlIndividualConfiguration();
-
group('not_create_document_fragment', () {
setUp(makeDocumentFragmentAdoptionThrow);
tearDown(restoreOldAdoptNode);
diff --git a/pkg/dev_compiler/test/codegen/lib/html/typed_arrays_1_test.dart b/pkg/dev_compiler/test/codegen/lib/html/typed_arrays_1_test.dart
index c3eb811..3bbd336 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/typed_arrays_1_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/typed_arrays_1_test.dart
@@ -2,17 +2,16 @@
// 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 TypedArrays1Test;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
import 'dart:html';
import 'dart:typed_data';
-main() {
- useHtmlIndividualConfiguration();
+import 'package:expect/minitest.dart';
- var isnumList = predicate((x) => x is List<num>, 'is a List<num>');
- var isStringList = predicate((x) => x is List<String>, 'is a List<String>');
+main() {
+ var isList = predicate((x) => x is List, 'is a List');
+ var isNumList = predicate((x) => x is List<num>, 'is a List<num>');
+ var isNotStringList =
+ predicate((x) => x is! List<String>, 'is not a List<String>');
var expectation = Platform.supportsTypedData ? returnsNormally : throws;
group('supported', () {
@@ -63,8 +62,8 @@
expect(() {
var a = new Float32List(10);
expect(a, isList);
- expect(a, isnumList);
- expect(a, isNot(isStringList));
+ expect(a, isNumList);
+ expect(a, isNotStringList);
}, expectation);
});
}
diff --git a/pkg/dev_compiler/test/codegen/lib/html/typed_arrays_2_test.dart b/pkg/dev_compiler/test/codegen/lib/html/typed_arrays_2_test.dart
index 5a0d83a..15a0bd6 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/typed_arrays_2_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/typed_arrays_2_test.dart
@@ -2,15 +2,12 @@
// 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 TypedArrays2Test;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
import 'dart:typed_data';
-main() {
- useHtmlConfiguration();
+import 'package:expect/minitest.dart';
+main() {
// Only perform tests if ArrayBuffer is supported.
if (!Platform.supportsTypedData) {
return;
diff --git a/pkg/dev_compiler/test/codegen/lib/html/typed_arrays_3_test.dart b/pkg/dev_compiler/test/codegen/lib/html/typed_arrays_3_test.dart
index efa4e17..b465a99 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/typed_arrays_3_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/typed_arrays_3_test.dart
@@ -2,15 +2,12 @@
// 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 TypedArrays3Test;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
import 'dart:typed_data';
-main() {
- useHtmlConfiguration();
+import 'package:expect/minitest.dart';
+main() {
// Only perform tests if ArrayBuffer is supported.
if (!Platform.supportsTypedData) {
return;
diff --git a/pkg/dev_compiler/test/codegen/lib/html/typed_arrays_4_test.dart b/pkg/dev_compiler/test/codegen/lib/html/typed_arrays_4_test.dart
index 9f00357..c75ade8 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/typed_arrays_4_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/typed_arrays_4_test.dart
@@ -2,15 +2,12 @@
// 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 TypedArrays4Test;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
import 'dart:typed_data';
-main() {
- useHtmlConfiguration();
+import 'package:expect/minitest.dart';
+main() {
// Only perform tests if ArrayBuffer is supported.
if (!Platform.supportsTypedData) {
return;
diff --git a/pkg/dev_compiler/test/codegen/lib/html/typed_arrays_5_test.dart b/pkg/dev_compiler/test/codegen/lib/html/typed_arrays_5_test.dart
index db149f6..555a7c9 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/typed_arrays_5_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/typed_arrays_5_test.dart
@@ -2,15 +2,12 @@
// 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 typed_arrays_5_test;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
import 'dart:typed_data';
-main() {
- useHtmlConfiguration();
+import 'package:expect/minitest.dart';
+main() {
// Only perform tests if ArrayBuffer is supported.
if (!Platform.supportsTypedData) {
return;
diff --git a/pkg/dev_compiler/test/codegen/lib/html/typed_arrays_arraybuffer_test.dart b/pkg/dev_compiler/test/codegen/lib/html/typed_arrays_arraybuffer_test.dart
index 07541c8..69c98bb 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/typed_arrays_arraybuffer_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/typed_arrays_arraybuffer_test.dart
@@ -2,15 +2,12 @@
// 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 typed_arrays_arraybuffer_test;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
import 'dart:typed_data';
-main() {
- useHtmlConfiguration();
+import 'package:expect/minitest.dart';
+main() {
// Only perform tests if ArrayBuffer is supported.
if (!Platform.supportsTypedData) {
return;
diff --git a/pkg/dev_compiler/test/codegen/lib/html/typed_arrays_dataview_test.dart b/pkg/dev_compiler/test/codegen/lib/html/typed_arrays_dataview_test.dart
index a56aecd..cd78a40 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/typed_arrays_dataview_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/typed_arrays_dataview_test.dart
@@ -2,15 +2,12 @@
// 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 typed_arrays_dataview_test;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
import 'dart:typed_data';
-main() {
- useHtmlConfiguration();
+import 'package:expect/minitest.dart';
+main() {
// Only perform tests if ArrayBuffer is supported.
if (!Platform.supportsTypedData) {
return;
diff --git a/pkg/dev_compiler/test/codegen/lib/html/typed_arrays_range_checks_test.dart b/pkg/dev_compiler/test/codegen/lib/html/typed_arrays_range_checks_test.dart
index 1eb2222..4551f98 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/typed_arrays_range_checks_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/typed_arrays_range_checks_test.dart
@@ -2,12 +2,11 @@
// 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 TypedArraysRangeCheckTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
import 'dart:typed_data';
+import 'package:expect/minitest.dart';
+
const N = 1024;
class _TestList {
@@ -28,14 +27,12 @@
}
main() {
- useHtmlConfiguration();
-
// Only perform tests if ArrayBuffer is supported.
if (!Platform.supportsTypedData) {
return;
}
- test('outOfRangeAccess_dynamic', () {
+ test('outOfRangeAccess', () {
var a = _obfuscatedList();
expect(() => a[a.length], throws);
@@ -54,24 +51,4 @@
expect(() => a[1.5] = 0xdeadbeef, throws);
expect(() => a['length'] = 1, throws);
});
-
- test('outOfRange_typed', () {
- Uint8List a = new Uint8List(N);
-
- expect(() => a[a.length], throws);
- expect(() => a[a.length + 1], throws);
- expect(() => a[a.length + N], throws);
-
- expect(() => a[-1], throws);
- expect(() => a[1.5], throws);
- expect(() => a['length'], throws);
-
- expect(() => a[a.length] = 0xdeadbeef, throws);
- expect(() => a[a.length + 1] = 0xdeadbeef, throws);
- expect(() => a[a.length + N] = 0xdeadbeef, throws);
-
- expect(() => a[-1] = 0xdeadbeef, throws);
- expect(() => a[1.5] = 0xdeadbeef, throws);
- expect(() => a['length'] = 1, throws);
- });
}
diff --git a/pkg/dev_compiler/test/codegen/lib/html/typed_arrays_simd_test.dart b/pkg/dev_compiler/test/codegen/lib/html/typed_arrays_simd_test.dart
index 0e3d780..5de04dd 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/typed_arrays_simd_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/typed_arrays_simd_test.dart
@@ -2,12 +2,11 @@
// 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 TypedArraysSimdTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
import 'dart:typed_data';
+import 'package:expect/minitest.dart';
+
const _FLOATING_POINT_ERROR = 0.0000000001;
floatEquals(value) => closeTo(value, _FLOATING_POINT_ERROR);
@@ -19,8 +18,6 @@
}
main() {
- useHtmlConfiguration();
-
// Only perform tests if ArrayBuffer is supported.
if (!Platform.supportsTypedData) {
return;
diff --git a/pkg/dev_compiler/test/codegen/lib/html/typing_test.dart b/pkg/dev_compiler/test/codegen/lib/html/typing_test.dart
index 68ba294..e353bf5 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/typing_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/typing_test.dart
@@ -1,11 +1,8 @@
-library TypingTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
-main() {
- useHtmlConfiguration();
+import 'package:expect/minitest.dart';
+main() {
var isStyleSheetList =
predicate((x) => x is List<StyleSheet>, 'is a List<StyleSheet>');
@@ -23,15 +20,16 @@
});
test('StyleSheetList', () {
- List<StyleSheet> asList = window.document.styleSheets;
+ var document = window.document as HtmlDocument;
+ List<StyleSheet> asList = document.styleSheets;
expect(asList, isStyleSheetList);
// Check it's Iterable.
int counter = 0;
- for (StyleSheet styleSheet in window.document.styleSheets) {
+ for (StyleSheet styleSheet in document.styleSheets) {
counter++;
}
- // There is one style sheet from the unittest framework.
- expect(counter, 1);
+ // There are no style sheets.
+ expect(counter, 0);
});
}
diff --git a/pkg/dev_compiler/test/codegen/lib/html/unknownelement_test.dart b/pkg/dev_compiler/test/codegen/lib/html/unknownelement_test.dart
index 21ba1ef..43b30cf 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/unknownelement_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/unknownelement_test.dart
@@ -2,22 +2,19 @@
// 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 UnknownElementTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
-main() {
- useHtmlConfiguration();
+import 'package:expect/minitest.dart';
+main() {
var isUnknownElement =
predicate((x) => x is UnknownElement, 'is an UnknownELement');
- var foo = new Element.tag('foo');
+ dynamic foo = new Element.tag('foo');
foo.id = 'foo';
var bar = new Element.tag('bar');
bar.id = 'bar';
- document.body.nodes.addAll([foo, bar]);
+ document.body.nodes.addAll(<Node>[foo, bar]);
test('type-check', () {
expect(foo, isUnknownElement);
diff --git a/pkg/dev_compiler/test/codegen/lib/html/uri_test.dart b/pkg/dev_compiler/test/codegen/lib/html/uri_test.dart
index 90798849..32ec865 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/uri_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/uri_test.dart
@@ -2,13 +2,11 @@
// 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:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
-main() {
- useHtmlConfiguration();
+import 'package:expect/minitest.dart';
+main() {
test('Uri.base', () {
expect(Uri.base.scheme, "http");
expect(Uri.base.toString(), window.location.href);
diff --git a/pkg/dev_compiler/test/codegen/lib/html/util.dart b/pkg/dev_compiler/test/codegen/lib/html/util.dart
index 52735f2..0cf55fb 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/util.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/util.dart
@@ -5,15 +5,13 @@
library test.html.util;
import 'dart:html';
-import 'package:unittest/unittest.dart';
+import 'package:expect/minitest.dart';
-void expectUnsupported(f) => expect(f, throwsUnsupportedError);
-
-void expectEmptyRect(ClientRect rect) {
- expect(rect.bottom, isZero);
- expect(rect.top, isZero);
- expect(rect.left, isZero);
- expect(rect.right, isZero);
- expect(rect.height, isZero);
- expect(rect.width, isZero);
+void expectEmptyRect(Rectangle rect) {
+ expect(rect.bottom, 0);
+ expect(rect.top, 0);
+ expect(rect.left, 0);
+ expect(rect.right, 0);
+ expect(rect.height, 0);
+ expect(rect.width, 0);
}
diff --git a/pkg/dev_compiler/test/codegen/lib/html/webgl_1_test.dart b/pkg/dev_compiler/test/codegen/lib/html/webgl_1_test.dart
index d6e6f1f..ce296ee 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/webgl_1_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/webgl_1_test.dart
@@ -2,19 +2,19 @@
// 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 web_gl_test;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
import 'dart:html';
import 'dart:typed_data';
import 'dart:web_gl';
import 'dart:web_gl' as gl;
+import 'package:expect/minitest.dart';
+
// Test that WebGL is present in dart:web_gl API
-main() {
- useHtmlIndividualConfiguration();
+final isRenderingContext = predicate((x) => x is RenderingContext);
+final isContextAttributes = predicate((x) => x is gl.ContextAttributes);
+main() {
group('supported', () {
test('supported', () {
expect(RenderingContext.supported, isTrue);
@@ -27,7 +27,7 @@
var context = canvas.getContext3d();
if (RenderingContext.supported) {
expect(context, isNotNull);
- expect(context, new isInstanceOf<RenderingContext>());
+ expect(context, isRenderingContext);
} else {
expect(context, isNull);
}
@@ -36,7 +36,8 @@
if (RenderingContext.supported) {
test('simple', () {
var canvas = new CanvasElement();
- var context = canvas.getContext('experimental-webgl');
+ var context =
+ canvas.getContext('experimental-webgl') as gl.RenderingContext;
var shader = context.createShader(gl.VERTEX_SHADER);
context.shaderSource(shader, 'void main() { }');
context.compileShader(shader);
@@ -48,11 +49,11 @@
var canvas = new CanvasElement();
var context = canvas.getContext3d();
expect(context, isNotNull);
- expect(context, new isInstanceOf<RenderingContext>());
+ expect(context, isRenderingContext);
context = canvas.getContext3d(depth: false);
expect(context, isNotNull);
- expect(context, new isInstanceOf<RenderingContext>());
+ expect(context, isRenderingContext);
});
test('texImage2D', () {
@@ -95,7 +96,7 @@
var attributes = context.getContextAttributes();
expect(attributes, isNotNull);
- expect(attributes, new isInstanceOf<gl.ContextAttributes>());
+ expect(attributes, isContextAttributes);
expect(attributes.alpha, isBoolean);
expect(attributes.antialias, isBoolean);
diff --git a/pkg/dev_compiler/test/codegen/lib/html/window_eq_test.dart b/pkg/dev_compiler/test/codegen/lib/html/window_eq_test.dart
index 6995a90..93313ab 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/window_eq_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/window_eq_test.dart
@@ -1,14 +1,12 @@
-library WindowEqualityTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
+import 'package:expect/minitest.dart';
+
main() {
- useHtmlConfiguration();
var obfuscated = null;
test('notNull', () {
expect(window, isNotNull);
- expect(window, isNot(equals(obfuscated)));
+ expect(window != obfuscated, isTrue);
});
}
diff --git a/pkg/dev_compiler/test/codegen/lib/html/window_mangling_test.dart b/pkg/dev_compiler/test/codegen/lib/html/window_mangling_test.dart
index f1a8b38..46f03c8 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/window_mangling_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/window_mangling_test.dart
@@ -2,11 +2,10 @@
// 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 WindowManglingTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html' as dom;
+import 'package:expect/minitest.dart';
+
// Defined in dom.Window.
get navigator => "Dummy";
@@ -14,13 +13,12 @@
$eq$(x, y) => false;
main() {
- useHtmlConfiguration();
var win = dom.window;
test('windowMethod', () {
final message = navigator;
final x = win.navigator;
- expect(x, isNot(equals(message)));
+ expect(x, notEquals(message));
});
test('windowEquals', () {
diff --git a/pkg/dev_compiler/test/codegen/lib/html/window_nosuchmethod_test.dart b/pkg/dev_compiler/test/codegen/lib/html/window_nosuchmethod_test.dart
index 93cb592..4cc84b4 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/window_nosuchmethod_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/window_nosuchmethod_test.dart
@@ -2,12 +2,10 @@
// 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 WindowNSMETest;
-import "package:expect/expect.dart";
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html' as dom;
+import 'package:expect/minitest.dart';
+
// Not defined in dom.Window.
foo(x) => x;
@@ -18,20 +16,12 @@
int inscrutable(int x) => x == 0 ? 0 : x | inscrutable(x & (x - 1));
main() {
- useHtmlConfiguration();
- var things = [new Unused(), dom.window];
+ var things = <dynamic>[new Unused(), dom.window];
test('windowNonMethod', () {
var win = things[inscrutable(1)];
final message = foo("Hello World");
- try {
- String x = win.foo(message);
- expect(false, isTrue, reason: 'Should not reach here: $x');
- } on NoSuchMethodError catch (e) {
- // Expected exception.
- } on Exception catch (e) {
- expect(false, isTrue, reason: 'Wrong exception: $e');
- }
+ expect(() => win.foo(message), throwsNoSuchMethodError);
});
test('foo', () {
@@ -40,16 +30,10 @@
expect(x, 'not bar');
});
- // Use dom.window direclty in case the compiler does type inference.
+ // Use dom.window directly in case the compiler does type inference.
test('windowNonMethod2', () {
final message = foo("Hello World");
- try {
- String x = dom.window.foo(message);
- expect(false, isTrue, reason: 'Should not reach here: $x');
- } on NoSuchMethodError catch (e) {
- // Expected exception.
- } on Exception catch (e) {
- expect(false, isTrue, reason: 'Wrong exception: $e');
- }
+ expect(() => (dom.window as dynamic).foo(message),
+ throwsNoSuchMethodError);
});
}
diff --git a/pkg/dev_compiler/test/codegen/lib/html/window_test.dart b/pkg/dev_compiler/test/codegen/lib/html/window_test.dart
index 51ccdfd..ab79e66 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/window_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/window_test.dart
@@ -2,14 +2,11 @@
// 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 WindowTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
import 'dart:html';
-main() {
- useHtmlConfiguration();
+import 'package:expect/minitest.dart';
+main() {
test('scrollXY', () {
expect(window.scrollX, 0);
expect(window.scrollY, 0);
diff --git a/pkg/dev_compiler/test/codegen/lib/html/wrapping_collections_test.dart b/pkg/dev_compiler/test/codegen/lib/html/wrapping_collections_test.dart
index 218d255..0d4fa1f 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/wrapping_collections_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/wrapping_collections_test.dart
@@ -1,10 +1,8 @@
-library wrapping_collection_test;
-
import 'dart:html';
import 'dart:html_common';
import 'dart:js' as js;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_config.dart';
+
+import 'package:expect/minitest.dart';
/// Test that if we access objects through JS-interop we get the
/// appropriate objects, even if dart:html maps them.
diff --git a/pkg/dev_compiler/test/codegen/lib/html/xsltprocessor_test.dart b/pkg/dev_compiler/test/codegen/lib/html/xsltprocessor_test.dart
index b645d81..3dd93a8 100644
--- a/pkg/dev_compiler/test/codegen/lib/html/xsltprocessor_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/html/xsltprocessor_test.dart
@@ -1,12 +1,8 @@
-library XSLTProcessorTest;
-import 'package:unittest/unittest.dart';
-import 'package:unittest/html_individual_config.dart';
import 'dart:html';
+import 'package:expect/minitest.dart';
+
main() {
-
- useHtmlIndividualConfiguration();
-
group('supported', () {
test('supported', () {
expect(XsltProcessor.supported, true);
diff --git a/pkg/dev_compiler/test/codegen/lib/math/point_test.dart b/pkg/dev_compiler/test/codegen/lib/math/point_test.dart
index 93d6c4a..cb694b9 100644
--- a/pkg/dev_compiler/test/codegen/lib/math/point_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/math/point_test.dart
@@ -2,89 +2,98 @@
// 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 point_test;
-
import 'dart:math';
-import 'package:unittest/unittest.dart';
+import 'package:expect/expect.dart';
main() {
- test('constructor', () {
+ // constructor
+ {
var point = new Point(0, 0);
- expect(point.x, 0);
- expect(point.y, 0);
- expect('$point', 'Point(0, 0)');
- });
+ Expect.equals(0, point.x);
+ Expect.equals(0, point.y);
+ Expect.equals('Point(0, 0)', '$point');
+ }
- test('constructor X', () {
+ // constructor X
+ {
var point = new Point<int>(10, 0);
- expect(point.x, 10);
- expect(point.y, 0);
- expect('$point', 'Point(10, 0)');
- });
+ Expect.equals(10, point.x);
+ Expect.equals(0, point.y);
+ Expect.equals('Point(10, 0)', '$point');
+ }
- test('constructor X Y', () {
+ // constructor X Y
+ {
var point = new Point<int>(10, 20);
- expect(point.x, 10);
- expect(point.y, 20);
- expect('$point', 'Point(10, 20)');
- });
+ Expect.equals(10, point.x);
+ Expect.equals(20, point.y);
+ Expect.equals('Point(10, 20)', '$point');
+ }
- test('constructor X Y double', () {
+ // constructor X Y double
+ {
var point = new Point<double>(10.5, 20.897);
- expect(point.x, 10.5);
- expect(point.y, 20.897);
- expect('$point', 'Point(10.5, 20.897)');
- });
+ Expect.equals(10.5, point.x);
+ Expect.equals(20.897, point.y);
+ Expect.equals('Point(10.5, 20.897)', '$point');
+ }
- test('constructor X Y NaN', () {
+ // constructor X Y NaN
+ {
var point = new Point(double.NAN, 1000);
- expect(point.x, isNaN);
- expect(point.y, 1000);
- expect('$point', 'Point(NaN, 1000)');
- });
+ Expect.isTrue(point.x.isNaN);
+ Expect.equals(1000, point.y);
+ Expect.equals('Point(NaN, 1000)', '$point');
+ }
- test('squaredDistanceTo', () {
+ // squaredDistanceTo
+ {
var a = new Point(7, 11);
var b = new Point(3, -1);
- expect(a.squaredDistanceTo(b), 160);
- expect(b.squaredDistanceTo(a), 160);
- });
+ Expect.equals(160, a.squaredDistanceTo(b));
+ Expect.equals(160, b.squaredDistanceTo(a));
+ }
- test('distanceTo', () {
+ // distanceTo
+ {
var a = new Point(-2, -3);
var b = new Point(2, 0);
- expect(a.distanceTo(b), 5);
- expect(b.distanceTo(a), 5);
- });
+ Expect.equals(5, a.distanceTo(b));
+ Expect.equals(5, b.distanceTo(a));
+ }
- test('subtract', () {
+ // subtract
+ {
var a = new Point(5, 10);
var b = new Point(2, 50);
- expect(a - b, new Point(3, -40));
- });
+ Expect.equals(new Point(3, -40), a - b);
+ }
- test('add', () {
+ // add
+ {
var a = new Point(5, 10);
var b = new Point(2, 50);
- expect(a + b, new Point(7, 60));
- });
+ Expect.equals(new Point(7, 60), a + b);
+ }
- test('hashCode', () {
+ // hashCode
+ {
var a = new Point(0, 1);
var b = new Point(0, 1);
- expect(a.hashCode, b.hashCode);
+ Expect.equals(b.hashCode, a.hashCode);
var c = new Point(1, 0);
- expect(a.hashCode == c.hashCode, isFalse);
- });
+ Expect.isFalse(a.hashCode == c.hashCode);
+ }
- test('magnitute', () {
+ // magnitude
+ {
var a = new Point(5, 10);
var b = new Point(0, 0);
- expect(a.magnitude, a.distanceTo(b));
- expect(b.magnitude, 0);
+ Expect.equals(a.distanceTo(b), a.magnitude);
+ Expect.equals(0, b.magnitude);
var c = new Point(-5, -10);
- expect(c.magnitude, a.distanceTo(b));
- });
+ Expect.equals(a.distanceTo(b), c.magnitude);
+ }
}
diff --git a/pkg/dev_compiler/test/codegen/lib/math/rectangle_test.dart b/pkg/dev_compiler/test/codegen/lib/math/rectangle_test.dart
index baacd96..493a614 100644
--- a/pkg/dev_compiler/test/codegen/lib/math/rectangle_test.dart
+++ b/pkg/dev_compiler/test/codegen/lib/math/rectangle_test.dart
@@ -2,249 +2,254 @@
// 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 rect_test;
-
import 'dart:math';
-import 'package:unittest/unittest.dart';
+import 'package:expect/expect.dart';
main() {
- Rectangle createRectangle(List<num> a) {
- return a != null ? new Rectangle(a[0], a[1], a[2] - a[0], a[3] - a[1])
- : null;
- }
-
- test('construction', () {
- var r0 = new Rectangle(10, 20, 30, 40);
- expect(r0.toString(), 'Rectangle (10, 20) 30 x 40');
- expect(r0.right, 40);
- expect(r0.bottom, 60);
-
- var r1 = new Rectangle.fromPoints(r0.topLeft, r0.bottomRight);
- expect(r1, r0);
-
- var r2 = new Rectangle.fromPoints(r0.bottomRight, r0.topLeft);
- expect(r2, r0);
- });
-
- test('intersection', () {
- var tests = [
- [[10, 10, 20, 20], [15, 15, 25, 25], [15, 15, 20, 20]],
- [[10, 10, 20, 20], [20, 0, 30, 10], [20, 10, 20, 10]],
- [[0, 0, 1, 1], [10, 11, 12, 13], null],
- [[11, 12, 98, 99], [22, 23, 34, 35], [22, 23, 34, 35]]];
-
- for (var test in tests) {
- var r0 = createRectangle(test[0]);
- var r1 = createRectangle(test[1]);
- var expected = createRectangle(test[2]);
-
- expect(r0.intersection(r1), expected);
- expect(r1.intersection(r0), expected);
- }
- });
-
- test('intersects', () {
- var r0 = new Rectangle(10, 10, 20, 20);
- var r1 = new Rectangle(15, 15, 25, 25);
- var r2 = new Rectangle(0, 0, 1, 1);
-
- expect(r0.intersects(r1), isTrue);
- expect(r1.intersects(r0), isTrue);
-
- expect(r0.intersects(r2), isFalse);
- expect(r2.intersects(r0), isFalse);
- });
-
- test('boundingBox', () {
- var tests = [
- [[10, 10, 20, 20], [15, 15, 25, 25], [10, 10, 25, 25]],
- [[10, 10, 20, 20], [20, 0, 30, 10], [10, 0, 30, 20]],
- [[0, 0, 1, 1], [10, 11, 12, 13], [0, 0, 12, 13]],
- [[11, 12, 98, 99], [22, 23, 34, 35], [11, 12, 98, 99]]];
-
- for (var test in tests) {
- var r0 = createRectangle(test[0]);
- var r1 = createRectangle(test[1]);
- var expected = createRectangle(test[2]);
-
- expect(r0.boundingBox(r1), expected);
- expect(r1.boundingBox(r0), expected);
- }
- });
-
- test('containsRectangle', () {
- var r = new Rectangle(-10, 0, 20, 10);
- expect(r.containsRectangle(r), isTrue);
-
- expect(r.containsRectangle(
- new Rectangle(double.NAN, double.NAN, double.NAN, double.NAN)), isFalse);
-
- var r2 = new Rectangle(0, 2, 5, 5);
- expect(r.containsRectangle(r2), isTrue);
- expect(r2.containsRectangle(r), isFalse);
-
- r2 = new Rectangle(-11, 2, 5, 5);
- expect(r.containsRectangle(r2), isFalse);
- r2 = new Rectangle(0, 2, 15, 5);
- expect(r.containsRectangle(r2), isFalse);
- r2 = new Rectangle(0, 2, 5, 10);
- expect(r.containsRectangle(r2), isFalse);
- r2 = new Rectangle(0, 0, 5, 10);
- expect(r.containsRectangle(r2), isTrue);
- });
-
- test('containsPoint', () {
- var r = new Rectangle(20, 40, 60, 80);
-
- // Test middle.
- expect(r.containsPoint(new Point(50, 80)), isTrue);
-
- // Test edges.
- expect(r.containsPoint(new Point(20, 40)), isTrue);
- expect(r.containsPoint(new Point(50, 40)), isTrue);
- expect(r.containsPoint(new Point(80, 40)), isTrue);
- expect(r.containsPoint(new Point(80, 80)), isTrue);
- expect(r.containsPoint(new Point(80, 120)), isTrue);
- expect(r.containsPoint(new Point(50, 120)), isTrue);
- expect(r.containsPoint(new Point(20, 120)), isTrue);
- expect(r.containsPoint(new Point(20, 80)), isTrue);
-
- // Test outside.
- expect(r.containsPoint(new Point(0, 0)), isFalse);
- expect(r.containsPoint(new Point(50, 0)), isFalse);
- expect(r.containsPoint(new Point(100, 0)), isFalse);
- expect(r.containsPoint(new Point(100, 80)), isFalse);
- expect(r.containsPoint(new Point(100, 160)), isFalse);
- expect(r.containsPoint(new Point(50, 160)), isFalse);
- expect(r.containsPoint(new Point(0, 160)), isFalse);
- expect(r.containsPoint(new Point(0, 80)), isFalse);
- });
-
- test('hashCode', () {
- var a = new Rectangle(0, 1, 2, 3);
- var b = new Rectangle(0, 1, 2, 3);
- expect(a.hashCode, b.hashCode);
-
- var c = new Rectangle(1, 0, 2, 3);
- expect(a.hashCode == c.hashCode, isFalse);
- });
-
- { // Edge cases for boundingBox/intersection
- edgeTest(a, l) {
- test('edge case $a/$l', () {
- var r = new Rectangle(a, a, l, l);
- expect(r.boundingBox(r), r);
- expect(r.intersection(r), r);
- });
- }
-
- var bignum1 = 0x20000000000000 + 0.0;
- var bignum2 = 0x20000000000002 + 0.0;
- var bignum3 = 0x20000000000004 + 0.0;
- edgeTest(1.0, bignum1);
- edgeTest(1.0, bignum2);
- edgeTest(1.0, bignum3);
- edgeTest(bignum1, 1.0);
- edgeTest(bignum2, 1.0);
- edgeTest(bignum3, 1.0);
- }
-
- test("equality with different widths", () {
- var bignum = 0x80000000000008 + 0.0;
- var r1 = new Rectangle(bignum, bignum, 1.0, 1.0);
- var r2 = new Rectangle(bignum, bignum, 2.0, 2.0);
- expect(r1, r2);
- expect(r1.hashCode, r2.hashCode);
- expect(r1.right, r2.right);
- expect(r1.bottom, r2.bottom);
- expect(r1.width, 1.0);
- expect(r2.width, 2.0);
- });
-
- test('negative lengths', () {
- // Constructor allows negative lengths, but clamps them to zero.
- expect(new Rectangle(4, 4, -2, -2), new Rectangle(4, 4, 0, 0));
- expect(new MutableRectangle(4, 4, -2, -2), new Rectangle(4, 4, 0, 0));
-
- // Setters clamp negative lengths to zero.
- var r = new MutableRectangle(0, 0, 1, 1);
- r.width = -1;
- r.height = -1;
- expect(r, new Rectangle(0, 0, 0, 0));
-
- // Test that doubles are clamped to double zero.
- r = new Rectangle(1.5, 1.5, -2.5, -2.5);
- expect(identical(r.width, 0.0), isTrue);
- expect(identical(r.height, 0.0), isTrue);
- });
-
- // A NaN-value in any rectangle value means the rectange is considered
- // empty (contains no points, doesn't intersect any other rectangle).
- const NaN = double.NAN;
- var isNaN = predicate((x) => x is double && x.isNaN, "NaN");
-
- test('NaN left', () {
- var rectangles = [
- const Rectangle(NaN, 1, 2, 3),
- new MutableRectangle(NaN, 1, 2, 3),
- new Rectangle.fromPoints(new Point(NaN, 1), new Point(2, 4)),
- new MutableRectangle.fromPoints(new Point(NaN, 1), new Point(2, 4)),
- ];
- for (var r in rectangles) {
- expect(r.containsPoint(new Point(0, 1)), false);
- expect(r.containsRectangle(new Rectangle(0, 1, 2, 3)), false);
- expect(r.intersects(new Rectangle(0, 1, 2, 3)), false);
- expect(r.left, isNaN);
- expect(r.right, isNaN);
- }
- });
-
- test('NaN top', () {
- var rectangles = [
- const Rectangle(0, NaN, 2, 3),
- new MutableRectangle(0, NaN, 2, 3),
- new Rectangle.fromPoints(new Point(0, NaN), new Point(2, 4)),
- new MutableRectangle.fromPoints(new Point(0, NaN), new Point(2, 4)),
- ];
- for (var r in rectangles) {
- expect(r.containsPoint(new Point(0, 1)), false);
- expect(r.containsRectangle(new Rectangle(0, 1, 2, 3)), false);
- expect(r.intersects(new Rectangle(0, 1, 2, 3)), false);
- expect(r.top, isNaN);
- expect(r.bottom, isNaN);
- }
- });
-
- test('NaN width', () {
- var rectangles = [
- const Rectangle(0, 1, NaN, 3),
- new MutableRectangle(0, 1, NaN, 3),
- new Rectangle.fromPoints(new Point(0, 1), new Point(NaN, 4)),
- new MutableRectangle.fromPoints(new Point(0, 1), new Point(NaN, 4)),
- ];
- for (var r in rectangles) {
- expect(r.containsPoint(new Point(0, 1)), false);
- expect(r.containsRectangle(new Rectangle(0, 1, 2, 3)), false);
- expect(r.intersects(new Rectangle(0, 1, 2, 3)), false);
- expect(r.right, isNaN);
- expect(r.width, isNaN);
- }
- });
-
- test('NaN heigth', () {
- var rectangles = [
- const Rectangle(0, 1, 2, NaN),
- new MutableRectangle(0, 1, 2, NaN),
- new Rectangle.fromPoints(new Point(0, 1), new Point(2, NaN)),
- new MutableRectangle.fromPoints(new Point(0, 1), new Point(2, NaN)),
- ];
- for (var r in rectangles) {
- expect(r.containsPoint(new Point(0, 1)), false);
- expect(r.containsRectangle(new Rectangle(0, 1, 2, 3)), false);
- expect(r.intersects(new Rectangle(0, 1, 2, 3)), false);
- expect(r.bottom, isNaN);
- expect(r.height, isNaN);
- }
- });
+ testConstruction();
+ testIntersection();
+ testIntersects();
+ testBoundingBox();
+ testContainsRectangle();
+ testContainsPoint();
+ testHashCode();
+ testEdgeCases();
+ testEquality();
+ testNegativeLengths();
+ testNaNLeft();
+ testNaNTop();
+ testNaNWidth();
+ testNaNHeight();
}
+Rectangle createRectangle(List<num> a) {
+ return a != null ? new Rectangle(a[0], a[1], a[2] - a[0], a[3] - a[1])
+ : null;
+}
+
+testConstruction() {
+ var r0 = new Rectangle(10, 20, 30, 40);
+ Expect.equals('Rectangle (10, 20) 30 x 40', r0.toString());
+ Expect.equals(40, r0.right);
+ Expect.equals(60, r0.bottom);
+
+ var r1 = new Rectangle.fromPoints(r0.topLeft, r0.bottomRight);
+ Expect.equals(r0, r1);
+
+ var r2 = new Rectangle.fromPoints(r0.bottomRight, r0.topLeft);
+ Expect.equals(r0, r2);
+}
+
+testIntersection() {
+ var tests = [
+ [[10, 10, 20, 20], [15, 15, 25, 25], [15, 15, 20, 20]],
+ [[10, 10, 20, 20], [20, 0, 30, 10], [20, 10, 20, 10]],
+ [[0, 0, 1, 1], [10, 11, 12, 13], null],
+ [[11, 12, 98, 99], [22, 23, 34, 35], [22, 23, 34, 35]]];
+
+ for (var test in tests) {
+ var r0 = createRectangle(test[0]);
+ var r1 = createRectangle(test[1]);
+ var expected = createRectangle(test[2]);
+
+ Expect.equals(expected, r0.intersection(r1));
+ Expect.equals(expected, r1.intersection(r0));
+ }
+}
+
+testIntersects() {
+ var r0 = new Rectangle(10, 10, 20, 20);
+ var r1 = new Rectangle(15, 15, 25, 25);
+ var r2 = new Rectangle(0, 0, 1, 1);
+
+ Expect.isTrue(r0.intersects(r1));
+ Expect.isTrue(r1.intersects(r0));
+
+ Expect.isFalse(r0.intersects(r2));
+ Expect.isFalse(r2.intersects(r0));
+}
+
+testBoundingBox() {
+ var tests = [
+ [[10, 10, 20, 20], [15, 15, 25, 25], [10, 10, 25, 25]],
+ [[10, 10, 20, 20], [20, 0, 30, 10], [10, 0, 30, 20]],
+ [[0, 0, 1, 1], [10, 11, 12, 13], [0, 0, 12, 13]],
+ [[11, 12, 98, 99], [22, 23, 34, 35], [11, 12, 98, 99]]];
+
+ for (var test in tests) {
+ var r0 = createRectangle(test[0]);
+ var r1 = createRectangle(test[1]);
+ var expected = createRectangle(test[2]);
+
+ Expect.equals(expected, r0.boundingBox(r1));
+ Expect.equals(expected, r1.boundingBox(r0));
+ }
+}
+
+testContainsRectangle() {
+ var r = new Rectangle(-10, 0, 20, 10);
+ Expect.isTrue(r.containsRectangle(r));
+
+ Expect.isFalse(r.containsRectangle(
+ new Rectangle(double.NAN, double.NAN, double.NAN, double.NAN)));
+
+ var r2 = new Rectangle(0, 2, 5, 5);
+ Expect.isTrue(r.containsRectangle(r2));
+ Expect.isFalse(r2.containsRectangle(r));
+
+ r2 = new Rectangle(-11, 2, 5, 5);
+ Expect.isFalse(r.containsRectangle(r2));
+ r2 = new Rectangle(0, 2, 15, 5);
+ Expect.isFalse(r.containsRectangle(r2));
+ r2 = new Rectangle(0, 2, 5, 10);
+ Expect.isFalse(r.containsRectangle(r2));
+ r2 = new Rectangle(0, 0, 5, 10);
+ Expect.isTrue(r.containsRectangle(r2));
+}
+
+testContainsPoint() {
+ var r = new Rectangle(20, 40, 60, 80);
+
+ // Test middle.
+ Expect.isTrue(r.containsPoint(new Point(50, 80)));
+
+ // Test edges.
+ Expect.isTrue(r.containsPoint(new Point(20, 40)));
+ Expect.isTrue(r.containsPoint(new Point(50, 40)));
+ Expect.isTrue(r.containsPoint(new Point(80, 40)));
+ Expect.isTrue(r.containsPoint(new Point(80, 80)));
+ Expect.isTrue(r.containsPoint(new Point(80, 120)));
+ Expect.isTrue(r.containsPoint(new Point(50, 120)));
+ Expect.isTrue(r.containsPoint(new Point(20, 120)));
+ Expect.isTrue(r.containsPoint(new Point(20, 80)));
+
+ // Test outside.
+ Expect.isFalse(r.containsPoint(new Point(0, 0)));
+ Expect.isFalse(r.containsPoint(new Point(50, 0)));
+ Expect.isFalse(r.containsPoint(new Point(100, 0)));
+ Expect.isFalse(r.containsPoint(new Point(100, 80)));
+ Expect.isFalse(r.containsPoint(new Point(100, 160)));
+ Expect.isFalse(r.containsPoint(new Point(50, 160)));
+ Expect.isFalse(r.containsPoint(new Point(0, 160)));
+ Expect.isFalse(r.containsPoint(new Point(0, 80)));
+}
+
+testHashCode() {
+ var a = new Rectangle(0, 1, 2, 3);
+ var b = new Rectangle(0, 1, 2, 3);
+ Expect.equals(b.hashCode, a.hashCode);
+
+ var c = new Rectangle(1, 0, 2, 3);
+ Expect.isFalse(a.hashCode == c.hashCode);
+}
+
+testEdgeCases() {
+ edgeTest(double a, double l) {
+ var r = new Rectangle(a, a, l, l);
+ Expect.equals(r, r.boundingBox(r));
+ Expect.equals(r, r.intersection(r));
+ }
+
+ var bignum1 = 0x20000000000000 + 0.0;
+ var bignum2 = 0x20000000000002 + 0.0;
+ var bignum3 = 0x20000000000004 + 0.0;
+ edgeTest(1.0, bignum1);
+ edgeTest(1.0, bignum2);
+ edgeTest(1.0, bignum3);
+ edgeTest(bignum1, 1.0);
+ edgeTest(bignum2, 1.0);
+ edgeTest(bignum3, 1.0);
+}
+
+testEquality() {
+ var bignum = 0x80000000000008 + 0.0;
+ var r1 = new Rectangle(bignum, bignum, 1.0, 1.0);
+ var r2 = new Rectangle(bignum, bignum, 2.0, 2.0);
+ Expect.equals(r2, r1);
+ Expect.equals(r2.hashCode, r1.hashCode);
+ Expect.equals(r2.right, r1.right);
+ Expect.equals(r2.bottom, r1.bottom);
+ Expect.equals(1.0, r1.width);
+ Expect.equals(2.0, r2.width);
+}
+
+testNegativeLengths() {
+ // Constructor allows negative lengths, but clamps them to zero.
+ Expect.equals(new Rectangle(4, 4, 0, 0), new Rectangle(4, 4, -2, -2));
+ Expect.equals(new Rectangle(4, 4, 0, 0),
+ new MutableRectangle(4, 4, -2, -2));
+
+ // Setters clamp negative lengths to zero.
+ var mutable = new MutableRectangle(0, 0, 1, 1);
+ mutable.width = -1;
+ mutable.height = -1;
+ Expect.equals(new Rectangle(0, 0, 0, 0), mutable);
+
+ // Test that doubles are clamped to double zero.
+ var rectangle = new Rectangle(1.5, 1.5, -2.5, -2.5);
+ Expect.isTrue(identical(rectangle.width, 0.0));
+ Expect.isTrue(identical(rectangle.height, 0.0));
+}
+
+testNaNLeft() {
+ var rectangles = [
+ const Rectangle(double.NAN, 1, 2, 3),
+ new MutableRectangle(double.NAN, 1, 2, 3),
+ new Rectangle.fromPoints(new Point(double.NAN, 1), new Point(2, 4)),
+ new MutableRectangle.fromPoints(new Point(double.NAN, 1), new Point(2, 4)),
+ ];
+ for (var r in rectangles) {
+ Expect.isFalse(r.containsPoint(new Point(0, 1)));
+ Expect.isFalse(r.containsRectangle(new Rectangle(0, 1, 2, 3)));
+ Expect.isFalse(r.intersects(new Rectangle(0, 1, 2, 3)));
+ Expect.isTrue(r.left.isNaN);
+ Expect.isTrue(r.right.isNaN);
+ }
+}
+testNaNTop() {
+ var rectangles = [
+ const Rectangle(0, double.NAN, 2, 3),
+ new MutableRectangle(0, double.NAN, 2, 3),
+ new Rectangle.fromPoints(new Point(0, double.NAN), new Point(2, 4)),
+ new MutableRectangle.fromPoints(new Point(0, double.NAN), new Point(2, 4)),
+ ];
+ for (var r in rectangles) {
+ Expect.isFalse(r.containsPoint(new Point(0, 1)));
+ Expect.isFalse(r.containsRectangle(new Rectangle(0, 1, 2, 3)));
+ Expect.isFalse(r.intersects(new Rectangle(0, 1, 2, 3)));
+ Expect.isTrue(r.top.isNaN);
+ Expect.isTrue(r.bottom.isNaN);
+ }
+}
+
+testNaNWidth() {
+ var rectangles = [
+ const Rectangle(0, 1, double.NAN, 3),
+ new MutableRectangle(0, 1, double.NAN, 3),
+ new Rectangle.fromPoints(new Point(0, 1), new Point(double.NAN, 4)),
+ new MutableRectangle.fromPoints(new Point(0, 1), new Point(double.NAN, 4)),
+ ];
+ for (var r in rectangles) {
+ Expect.isFalse(r.containsPoint(new Point(0, 1)));
+ Expect.isFalse(r.containsRectangle(new Rectangle(0, 1, 2, 3)));
+ Expect.isFalse(r.intersects(new Rectangle(0, 1, 2, 3)));
+ Expect.isTrue(r.right.isNaN);
+ Expect.isTrue(r.width.isNaN);
+ }
+}
+
+testNaNHeight() {
+ var rectangles = [
+ const Rectangle(0, 1, 2, double.NAN),
+ new MutableRectangle(0, 1, 2, double.NAN),
+ new Rectangle.fromPoints(new Point(0, 1), new Point(2, double.NAN)),
+ new MutableRectangle.fromPoints(new Point(0, 1), new Point(2, double.NAN)),
+ ];
+ for (var r in rectangles) {
+ Expect.isFalse(r.containsPoint(new Point(0, 1)));
+ Expect.isFalse(r.containsRectangle(new Rectangle(0, 1, 2, 3)));
+ Expect.isFalse(r.intersects(new Rectangle(0, 1, 2, 3)));
+ Expect.isTrue(r.bottom.isNaN);
+ Expect.isTrue(r.height.isNaN);
+ }
+}
\ No newline at end of file
diff --git a/pkg/dev_compiler/test/codegen_expected/expect.js b/pkg/dev_compiler/test/codegen_expected/expect.js
index f2a8dcc..793ac41 100644
--- a/pkg/dev_compiler/test/codegen_expected/expect.js
+++ b/pkg/dev_compiler/test/codegen_expected/expect.js
@@ -208,6 +208,37 @@
}
expect.Expect._fail(sb.toString());
}
+ static deepEquals(expected, actual) {
+ if (dart.equals(expected, actual)) return;
+ if (typeof expected == 'string' && typeof actual == 'string') {
+ expect.Expect.stringEquals(expected, actual);
+ } else if (core.Iterable.is(expected) && core.Iterable.is(actual)) {
+ let expectedLength = expected[dartx.length];
+ let actualLength = actual[dartx.length];
+ let length = dart.notNull(expectedLength) < dart.notNull(actualLength) ? expectedLength : actualLength;
+ for (let i = 0; i < dart.notNull(length); i++) {
+ expect.Expect.deepEquals(expected[dartx.elementAt](i), actual[dartx.elementAt](i));
+ }
+ if (expectedLength != actualLength) {
+ let nextElement = (dart.notNull(expectedLength) > dart.notNull(length) ? expected : actual)[dartx.elementAt](length);
+ expect.Expect._fail('Expect.deepEquals(list length, ' + dart.str`expected: <${expectedLength}>, actual: <${actualLength}>) ` + dart.str`fails: Next element <${nextElement}>`);
+ }
+ } else if (core.Map.is(expected) && core.Map.is(actual)) {
+ for (let key of expected[dartx.keys]) {
+ if (!dart.test(actual[dartx.containsKey](key))) {
+ expect.Expect._fail(dart.str`Expect.deepEquals(missing expected key: <${key}>) fails`);
+ }
+ expect.Expect.deepEquals(expected[dartx.get](key), actual[dartx.get](key));
+ }
+ for (let key of actual[dartx.keys]) {
+ if (!dart.test(expected[dartx.containsKey](key))) {
+ expect.Expect._fail(dart.str`Expect.deepEquals(unexpected key: <${key}>) fails`);
+ }
+ }
+ } else {
+ expect.Expect._fail(dart.str`Expect.deepEquals(expected: <${expected}>, actual: <${actual}>) ` + "fails.");
+ }
+ }
static throws(f, check, reason) {
if (check === void 0) check = null;
if (reason === void 0) reason = null;
@@ -253,11 +284,12 @@
mapEquals: dart.definiteFunctionType(dart.void, [core.Map, core.Map], [core.String]),
stringEquals: dart.definiteFunctionType(dart.void, [core.String, core.String], [core.String]),
setEquals: dart.definiteFunctionType(dart.void, [core.Iterable, core.Iterable], [core.String]),
+ deepEquals: dart.definiteFunctionType(dart.void, [core.Object, core.Object]),
throws: dart.definiteFunctionType(dart.void, [VoidTovoid()], [expect._CheckExceptionFn, core.String]),
_getMessage: dart.definiteFunctionType(core.String, [core.String]),
_fail: dart.definiteFunctionType(dart.void, [core.String])
}),
- names: ['_truncateString', '_stringDifference', 'equals', 'isTrue', 'isFalse', 'isNull', 'isNotNull', 'identical', 'fail', 'approxEquals', 'notEquals', 'listEquals', 'mapEquals', 'stringEquals', 'setEquals', 'throws', '_getMessage', '_fail']
+ names: ['_truncateString', '_stringDifference', 'equals', 'isTrue', 'isFalse', 'isNull', 'isNotNull', 'identical', 'fail', 'approxEquals', 'notEquals', 'listEquals', 'mapEquals', 'stringEquals', 'setEquals', 'deepEquals', 'throws', '_getMessage', '_fail']
});
expect._identical = function(a, b) {
return core.identical(a, b);
diff --git a/pkg/dev_compiler/test/codegen_expected/minitest.js b/pkg/dev_compiler/test/codegen_expected/minitest.js
new file mode 100644
index 0000000..f251c5e
--- /dev/null
+++ b/pkg/dev_compiler/test/codegen_expected/minitest.js
@@ -0,0 +1,229 @@
+define(['dart_sdk', 'expect'], function(dart_sdk, expect) {
+ 'use strict';
+ const core = dart_sdk.core;
+ const _interceptors = dart_sdk._interceptors;
+ const dart = dart_sdk.dart;
+ const dartx = dart_sdk.dartx;
+ const expect$ = expect.expect;
+ const minitest = Object.create(null);
+ let JSArrayOf_Group = () => (JSArrayOf_Group = dart.constFn(_interceptors.JSArray$(minitest._Group)))();
+ let VoidTodynamic = () => (VoidTodynamic = dart.constFn(dart.functionType(dart.dynamic, [])))();
+ let ObjectTobool = () => (ObjectTobool = dart.constFn(dart.functionType(core.bool, [core.Object])))();
+ let ObjectTovoid = () => (ObjectTovoid = dart.constFn(dart.definiteFunctionType(dart.void, [core.Object])))();
+ let dynamicTobool = () => (dynamicTobool = dart.constFn(dart.definiteFunctionType(core.bool, [dart.dynamic])))();
+ let VoidTovoid = () => (VoidTovoid = dart.constFn(dart.definiteFunctionType(dart.void, [])))();
+ let StringAndFnTovoid = () => (StringAndFnTovoid = dart.constFn(dart.definiteFunctionType(dart.void, [core.String, VoidTodynamic()])))();
+ let FnTovoid = () => (FnTovoid = dart.constFn(dart.definiteFunctionType(dart.void, [VoidTodynamic()])))();
+ let ObjectAndObject__Tovoid = () => (ObjectAndObject__Tovoid = dart.constFn(dart.definiteFunctionType(dart.void, [core.Object, core.Object], {reason: core.String})))();
+ let StringTovoid = () => (StringTovoid = dart.constFn(dart.definiteFunctionType(dart.void, [core.String])))();
+ let ObjectToObject = () => (ObjectToObject = dart.constFn(dart.definiteFunctionType(core.Object, [core.Object])))();
+ let Fn__ToObject = () => (Fn__ToObject = dart.constFn(dart.definiteFunctionType(core.Object, [ObjectTobool()], [core.String])))();
+ let numAndnumToObject = () => (numAndnumToObject = dart.constFn(dart.definiteFunctionType(core.Object, [core.num, core.num])))();
+ let numToObject = () => (numToObject = dart.constFn(dart.definiteFunctionType(core.Object, [core.num])))();
+ minitest._Action = dart.typedef('_Action', () => dart.functionType(dart.void, []));
+ minitest._ExpectationFunction = dart.typedef('_ExpectationFunction', () => dart.functionType(dart.void, [core.Object]));
+ dart.defineLazy(minitest, {
+ get _groups() {
+ return JSArrayOf_Group().of([new minitest._Group()]);
+ }
+ });
+ dart.defineLazy(minitest, {
+ get isFalse() {
+ return new minitest._Expectation(expect$.Expect.isFalse);
+ }
+ });
+ dart.defineLazy(minitest, {
+ get isNotNull() {
+ return new minitest._Expectation(expect$.Expect.isNotNull);
+ }
+ });
+ dart.defineLazy(minitest, {
+ get isNull() {
+ return new minitest._Expectation(expect$.Expect.isNull);
+ }
+ });
+ dart.defineLazy(minitest, {
+ get isTrue() {
+ return new minitest._Expectation(expect$.Expect.isTrue);
+ }
+ });
+ dart.defineLazy(minitest, {
+ get returnsNormally() {
+ return new minitest._Expectation(dart.fn(actual => {
+ try {
+ minitest._Action.as(actual)();
+ } catch (error) {
+ expect$.Expect.fail(dart.str`Expected function to return normally, but threw:\n${error}`);
+ }
+
+ }, ObjectTovoid()));
+ }
+ });
+ dart.defineLazy(minitest, {
+ get throws() {
+ return new minitest._Expectation(dart.fn(actual => {
+ expect$.Expect.throws(minitest._Action.as(actual));
+ }, ObjectTovoid()));
+ }
+ });
+ dart.defineLazy(minitest, {
+ get throwsArgumentError() {
+ return new minitest._Expectation(dart.fn(actual => {
+ expect$.Expect.throws(minitest._Action.as(actual), dart.fn(error => core.ArgumentError.is(error), dynamicTobool()));
+ }, ObjectTovoid()));
+ }
+ });
+ dart.defineLazy(minitest, {
+ get throwsNoSuchMethodError() {
+ return new minitest._Expectation(dart.fn(actual => {
+ expect$.Expect.throws(minitest._Action.as(actual), dart.fn(error => core.NoSuchMethodError.is(error), dynamicTobool()));
+ }, ObjectTovoid()));
+ }
+ });
+ dart.defineLazy(minitest, {
+ get throwsRangeError() {
+ return new minitest._Expectation(dart.fn(actual => {
+ expect$.Expect.throws(minitest._Action.as(actual), dart.fn(error => core.RangeError.is(error), dynamicTobool()));
+ }, ObjectTovoid()));
+ }
+ });
+ dart.defineLazy(minitest, {
+ get throwsStateError() {
+ return new minitest._Expectation(dart.fn(actual => {
+ expect$.Expect.throws(minitest._Action.as(actual), dart.fn(error => core.StateError.is(error), dynamicTobool()));
+ }, ObjectTovoid()));
+ }
+ });
+ dart.defineLazy(minitest, {
+ get throwsUnsupportedError() {
+ return new minitest._Expectation(dart.fn(actual => {
+ expect$.Expect.throws(minitest._Action.as(actual), dart.fn(error => core.UnsupportedError.is(error), dynamicTobool()));
+ }, ObjectTovoid()));
+ }
+ });
+ minitest.finishTests = function() {
+ minitest._groups[dartx.clear]();
+ minitest._groups[dartx.add](new minitest._Group());
+ };
+ dart.fn(minitest.finishTests, VoidTovoid());
+ minitest.group = function(description, body) {
+ minitest._groups[dartx.add](new minitest._Group());
+ try {
+ body();
+ } finally {
+ minitest._groups[dartx.removeLast]();
+ }
+ };
+ dart.fn(minitest.group, StringAndFnTovoid());
+ minitest.test = function(description, body) {
+ for (let group of minitest._groups) {
+ if (group.setUpFunction != null) group.setUpFunction();
+ }
+ try {
+ body();
+ } finally {
+ for (let i = dart.notNull(minitest._groups[dartx.length]) - 1; i >= 0; i--) {
+ let group = minitest._groups[dartx.get](i);
+ if (group.tearDownFunction != null) group.tearDownFunction();
+ }
+ }
+ };
+ dart.fn(minitest.test, StringAndFnTovoid());
+ minitest.setUp = function(body) {
+ dart.assert(minitest._groups[dartx.last].setUpFunction == null);
+ minitest._groups[dartx.last].setUpFunction = body;
+ };
+ dart.fn(minitest.setUp, FnTovoid());
+ minitest.tearDown = function(body) {
+ dart.assert(minitest._groups[dartx.last].tearDownFunction == null);
+ minitest._groups[dartx.last].tearDownFunction = body;
+ };
+ dart.fn(minitest.tearDown, FnTovoid());
+ minitest.expect = function(actual, expected, opts) {
+ let reason = opts && 'reason' in opts ? opts.reason : null;
+ if (!minitest._Expectation.is(expected)) {
+ expected = minitest.equals(expected);
+ }
+ let expectation = minitest._Expectation.as(expected);
+ expectation.function(actual);
+ };
+ dart.fn(minitest.expect, ObjectAndObject__Tovoid());
+ minitest.fail = function(message) {
+ expect$.Expect.fail(message);
+ };
+ dart.fn(minitest.fail, StringTovoid());
+ minitest.equals = function(value) {
+ return new minitest._Expectation(dart.fn(actual => {
+ expect$.Expect.deepEquals(value, actual);
+ }, ObjectTovoid()));
+ };
+ dart.fn(minitest.equals, ObjectToObject());
+ minitest.notEquals = function(value) {
+ return new minitest._Expectation(dart.fn(actual => {
+ expect$.Expect.notEquals(value, actual);
+ }, ObjectTovoid()));
+ };
+ dart.fn(minitest.notEquals, ObjectToObject());
+ minitest.unorderedEquals = function(value) {
+ return new minitest._Expectation(dart.fn(actual => {
+ expect$.Expect.setEquals(core.Iterable._check(value), core.Iterable._check(actual));
+ }, ObjectTovoid()));
+ };
+ dart.fn(minitest.unorderedEquals, ObjectToObject());
+ minitest.predicate = function(fn, description) {
+ if (description === void 0) description = null;
+ return new minitest._Expectation(dart.fn(actual => {
+ expect$.Expect.isTrue(fn(actual));
+ }, ObjectTovoid()));
+ };
+ dart.fn(minitest.predicate, Fn__ToObject());
+ minitest.inInclusiveRange = function(min, max) {
+ return new minitest._Expectation(dart.fn(actual => {
+ let actualNum = core.num.as(actual);
+ if (dart.notNull(actualNum) < dart.notNull(min) || dart.notNull(actualNum) > dart.notNull(max)) {
+ minitest.fail(dart.str`Expected ${actualNum} to be in the inclusive range [${min}, ${max}].`);
+ }
+ }, ObjectTovoid()));
+ };
+ dart.fn(minitest.inInclusiveRange, numAndnumToObject());
+ minitest.greaterThan = function(value) {
+ return new minitest._Expectation(dart.fn(actual => {
+ let actualNum = core.num.as(actual);
+ if (dart.notNull(actualNum) <= dart.notNull(value)) {
+ minitest.fail(dart.str`Expected ${actualNum} to be greater than ${value}.`);
+ }
+ }, ObjectTovoid()));
+ };
+ dart.fn(minitest.greaterThan, numToObject());
+ minitest.same = function(value) {
+ return new minitest._Expectation(dart.fn(actual => {
+ expect$.Expect.identical(value, actual);
+ }, ObjectTovoid()));
+ };
+ dart.fn(minitest.same, ObjectToObject());
+ minitest._Group = class _Group extends core.Object {
+ new() {
+ this.setUpFunction = null;
+ this.tearDownFunction = null;
+ }
+ };
+ dart.setSignature(minitest._Group, {
+ fields: () => ({
+ setUpFunction: minitest._Action,
+ tearDownFunction: minitest._Action
+ })
+ });
+ minitest._Expectation = class _Expectation extends core.Object {
+ new(func) {
+ this.function = func;
+ }
+ };
+ dart.setSignature(minitest._Expectation, {
+ constructors: () => ({new: dart.definiteFunctionType(minitest._Expectation, [minitest._ExpectationFunction])}),
+ fields: () => ({function: minitest._ExpectationFunction})
+ });
+ // Exports:
+ return {
+ minitest: minitest
+ };
+});
diff --git a/pkg/dev_compiler/test/not_yet_strong_tests.dart b/pkg/dev_compiler/test/not_yet_strong_tests.dart
index 013db81..14df2315 100644
--- a/pkg/dev_compiler/test/not_yet_strong_tests.dart
+++ b/pkg/dev_compiler/test/not_yet_strong_tests.dart
@@ -2427,50 +2427,21 @@
'lib/convert/chunked_conversion_utf8_test',
'lib/convert/line_splitter_test',
'lib/html/cross_frame_test',
- 'lib/html/css_rule_list_test',
- 'lib/html/custom/constructor_calls_created_synchronously_test',
- 'lib/html/custom/created_callback_test',
- 'lib/html/custom/document_register_basic_test',
- 'lib/html/custom/document_register_type_extensions_test',
- 'lib/html/custom/element_upgrade_test',
- 'lib/html/custom_elements_23127_test',
- 'lib/html/custom_elements_test',
- 'lib/html/datalistelement_test',
- 'lib/html/documentfragment_test',
- 'lib/html/element_add_test',
- 'lib/html/element_classes_test',
'lib/html/element_test',
'lib/html/events_test',
'lib/html/fileapi_test',
'lib/html/filereader_test',
'lib/html/fontface_loaded_test',
- 'lib/html/htmlcollection_test',
- 'lib/html/htmlelement_test',
- 'lib/html/htmloptionscollection_test',
- 'lib/html/indexeddb_2_test',
'lib/html/js_function_getter_trust_types_test',
- 'lib/html/js_test',
- 'lib/html/js_util_test',
'lib/html/js_typed_interop_side_cast_exp_test',
'lib/html/js_typed_interop_side_cast_test',
'lib/html/keyboard_event_test',
- 'lib/html/localstorage_test',
'lib/html/mutationobserver_test',
- 'lib/html/node_test',
- 'lib/html/node_validator_important_if_you_suppress_make_the_bug_critical_test',
'lib/html/postmessage_structured_test',
- 'lib/html/queryall_test',
'lib/html/resource_http_test',
- 'lib/html/selectelement_test',
- 'lib/html/track_element_constructor_test',
'lib/html/transferables_test',
- 'lib/html/typed_arrays_range_checks_test',
- 'lib/html/typing_test',
- 'lib/html/unknownelement_test',
'lib/html/webgl_1_test',
- 'lib/html/window_nosuchmethod_test',
'lib/html/wrapping_collections_test',
- 'lib/math/rectangle_test',
// TODO(jmesserly): these are both under "dart:html" as well.
'js_test',
'js_util_test'
diff --git a/pkg/dev_compiler/tool/build_test_pkgs.sh b/pkg/dev_compiler/tool/build_test_pkgs.sh
index 5b348e2..42ab6c9 100755
--- a/pkg/dev_compiler/tool/build_test_pkgs.sh
+++ b/pkg/dev_compiler/tool/build_test_pkgs.sh
@@ -8,8 +8,8 @@
SDK=--dart-sdk-summary=lib/js/amd/dart_sdk.sum
./bin/dartdevc.dart $SDK -o gen/codegen_output/pkg/expect.js \
- --url-mapping=package:expect/expect.dart,test/codegen/expect.dart \
- package:expect/expect.dart
+ package:expect/expect.dart \
+ package:expect/minitest.dart
./bin/dartdevc.dart $SDK -o gen/codegen_output/pkg/async_helper.js \
--url-mapping=package:async_helper/async_helper.dart,test/codegen/async_helper.dart \
diff --git a/pkg/dev_compiler/tool/input_sdk/lib/math/math.dart b/pkg/dev_compiler/tool/input_sdk/lib/math/math.dart
index 73768c9..0f651b7 100644
--- a/pkg/dev_compiler/tool/input_sdk/lib/math/math.dart
+++ b/pkg/dev_compiler/tool/input_sdk/lib/math/math.dart
@@ -4,9 +4,9 @@
/**
* Mathematical constants and functions, plus a random number generator.
- *
+ *
* To use this library in your code:
- *
+ *
* import 'dart:math';
*/
library dart.math;
@@ -67,32 +67,7 @@
* same mathematical value) then it is unspecified which of the two arguments
* is returned.
*/
-num/*=T*/ min/*<T extends num>*/(num/*=T*/ a, num/*=T*/ b) {
- // These partially redundant type checks improve code quality for dart2js.
- // Most of the improvement is at call sites from the inferred non-null num
- // return type.
- if (a is! num) throw new ArgumentError(a);
- if (b is! num) throw new ArgumentError(b);
-
- if (a > b) return b;
- if (a < b) return a;
- if (b is double) {
- // Special case for NaN and -0.0. If one argument is NaN return NaN.
- // [min] must also distinguish between -0.0 and 0.0.
- if (a is double) {
- if (a == 0.0) {
- // a is either 0.0 or -0.0. b is either 0.0, -0.0 or NaN.
- // The following returns -0.0 if either a or b is -0.0, and it
- // returns NaN if b is NaN.
- return (a + b) * a * b;
- }
- }
- // Check for NaN and b == -0.0.
- if (a == 0 && b.isNegative || b.isNaN) return b;
- return a;
- }
- return a;
-}
+external num/*=T*/ min/*<T extends num>*/(num/*=T*/ a, num/*=T*/ b);
/**
* Returns the larger of two numbers.
@@ -102,34 +77,7 @@
* otherwise equal (including int and doubles with the same mathematical value)
* then it is unspecified which of the two arguments is returned.
*/
-num/*=T*/ max/*<T extends num>*/(num/*=T*/ a, num/*=T*/ b) {
- // These partially redundant type checks improve code quality for dart2js.
- // Most of the improvement is at call sites from the inferred non-null num
- // return type.
- if (a is! num) throw new ArgumentError(a);
- if (b is! num) throw new ArgumentError(b);
-
- if (a > b) return a;
- if (a < b) return b;
- if (b is double) {
- // Special case for NaN and -0.0. If one argument is NaN return NaN.
- // [max] must also distinguish between -0.0 and 0.0.
- if (a is double) {
- if (a == 0.0) {
- // a is either 0.0 or -0.0. b is either 0.0, -0.0, or NaN.
- // The following returns 0.0 if either a or b is 0.0, and it
- // returns NaN if b is NaN.
- return a + b;
- }
- }
- // Check for NaN.
- if (b.isNaN) return b;
- return a;
- }
- // max(-0.0, 0) must return 0.
- if (b == 0 && a.isNegative) return b;
- return a;
-}
+external num/*=T*/ max/*<T extends num>*/(num/*=T*/ a, num/*=T*/ b);
/**
* A variant of [atan].
diff --git a/pkg/dev_compiler/tool/input_sdk/lib/math/rectangle.dart b/pkg/dev_compiler/tool/input_sdk/lib/math/rectangle.dart
index 6fe2075..bae6602 100644
--- a/pkg/dev_compiler/tool/input_sdk/lib/math/rectangle.dart
+++ b/pkg/dev_compiler/tool/input_sdk/lib/math/rectangle.dart
@@ -40,8 +40,15 @@
bool operator ==(other) {
if (other is !Rectangle) return false;
- return left == other.left && top == other.top && right == other.right &&
- bottom == other.bottom;
+ // TODO(rnystrom): Type promotion doesn't currently promote the [other]
+ // to Rectangle from the above line, so do it explicitly here to avoid a
+ // dynamic send and work around:
+ // https://github.com/dart-lang/sdk/issues/27551
+ var otherRect = other as Rectangle;
+ return left == otherRect.left &&
+ top == otherRect.top &&
+ right == otherRect.right &&
+ bottom == otherRect.bottom;
}
int get hashCode => _JenkinsSmiHash.hash4(left.hashCode, top.hashCode,
diff --git a/pkg/dev_compiler/tool/input_sdk/patch/math_patch.dart b/pkg/dev_compiler/tool/input_sdk/patch/math_patch.dart
index fc54f63..73a6723 100644
--- a/pkg/dev_compiler/tool/input_sdk/patch/math_patch.dart
+++ b/pkg/dev_compiler/tool/input_sdk/patch/math_patch.dart
@@ -8,6 +8,14 @@
import 'dart:typed_data' show ByteData;
@patch
+num/*=T*/ min/*<T extends num>*/(num/*=T*/ a, num/*=T*/ b)
+ => JS('num', r'Math.min(#, #)', checkNum(a), checkNum(b)) as num/*=T*/;
+
+@patch
+num/*=T*/ max/*<T extends num>*/(num/*=T*/ a, num/*=T*/ b)
+ => JS('num', r'Math.max(#, #)', checkNum(a), checkNum(b)) as num/*=T*/;
+
+@patch
double sqrt(num x)
=> JS('num', r'Math.sqrt(#)', checkNum(x));
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/runtime.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/runtime.dart
index d5a5ae2..6b79332 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/runtime.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/runtime.dart
@@ -10,7 +10,7 @@
import 'dart:_foreign_helper' show JS, JSExportName, rest, spread;
import 'dart:_interceptors' show JSArray;
import 'dart:_js_helper' show SyncIterable, BooleanConversionAssertionError,
- CastErrorImplementation, TypeErrorImplementation,
+ CastErrorImplementation, TypeErrorImplementation,
StrongModeCastError, StrongModeTypeError, StrongModeErrorImplementation,
getTraceFromException, Primitives;
@@ -25,10 +25,3 @@
@JSExportName('global')
final global_ = JS('', 'typeof window == "undefined" ? global : window');
final JsSymbol = JS('', 'Symbol');
-
-// TODO(vsm): This is referenced (as init.globalState) from
-// isolate_helper.dart. Where should it go?
-// See: https://github.com/dart-lang/dev_compiler/issues/164
-// exports.globalState = null;
-// TODO(ochafik).
-// _js_helper.checkNum = operations.notNull;
diff --git a/pkg/dev_compiler/tool/input_sdk/private/interceptors.dart b/pkg/dev_compiler/tool/input_sdk/private/interceptors.dart
index 307726b..daa0e77 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/interceptors.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/interceptors.dart
@@ -44,18 +44,9 @@
* have a type mask that contains the objects that we can use the
* native JS [] operator and length on.
*/
-abstract class JSIndexable {
+abstract class JSIndexable<E> {
int get length;
- operator[](int index);
-}
-
-/**
- * The supertype for JSMutableArray and
- * JavaScriptIndexingBehavior. Used by the backend to have a type mask
- * that contains the objects we can use the JS []= operator on.
- */
-abstract class JSMutableIndexable extends JSIndexable {
- operator[]=(int index, var value);
+ E operator[](int index);
}
/**
diff --git a/pkg/dev_compiler/tool/input_sdk/private/js_array.dart b/pkg/dev_compiler/tool/input_sdk/private/js_array.dart
index b937132..80a5289 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/js_array.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/js_array.dart
@@ -11,7 +11,7 @@
* argument added to each member.
*/
@JsPeerInterface(name: 'Array')
-class JSArray<E> implements List<E>, JSIndexable {
+class JSArray<E> implements List<E>, JSIndexable<E> {
const JSArray();
@@ -587,7 +587,7 @@
* these classes can have specialized implementations. Doing so will challenge
* many assuptions in the JS backend.
*/
-class JSMutableArray<E> extends JSArray<E> implements JSMutableIndexable {}
+class JSMutableArray<E> extends JSArray<E> {}
class JSFixedArray<E> extends JSMutableArray<E> {}
class JSExtendableArray<E> extends JSMutableArray<E> {}
class JSUnmodifiableArray<E> extends JSArray<E> {} // Already is JSIndexable.
diff --git a/pkg/dev_compiler/tool/input_sdk/private/js_helper.dart b/pkg/dev_compiler/tool/input_sdk/private/js_helper.dart
index 09e9a78..351d94d 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/js_helper.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/js_helper.dart
@@ -768,7 +768,7 @@
* objects that support integer indexing. This interface is not
* visible to anyone, and is only injected into special libraries.
*/
-abstract class JavaScriptIndexingBehavior extends JSMutableIndexable {
+abstract class JavaScriptIndexingBehavior {
}
// TODO(lrn): These exceptions should be implemented in core.
diff --git a/pkg/dev_compiler/tool/input_sdk/private/js_mirrors.dart b/pkg/dev_compiler/tool/input_sdk/private/js_mirrors.dart
index 84e5143..151affb 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/js_mirrors.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/js_mirrors.dart
@@ -73,58 +73,71 @@
typedef T _Lazy<T>();
+String _getNameForESSymbol(member) {
+ // Convert private JS symbol "Symbol(_foo)" to string "_foo".
+ var str = member.toString();
+ assert(str.startsWith('Symbol(') && str.endsWith(')'));
+ return str.substring(7, str.length - 1);
+}
+
+Map _toDartMap(data) {
+ if (data == null) return {};
+ var map = JS('Map', '#.map(#)', _dart, data);
+ // Note: we recorded a map from fields/methods to their type and metadata.
+ // The key is a string name for public members but an ES6 symbol for private
+ // ones. That's works nicely for dynamic operations, but dart:mirrors expects
+ // strings, so we convert back here.
+ var privateMembers = JS('', 'Object.getOwnPropertySymbols(#)', data);
+ for (var member in privateMembers) {
+ var name = _getNameForESSymbol(member);
+ map[name] = JS('', '#[#]', data, member);
+ }
+ return map;
+}
+
Map _getConstructors(obj) {
List sig = JS('', '#.getConstructorSig(#)', _dart, obj);
- if (sig == null) return {};
- return JS('', '#.map(#)', _dart, sig);
+ return _toDartMap(sig);
}
Map _getFields(obj) {
List sig = JS('', '#.getFieldSig(#)', _dart, obj);
- if (sig == null) return {};
- return JS('', '#.map(#)', _dart, sig);
+ return _toDartMap(sig);
}
Map _getMethods(obj) {
List sig = JS('', '#.getMethodSig(#)', _dart, obj);
- if (sig == null) return {};
- return JS('', '#.map(#)', _dart, sig);
+ return _toDartMap(sig);
}
Map _getGetters(obj) {
List sig = JS('', '#.getGetterSig(#)', _dart, obj);
- if (sig == null) return {};
- return JS('', '#.map(#)', _dart, sig);
+ return _toDartMap(sig);
}
Map _getSetters(obj) {
List sig = JS('', '#.getSetterSig(#)', _dart, obj);
- if (sig == null) return {};
- return JS('', '#.map(#)', _dart, sig);
+ return _toDartMap(sig);
}
Map _getStaticFields(obj) {
List sig = JS('', '#.getStaticFieldSig(#)', _dart, obj);
- if (sig == null) return {};
- return JS('', '#.map(#)', _dart, sig);
+ return _toDartMap(sig);
}
Map _getStatics(obj) {
List sig = JS('', '#.getStaticSig(#)', _dart, obj);
- if (sig == null) return {};
- return JS('', '#.map(#)', _dart, sig);
+ return _toDartMap(sig);
}
Map _getStaticGetters(obj) {
List sig = JS('', '#.getStaticGetterSig(#)', _dart, obj);
- if (sig == null) return {};
- return JS('', '#.map(#)', _dart, sig);
+ return _toDartMap(sig);
}
Map _getStaticSetters(obj) {
List sig = JS('', '#.getStaticSetterSig(#)', _dart, obj);
- if (sig == null) return {};
- return JS('', '#.map(#)', _dart, sig);
+ return _toDartMap(sig);
}
// TODO(vsm): These methods need to validate whether we really have a
@@ -135,7 +148,15 @@
dynamic _wrap(obj) => JS('', '#.wrapType(#)', _dart, obj);
_unimplemented(Type t, Invocation i) {
- throw new UnimplementedError('$t.${i.memberName} unimplemented');
+ throw new UnimplementedError('$t.${getName(i.memberName)} unimplemented');
+}
+
+dynamic _toJsMap(Map<Symbol, dynamic> map) {
+ var obj = JS('', '{}');
+ map.forEach((Symbol key, value) {
+ JS('', '#[#] = #', obj, getName(key), value);
+ });
+ return obj;
}
class JsMirror implements Mirror {
@@ -184,21 +205,41 @@
return identityHashCode(reflectee) ^ 0x36363636;
}
- InstanceMirror getField(Symbol symbol) {
+ // Returns a String for public members or an ES6 symbol for private members.
+ _getAccessor(dynamic reflectee, Symbol symbol, [List<dynamic> args,
+ Map<Symbol, dynamic> namedArgs]) {
var name = getName(symbol);
+ if (!name.startsWith('_')) return name;
+
+ // TODO(vsm): Ideally, we'd record ES6 symbols properly during codegen if
+ // mirrors is enabled. Here, we're trying to recover it from the receiver
+ // instead.
+ //
+ // Get private fields and members. Members are on proto.
+ var privateMembers = JS('', 'Object.getOwnPropertySymbols(#)', reflectee)
+ ..addAll(JS('', 'Object.getOwnPropertySymbols(#.__proto__)', reflectee));
+ for (var member in privateMembers) {
+ var privateName = _getNameForESSymbol(member);
+ if (name == privateName) return member;
+ }
+ return new NoSuchMethodError(reflectee, symbol, args, namedArgs);
+ }
+
+ InstanceMirror getField(Symbol symbol) {
+ var name = _getAccessor(reflectee, symbol);
var field = _dload(reflectee, name);
return reflect(field);
}
InstanceMirror setField(Symbol symbol, Object value) {
- var name = getName(symbol);
+ var name = _getAccessor(reflectee, symbol);
_dput(reflectee, name, value);
return reflect(value);
}
InstanceMirror invoke(Symbol symbol, List<dynamic> args,
[Map<Symbol, dynamic> namedArgs]) {
- var name = getName(symbol);
+ var name = _getAccessor(reflectee, symbol, args, namedArgs);
if (namedArgs != null) {
args = new List.from(args);
args.add(_toJsMap(namedArgs));
@@ -207,13 +248,7 @@
return reflect(result);
}
- dynamic _toJsMap(Map<Symbol, dynamic> map) {
- var obj = JS('', '{}');
- map.forEach((Symbol key, value) {
- JS('', '#[#] = #', obj, getName(key), value);
- });
- return obj;
- }
+ String toString() => "InstanceMirror on '$reflectee'";
}
class JsClosureMirror extends JsInstanceMirror implements ClosureMirror {
@@ -246,7 +281,12 @@
List<InstanceMirror> get metadata {
if (_metadata == null) {
// Load metadata.
- var fn = JS('Function', '#[dart.metadata]', _unwrap(_cls));
+ var unwrapped = _unwrap(_cls);
+ // Only get metadata directly embedded on this class, not its
+ // superclasses.
+ var fn = JS('Function',
+ 'Object.hasOwnProperty.call(#, dart.metadata) ? #[dart.metadata] : null',
+ unwrapped, unwrapped);
_metadata = (fn == null)
? const <InstanceMirror>[]
: new List<InstanceMirror>.unmodifiable(
@@ -352,6 +392,32 @@
return reflect(instance);
}
+ // TODO(vsm): Need to check for NSM, types on accessors below. Unlike the
+ // InstanceMirror case, there is no dynamic helper to delegate to - we never
+ // need a dload, etc. on a static.
+
+ InstanceMirror getField(Symbol symbol) {
+ var name = getName(symbol);
+ return reflect(JS('', '#[#]', _unwrap(_cls), name));
+ }
+
+ InstanceMirror setField(Symbol symbol, Object value) {
+ var name = getName(symbol);
+ JS('', '#[#] = #', _unwrap(_cls), name, value);
+ return reflect(value);
+ }
+
+ InstanceMirror invoke(Symbol symbol, List<dynamic> args,
+ [Map<Symbol, dynamic> namedArgs]) {
+ var name = getName(symbol);
+ if (namedArgs != null) {
+ args = new List.from(args);
+ args.add(_toJsMap(namedArgs));
+ }
+ var result = JS('', '#.#(...#)', _unwrap(_cls), name, args);
+ return reflect(result);
+ }
+
List<ClassMirror> get superinterfaces {
_Lazy<List<Type>> interfaceThunk = JS('', '#[dart.implements]', _unwrap(_cls));
if (interfaceThunk == null) {
@@ -385,6 +451,8 @@
return reflectType(_wrap(JS('Type', '#.__proto__', _unwrap(_cls))));
}
}
+
+ String toString() => "ClassMirror on '$_cls'";
}
class JsVariableMirror extends JsMirror implements VariableMirror {
@@ -403,11 +471,15 @@
: type = reflectType(t),
metadata = new List<InstanceMirror>.unmodifiable(
annotations.map((a) => reflect(a)));
+
+ String toString() => "VariableMirror on '$_name'";
}
class JsParameterMirror extends JsVariableMirror implements ParameterMirror {
JsParameterMirror._(String name, Type t, List annotations)
: super._(name, t, annotations);
+
+ String toString() => "ParameterMirror on '$_name'";
}
class JsMethodMirror extends JsMirror implements MethodMirror {
@@ -453,7 +525,9 @@
_metadata = const [];
return;
}
- if (ftype is List) {
+
+ // TODO(vsm): Why does generic function type trigger true for List?
+ if (ftype is! Function && ftype is List) {
// Record metadata
_metadata = new List<InstanceMirror>.unmodifiable(
ftype.skip(1).map((a) => reflect(a)));
@@ -462,6 +536,14 @@
_metadata = const [];
}
+ // TODO(vsm): Handle generic function types properly. Or deprecate mirrors
+ // before we need to!
+ if (JS('bool', 'typeof(#) == "function"', ftype)) {
+ // Instantiate the generic version.
+ // TODO(vsm): Can't use arguments.length on arrow function.
+ ftype = JS('', '#.apply(null, #)', ftype, [dynamic, dynamic, dynamic]);
+ }
+
// TODO(vsm): Add named args.
List args = ftype.args;
List opts = ftype.optionals;
@@ -485,4 +567,6 @@
_params = new List.unmodifiable(params);
}
+
+ String toString() => "MethodMirror on '$_name'";
}
diff --git a/pkg/dev_compiler/tool/input_sdk/private/js_string.dart b/pkg/dev_compiler/tool/input_sdk/private/js_string.dart
index 3a28309..57556b2 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/js_string.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/js_string.dart
@@ -11,7 +11,7 @@
* argument added to each member.
*/
@JsPeerInterface(name: 'String')
-class JSString extends Interceptor implements String, JSIndexable {
+class JSString extends Interceptor implements String, JSIndexable<String> {
const JSString();
int codeUnitAt(int index) {
diff --git a/pkg/dev_compiler/tool/input_sdk/private/native_typed_data.dart b/pkg/dev_compiler/tool/input_sdk/private/native_typed_data.dart
index 40c3f76..d823c36 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/native_typed_data.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/native_typed_data.dart
@@ -752,8 +752,7 @@
abstract class NativeTypedArray extends NativeTypedData
implements JavaScriptIndexingBehavior {
- // TODO(jmesserly): moved `length` to subclass to (somewhat) mitigate
- // <https://github.com/dart-lang/dev_compiler/issues/138>
+ int get length;
void _setRangeFast(int start, int end,
NativeTypedArray source, int skipCount) {
diff --git a/pkg/dev_compiler/tool/sdk_expected_errors.txt b/pkg/dev_compiler/tool/sdk_expected_errors.txt
index a7b684d..a62967e 100644
--- a/pkg/dev_compiler/tool/sdk_expected_errors.txt
+++ b/pkg/dev_compiler/tool/sdk_expected_errors.txt
@@ -1,30 +1,10 @@
-[error] Base class introduces an invalid override. The type of JSArray.[]= ((int, E) → void) is not a subtype of JSMutableIndexable.[]= ((int, dynamic) → dynamic). (dart:_interceptors/js_array.dart, line 590, col 25)
-[error] Invalid override. The type of NativeTypedArrayOfDouble.[]= ((int, num) → void) is not a subtype of JSMutableIndexable.[]= ((int, dynamic) → dynamic). (dart:_native_typed_data, line 793, col 3)
[error] Could not infer type parameter T, _ControllerEventSinkWrapper<dynamic> must be of type EventSink<T>. (dart:async/stream.dart, line 1346, col 16)
[error] The argument type '_ControllerEventSinkWrapper' cannot be assigned to the parameter type 'EventSink<T>'. (dart:async/stream.dart, line 1346, col 53)
[error] Invalid override. The type of ChunkedConverter.bind ((dynamic) → dynamic) is not a subtype of Converter<S, T>.bind ((Stream<S>) → Stream<T>). (dart:convert/chunked_conversion.dart, line 14, col 3)
[error] Invalid override. The type of ChunkedConverter.bind ((dynamic) → dynamic) is not a subtype of StreamTransformer<S, T>.bind ((Stream<S>) → Stream<T>). (dart:convert/chunked_conversion.dart, line 14, col 3)
[error] Invalid override. The type of ChunkedConverter.startChunkedConversion ((dynamic) → dynamic) is not a subtype of Converter<S, T>.startChunkedConversion ((Sink<T>) → Sink<S>). (dart:convert/chunked_conversion.dart, line 15, col 3)
-[error] Invalid override. The type of FileList.[]= ((int, File) → void) is not a subtype of JSMutableIndexable.[]= ((int, dynamic) → dynamic). (dart:html, line 16868, col 3)
-[error] Invalid override. The type of HtmlCollection.[]= ((int, Node) → void) is not a subtype of JSMutableIndexable.[]= ((int, dynamic) → dynamic). (dart:html, line 18903, col 3)
-[error] Invalid override. The type of MimeTypeArray.[]= ((int, MimeType) → void) is not a subtype of JSMutableIndexable.[]= ((int, dynamic) → dynamic). (dart:html, line 23817, col 3)
-[error] Invalid override. The type of NodeList.[]= ((int, Node) → void) is not a subtype of JSMutableIndexable.[]= ((int, dynamic) → dynamic). (dart:html, line 25466, col 3)
-[error] Invalid override. The type of PluginArray.[]= ((int, Plugin) → void) is not a subtype of JSMutableIndexable.[]= ((int, dynamic) → dynamic). (dart:html, line 26970, col 3)
-[error] Invalid override. The type of SourceBufferList.[]= ((int, SourceBuffer) → void) is not a subtype of JSMutableIndexable.[]= ((int, dynamic) → dynamic). (dart:html, line 30208, col 3)
-[error] Invalid override. The type of SpeechGrammarList.[]= ((int, SpeechGrammar) → void) is not a subtype of JSMutableIndexable.[]= ((int, dynamic) → dynamic). (dart:html, line 30409, col 3)
-[error] Invalid override. The type of TextTrackList.[]= ((int, TextTrack) → void) is not a subtype of JSMutableIndexable.[]= ((int, dynamic) → dynamic). (dart:html, line 32568, col 3)
-[error] Invalid override. The type of TouchList.[]= ((int, Touch) → void) is not a subtype of JSMutableIndexable.[]= ((int, dynamic) → dynamic). (dart:html, line 32903, col 3)
-[error] Invalid override. The type of _CssRuleList.[]= ((int, CssRule) → void) is not a subtype of JSMutableIndexable.[]= ((int, dynamic) → dynamic). (dart:html, line 37674, col 3)
-[error] Invalid override. The type of _GamepadList.[]= ((int, Gamepad) → void) is not a subtype of JSMutableIndexable.[]= ((int, dynamic) → dynamic). (dart:html, line 37928, col 3)
-[error] Invalid override. The type of _NamedNodeMap.[]= ((int, Node) → void) is not a subtype of JSMutableIndexable.[]= ((int, dynamic) → dynamic). (dart:html, line 38135, col 3)
-[error] Invalid override. The type of _SpeechRecognitionResultList.[]= ((int, SpeechRecognitionResult) → void) is not a subtype of JSMutableIndexable.[]= ((int, dynamic) → dynamic). (dart:html, line 38351, col 3)
-[error] Invalid override. The type of _StyleSheetList.[]= ((int, StyleSheet) → void) is not a subtype of JSMutableIndexable.[]= ((int, dynamic) → dynamic). (dart:html, line 38415, col 3)
[error] Invalid override. The type of _EventStreamSubscription.asFuture (([dynamic]) → Future<dynamic>) is not a subtype of StreamSubscription<T>.asFuture (<E>([E]) → Future<E>). (dart:html, line 40152, col 3)
[error] Invalid override. The type of JsArray.[]= ((Object, E) → void) is not a subtype of JsObject.[]= ((Object, dynamic) → dynamic). (dart:js, line 363, col 3)
-[error] The return type 'double' is not a 'T', as defined by the method 'min'. (dart:math, line 90, col 16)
-[error] The return type 'double' is not a 'T', as defined by the method 'min'. (dart:math, line 94, col 51)
-[error] The return type 'double' is not a 'T', as defined by the method 'max'. (dart:math, line 125, col 16)
-[error] The return type 'double' is not a 'T', as defined by the method 'max'. (dart:math, line 129, col 25)
[warning] Unsound implicit cast from dynamic to List<String> (dart:_debugger, line 39, col 45)
[warning] Unsound implicit cast from dynamic to List<NameValuePair> (dart:_debugger, line 750, col 43)
[warning] Unsound implicit cast from dynamic to List<String> (dart:_isolate_helper, line 839, col 37)
@@ -44,7 +24,7 @@
[warning] Unsound implicit cast from dynamic to E (dart:_interceptors/js_array.dart, line 564, col 12)
[warning] Unsound implicit cast from dynamic to JSArray<String> (dart:_js_helper, line 79, col 37)
[warning] Unsound implicit cast from dynamic to E (dart:_js_helper, line 882, col 16)
-[warning] Unsound implicit cast from dynamic to () → List<Type> (dart:_js_mirrors, line 356, col 40)
+[warning] Unsound implicit cast from dynamic to () → List<Type> (dart:_js_mirrors, line 422, col 40)
[warning] Unsound implicit cast from dynamic to List<String> (dart:_interceptors/js_string.dart, line 92, col 14)
[warning] Unsound implicit cast from dynamic to List<String> (dart:_interceptors/js_string.dart, line 95, col 14)
[warning] Unsound implicit cast from dynamic to LinkedHashMapCell<K, V> (dart:_js_helper/linked_hash_map.dart, line 119, col 40)
@@ -139,9 +119,9 @@
[warning] Unsound implicit cast from dynamic to Rectangle<num> (dart:html, line 37634, col 14)
[warning] Unsound implicit cast from (T) → void to (Event) → dynamic (dart:html, line 40090, col 67)
[warning] Unsound implicit cast from (T) → void to (Event) → dynamic (dart:html, line 40112, col 45)
-[warning] Unsound implicit cast from num to T (dart:math/rectangle.dart, line 151, col 22)
-[warning] Unsound implicit cast from num to T (dart:math/rectangle.dart, line 152, col 23)
-[warning] Unsound implicit cast from num to T (dart:math/rectangle.dart, line 275, col 10)
+[warning] Unsound implicit cast from num to T (dart:math/rectangle.dart, line 158, col 22)
+[warning] Unsound implicit cast from num to T (dart:math/rectangle.dart, line 159, col 23)
+[warning] Unsound implicit cast from num to T (dart:math/rectangle.dart, line 282, col 10)
[warning] The final variables 'href' and 'target' must be initialized (dart:svg, line 60, col 3)
[warning] The final variables 'requiredExtensions', 'requiredFeatures' and '2' more must be initialized (dart:svg, line 489, col 3)
[warning] The final variables 'cx', 'cy' and '1' more must be initialized (dart:svg, line 562, col 3)
diff --git a/pkg/expect/lib/expect.dart b/pkg/expect/lib/expect.dart
index 616920b..4ee2832 100644
--- a/pkg/expect/lib/expect.dart
+++ b/pkg/expect/lib/expect.dart
@@ -81,7 +81,7 @@
var truncExpected = _truncateString(expected, start, end, 20);
var truncActual = _truncateString(actual, start, end, 20);
return "at index $start: Expected <$truncExpected>, "
- "Found: <$truncActual>";
+ "Found: <$truncActual>";
}
}
return null;
@@ -146,7 +146,7 @@
if (_identical(expected, actual)) return;
String msg = _getMessage(reason);
_fail("Expect.identical(expected: <$expected>, actual: <$actual>$msg) "
- "fails.");
+ "fails.");
}
// Unconditional failure.
@@ -159,10 +159,8 @@
* given tolerance. If no tolerance is given, tolerance is assumed to be the
* value 4 significant digits smaller than the value given for expected.
*/
- static void approxEquals(num expected,
- num actual,
- [num tolerance = null,
- String reason = null]) {
+ static void approxEquals(num expected, num actual,
+ [num tolerance = null, String reason = null]) {
if (tolerance == null) {
tolerance = (expected / 1e4).abs();
}
@@ -171,14 +169,14 @@
String msg = _getMessage(reason);
_fail('Expect.approxEquals(expected:<$expected>, actual:<$actual>, '
- 'tolerance:<$tolerance>$msg) fails');
+ 'tolerance:<$tolerance>$msg) fails');
}
static void notEquals(unexpected, actual, [String reason = null]) {
if (unexpected != actual) return;
String msg = _getMessage(reason);
_fail("Expect.notEquals(unexpected: <$unexpected>, actual:<$actual>$msg) "
- "fails.");
+ "fails.");
}
/**
@@ -193,16 +191,16 @@
for (int i = 0; i < n; i++) {
if (expected[i] != actual[i]) {
_fail('Expect.listEquals(at index $i, '
- 'expected: <${expected[i]}>, actual: <${actual[i]}>$msg) fails');
+ 'expected: <${expected[i]}>, actual: <${actual[i]}>$msg) fails');
}
}
// We check on length at the end in order to provide better error
// messages when an unexpected item is inserted in a list.
if (expected.length != actual.length) {
_fail('Expect.listEquals(list length, '
- 'expected: <${expected.length}>, actual: <${actual.length}>$msg) '
- 'fails: Next element <'
- '${expected.length > n ? expected[n] : actual[n]}>');
+ 'expected: <${expected.length}>, actual: <${actual.length}>$msg) '
+ 'fails: Next element <'
+ '${expected.length > n ? expected[n] : actual[n]}>');
}
}
@@ -235,9 +233,8 @@
* Specialized equality test for strings. When the strings don't match,
* this method shows where the mismatch starts and ends.
*/
- static void stringEquals(String expected,
- String actual,
- [String reason = null]) {
+ static void stringEquals(String expected, String actual,
+ [String reason = null]) {
if (expected == actual) return;
String msg = _getMessage(reason);
@@ -262,10 +259,11 @@
}
// Scan from the right until we find the mismatch.
- int eRem = eLen - left; // Remaining length ignoring left match.
+ int eRem = eLen - left; // Remaining length ignoring left match.
int aRem = aLen - left;
while (true) {
- if (right == eRem || right == aRem ||
+ if (right == eRem ||
+ right == aRem ||
expected[eLen - right - 1] != actual[aLen - right - 1]) {
break;
}
@@ -293,12 +291,14 @@
// If snippets are long, elide the middle.
if (eSnippet.length > 43) {
- eSnippet = eSnippet.substring(0, 20) + "..." +
- eSnippet.substring(eSnippet.length - 20);
+ eSnippet = eSnippet.substring(0, 20) +
+ "..." +
+ eSnippet.substring(eSnippet.length - 20);
}
if (aSnippet.length > 43) {
- aSnippet = aSnippet.substring(0, 20) + "..." +
- aSnippet.substring(aSnippet.length - 20);
+ aSnippet = aSnippet.substring(0, 20) +
+ "..." +
+ aSnippet.substring(aSnippet.length - 20);
}
// Add "..." before and after, unless the snippets reach the end.
String leftLead = "...";
@@ -307,8 +307,8 @@
if (right <= 10) rightTail = "";
String diff = '\nDiff ($left..${eLen - right}/${aLen - right}):\n'
- '$leftLead$leftSnippet[ $eSnippet ]$rightSnippet$rightTail\n'
- '$leftLead$leftSnippet[ $aSnippet ]$rightSnippet$rightTail';
+ '$leftLead$leftSnippet[ $eSnippet ]$rightSnippet$rightTail\n'
+ '$leftLead$leftSnippet[ $aSnippet ]$rightSnippet$rightTail';
_fail("$defaultMessage$diff");
}
@@ -316,9 +316,8 @@
* Checks that every element of [expected] is also in [actual], and that
* every element of [actual] is also in [expected].
*/
- static void setEquals(Iterable expected,
- Iterable actual,
- [String reason = null]) {
+ static void setEquals(Iterable expected, Iterable actual,
+ [String reason = null]) {
final missingSet = new Set.from(expected);
missingSet.removeAll(actual);
final extraSet = new Set.from(actual);
@@ -349,6 +348,58 @@
}
/**
+ * Checks that [expected] is equivalent to [actual].
+ *
+ * If the objects are iterables or maps, recurses into them.
+ */
+ static void deepEquals(Object expected, Object actual) {
+ // Early exit check for equality.
+ if (expected == actual) return;
+
+ if (expected is String && actual is String) {
+ stringEquals(expected, actual);
+ } else if (expected is Iterable && actual is Iterable) {
+ var expectedLength = expected.length;
+ var actualLength = actual.length;
+
+ var length =
+ expectedLength < actualLength ? expectedLength : actualLength;
+ for (var i = 0; i < length; i++) {
+ deepEquals(expected.elementAt(i), actual.elementAt(i));
+ }
+
+ // We check on length at the end in order to provide better error
+ // messages when an unexpected item is inserted in a list.
+ if (expectedLength != actualLength) {
+ var nextElement =
+ (expectedLength > length ? expected : actual).elementAt(length);
+ _fail('Expect.deepEquals(list length, '
+ 'expected: <$expectedLength>, actual: <$actualLength>) '
+ 'fails: Next element <$nextElement>');
+ }
+ } else if (expected is Map && actual is Map) {
+ // Make sure all of the values are present in both and match.
+ for (final key in expected.keys) {
+ if (!actual.containsKey(key)) {
+ _fail('Expect.deepEquals(missing expected key: <$key>) fails');
+ }
+
+ Expect.deepEquals(expected[key], actual[key]);
+ }
+
+ // Make sure the actual map doesn't have any extra keys.
+ for (final key in actual.keys) {
+ if (!expected.containsKey(key)) {
+ _fail('Expect.deepEquals(unexpected key: <$key>) fails');
+ }
+ }
+ } else {
+ _fail("Expect.deepEquals(expected: <$expected>, actual: <$actual>) "
+ "fails.");
+ }
+ }
+
+ /**
* Calls the function [f] and verifies that it throws an exception.
* The optional [check] function can provide additional validation
* that the correct exception is being thrown. For example, to check
@@ -357,8 +408,7 @@
* Expect.throws(myThrowingFunction, (e) => e is MyException);
*/
static void throws(void f(),
- [bool check(exception) = null,
- String reason = null]) {
+ [_CheckExceptionFn check = null, String reason = null]) {
String msg = reason == null ? "" : "($reason)";
if (f is! _Nullary) {
// Only throws from executing the funtion body should count as throwing.
@@ -378,8 +428,8 @@
_fail('Expect.throws$msg fails: Did not throw');
}
- static String _getMessage(String reason)
- => (reason == null) ? "" : ", '$reason'";
+ static String _getMessage(String reason) =>
+ (reason == null) ? "" : ", '$reason'";
static void _fail(String message) {
throw new ExpectException(message);
@@ -388,7 +438,8 @@
bool _identical(a, b) => identical(a, b);
-typedef _Nullary(); // Expect.throws argument must be this type.
+typedef bool _CheckExceptionFn(exception);
+typedef _Nullary(); // Expect.throws argument must be this type.
class ExpectException implements Exception {
ExpectException(this.message);
diff --git a/pkg/expect/lib/minitest.dart b/pkg/expect/lib/minitest.dart
new file mode 100644
index 0000000..d3057c2
--- /dev/null
+++ b/pkg/expect/lib/minitest.dart
@@ -0,0 +1,195 @@
+// 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.
+
+/// A minimal, dependency-free emulation layer for a subset of the
+/// unittest/test API used by the language and core library (especially HTML)
+/// tests.
+///
+/// A number of our language and core library tests were written against the
+/// unittest package, which is now deprecated in favor of the new test package.
+/// The latter is much better feature-wise, but is also quite complex and has
+/// many dependencies. For low-level language and core library tests, we don't
+/// want to have to pull in a large number of dependencies and be able to run
+/// them correctly in order to run a test, so we want to test them against
+/// something simpler.
+///
+/// When possible, we just use the tiny expect library. But to avoid rewriting
+/// all of the existing tests that use unittest, they can instead use this,
+/// which shims the unittest API with as little code as possible and calls into
+/// expect.
+///
+/// Eventually, it would be good to refactor those tests to use the expect
+/// package directly and remove this.
+
+import 'package:expect/expect.dart';
+
+typedef void _Action();
+typedef void _ExpectationFunction(Object actual);
+
+final List<_Group> _groups = [new _Group()];
+
+final Object isFalse = new _Expectation(Expect.isFalse);
+final Object isNotNull = new _Expectation(Expect.isNotNull);
+final Object isNull = new _Expectation(Expect.isNull);
+final Object isTrue = new _Expectation(Expect.isTrue);
+
+final Object returnsNormally = new _Expectation((actual) {
+ try {
+ (actual as _Action)();
+ } catch (error) {
+ Expect.fail("Expected function to return normally, but threw:\n$error");
+ }
+});
+
+final Object throws = new _Expectation((actual) {
+ Expect.throws(actual as _Action);
+});
+
+final Object throwsArgumentError = new _Expectation((actual) {
+ Expect.throws(actual as _Action, (error) => error is ArgumentError);
+});
+
+final Object throwsNoSuchMethodError = new _Expectation((actual) {
+ Expect.throws(actual as _Action, (error) => error is NoSuchMethodError);
+});
+
+final Object throwsRangeError = new _Expectation((actual) {
+ Expect.throws(actual as _Action, (error) => error is RangeError);
+});
+
+final Object throwsStateError = new _Expectation((actual) {
+ Expect.throws(actual as _Action, (error) => error is StateError);
+});
+
+final Object throwsUnsupportedError = new _Expectation((actual) {
+ Expect.throws(actual as _Action, (error) => error is UnsupportedError);
+});
+
+/// The test runner should call this once after running a test file.
+void finishTests() {
+ _groups.clear();
+ _groups.add(new _Group());
+}
+
+void group(String description, body()) {
+ // TODO(rnystrom): Do something useful with the description.
+ _groups.add(new _Group());
+
+ try {
+ body();
+ } finally {
+ _groups.removeLast();
+ }
+}
+
+void test(String description, body()) {
+ // TODO(rnystrom): Do something useful with the description.
+ for (var group in _groups) {
+ if (group.setUpFunction != null) group.setUpFunction();
+ }
+
+ try {
+ body();
+ } finally {
+ for (var i = _groups.length - 1; i >= 0; i--) {
+ var group = _groups[i];
+ if (group.tearDownFunction != null) group.tearDownFunction();
+ }
+ }
+}
+
+void setUp(body()) {
+ // Can't define multiple setUps at the same level.
+ assert(_groups.last.setUpFunction == null);
+ _groups.last.setUpFunction = body;
+}
+
+void tearDown(body()) {
+ // Can't define multiple tearDowns at the same level.
+ assert(_groups.last.tearDownFunction == null);
+ _groups.last.tearDownFunction = body;
+}
+
+void expect(Object actual, Object expected, {String reason}) {
+ // TODO(rnystrom): Do something useful with reason.
+ if (expected is! _Expectation) {
+ expected = equals(expected);
+ }
+
+ var expectation = expected as _Expectation;
+ expectation.function(actual);
+}
+
+void fail(String message) {
+ Expect.fail(message);
+}
+
+Object equals(Object value) => new _Expectation((actual) {
+ Expect.deepEquals(value, actual);
+ });
+
+Object notEquals(Object value) => new _Expectation((actual) {
+ Expect.notEquals(value, actual);
+ });
+
+Object unorderedEquals(Object value) => new _Expectation((actual) {
+ Expect.setEquals(value, actual);
+ });
+
+// TODO(bob): Do something useful with the description.
+Object predicate(bool fn(Object value), [String description]) =>
+ new _Expectation((actual) {
+ Expect.isTrue(fn(actual));
+ });
+
+Object inInclusiveRange(num min, num max) => new _Expectation((actual) {
+ var actualNum = actual as num;
+ if (actualNum < min || actualNum > max) {
+ fail("Expected $actualNum to be in the inclusive range [$min, $max].");
+ }
+ });
+
+Object greaterThan(num value) => new _Expectation((actual) {
+ var actualNum = actual as num;
+ if (actualNum <= value) {
+ fail("Expected $actualNum to be greater than $value.");
+ }
+ });
+
+Object same(Object value) => new _Expectation((actual) {
+ Expect.identical(value, actual);
+ });
+
+Object closeTo(num value, num tolerance) => new _Expectation((actual) {
+ Expect.approxEquals(value, actual, tolerance);
+ });
+
+/// Succeeds if the actual value is any of the given strings. Unlike matcher's
+/// [anyOf], this only works with strings and requires an explicit list.
+Object anyOf(List<String> expected) => new _Expectation((actual) {
+ for (var string in expected) {
+ if (actual == string) return;
+ }
+
+ fail("Expected $actual to be one of $expected.");
+ });
+
+/// One level of group() nesting to track an optional [setUp()] and [tearDown()]
+/// function for the group.
+///
+/// There is also an implicit top level group.
+class _Group {
+ _Action setUpFunction;
+ _Action tearDownFunction;
+}
+
+/// A wrapper around an expectation function.
+///
+/// This function is passed the actual value and should throw an
+/// [ExpectException] if the value doesn't match the expectation.
+class _Expectation {
+ final _ExpectationFunction function;
+
+ _Expectation(this.function);
+}
diff --git a/pkg/pkg.status b/pkg/pkg.status
index db253b5..0219688 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -34,6 +34,7 @@
analysis_server/test/completion_test: Pass, Slow
[ $runtime == vm && $system == windows]
+analysis_server/*: Skip # Issue 27557
analysis_server/test/analysis/get_errors_test: Skip # runtime error, Issue 22180
analysis_server/test/integration/analysis/analysis_options_test: RuntimeError # Issue 24796
analyzer/test/generated/all_the_rest_test: Fail # Issue 21772
@@ -48,6 +49,7 @@
collection/test/equality_test/04: Fail # Issue 1533
collection/test/equality_test/05: Fail # Issue 1533
collection/test/equality_test/none: Pass, Fail # Issue 14348
+compiler/tool/*: SkipByDesign # Only meant to run on vm
lookup_map/test/version_check_test: SkipByDesign # Only meant to run in vm.
typed_data/test/typed_buffers_test/01: Fail # Not supporting Int64List, Uint64List.
@@ -95,6 +97,7 @@
analyzer/tool/task_dependency_graph/check_test: SkipByDesign # Uses dart:io.
analyzer/tool/summary/check_test: SkipByDesign # Uses dart:io.
analyzer2dart/*: SkipByDesign # Uses dart:io.
+compiler/tool/*: SkipByDesign # Only meant to run on vm
http_server/test/*: Fail, OK # Uses dart:io.
observe/test/transformer_test: Fail, OK # Uses dart:io.
observe/test/unique_message_test: SkipByDesign # Uses dart:io.
diff --git a/pkg/pkg_files.gyp b/pkg/pkg_files.gyp
index 9dd13e3..55dd284 100644
--- a/pkg/pkg_files.gyp
+++ b/pkg/pkg_files.gyp
@@ -9,8 +9,8 @@
# This target lists all the files in pkg and third_party/pkg,
# and creates the timestamp pkg_files.stamp, which depends on some
# intermediate helper timestamps.
- # We split third_party/pkg up into three groups, based on the last
- # character before .dart at the end of the filename.
+ # We split third_party/pkg up into three groups, based on the first letter
+ # of the package name.
{
'target_name': 'pkg_files_stamp',
'type': 'none',
@@ -19,12 +19,10 @@
'action_name': 'make_pkg_files_stamp',
'inputs': [
'../tools/create_timestamp_file.py',
- '<!@(["python", "../tools/list_files.py",'
- '"^(?!.*/test/).*(?<!_test)[.]dart$",'
- '"."])',
- '<(SHARED_INTERMEDIATE_DIR)/third_party_pkg_files_1.stamp',
- '<(SHARED_INTERMEDIATE_DIR)/third_party_pkg_files_2.stamp',
- '<(SHARED_INTERMEDIATE_DIR)/third_party_pkg_files_3.stamp',
+ '<!@(["python", "../tools/list_dart_files.py", "."])',
+ '<(SHARED_INTERMEDIATE_DIR)/third_party_pkg_files_a_k.stamp',
+ '<(SHARED_INTERMEDIATE_DIR)/third_party_pkg_files_l_r.stamp',
+ '<(SHARED_INTERMEDIATE_DIR)/third_party_pkg_files_s_z.stamp',
],
'outputs': [
'<(SHARED_INTERMEDIATE_DIR)/pkg_files.stamp',
@@ -35,15 +33,13 @@
],
},
{
- 'action_name': 'make_third_party_pkg_files_1_stamp',
+ 'action_name': 'make_third_party_pkg_files_a_k_stamp',
'inputs': [
'../tools/create_timestamp_file.py',
- '<!@(["python", "../tools/list_files.py",'
- '"^(?!.*_test\.dart).*[a-k]\.dart$",'
- '"../third_party/pkg"])',
+ '<!@(["python", "../tools/list_dart_files.py", "../third_party/pkg", "[a-k].*"])',
],
'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/third_party_pkg_files_1.stamp',
+ '<(SHARED_INTERMEDIATE_DIR)/third_party_pkg_files_a_k.stamp',
],
'action': [
'python', '../tools/create_timestamp_file.py',
@@ -51,15 +47,13 @@
],
},
{
- 'action_name': 'make_third_party_pkg_files_2_stamp',
+ 'action_name': 'make_third_party_pkg_files_l_r_stamp',
'inputs': [
'../tools/create_timestamp_file.py',
- '<!@(["python", "../tools/list_files.py",'
- '"^(?!.*_test\.dart).*[l-r]\.dart$",'
- '"../third_party/pkg"])',
+ '<!@(["python", "../tools/list_dart_files.py", "../third_party/pkg", "[l-r].*"])',
],
'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/third_party_pkg_files_2.stamp',
+ '<(SHARED_INTERMEDIATE_DIR)/third_party_pkg_files_l_r.stamp',
],
'action': [
'python', '../tools/create_timestamp_file.py',
@@ -67,15 +61,13 @@
],
},
{
- 'action_name': 'make_third_party_pkg_files_3_stamp',
+ 'action_name': 'make_third_party_pkg_files_s_z_stamp',
'inputs': [
'../tools/create_timestamp_file.py',
- '<!@(["python", "../tools/list_files.py",'
- '"^(?!.*_test\.dart).*[^a-r]\.dart$",'
- '"../third_party/pkg"])',
+ '<!@(["python", "../tools/list_dart_files.py", "../third_party/pkg", "[s-z].*"])',
],
'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/third_party_pkg_files_3.stamp',
+ '<(SHARED_INTERMEDIATE_DIR)/third_party_pkg_files_s_z.stamp',
],
'action': [
'python', '../tools/create_timestamp_file.py',
diff --git a/pkg/typed_mock/BUILD.gn b/pkg/typed_mock/BUILD.gn
new file mode 100644
index 0000000..b00e00b
--- /dev/null
+++ b/pkg/typed_mock/BUILD.gn
@@ -0,0 +1,11 @@
+# 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("//build/dart/dart_package.gni")
+
+dart_package("typed_mock") {
+ package_name = "typed_mock"
+
+ source_dir = "lib"
+}
diff --git a/runtime/BUILD.gn b/runtime/BUILD.gn
index afc963ab..e7e21bf 100644
--- a/runtime/BUILD.gn
+++ b/runtime/BUILD.gn
@@ -153,36 +153,37 @@
defines += ["NDEBUG"]
}
- cflags = [
- "-Werror",
- "-Wall",
- "-Wextra", # Also known as -W.
- "-Wno-unused-parameter",
- "-Wnon-virtual-dtor",
- "-Wvla",
- "-Wno-conversion-null",
- "-Woverloaded-virtual",
- "-g3",
- "-ggdb3",
- "-fno-rtti",
- "-fno-exceptions",
- ]
+ if (!is_win) {
+ cflags = [
+ "-Werror",
+ "-Wall",
+ "-Wextra", # Also known as -W.
+ "-Wno-unused-parameter",
+ "-Wnon-virtual-dtor",
+ "-Wvla",
+ "-Wno-conversion-null",
+ "-Woverloaded-virtual",
+ "-g3",
+ "-ggdb3",
+ "-fno-rtti",
+ "-fno-exceptions",
+ ]
- if (dart_debug) {
- cflags += [
- "-O1",
- ]
- } else {
- cflags += [
- "-O3",
- ]
- }
+ if (dart_debug) {
+ cflags += [
+ "-O1",
+ ]
+ } else {
+ cflags += [
+ "-O3",
+ ]
+ }
- if (defined(is_asan) && is_asan) {
- ldflags = [
- "-Wl,-u_sanitizer_options_link_helper",
- "-fsanitize=address",
- ]
+ if (defined(is_asan) && is_asan) {
+ ldflags = [
+ "-fsanitize=address",
+ ]
+ }
}
}
@@ -237,6 +238,17 @@
]
}
+libdart_library("libdart_noopt") {
+ extra_configs = [
+ ":dart_maybe_precompiled_runtime_config",
+ ":dart_precompiler_config",
+ ]
+ extra_deps = [
+ "vm:libdart_lib",
+ "vm:libdart_vm_noopt",
+ ]
+}
+
libdart_library("libdart_precompiled_runtime") {
extra_configs = [
":dart_precompiled_runtime_config"
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index 549807b..df8d405 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -203,9 +203,11 @@
}
config("libdart_builtin_config") {
- libs = [
- "dl",
- ]
+ if (!is_win) {
+ libs = [
+ "dl",
+ ]
+ }
if (is_android) {
libs += [
"android",
@@ -300,6 +302,16 @@
"CoreServices.framework"
]
}
+
+ if (is_win) {
+ libs = [
+ "iphlpapi.lib",
+ "psapi.lib",
+ "ws2_32.lib",
+ "Rpcrt4.lib",
+ "winmm.lib",
+ ]
+ }
}
# A source set for the implementation of 'dart:io' library
@@ -374,9 +386,14 @@
if (is_mac || is_ios) {
libs = [
"CoreFoundation.framework",
- "CoreServices.framework",
"Security.framework",
]
+
+ if (is_mac) {
+ libs += [
+ "CoreServices.framework",
+ ]
+ }
} else if (defined(is_fuchsia) && is_fuchsia) {
defines += [
"DART_IO_SECURE_SOCKET_DISABLED"
@@ -540,9 +557,25 @@
"//third_party",
]
- ldflags = [
- "-rdynamic",
- ]
+ if (is_win) {
+ ldflags = [
+ "/EXPORT:Dart_True"
+ ]
+ } else {
+ ldflags = [
+ "-rdynamic",
+ ]
+ }
+
+ if (is_win) {
+ libs = [
+ "iphlpapi.lib",
+ "psapi.lib",
+ "ws2_32.lib",
+ "Rpcrt4.lib",
+ "winmm.lib",
+ ]
+ }
}
}
@@ -555,6 +588,17 @@
]
}
+ dart_executable("dart_noopt") {
+ extra_configs = [
+ "..:dart_precompiler_config",
+ ]
+ extra_deps = [
+ "..:libdart_noopt",
+ ":dart_snapshot_cc",
+ "../observatory:standalone_observatory_archive",
+ ]
+ }
+
dart_executable("dart_precompiled_runtime") {
extra_configs = [
"..:dart_precompiled_runtime_config"
@@ -703,9 +747,21 @@
"run_vm_tests.cc",
] + builtin_impl_tests_list.sources + vm_tests
- ldflags = [
- "-rdynamic",
- ]
+ if (!is_win) {
+ ldflags = [
+ "-rdynamic",
+ ]
+ }
+
+ if (is_win) {
+ libs = [
+ "iphlpapi.lib",
+ "psapi.lib",
+ "ws2_32.lib",
+ "Rpcrt4.lib",
+ "winmm.lib",
+ ]
+ }
}
if (!defined(is_fuchsia) || !is_fuchsia) {
@@ -724,6 +780,15 @@
# The only effect of DART_SHARED_LIB is to export the Dart API.
"DART_SHARED_LIB",
]
+ if (is_win) {
+ libs = [
+ "dart.lib"
+ ]
+ abs_root_out_dir = rebase_path(root_out_dir)
+ ldflags = [
+ "/LIBPATH:$abs_root_out_dir"
+ ]
+ }
}
shared_library("sample_extension") {
@@ -741,5 +806,14 @@
# The only effect of DART_SHARED_LIB is to export the Dart API.
"DART_SHARED_LIB",
]
+ if (is_win) {
+ libs = [
+ "dart.lib"
+ ]
+ abs_root_out_dir = rebase_path(root_out_dir)
+ ldflags = [
+ "/LIBPATH:$abs_root_out_dir"
+ ]
+ }
}
}
diff --git a/runtime/bin/bin.gypi b/runtime/bin/bin.gypi
index 650f587..f460a08 100644
--- a/runtime/bin/bin.gypi
+++ b/runtime/bin/bin.gypi
@@ -1147,7 +1147,7 @@
},
},
}],
- ['OS == "linux" and asan == 0', {
+ ['OS == "linux" and asan == 0 and msan == 0', {
'dependencies': [
'../third_party/tcmalloc/tcmalloc.gypi:tcmalloc',
],
@@ -1398,7 +1398,7 @@
'libraries': [ '-lws2_32.lib', '-lRpcrt4.lib', '-lwinmm.lib' ],
},
}],
- ['OS == "linux" and asan == 0', {
+ ['OS == "linux" and asan == 0 and msan == 0', {
'dependencies': [
'../third_party/tcmalloc/tcmalloc.gypi:tcmalloc',
],
diff --git a/runtime/bin/dart_io_entries.txt b/runtime/bin/dart_io_entries.txt
index 4cfcd70..b24bd38 100644
--- a/runtime/bin/dart_io_entries.txt
+++ b/runtime/bin/dart_io_entries.txt
@@ -12,8 +12,13 @@
dart:io,TlsException,TlsException.
dart:io,X509Certificate,X509Certificate._
dart:io,_ExternalBuffer,set:data
+dart:io,_ExternalBuffer,get:start
+dart:io,_ExternalBuffer,set:start
+dart:io,_ExternalBuffer,set:end
+dart:io,_ExternalBuffer,get:end
dart:io,_Platform,set:_nativeScript
dart:io,_ProcessStartStatus,set:_errorCode
dart:io,_ProcessStartStatus,set:_errorMessage
+dart:io,_SecureFilterImpl,get:buffers
dart:io,_SecureFilterImpl,get:ENCRYPTED_SIZE
dart:io,_SecureFilterImpl,get:SIZE
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
index e723764..dd13e6d 100644
--- a/runtime/bin/dartutils.cc
+++ b/runtime/bin/dartutils.cc
@@ -18,6 +18,7 @@
#include "platform/assert.h"
#include "platform/globals.h"
+#include "platform/memory_sanitizer.h"
// Return the error from the containing function if handle is in error handle.
#define RETURN_IF_ERROR(handle) \
@@ -46,7 +47,47 @@
const char* const DartUtils::kHttpScheme = "http:";
const char* const DartUtils::kVMServiceLibURL = "dart:vmservice";
-const uint8_t DartUtils::magic_number[] = { 0xf5, 0xf5, 0xdc, 0xdc };
+
+struct MagicNumberData {
+ static const intptr_t kLength = 4;
+
+ const uint8_t bytes[kLength];
+ bool should_skip;
+};
+
+
+MagicNumberData snapshot_magic_number = { { 0xf5, 0xf5, 0xdc, 0xdc }, true };
+MagicNumberData kernel_magic_number = { {0x90, 0xab, 0xcd, 0xef}, false };
+
+
+bool TryReadKernel(const char* script_uri,
+ const uint8_t** kernel_file,
+ intptr_t* kernel_length) {
+ *kernel_file = NULL;
+ *kernel_length = -1;
+ bool is_kernel_file = false;
+ void* script_file = DartUtils::OpenFile(script_uri, false);
+ if (script_file != NULL) {
+ const uint8_t* buffer = NULL;
+ DartUtils::ReadFile(&buffer, kernel_length, script_file);
+ DartUtils::CloseFile(script_file);
+ if (*kernel_length > 0 && buffer != NULL) {
+ *kernel_file = buffer;
+ if (DartUtils::SniffForMagicNumber(&buffer, kernel_length) !=
+ DartUtils::kKernelMagicNumber) {
+ free(const_cast<uint8_t*>(buffer));
+ *kernel_file = NULL;
+ } else {
+ // Do not free buffer if this is a kernel file - kernel_file will be
+ // backed by the same memory as the buffer and caller will own it.
+ // Caller is responsible for freeing the buffer when this function
+ // returns true.
+ is_kernel_file = true;
+ }
+ }
+ }
+ return is_kernel_file;
+}
static bool IsWindowsHost() {
@@ -191,17 +232,6 @@
}
-void* DartUtils::MapExecutable(const char* name, intptr_t* len) {
- File* file = File::Open(name, File::kRead);
- if (file == NULL) {
- return NULL;
- }
- void* addr = file->MapExecutable(len);
- file->Release();
- return addr;
-}
-
-
void* DartUtils::OpenFile(const char* name, bool write) {
File* file = File::Open(name, write ? File::kWriteTruncate : File::kRead);
return reinterpret_cast<void*>(file);
@@ -467,30 +497,39 @@
}
-const uint8_t* DartUtils::SniffForMagicNumber(const uint8_t* text_buffer,
- intptr_t* buffer_len,
- bool* is_snapshot) {
- intptr_t len = sizeof(magic_number);
- if (*buffer_len <= len) {
- *is_snapshot = false;
- return text_buffer;
- }
- for (intptr_t i = 0; i < len; i++) {
- if (text_buffer[i] != magic_number[i]) {
- *is_snapshot = false;
- return text_buffer;
+static bool CheckMagicNumber(const uint8_t** buf,
+ intptr_t* len,
+ const MagicNumberData& magic_number) {
+ if ((*len >= MagicNumberData::kLength) &&
+ (memcmp(*buf, magic_number.bytes, MagicNumberData::kLength) == 0)) {
+ if (magic_number.should_skip) {
+ *buf += MagicNumberData::kLength;
+ *len -= MagicNumberData::kLength;
}
+ return true;
}
- *is_snapshot = true;
- ASSERT(*buffer_len > len);
- *buffer_len -= len;
- return text_buffer + len;
+ return false;
+}
+
+
+DartUtils::MagicNumber DartUtils::SniffForMagicNumber(const uint8_t** buf,
+ intptr_t* len) {
+ if (CheckMagicNumber(buf, len, snapshot_magic_number)) {
+ return kSnapshotMagicNumber;
+ }
+
+ if (CheckMagicNumber(buf, len, kernel_magic_number)) {
+ return kKernelMagicNumber;
+ }
+
+ return kUnknownMagicNumber;
}
void DartUtils::WriteMagicNumber(File* file) {
// Write a magic number and version information into the snapshot file.
- bool bytes_written = file->WriteFully(magic_number, sizeof(magic_number));
+ bool bytes_written = file->WriteFully(snapshot_magic_number.bytes,
+ MagicNumberData::kLength);
ASSERT(bytes_written);
}
@@ -558,12 +597,14 @@
if (Dart_IsNull(tag_in) && Dart_IsNull(library_uri)) {
// Entry file. Check for payload and load accordingly.
- bool is_snapshot = false;
- const uint8_t *payload =
- DartUtils::SniffForMagicNumber(data, &num_bytes, &is_snapshot);
+ const uint8_t* payload = data;
+ const DartUtils::MagicNumber payload_type =
+ DartUtils::SniffForMagicNumber(&payload, &num_bytes);
- if (is_snapshot) {
+ if (payload_type == DartUtils::kSnapshotMagicNumber) {
result = Dart_LoadScriptFromSnapshot(payload, num_bytes);
+ } else if (payload_type == DartUtils::kKernelMagicNumber) {
+ UNREACHABLE();
} else {
Dart_Handle source = Dart_NewStringFromUTF8(data, num_bytes);
if (Dart_IsError(source)) {
@@ -927,6 +968,7 @@
va_end(args);
char* buffer = reinterpret_cast<char*>(Dart_ScopeAllocate(len + 1));
+ MSAN_UNPOISON(buffer, (len + 1));
va_list args2;
va_start(args2, format);
vsnprintf(buffer, (len + 1), format, args2);
diff --git a/runtime/bin/dartutils.h b/runtime/bin/dartutils.h
index b9fe476..ff2ae20 100644
--- a/runtime/bin/dartutils.h
+++ b/runtime/bin/dartutils.h
@@ -33,6 +33,15 @@
return handle;
}
+// Tries to read [script_uri] as a Kernel IR file. If successful this function
+// returns `true` and sets [kernel_file] and [kernel_length] to be the memory
+// contents.
+//
+// The caller is responsible for free()ing [kernel_file] if `true` was returned.
+bool TryReadKernel(const char* script_uri,
+ const uint8_t** kernel_file,
+ intptr_t* kernel_length);
+
class CommandLineOptions {
public:
explicit CommandLineOptions(int max_count)
@@ -200,14 +209,21 @@
static Dart_Handle ResolveUriInWorkingDirectory(Dart_Handle script_uri);
static Dart_Handle ResolveScript(Dart_Handle url);
+ enum MagicNumber {
+ kSnapshotMagicNumber,
+ kKernelMagicNumber,
+ kUnknownMagicNumber
+ };
+
+ // static const uint8_t* GetMagicNumber(MagicNumber number);
+
// Sniffs the specified text_buffer to see if it contains the magic number
// representing a script snapshot. If the text_buffer is a script snapshot
// the return value is an updated pointer to the text_buffer pointing past
// the magic number value. The 'buffer_len' parameter is also appropriately
// adjusted.
- static const uint8_t* SniffForMagicNumber(const uint8_t* text_buffer,
- intptr_t* buffer_len,
- bool* is_snapshot);
+ static MagicNumber SniffForMagicNumber(const uint8_t** text_buffer,
+ intptr_t* buffer_len);
// Write a magic number to indicate a script snapshot file.
static void WriteMagicNumber(File* file);
@@ -231,8 +247,6 @@
static const char* const kHttpScheme;
static const char* const kVMServiceLibURL;
- static const uint8_t magic_number[];
-
static Dart_Handle LibraryFilePath(Dart_Handle library_uri);
private:
diff --git a/runtime/bin/eventhandler_fuchsia.cc b/runtime/bin/eventhandler_fuchsia.cc
index cdd4fad..ff947ea 100644
--- a/runtime/bin/eventhandler_fuchsia.cc
+++ b/runtime/bin/eventhandler_fuchsia.cc
@@ -24,6 +24,7 @@
if (status != NO_ERROR) {
FATAL1("mx_msgpipe_create failed: %s\n", mx_strstatus(status));
}
+ shutdown_ = false;
}
diff --git a/runtime/bin/extensions_android.cc b/runtime/bin/extensions_android.cc
index c34902c..44df410 100644
--- a/runtime/bin/extensions_android.cc
+++ b/runtime/bin/extensions_android.cc
@@ -11,7 +11,8 @@
namespace dart {
namespace bin {
-const char* kPrecompiledLibraryName = "libprecompiled.so";
+const char* kPrecompiledVMIsolateSymbolName = "_kVmIsolateSnapshot";
+const char* kPrecompiledIsolateSymbolName = "_kIsolateSnapshot";
const char* kPrecompiledInstructionsSymbolName = "_kInstructionsSnapshot";
const char* kPrecompiledDataSymbolName = "_kDataSnapshot";
diff --git a/runtime/bin/extensions_fuchsia.cc b/runtime/bin/extensions_fuchsia.cc
index d474672..691cac3 100644
--- a/runtime/bin/extensions_fuchsia.cc
+++ b/runtime/bin/extensions_fuchsia.cc
@@ -11,7 +11,8 @@
namespace dart {
namespace bin {
-const char* kPrecompiledLibraryName = "libprecompiled.so";
+const char* kPrecompiledVMIsolateSymbolName = "_kVmIsolateSnapshot";
+const char* kPrecompiledIsolateSymbolName = "_kIsolateSnapshot";
const char* kPrecompiledInstructionsSymbolName = "_kInstructionsSnapshot";
const char* kPrecompiledDataSymbolName = "_kDataSnapshot";
diff --git a/runtime/bin/extensions_linux.cc b/runtime/bin/extensions_linux.cc
index 8a25cba..264c4ee 100644
--- a/runtime/bin/extensions_linux.cc
+++ b/runtime/bin/extensions_linux.cc
@@ -11,7 +11,8 @@
namespace dart {
namespace bin {
-const char* kPrecompiledLibraryName = "libprecompiled.so";
+const char* kPrecompiledVMIsolateSymbolName = "_kVmIsolateSnapshot";
+const char* kPrecompiledIsolateSymbolName = "_kIsolateSnapshot";
const char* kPrecompiledInstructionsSymbolName = "_kInstructionsSnapshot";
const char* kPrecompiledDataSymbolName = "_kDataSnapshot";
diff --git a/runtime/bin/extensions_macos.cc b/runtime/bin/extensions_macos.cc
index 9910f10..69d712d 100644
--- a/runtime/bin/extensions_macos.cc
+++ b/runtime/bin/extensions_macos.cc
@@ -11,7 +11,8 @@
namespace dart {
namespace bin {
-const char* kPrecompiledLibraryName = "libprecompiled.dylib";
+const char* kPrecompiledVMIsolateSymbolName = "kVmIsolateSnapshot";
+const char* kPrecompiledIsolateSymbolName = "kIsolateSnapshot";
const char* kPrecompiledInstructionsSymbolName = "kInstructionsSnapshot";
const char* kPrecompiledDataSymbolName = "kDataSnapshot";
diff --git a/runtime/bin/extensions_win.cc b/runtime/bin/extensions_win.cc
index 493acad..da626f1 100644
--- a/runtime/bin/extensions_win.cc
+++ b/runtime/bin/extensions_win.cc
@@ -12,7 +12,8 @@
namespace dart {
namespace bin {
-const char* kPrecompiledLibraryName = "precompiled.dll";
+const char* kPrecompiledVMIsolateSymbolName = "_kVmIsolateSnapshot";
+const char* kPrecompiledIsolateSymbolName = "_kIsolateSnapshot";
const char* kPrecompiledInstructionsSymbolName = "_kInstructionsSnapshot";
const char* kPrecompiledDataSymbolName = "_kDataSnapshot";
diff --git a/runtime/bin/file.h b/runtime/bin/file.h
index 6b22793..c30c02d 100644
--- a/runtime/bin/file.h
+++ b/runtime/bin/file.h
@@ -88,7 +88,11 @@
intptr_t GetFD();
- void* MapExecutable(intptr_t* num_bytes);
+ enum MapType {
+ kReadOnly = 0,
+ kReadExecute = 1,
+ };
+ void* Map(MapType type, int64_t position, int64_t length);
// Read/Write attempt to transfer num_bytes to/from buffer. It returns
// the number of bytes read/written.
diff --git a/runtime/bin/file_android.cc b/runtime/bin/file_android.cc
index 9bcf44c..a139876 100644
--- a/runtime/bin/file_android.cc
+++ b/runtime/bin/file_android.cc
@@ -78,17 +78,23 @@
}
-void* File::MapExecutable(intptr_t* len) {
+void* File::Map(MapType type, int64_t position, int64_t length) {
ASSERT(handle_->fd() >= 0);
-
- intptr_t length = Length();
- void* addr = mmap(0, length,
- PROT_READ | PROT_EXEC, MAP_PRIVATE,
- handle_->fd(), 0);
+ int prot = PROT_NONE;
+ switch (type) {
+ case kReadOnly:
+ prot = PROT_READ;
+ break;
+ case kReadExecute:
+ prot = PROT_READ | PROT_EXEC;
+ break;
+ default:
+ return NULL;
+ }
+ void* addr = mmap(NULL, length, prot, MAP_PRIVATE,
+ handle_->fd(), position);
if (addr == MAP_FAILED) {
- *len = -1;
- } else {
- *len = length;
+ return NULL;
}
return addr;
}
diff --git a/runtime/bin/file_fuchsia.cc b/runtime/bin/file_fuchsia.cc
index fdc2623..da22733 100644
--- a/runtime/bin/file_fuchsia.cc
+++ b/runtime/bin/file_fuchsia.cc
@@ -75,7 +75,7 @@
}
-void* File::MapExecutable(intptr_t* len) {
+void* File::Map(MapType type, int64_t position, int64_t length) {
UNIMPLEMENTED();
return NULL;
}
diff --git a/runtime/bin/file_linux.cc b/runtime/bin/file_linux.cc
index 4f61db1..e6b27f8 100644
--- a/runtime/bin/file_linux.cc
+++ b/runtime/bin/file_linux.cc
@@ -77,16 +77,23 @@
}
-void* File::MapExecutable(intptr_t* len) {
+void* File::Map(MapType type, int64_t position, int64_t length) {
ASSERT(handle_->fd() >= 0);
- intptr_t length = Length();
- void* addr = mmap(0, length,
- PROT_READ | PROT_EXEC, MAP_PRIVATE,
- handle_->fd(), 0);
+ int prot = PROT_NONE;
+ switch (type) {
+ case kReadOnly:
+ prot = PROT_READ;
+ break;
+ case kReadExecute:
+ prot = PROT_READ | PROT_EXEC;
+ break;
+ default:
+ return NULL;
+ }
+ void* addr = mmap(NULL, length, prot, MAP_PRIVATE,
+ handle_->fd(), position);
if (addr == MAP_FAILED) {
- *len = -1;
- } else {
- *len = length;
+ return NULL;
}
return addr;
}
diff --git a/runtime/bin/file_macos.cc b/runtime/bin/file_macos.cc
index 38699cd..0720b6f 100644
--- a/runtime/bin/file_macos.cc
+++ b/runtime/bin/file_macos.cc
@@ -80,16 +80,23 @@
}
-void* File::MapExecutable(intptr_t* len) {
+void* File::Map(MapType type, int64_t position, int64_t length) {
ASSERT(handle_->fd() >= 0);
- intptr_t length = Length();
- void* addr = mmap(0, length,
- PROT_READ | PROT_EXEC, MAP_PRIVATE,
- handle_->fd(), 0);
+ int prot = PROT_NONE;
+ switch (type) {
+ case kReadOnly:
+ prot = PROT_READ;
+ break;
+ case kReadExecute:
+ prot = PROT_READ | PROT_EXEC;
+ break;
+ default:
+ return NULL;
+ }
+ void* addr = mmap(NULL, length, prot, MAP_PRIVATE,
+ handle_->fd(), position);
if (addr == MAP_FAILED) {
- *len = -1;
- } else {
- *len = length;
+ return NULL;
}
return addr;
}
diff --git a/runtime/bin/file_win.cc b/runtime/bin/file_win.cc
index f487a88..c9f98b5 100644
--- a/runtime/bin/file_win.cc
+++ b/runtime/bin/file_win.cc
@@ -74,7 +74,7 @@
}
-void* File::MapExecutable(intptr_t* len) {
+void* File::Map(MapType type, int64_t position, int64_t length) {
UNIMPLEMENTED();
return NULL;
}
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index 319a322..cf1ba38 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -487,6 +487,7 @@
// Now load the contents of the specified uri.
const char* resolved_uri_string = DartUtils::GetStringValue(resolved_uri);
Dart_Handle source = LoadUrlContents(resolved_uri_string);
+
if (Dart_IsError(source)) {
return source;
}
@@ -1036,16 +1037,6 @@
Dart_QualifiedFunctionName* standalone_entry_points) {
ASSERT(IsSnapshottingForPrecompilation());
Dart_Handle result;
- uint8_t* vm_isolate_buffer = NULL;
- intptr_t vm_isolate_size = 0;
- uint8_t* isolate_buffer = NULL;
- intptr_t isolate_size = 0;
- uint8_t* assembly_buffer = NULL;
- intptr_t assembly_size = 0;
- uint8_t* instructions_blob_buffer = NULL;
- intptr_t instructions_blob_size = 0;
- uint8_t* rodata_blob_buffer = NULL;
- intptr_t rodata_blob_size = 0;
// Precompile with specified embedder entry points
result = Dart_Precompile(standalone_entry_points, true);
@@ -1054,14 +1045,23 @@
// Create a precompiled snapshot.
bool as_assembly = assembly_filename != NULL;
if (as_assembly) {
- result = Dart_CreatePrecompiledSnapshotAssembly(&vm_isolate_buffer,
- &vm_isolate_size,
- &isolate_buffer,
- &isolate_size,
- &assembly_buffer,
+ uint8_t* assembly_buffer = NULL;
+ intptr_t assembly_size = 0;
+ result = Dart_CreatePrecompiledSnapshotAssembly(&assembly_buffer,
&assembly_size);
CHECK_RESULT(result);
+ WriteSnapshotFile(assembly_filename,
+ assembly_buffer,
+ assembly_size);
} else {
+ uint8_t* vm_isolate_buffer = NULL;
+ intptr_t vm_isolate_size = 0;
+ uint8_t* isolate_buffer = NULL;
+ intptr_t isolate_size = 0;
+ uint8_t* instructions_blob_buffer = NULL;
+ intptr_t instructions_blob_size = 0;
+ uint8_t* rodata_blob_buffer = NULL;
+ intptr_t rodata_blob_size = 0;
result = Dart_CreatePrecompiledSnapshotBlob(&vm_isolate_buffer,
&vm_isolate_size,
&isolate_buffer,
@@ -1071,20 +1071,12 @@
&rodata_blob_buffer,
&rodata_blob_size);
CHECK_RESULT(result);
- }
-
- // Now write the snapshot pieces out to the specified files and exit.
- WriteSnapshotFile(vm_isolate_snapshot_filename,
- vm_isolate_buffer,
- vm_isolate_size);
- WriteSnapshotFile(isolate_snapshot_filename,
- isolate_buffer,
- isolate_size);
- if (as_assembly) {
- WriteSnapshotFile(assembly_filename,
- assembly_buffer,
- assembly_size);
- } else {
+ WriteSnapshotFile(vm_isolate_snapshot_filename,
+ vm_isolate_buffer,
+ vm_isolate_size);
+ WriteSnapshotFile(isolate_snapshot_filename,
+ isolate_buffer,
+ isolate_size);
WriteSnapshotFile(instructions_blob_filename,
instructions_blob_buffer,
instructions_blob_size);
@@ -1092,6 +1084,7 @@
rodata_blob_buffer,
rodata_blob_size);
}
+
Dart_ExitScope();
// Shutdown the isolate.
@@ -1320,13 +1313,31 @@
Dart_QualifiedFunctionName* entry_points =
ParseEntryPointsManifestIfPresent();
+ intptr_t payload_bytes = 0;
+ const uint8_t* payload = NULL;
+ const bool is_kernel_file =
+ TryReadKernel(app_script_name, &payload, &payload_bytes);
+
+ if (is_kernel_file) {
+ Dart_Handle library = Dart_LoadKernel(payload, payload_bytes);
+ free(const_cast<uint8_t*>(payload));
+ if (Dart_IsError(library)) FATAL("Failed to load app from Kernel IR");
+ } else {
+ // Set up the library tag handler in such a manner that it will use the
+ // URL mapping specified on the command line to load the libraries.
+ result = Dart_SetLibraryTagHandler(CreateSnapshotLibraryTagHandler);
+ CHECK_RESULT(result);
+ }
+
SetupStubNativeResolversForPrecompilation(entry_points);
- // Load the specified script.
- library = LoadSnapshotCreationScript(app_script_name);
- VerifyLoaded(library);
+ if (!is_kernel_file) {
+ // Load the specified script.
+ library = LoadSnapshotCreationScript(app_script_name);
+ VerifyLoaded(library);
- ImportNativeEntryPointLibrariesIntoRoot(entry_points);
+ ImportNativeEntryPointLibrariesIntoRoot(entry_points);
+ }
// Ensure that we mark all libraries as loaded.
result = Dart_FinalizeLoading(false);
diff --git a/runtime/bin/loader.cc b/runtime/bin/loader.cc
index 4d35728..d69def1 100644
--- a/runtime/bin/loader.cc
+++ b/runtime/bin/loader.cc
@@ -336,15 +336,12 @@
}
// Check for payload and load accordingly.
- bool is_snapshot = false;
const uint8_t* payload = result->payload;
intptr_t payload_length = result->payload_length;
- payload =
- DartUtils::SniffForMagicNumber(payload,
- &payload_length,
- &is_snapshot);
+ const DartUtils::MagicNumber payload_type =
+ DartUtils::SniffForMagicNumber(&payload, &payload_length);
Dart_Handle source = Dart_Null();
- if (!is_snapshot) {
+ if (payload_type == DartUtils::kUnknownMagicNumber) {
source = Dart_NewStringFromUTF8(result->payload,
result->payload_length);
if (Dart_IsError(source)) {
@@ -377,8 +374,10 @@
}
break;
case Dart_kScriptTag:
- if (is_snapshot) {
+ if (payload_type == DartUtils::kSnapshotMagicNumber) {
dart_result = Dart_LoadScriptFromSnapshot(payload, payload_length);
+ } else if (payload_type == DartUtils::kKernelMagicNumber) {
+ dart_result = Dart_LoadKernel(payload, payload_length);
} else {
dart_result = Dart_LoadScript(uri, resolved_uri, source, 0, 0);
}
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 8a80c7e..1086134 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -97,16 +97,11 @@
#endif
-extern const char* kPrecompiledLibraryName;
+extern const char* kPrecompiledVMIsolateSymbolName;
+extern const char* kPrecompiledIsolateSymbolName;
extern const char* kPrecompiledInstructionsSymbolName;
extern const char* kPrecompiledDataSymbolName;
-static const char* kVMIsolateSuffix = "snapshot.vmisolate";
-static const char* kIsolateSuffix = "snapshot.isolate";
-static const char* kAssemblySuffix = "snapshot.S";
-static const char* kInstructionsSuffix = "snapshot.instructions";
-static const char* kRODataSuffix = "snapshot.rodata";
-
// Global flag that is used to indicate that we want to trace resolution of
// URIs and the loading of libraries, parts and scripts.
@@ -276,32 +271,32 @@
ASSERT(arg != NULL);
if (*arg == '\0') {
// Ignore empty -D option.
- Log::PrintErr("No arguments given to -D option\n");
+ Log::PrintErr("No arguments given to -D option, ignoring it\n");
return true;
}
- if (environment == NULL) {
- environment = new HashMap(&HashMap::SameStringValue, 4);
- }
// Split the name=value part of the -Dname=value argument.
const char* equals_pos = strchr(arg, '=');
if (equals_pos == NULL) {
// No equal sign (name without value) currently not supported.
- Log::PrintErr("No value given to -D option\n");
- return false;
+ Log::PrintErr("No value given in -D%s option, ignoring it\n", arg);
+ return true;
}
char* name;
char* value = NULL;
int name_len = equals_pos - arg;
if (name_len == 0) {
- Log::PrintErr("No name given to -D option\n");
- return false;
+ Log::PrintErr("No name given in -D%s option, ignoring it\n", arg);
+ return true;
}
// Split name=value into name and value.
name = reinterpret_cast<char*>(malloc(name_len + 1));
strncpy(name, arg, name_len);
name[name_len] = '\0';
value = strdup(equals_pos + 1);
+ if (environment == NULL) {
+ environment = new HashMap(&HashMap::SameStringValue, 4);
+ }
HashMap::Entry* entry = environment->Lookup(
GetHashmapKeyFromString(name), HashMap::StringHash(name), true);
ASSERT(entry != NULL); // Lookup adds an entry if key not found.
@@ -378,15 +373,6 @@
}
-static bool ProcessRunAppSnapshotOption(
- const char* filename, CommandLineOptions* vm_options) {
- ASSERT(filename != NULL);
- snapshot_filename = filename;
- run_app_snapshot = true;
- return true;
-}
-
-
static bool ProcessEnableVmServiceOption(const char* option_value,
CommandLineOptions* vm_options) {
ASSERT(option_value != NULL);
@@ -565,7 +551,6 @@
{ "--observe", ProcessObserveOption },
{ "--snapshot=", ProcessSnapshotFilenameOption },
{ "--snapshot-kind=", ProcessSnapshotKindOption },
- { "--run-app-snapshot=", ProcessRunAppSnapshotOption },
{ "--use-blobs", ProcessUseBlobsOption },
{ "--trace-loading", ProcessTraceLoadingOption },
{ "--hot-reload-test-mode", ProcessHotReloadTestModeOption },
@@ -1207,93 +1192,199 @@
}
-static void ReadSnapshotFile(const char* snapshot_directory,
- const char* filename,
- const uint8_t** buffer) {
- char* concat = NULL;
- const char* qualified_filename;
- if ((snapshot_directory != NULL) && (strlen(snapshot_directory) > 0)) {
- intptr_t len = snprintf(NULL, 0, "%s/%s", snapshot_directory, filename);
- concat = new char[len + 1];
- snprintf(concat, len + 1, "%s/%s", snapshot_directory, filename);
- qualified_filename = concat;
- } else {
- qualified_filename = filename;
- }
+static const int64_t kAppSnapshotHeaderSize = 5 * sizeof(int64_t); // NOLINT
+static const int64_t kAppSnapshotMagicNumber = 0xf6f6dcdc;
+static const int64_t kAppSnapshotPageSize = 4 * KB;
- void* file = DartUtils::OpenFile(qualified_filename, false);
+
+static bool ReadAppSnapshotBlobs(const char* script_name,
+ const uint8_t** vmisolate_buffer,
+ const uint8_t** isolate_buffer,
+ const uint8_t** instructions_buffer,
+ const uint8_t** rodata_buffer) {
+ File* file = File::Open(script_name, File::kRead);
if (file == NULL) {
- fprintf(stderr,
- "Error: Unable to open file %s for reading snapshot\n",
- qualified_filename);
- fflush(stderr);
- Platform::Exit(kErrorExitCode);
+ return false;
}
- intptr_t len = -1;
- DartUtils::ReadFile(buffer, &len, file);
- if ((*buffer == NULL) || (len == -1)) {
- fprintf(stderr,
- "Error: Unable to read snapshot file %s\n", qualified_filename);
- fflush(stderr);
- Platform::Exit(kErrorExitCode);
+ if (file->Length() < kAppSnapshotHeaderSize) {
+ file->Release();
+ return false;
}
- DartUtils::CloseFile(file);
- if (concat != NULL) {
- delete[] concat;
+ int64_t header[5];
+ ASSERT(sizeof(header) == kAppSnapshotHeaderSize);
+ if (!file->ReadFully(&header, kAppSnapshotHeaderSize)) {
+ file->Release();
+ return false;
}
+ if (header[0] != kAppSnapshotMagicNumber) {
+ file->Release();
+ return false;
+ }
+
+ int64_t vmisolate_position =
+ Utils::RoundUp(file->Position(), kAppSnapshotPageSize);
+ int64_t isolate_position =
+ Utils::RoundUp(vmisolate_position + header[1], kAppSnapshotPageSize);
+ int64_t rodata_position =
+ Utils::RoundUp(isolate_position + header[2], kAppSnapshotPageSize);
+ int64_t instructions_position =
+ Utils::RoundUp(rodata_position + header[3], kAppSnapshotPageSize);
+
+ void* read_only_buffer =
+ file->Map(File::kReadOnly, vmisolate_position,
+ instructions_position - vmisolate_position);
+ if (read_only_buffer == NULL) {
+ ErrorExit(kErrorExitCode, "Failed to memory map snapshot\n");
+ }
+
+ *vmisolate_buffer = reinterpret_cast<const uint8_t*>(read_only_buffer)
+ + (vmisolate_position - vmisolate_position);
+ *isolate_buffer = reinterpret_cast<const uint8_t*>(read_only_buffer)
+ + (isolate_position - vmisolate_position);
+ if (header[3] == 0) {
+ *rodata_buffer = NULL;
+ } else {
+ *rodata_buffer = reinterpret_cast<const uint8_t*>(read_only_buffer)
+ + (rodata_position - vmisolate_position);
+ }
+
+ if (header[4] == 0) {
+ *instructions_buffer = NULL;
+ } else {
+ *instructions_buffer = reinterpret_cast<const uint8_t*>(
+ file->Map(File::kReadExecute, instructions_position, header[4]));
+ if (*instructions_buffer == NULL) {
+ ErrorExit(kErrorExitCode, "Failed to memory map snapshot2\n");
+ }
+ }
+
+ file->Release();
+ return true;
}
-static void ReadExecutableSnapshotFile(const char* snapshot_directory,
- const char* filename,
- const uint8_t** buffer) {
- char* concat = NULL;
- const char* qualified_filename;
- if ((snapshot_directory != NULL) && (strlen(snapshot_directory) > 0)) {
- intptr_t len = snprintf(NULL, 0, "%s/%s", snapshot_directory, filename);
- concat = new char[len + 1];
- snprintf(concat, len + 1, "%s/%s", snapshot_directory, filename);
- qualified_filename = concat;
- } else {
- qualified_filename = filename;
- }
-
- intptr_t len = -1;
- *buffer = reinterpret_cast<uint8_t*>(
- DartUtils::MapExecutable(qualified_filename, &len));
- if ((*buffer == NULL) || (len == -1)) {
- fprintf(stderr,
- "Error: Unable to read snapshot file %s\n", qualified_filename);
- fflush(stderr);
- Platform::Exit(kErrorExitCode);
- }
- if (concat != NULL) {
- delete[] concat;
- }
-}
-
-
-static void* LoadLibrarySymbol(const char* snapshot_directory,
- const char* libname,
- const char* symname) {
- char* concat = NULL;
- const char* qualified_libname;
- if ((snapshot_directory != NULL) && (strlen(snapshot_directory) > 0)) {
- intptr_t len = snprintf(NULL, 0, "%s/%s", snapshot_directory, libname);
- concat = new char[len + 1];
- snprintf(concat, len + 1, "%s/%s", snapshot_directory, libname);
- qualified_libname = concat;
- } else {
- qualified_libname = libname;
- }
- void* library = Extensions::LoadExtensionLibrary(qualified_libname);
- if (concat != NULL) {
- delete concat;
- }
+static bool ReadAppSnapshotDynamicLibrary(const char* script_name,
+ const uint8_t** vmisolate_buffer,
+ const uint8_t** isolate_buffer,
+ const uint8_t** instructions_buffer,
+ const uint8_t** rodata_buffer) {
+ void* library = Extensions::LoadExtensionLibrary(script_name);
if (library == NULL) {
- return NULL;
+ return false;
}
- return Extensions::ResolveSymbol(library, symname);
+
+ *vmisolate_buffer = reinterpret_cast<const uint8_t*>(
+ Extensions::ResolveSymbol(library, kPrecompiledVMIsolateSymbolName));
+ if (*vmisolate_buffer == NULL) {
+ ErrorExit(kErrorExitCode, "Failed to resolve symbol '%s'\n",
+ kPrecompiledVMIsolateSymbolName);
+ }
+
+ *isolate_buffer = reinterpret_cast<const uint8_t*>(
+ Extensions::ResolveSymbol(library, kPrecompiledIsolateSymbolName));
+ if (*isolate_buffer == NULL) {
+ ErrorExit(kErrorExitCode, "Failed to resolve symbol '%s'\n",
+ kPrecompiledIsolateSymbolName);
+ }
+
+ *instructions_buffer = reinterpret_cast<const uint8_t*>(
+ Extensions::ResolveSymbol(library, kPrecompiledInstructionsSymbolName));
+ if (*instructions_buffer == NULL) {
+ ErrorExit(kErrorExitCode, "Failed to resolve symbol '%s'\n",
+ kPrecompiledInstructionsSymbolName);
+ }
+
+ *rodata_buffer = reinterpret_cast<const uint8_t*>(
+ Extensions::ResolveSymbol(library, kPrecompiledDataSymbolName));
+ if (*rodata_buffer == NULL) {
+ ErrorExit(kErrorExitCode, "Failed to resolve symbol '%s'\n",
+ kPrecompiledDataSymbolName);
+ }
+
+ return true;
+}
+
+
+static bool ReadAppSnapshot(const char* script_name,
+ const uint8_t** vmisolate_buffer,
+ const uint8_t** isolate_buffer,
+ const uint8_t** instructions_buffer,
+ const uint8_t** rodata_buffer) {
+ if (File::GetType(script_name, true) != File::kIsFile) {
+ // If 'script_name' refers to a pipe, don't read to check for an app
+ // snapshot since we cannot rewind if it isn't (and couldn't mmap it in
+ // anyway if it was).
+ return false;
+ }
+ if (ReadAppSnapshotBlobs(script_name,
+ vmisolate_buffer,
+ isolate_buffer,
+ instructions_buffer,
+ rodata_buffer)) {
+ return true;
+ }
+ return ReadAppSnapshotDynamicLibrary(script_name,
+ vmisolate_buffer,
+ isolate_buffer,
+ instructions_buffer,
+ rodata_buffer);
+}
+
+
+static bool WriteInt64(File* file, int64_t size) {
+ return file->WriteFully(&size, sizeof(size));
+}
+
+
+static void WriteAppSnapshot(const char* filename,
+ uint8_t* vmisolate_buffer,
+ intptr_t vmisolate_size,
+ uint8_t* isolate_buffer,
+ intptr_t isolate_size,
+ uint8_t* instructions_buffer,
+ intptr_t instructions_size,
+ uint8_t* rodata_buffer,
+ intptr_t rodata_size) {
+ File* file = File::Open(filename, File::kWriteTruncate);
+ if (file == NULL) {
+ ErrorExit(kErrorExitCode, "Unable to write snapshot file '%s'\n", filename);
+ }
+
+ file->WriteFully(&kAppSnapshotMagicNumber, sizeof(kAppSnapshotMagicNumber));
+ WriteInt64(file, vmisolate_size);
+ WriteInt64(file, isolate_size);
+ WriteInt64(file, rodata_size);
+ WriteInt64(file, instructions_size);
+ ASSERT(file->Position() == kAppSnapshotHeaderSize);
+
+ file->SetPosition(Utils::RoundUp(file->Position(), kAppSnapshotPageSize));
+ if (!file->WriteFully(vmisolate_buffer, vmisolate_size)) {
+ ErrorExit(kErrorExitCode, "Unable to write snapshot file '%s'\n", filename);
+ }
+
+ file->SetPosition(Utils::RoundUp(file->Position(), kAppSnapshotPageSize));
+ if (!file->WriteFully(isolate_buffer, isolate_size)) {
+ ErrorExit(kErrorExitCode, "Unable to write snapshot file '%s'\n", filename);
+ }
+
+ if (rodata_size != 0) {
+ file->SetPosition(Utils::RoundUp(file->Position(), kAppSnapshotPageSize));
+ if (!file->WriteFully(rodata_buffer, rodata_size)) {
+ ErrorExit(kErrorExitCode, "Unable to write snapshot file '%s'\n",
+ filename);
+ }
+ }
+
+ if (instructions_size != 0) {
+ file->SetPosition(Utils::RoundUp(file->Position(), kAppSnapshotPageSize));
+ if (!file->WriteFully(instructions_buffer, instructions_size)) {
+ ErrorExit(kErrorExitCode, "Unable to write snapshot file '%s'\n",
+ filename);
+ }
+ }
+
+ file->Flush();
+ file->Release();
}
@@ -1334,35 +1425,24 @@
&rodata_blob_size);
} else {
result = Dart_CreatePrecompiledSnapshotAssembly(
- &vm_isolate_buffer,
- &vm_isolate_size,
- &isolate_buffer,
- &isolate_size,
&assembly_buffer,
&assembly_size);
}
if (Dart_IsError(result)) {
ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result));
}
- WriteSnapshotFile(snapshot_filename, kVMIsolateSuffix,
- false,
- vm_isolate_buffer,
- vm_isolate_size);
- WriteSnapshotFile(snapshot_filename, kIsolateSuffix,
- false,
- isolate_buffer,
- isolate_size);
if (use_blobs) {
- WriteSnapshotFile(snapshot_filename, kInstructionsSuffix,
- false,
- instructions_blob_buffer,
- instructions_blob_size);
- WriteSnapshotFile(snapshot_filename, kRODataSuffix,
- false,
- rodata_blob_buffer,
- rodata_blob_size);
+ WriteAppSnapshot(snapshot_filename,
+ vm_isolate_buffer,
+ vm_isolate_size,
+ isolate_buffer,
+ isolate_size,
+ instructions_blob_buffer,
+ instructions_blob_size,
+ rodata_blob_buffer,
+ rodata_blob_size);
} else {
- WriteSnapshotFile(snapshot_filename, kAssemblySuffix,
+ WriteSnapshotFile(NULL, snapshot_filename,
false,
assembly_buffer,
assembly_size);
@@ -1371,10 +1451,6 @@
static void GeneratePrecompiledJITSnapshot() {
- if (!use_blobs) {
- ErrorExit(kErrorExitCode,
- "Generating app JIT snapshots as assembly unimplemented\n");
- }
uint8_t* vm_isolate_buffer = NULL;
intptr_t vm_isolate_size = 0;
uint8_t* isolate_buffer = NULL;
@@ -1395,22 +1471,15 @@
if (Dart_IsError(result)) {
ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result));
}
- WriteSnapshotFile(snapshot_filename, kVMIsolateSuffix,
- false,
- vm_isolate_buffer,
- vm_isolate_size);
- WriteSnapshotFile(snapshot_filename, kIsolateSuffix,
- false,
- isolate_buffer,
- isolate_size);
- WriteSnapshotFile(snapshot_filename, kInstructionsSuffix,
- false,
- instructions_blob_buffer,
- instructions_blob_size);
- WriteSnapshotFile(snapshot_filename, kRODataSuffix,
- false,
- rodata_blob_buffer,
- rodata_blob_size);
+ WriteAppSnapshot(snapshot_filename,
+ vm_isolate_buffer,
+ vm_isolate_size,
+ isolate_buffer,
+ isolate_size,
+ instructions_blob_buffer,
+ instructions_blob_size,
+ rodata_blob_buffer,
+ rodata_blob_size);
}
@@ -1430,16 +1499,12 @@
ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result));
}
- WriteSnapshotFile(snapshot_filename,
- kVMIsolateSuffix,
- false,
- vm_isolate_buffer,
- vm_isolate_size);
- WriteSnapshotFile(snapshot_filename,
- kIsolateSuffix,
- false,
- isolate_buffer,
- isolate_size);
+ WriteAppSnapshot(snapshot_filename,
+ vm_isolate_buffer,
+ vm_isolate_size,
+ isolate_buffer,
+ isolate_size,
+ NULL, 0, NULL, 0);
}
@@ -1561,9 +1626,14 @@
{ "dart:io", "TlsException", "TlsException." },
{ "dart:io", "X509Certificate", "X509Certificate._" },
{ "dart:io", "_ExternalBuffer", "set:data" },
+ { "dart:io", "_ExternalBuffer", "get:start" },
+ { "dart:io", "_ExternalBuffer", "set:start" },
+ { "dart:io", "_ExternalBuffer", "get:end" },
+ { "dart:io", "_ExternalBuffer", "set:end" },
{ "dart:io", "_Platform", "set:_nativeScript" },
{ "dart:io", "_ProcessStartStatus", "set:_errorCode" },
{ "dart:io", "_ProcessStartStatus", "set:_errorMessage" },
+ { "dart:io", "_SecureFilterImpl", "get:buffers" },
{ "dart:io", "_SecureFilterImpl", "get:ENCRYPTED_SIZE" },
{ "dart:io", "_SecureFilterImpl", "get:SIZE" },
{ "dart:vmservice_io", "::", "main" },
@@ -1778,6 +1848,17 @@
Platform::Exit(kErrorExitCode);
}
+ const uint8_t* instructions_snapshot = NULL;
+ const uint8_t* data_snapshot = NULL;
+
+ if (ReadAppSnapshot(script_name,
+ &vm_isolate_snapshot_buffer,
+ &isolate_snapshot_buffer,
+ &instructions_snapshot,
+ &data_snapshot)) {
+ run_app_snapshot = true;
+ }
+
#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
// Constant true if PRODUCT or DART_PRECOMPILED_RUNTIME.
if ((gen_snapshot_kind != kNone) || run_app_snapshot) {
@@ -1785,6 +1866,9 @@
}
#endif
+ if (gen_snapshot_kind == kAppJITAfterRun) {
+ vm_options.AddArgument("--fields_may_be_reset");
+ }
if ((gen_snapshot_kind == kAppAOT) || is_noopt) {
vm_options.AddArgument("--precompilation");
}
@@ -1798,31 +1882,6 @@
TimerUtils::InitOnce();
EventHandler::Start();
- const uint8_t* instructions_snapshot = NULL;
- const uint8_t* data_snapshot = NULL;
- if (run_app_snapshot) {
- ReadSnapshotFile(snapshot_filename, kVMIsolateSuffix,
- &vm_isolate_snapshot_buffer);
- ReadSnapshotFile(snapshot_filename, kIsolateSuffix,
- &isolate_snapshot_buffer);
- if (use_blobs) {
- ReadExecutableSnapshotFile(snapshot_filename,
- kInstructionsSuffix,
- &instructions_snapshot);
- ReadSnapshotFile(snapshot_filename, kRODataSuffix,
- &data_snapshot);
- } else {
- instructions_snapshot = reinterpret_cast<const uint8_t*>(
- LoadLibrarySymbol(snapshot_filename,
- kPrecompiledLibraryName,
- kPrecompiledInstructionsSymbolName));
- data_snapshot = reinterpret_cast<const uint8_t*>(
- LoadLibrarySymbol(snapshot_filename,
- kPrecompiledLibraryName,
- kPrecompiledDataSymbolName));
- }
- }
-
// Initialize the Dart VM.
Dart_InitializeParams init_params;
memset(&init_params, 0, sizeof(init_params));
diff --git a/runtime/bin/vmservice/server.dart b/runtime/bin/vmservice/server.dart
index e1cb822..32ee7d6 100644
--- a/runtime/bin/vmservice/server.dart
+++ b/runtime/bin/vmservice/server.dart
@@ -190,15 +190,23 @@
List fsNameList;
List fsPathList;
+ List fsPathBase64List;
Object fsName;
Object fsPath;
try {
// Extract the fs name and fs path from the request headers.
fsNameList = request.headers['dev_fs_name'];
- fsPathList = request.headers['dev_fs_path'];
fsName = fsNameList[0];
- fsPath = fsPathList[0];
+
+ fsPathList = request.headers['dev_fs_path'];
+ fsPathBase64List = request.headers['dev_fs_path_b64'];
+ // If the 'dev_fs_path_b64' header field was sent, use that instead.
+ if ((fsPathBase64List != null) && (fsPathBase64List.length > 0)) {
+ fsPath = UTF8.decode(BASE64.decode(fsPathBase64List[0]));
+ } else {
+ fsPath = fsPathList[0];
+ }
} catch (e) { /* ignore */ }
String result;
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index c9c0d1a..25db8c4 100755
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -2798,7 +2798,7 @@
* Loads the root script for current isolate from a snapshot.
*
* \param buffer A buffer which contains a snapshot of the script.
- * \param length Length of the passed in buffer.
+ * \param buffer_len Length of the passed in buffer.
*
* \return If no error occurs, the Library object corresponding to the root
* script is returned. Otherwise an error handle is returned.
@@ -2807,6 +2807,18 @@
intptr_t buffer_len);
/**
+ * Loads a dart application which was compiled to a Kernel binary.
+ *
+ * \param buffer A buffer which contains a Kernel binary.
+ * \param buffer_len Length of the passed in buffer.
+ *
+ * \return If no error occurs, the Library object corresponding to the root
+ * script is returned. Otherwise an error handle is returned.
+ */
+DART_EXPORT Dart_Handle Dart_LoadKernel(const uint8_t* buffer,
+ intptr_t buffer_len);
+
+/**
* Gets the library for the root script for the current isolate.
*
* If the root script has not yet been set for the current isolate,
@@ -3115,10 +3127,6 @@
* \return A valid handle if no error occurs during the operation.
*/
DART_EXPORT Dart_Handle Dart_CreatePrecompiledSnapshotAssembly(
- uint8_t** vm_isolate_snapshot_buffer,
- intptr_t* vm_isolate_snapshot_size,
- uint8_t** isolate_snapshot_buffer,
- intptr_t* isolate_snapshot_size,
uint8_t** assembly_buffer,
intptr_t* assembly_size);
diff --git a/runtime/lib/errors_patch.dart b/runtime/lib/errors_patch.dart
index 961f71c..654dfa3 100644
--- a/runtime/lib/errors_patch.dart
+++ b/runtime/lib/errors_patch.dart
@@ -166,14 +166,13 @@
int numPositionalArguments = arguments == null ? 0 : arguments.length;
numPositionalArguments -= numNamedArguments;
List positionalArguments;
- if (numPositionalArguments == 0) {
- // Differ between no arguments specified and 0 arguments.
- // TODO(srdjan): This can currently occur for unresolvable static methods.
- // In that case, the arguments are evaluated but not passed to the
+ if (numPositionalArguments > 0) {
+ // TODO(srdjan): Unresolvable static methods sometimes do not provide the
+ // arguments, because the arguments are evaluated but not passed to the
// throwing stub (see EffectGraphVisitor::BuildThrowNoSuchMethodError and
- // Parser::ThrowNoSuchMethodError)).
- positionalArguments = argumentNames == null ? null : [];
- } else {
+ // Parser::ThrowNoSuchMethodError)). There is no way to distinguish the
+ // case of no arguments from the case of the arguments not being passed
+ // in here, though. See https://github.com/dart-lang/sdk/issues/27572
positionalArguments = arguments.sublist(0, numPositionalArguments);
}
Map<Symbol, dynamic> namedArguments = new Map<Symbol, dynamic>();
@@ -234,127 +233,119 @@
value: (k) => namedArguments[k]),
this._existingArgumentNames = existingArgumentNames;
-
- String _developerMessage(args_mismatch) {
- if (_invocation_type < 0) {
- return "";
- }
- var type = _invocation_type & _InvocationMirror._TYPE_MASK;
+ @patch String toString() {
var level = (_invocation_type >> _InvocationMirror._CALL_SHIFT) &
- _InvocationMirror._CALL_MASK;
- var type_str =
- (const ["method", "getter", "setter", "getter or setter", "variable"])[type];
- var args_message = args_mismatch ? " with matching arguments" : "";
- var msg;
- var memberName =
- (_memberName == null) ? "" : internal.Symbol.getUnmangledName(_memberName);
+ _InvocationMirror._CALL_MASK;
+ var type = _invocation_type & _InvocationMirror._TYPE_MASK;
+ String memberName = (_memberName == null) ? "" :
+ internal.Symbol.getUnmangledName(_memberName);
if (type == _InvocationMirror._LOCAL_VAR) {
- return "cannot assign to final variable '$memberName'.\n\n";
+ return "NoSuchMethodError: Cannot assign to final variable '$memberName'";
}
+
+ StringBuffer arguments = new StringBuffer();
+ int argumentCount = 0;
+ if (_arguments != null) {
+ for (; argumentCount < _arguments.length; argumentCount++) {
+ if (argumentCount > 0) {
+ arguments.write(", ");
+ }
+ arguments.write(Error.safeToString(_arguments[argumentCount]));
+ }
+ }
+ if (_namedArguments != null) {
+ _namedArguments.forEach((Symbol key, var value) {
+ if (argumentCount > 0) {
+ arguments.write(", ");
+ }
+ arguments.write(internal.Symbol.getUnmangledName(key));
+ arguments.write(": ");
+ arguments.write(Error.safeToString(value));
+ argumentCount++;
+ });
+ }
+ bool args_mismatch = _existingArgumentNames != null;
+ String args_message = args_mismatch ? " with matching arguments" : "";
+
+ String type_str;
+ if (type >= 0 && type < 5) {
+ type_str = (const ["method", "getter", "setter", "getter or setter",
+ "variable"])[type];
+ }
+
+ StringBuffer msg_buf = new StringBuffer("NoSuchMethodError: ");
switch (level) {
case _InvocationMirror._DYNAMIC: {
if (_receiver == null) {
- msg = "The null object does not have a $type_str '$memberName'"
- "$args_message.";
+ if (args_mismatch) {
+ msg_buf.writeln("The null object does not have a $type_str "
+ "'$memberName'$args_message.");
+ } else {
+ msg_buf.writeln("The $type_str '$memberName' was called on null.");
+ }
} else {
if (_receiver is Function) {
- msg = "Closure call with mismatched arguments: "
- "function '$memberName'";
+ msg_buf.writeln("Closure call with mismatched arguments: "
+ "function '$memberName'");
} else {
- msg = "Class '${_receiver.runtimeType}' has no instance $type_str "
- "'$memberName'$args_message.";
+ msg_buf.writeln("Class '${_receiver.runtimeType}' has no instance "
+ "$type_str '$memberName'$args_message.");
}
}
break;
}
case _InvocationMirror._SUPER: {
- msg = "Super class of class '${_receiver.runtimeType}' has no instance "
- "$type_str '$memberName'$args_message.";
+ msg_buf.writeln("Super class of class '${_receiver.runtimeType}' has "
+ "no instance $type_str '$memberName'$args_message.");
+ memberName = "super.$memberName";
break;
}
case _InvocationMirror._STATIC: {
- msg = "No static $type_str '$memberName' declared in class "
- "'$_receiver'.";
+ msg_buf.writeln("No static $type_str '$memberName'$args_message "
+ "declared in class '$_receiver'.");
break;
}
case _InvocationMirror._CONSTRUCTOR: {
- msg = "No constructor '$memberName'$args_message declared in class '$_receiver'.";
+ msg_buf.writeln("No constructor '$memberName'$args_message declared "
+ "in class '$_receiver'.");
+ memberName = "new $memberName";
break;
}
case _InvocationMirror._TOP_LEVEL: {
- msg = "No top-level $type_str '$memberName'$args_message declared.";
+ msg_buf.writeln("No top-level $type_str '$memberName'$args_message "
+ "declared.");
break;
}
}
- return "$msg\n\n";
- }
- @patch String toString() {
- StringBuffer actual_buf = new StringBuffer();
- int i = 0;
- if (_arguments == null) {
- // Actual arguments unknown.
- // TODO(srdjan): Remove once arguments are passed for unresolvable
- // static methods.
- actual_buf.write("...");
+ if (level == _InvocationMirror._TOP_LEVEL) {
+ msg_buf.writeln("Receiver: top-level");
} else {
- for (; i < _arguments.length; i++) {
- if (i > 0) {
- actual_buf.write(", ");
- }
- actual_buf.write(Error.safeToString(_arguments[i]));
- }
+ msg_buf.writeln("Receiver: ${Error.safeToString(_receiver)}");
}
- if (_namedArguments != null) {
- _namedArguments.forEach((Symbol key, var value) {
- if (i > 0) {
- actual_buf.write(", ");
- }
- actual_buf.write(internal.Symbol.getUnmangledName(key));
- actual_buf.write(": ");
- actual_buf.write(Error.safeToString(value));
- i++;
- });
- }
- var args_mismatch = _existingArgumentNames != null;
- StringBuffer msg_buf = new StringBuffer(_developerMessage(args_mismatch));
- String receiver_str;
- var level = (_invocation_type >> _InvocationMirror._CALL_SHIFT) &
- _InvocationMirror._CALL_MASK;
- if ( level == _InvocationMirror._TOP_LEVEL) {
- receiver_str = "top-level";
+
+ if (type == _InvocationMirror._METHOD) {
+ msg_buf.write("Tried calling: $memberName($arguments)");
+ } else if (argumentCount == 0) {
+ msg_buf.write("Tried calling: $memberName");
+ } else if (type == _InvocationMirror._SETTER) {
+ msg_buf.write("Tried calling: $memberName$arguments");
} else {
- receiver_str = Error.safeToString(_receiver);
+ msg_buf.write("Tried calling: $memberName = $arguments");
}
- var memberName =
- (_memberName == null) ? "" : internal.Symbol.getUnmangledName(_memberName);
- var type = _invocation_type & _InvocationMirror._TYPE_MASK;
- if (type == _InvocationMirror._LOCAL_VAR) {
- msg_buf.write(
- "NoSuchMethodError: cannot assign to final variable '$memberName'");
- } else if (!args_mismatch) {
- msg_buf.write(
- "NoSuchMethodError: method not found: '$memberName'\n"
- "Receiver: $receiver_str\n"
- "Arguments: [$actual_buf]");
- } else {
- String actualParameters = actual_buf.toString();
- StringBuffer formal_buf = new StringBuffer();
+
+ if (args_mismatch) {
+ StringBuffer formalParameters = new StringBuffer();
for (int i = 0; i < _existingArgumentNames.length; i++) {
if (i > 0) {
- formal_buf.write(", ");
+ formalParameters.write(", ");
}
- formal_buf.write(_existingArgumentNames[i]);
+ formalParameters.write(_existingArgumentNames[i]);
}
- String formalParameters = formal_buf.toString();
- msg_buf.write(
- "NoSuchMethodError: incorrect number of arguments passed to "
- "method named '$memberName'\n"
- "Receiver: $receiver_str\n"
- "Tried calling: $memberName($actualParameters)\n"
- "Found: $memberName($formalParameters)");
+ msg_buf.write("\nFound: $memberName($formalParameters)");
}
+
return msg_buf.toString();
}
}
diff --git a/runtime/lib/isolate_patch.dart b/runtime/lib/isolate_patch.dart
index 7e4579a..3a02c7a 100644
--- a/runtime/lib/isolate_patch.dart
+++ b/runtime/lib/isolate_patch.dart
@@ -193,9 +193,9 @@
void _sendInternal(var message) native "SendPortImpl_sendInternal_";
}
-typedef _MainFunction();
-typedef _MainFunctionArgs(args);
-typedef _MainFunctionArgsMessage(args, message);
+typedef _NullaryFunction();
+typedef _UnaryFunction(args);
+typedef _BinaryFunction(args, message);
/**
* Takes the real entry point as argument and invokes it with the
@@ -253,9 +253,9 @@
port.close();
if (isSpawnUri) {
- if (entryPoint is _MainFunctionArgsMessage) {
+ if (entryPoint is _BinaryFunction) {
entryPoint(args, message);
- } else if (entryPoint is _MainFunctionArgs) {
+ } else if (entryPoint is _UnaryFunction) {
entryPoint(args);
} else {
entryPoint();
@@ -310,6 +310,11 @@
// `paused` isn't handled yet.
RawReceivePort readyPort;
try {
+ // Check for the type of `entryPoint` on the spawning isolate to make
+ // error-handling easier.
+ if (entryPoint is! _UnaryFunction) {
+ throw new ArgumentError(entryPoint);
+ }
// The VM will invoke [_startIsolate] with entryPoint as argument.
readyPort = new RawReceivePort();
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index 1478f04..611c3d3 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -1607,10 +1607,14 @@
}
if (field.is_final() || !field.is_reflectable()) {
+ const int kNumArgs = 1;
+ const Array& args = Array::Handle(Array::New(kNumArgs));
+ args.SetAt(0, value);
+
ThrowNoSuchMethod(AbstractType::Handle(klass.RareType()),
internal_setter_name,
setter,
- Object::null_array(),
+ args,
Object::null_array(),
InvocationMirror::kStatic,
InvocationMirror::kSetter);
@@ -1908,10 +1912,14 @@
}
if (field.is_final() || !field.is_reflectable()) {
+ const int kNumArgs = 1;
+ const Array& args = Array::Handle(Array::New(kNumArgs));
+ args.SetAt(0, value);
+
ThrowNoSuchMethod(Instance::null_instance(),
internal_setter_name,
setter,
- Object::null_array(),
+ args,
Object::null_array(),
InvocationMirror::kTopLevel,
InvocationMirror::kSetter);
diff --git a/runtime/observatory/BUILD.gn b/runtime/observatory/BUILD.gn
index a476414..fc7af6a 100644
--- a/runtime/observatory/BUILD.gn
+++ b/runtime/observatory/BUILD.gn
@@ -160,6 +160,10 @@
"Need inner_namespace in $target_name")
assert(defined(invoker.outer_namespace),
"Need outer_namespace in $target_name")
+ enable_compression = false
+ if (defined(invoker.compress) && invoker.compress) {
+ enable_compression = true
+ }
action(target_name) {
deps = [
":deploy_observatory",
@@ -167,10 +171,10 @@
script = "../tools/create_archive.py"
- inputs = [
- script,
- "$root_out_dir/observatory/deployed/web/main.dart.js",
- ]
+ inputs = [
+ script,
+ "$root_out_dir/observatory/deployed/web/main.dart.js",
+ ]
inner_namespace = invoker.inner_namespace
outer_namespace = invoker.outer_namespace
@@ -185,6 +189,9 @@
"--name", "observatory_assets_archive",
"--client_root", rebase_path("$root_out_dir/observatory/deployed/web/"),
]
+ if (enable_compression) {
+ args += [ "--compress" ]
+ }
outputs = [
"$root_gen_dir/observatory/${output_name}.cc",
@@ -209,6 +216,7 @@
}
observatory_archive("standalone_archive_observatory") {
+ compress = true
outer_namespace = "dart"
inner_namespace = "bin"
}
diff --git a/runtime/observatory/lib/event.dart b/runtime/observatory/lib/event.dart
index 4ca9106..07c7d41 100644
--- a/runtime/observatory/lib/event.dart
+++ b/runtime/observatory/lib/event.dart
@@ -138,6 +138,21 @@
}
}
+
+class PausePostRequestEvent implements M.PausePostRequestEvent {
+ final DateTime timestamp;
+ final M.IsolateRef isolate;
+ final M.Frame topFrame;
+ final bool atAsyncSuspension;
+ PausePostRequestEvent(
+ this.timestamp, this.isolate, this.topFrame, this.atAsyncSuspension) {
+ assert(timestamp != null);
+ assert(isolate != null);
+ assert(atAsyncSuspension != null);
+ }
+}
+
+
class PauseExceptionEvent implements M.PauseExceptionEvent {
final DateTime timestamp;
final M.IsolateRef isolate;
@@ -303,6 +318,12 @@
return new PauseStartEvent(event.timestamp, event.isolate);
case S.ServiceEvent.kPauseExit:
return new PauseExitEvent(event.timestamp, event.isolate);
+ case S.ServiceEvent.kPausePostRequest:
+ return new PausePostRequestEvent(
+ event.timestamp,
+ event.isolate,
+ event.topFrame,
+ event.atAsyncSuspension);
case S.ServiceEvent.kPauseBreakpoint:
return new PauseBreakpointEvent(
event.timestamp,
diff --git a/runtime/observatory/lib/src/models/objects/event.dart b/runtime/observatory/lib/src/models/objects/event.dart
index 18f491e..9fd7359 100644
--- a/runtime/observatory/lib/src/models/objects/event.dart
+++ b/runtime/observatory/lib/src/models/objects/event.dart
@@ -16,6 +16,7 @@
event is PauseBreakpointEvent ||
event is PauseInterruptedEvent ||
event is PauseExceptionEvent ||
+ event is PausePostRequestEvent ||
event is NoneEvent;
}
}
@@ -88,6 +89,15 @@
bool get atAsyncSuspension;
}
+abstract class PausePostRequestEvent extends DebugEvent {
+ /// [optional] The top stack frame associated with this event. There will be
+ /// no top frame if the isolate is idle (waiting in the message loop).
+ Frame get topFrame;
+
+ /// Is the isolate paused at an await, yield, or yield* statement?
+ bool get atAsyncSuspension;
+}
+
abstract class PauseExceptionEvent extends DebugEvent {
/// The top stack frame associated with this event.
Frame get topFrame;
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index 85d9385..32df1b2 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -1675,6 +1675,7 @@
case ServiceEvent.kPauseBreakpoint:
case ServiceEvent.kPauseInterrupted:
case ServiceEvent.kPauseException:
+ case ServiceEvent.kPausePostRequest:
case ServiceEvent.kNone:
case ServiceEvent.kResume:
assert((pauseEvent == null) ||
@@ -2017,6 +2018,7 @@
static const kPauseBreakpoint = 'PauseBreakpoint';
static const kPauseInterrupted = 'PauseInterrupted';
static const kPauseException = 'PauseException';
+ static const kPausePostRequest = 'PausePostRequest';
static const kNone = 'None';
static const kResume = 'Resume';
static const kBreakpointAdded = 'BreakpointAdded';
@@ -2067,6 +2069,7 @@
kind == kPauseBreakpoint ||
kind == kPauseInterrupted ||
kind == kPauseException ||
+ kind == kPausePostRequest ||
kind == kNone);
}
diff --git a/runtime/observatory/tests/observatory_ui/observatory_ui.status b/runtime/observatory/tests/observatory_ui/observatory_ui.status
index f683fd8..dcb5893 100644
--- a/runtime/observatory/tests/observatory_ui/observatory_ui.status
+++ b/runtime/observatory/tests/observatory_ui/observatory_ui.status
@@ -13,3 +13,6 @@
allocation_profile: Skip
cpu_profile_table: Skip
persistent_handles_page: Skip
+
+[ $runtime == ff || $runtime == chrome ]
+vm_connect/element_test: Skip # Times out
\ No newline at end of file
diff --git a/runtime/observatory/tests/service/dev_fs_http_put_weird_char_test.dart b/runtime/observatory/tests/service/dev_fs_http_put_weird_char_test.dart
new file mode 100644
index 0000000..517a832
--- /dev/null
+++ b/runtime/observatory/tests/service/dev_fs_http_put_weird_char_test.dart
@@ -0,0 +1,102 @@
+// 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.
+// VMOptions=--error_on_bad_type --error_on_bad_override
+
+import 'dart:async';
+import 'dart:convert';
+import 'dart:io';
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+import 'test_helper.dart';
+
+Future<String> readResponse(HttpClientResponse response) {
+ var completer = new Completer();
+ var contents = new StringBuffer();
+ response.transform(UTF8.decoder).listen((String data) {
+ contents.write(data);
+ }, onDone: () => completer.complete(contents.toString()));
+ return completer.future;
+}
+
+
+var tests = [
+ // Write a file with the \r character in the filename.
+ (VM vm) async {
+ var fsId = 'test';
+ var filePath = '/foo/b\rar.dart';
+ var filePathBase64 = BASE64.encode(UTF8.encode(filePath));
+ var fileContents = [0, 1, 2, 3, 4, 5, 6, 255];
+ var fileContentsBase64 = BASE64.encode(fileContents);
+
+ var result;
+ // Create DevFS.
+ result = await vm.invokeRpcNoUpgrade('_createDevFS', { 'fsName': fsId });
+ expect(result['type'], equals('FileSystem'));
+ expect(result['name'], equals(fsId));
+ expect(result['uri'], new isInstanceOf<String>());
+
+ // Write the file by issuing an HTTP PUT.
+ HttpClient client = new HttpClient();
+ HttpClientRequest request =
+ await client.putUrl(Uri.parse(serviceHttpAddress));
+ request.headers.add('dev_fs_name', fsId);
+ request.headers.add('dev_fs_path_b64', filePathBase64);
+ request.add(GZIP.encode([9]));
+ HttpClientResponse response = await request.close();
+ String responseBody = await readResponse(response);
+ result = JSON.decode(responseBody);
+ expect(result['result']['type'], equals('Success'));
+
+ // Trigger an error by issuing an HTTP PUT.
+ request = await client.putUrl(Uri.parse(serviceHttpAddress));
+ request.headers.add('dev_fs_name', fsId);
+ // omit the 'dev_fs_path' parameter.
+ request.write(GZIP.encode(fileContents));
+ response = await request.close();
+ responseBody = await readResponse(response);
+ result = JSON.decode(responseBody);
+ Map error = result['error']['data'];
+ expect(error, isNotNull);
+ expect(error['details'].contains("expects the 'path' parameter"), isTrue);
+
+ // Write the file again but this time with the true file contents.
+ client = new HttpClient();
+ request =
+ await client.putUrl(Uri.parse(serviceHttpAddress));
+ request.headers.add('dev_fs_name', fsId);
+ request.headers.add('dev_fs_path_b64', filePathBase64);
+ request.add(GZIP.encode(fileContents));
+ response = await request.close();
+ responseBody = await readResponse(response);
+ result = JSON.decode(responseBody);
+ expect(result['result']['type'], equals('Success'));
+
+ // Close the HTTP client.
+ client.close();
+
+ // Read the file back.
+ result = await vm.invokeRpcNoUpgrade('_readDevFSFile', {
+ 'fsName': fsId,
+ 'path': filePath,
+ });
+ expect(result['type'], equals('FSFile'));
+ expect(result['fileContents'], equals(fileContentsBase64));
+
+ // List all the files in the file system.
+ result = await vm.invokeRpcNoUpgrade('_listDevFSFiles', {
+ 'fsName': fsId,
+ });
+ expect(result['type'], equals('FSFileList'));
+ expect(result['files'].length, equals(1));
+ expect(result['files'][0]['name'], equals(filePath));
+
+ // Delete DevFS.
+ result = await vm.invokeRpcNoUpgrade('_deleteDevFS', {
+ 'fsName': fsId,
+ });
+ expect(result['type'], equals('Success'));
+ },
+];
+
+main(args) async => runVMTests(args, tests);
diff --git a/runtime/observatory/tests/service/issue_27238_test.dart b/runtime/observatory/tests/service/issue_27238_test.dart
index 052b107..07cf335 100644
--- a/runtime/observatory/tests/service/issue_27238_test.dart
+++ b/runtime/observatory/tests/service/issue_27238_test.dart
@@ -33,6 +33,7 @@
smartNext,
hasStoppedAtBreakpoint,
smartNext,
+ hasStoppedAtBreakpoint,
stoppedAtLine(LINE_B),
smartNext,
hasStoppedAtBreakpoint,
diff --git a/runtime/observatory/tests/service/reload_sources_test.dart b/runtime/observatory/tests/service/reload_sources_test.dart
new file mode 100644
index 0000000..4c8b4d9
--- /dev/null
+++ b/runtime/observatory/tests/service/reload_sources_test.dart
@@ -0,0 +1,44 @@
+// 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.
+// VMOptions=--error_on_bad_type --error_on_bad_override
+
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+import 'test_helper.dart';
+import 'dart:developer';
+import 'service_test_common.dart';
+
+testMain() {
+ debugger(); // Stop here.
+ print('1');
+ while (true) {
+ }
+}
+
+var tests = [
+ // Stopped at 'debugger' statement.
+ hasStoppedAtBreakpoint,
+ // Reload sources and request to pause post reload. The pause request will be
+ // ignored because we are already paused at a breakpoint.
+ reloadSources(true),
+ // Ensure that we are still stopped at a breakpoint.
+ hasStoppedAtBreakpoint,
+ // Resume the isolate into the while loop.
+ resumeIsolate,
+ // Reload sources and request to pause post reload. The pause request will
+ // be respected because we are not already paused.
+ reloadSources(true),
+ // Ensure that we are paused post reload request.
+ hasStoppedPostRequest,
+ // Resume the isolate.
+ resumeIsolate,
+ // Verify that it is running.
+ isolateIsRunning,
+ // Reload sources and do not request to pause post reload.
+ reloadSources(false),
+ // Verify that it is running.
+ isolateIsRunning,
+];
+
+main(args) => runIsolateTests(args, tests, testeeConcurrent: testMain);
diff --git a/runtime/observatory/tests/service/service.status b/runtime/observatory/tests/service/service.status
index 0c6e7dc..6810137 100644
--- a/runtime/observatory/tests/service/service.status
+++ b/runtime/observatory/tests/service/service.status
@@ -7,6 +7,8 @@
gc_test: Pass, RuntimeError # Issue 26490
pause_on_start_and_exit_test: Pass, RuntimeError # Issue 26470
pause_on_start_then_step_test: Pass, RuntimeError # Issue 26470
+# Reload is slow on the bots
+reload_sources_test: Pass, Slow
[ ($compiler == none || $compiler == precompiler) && ($runtime == vm || $runtime == dart_precompiled) ]
evaluate_activation_test/instance: RuntimeError # http://dartbug.com/20047
@@ -18,6 +20,7 @@
debugger_location_second_test: Pass, Slow
debugger_location_test: Pass, Slow
+
# Disable on simulators.
[ $arch == simarm || $arch == simmips || $arch == simarm64 ]
*: SkipSlow
@@ -63,3 +66,4 @@
[ $system == windows ]
dev_fs_weird_char_test: Skip # Windows disallows question mark in paths
+dev_fs_http_put_weird_char_test: Skip # Windows disallows carriage returns in paths
diff --git a/runtime/observatory/tests/service/service_test_common.dart b/runtime/observatory/tests/service/service_test_common.dart
index 935d426..2a68a52 100644
--- a/runtime/observatory/tests/service/service_test_common.dart
+++ b/runtime/observatory/tests/service/service_test_common.dart
@@ -144,6 +144,8 @@
return event is M.PauseExitEvent;
case ServiceEvent.kPauseStart:
return event is M.PauseStartEvent;
+ case ServiceEvent.kPausePostRequest:
+ return event is M.PausePostRequestEvent;
default:
return false;
}
@@ -188,6 +190,10 @@
return hasPausedFor(isolate, ServiceEvent.kPauseBreakpoint);
}
+Future<Isolate> hasStoppedPostRequest(Isolate isolate) {
+ return hasPausedFor(isolate, ServiceEvent.kPausePostRequest);
+}
+
Future<Isolate> hasStoppedWithUnhandledException(Isolate isolate) {
return hasPausedFor(isolate, ServiceEvent.kPauseException);
}
@@ -200,6 +206,16 @@
return hasPausedFor(isolate, ServiceEvent.kPauseStart);
}
+IsolateTest reloadSources([bool pause = false]) {
+ return (Isolate isolate) async {
+ Map<String, dynamic> params = <String, dynamic>{ };
+ if (pause == true) {
+ params['pause'] = pause;
+ }
+ return isolate.invokeRpc('reloadSources', params);
+ };
+}
+
// Currying is your friend.
IsolateTest setBreakpointAtLine(int line) {
return (Isolate isolate) async {
@@ -333,6 +349,11 @@
}
+Future isolateIsRunning(Isolate isolate) async {
+ await isolate.reload();
+ expect(isolate.running, true);
+}
+
Future<Class> getClassFromRootLib(Isolate isolate, String className) async {
Library rootLib = await isolate.rootLibrary.load();
for (var i = 0; i < rootLib.classes.length; i++) {
diff --git a/runtime/platform/assert.cc b/runtime/platform/assert.cc
index 000546a..524c7a2 100644
--- a/runtime/platform/assert.cc
+++ b/runtime/platform/assert.cc
@@ -20,6 +20,7 @@
// Print the file and line number into the buffer.
char buffer[4 * KB];
+ MSAN_UNPOISON(buffer, sizeof(buffer));
intptr_t file_and_line_length =
snprintf(buffer, sizeof(buffer), "%s: %d: error: ", file, line_);
diff --git a/runtime/platform/assert.h b/runtime/platform/assert.h
index 0e8969c..9c810c5 100644
--- a/runtime/platform/assert.h
+++ b/runtime/platform/assert.h
@@ -14,6 +14,7 @@
#endif
#include "platform/globals.h"
+#include "platform/memory_sanitizer.h"
#if !defined(DEBUG) && !defined(NDEBUG)
#error neither DEBUG nor NDEBUG defined
@@ -142,6 +143,7 @@
template<typename E, typename A>
+NO_SANITIZE_MEMORY
void DynamicAssertionHelper::StringEquals(const E& expected, const A& actual) {
std::ostringstream ess, ass;
ess << expected;
@@ -153,6 +155,7 @@
template<typename E, typename A>
+NO_SANITIZE_MEMORY
void DynamicAssertionHelper::IsSubstring(const E& needle, const A& haystack) {
std::ostringstream ess, ass;
ess << needle;
@@ -165,6 +168,7 @@
template<typename E, typename A>
+NO_SANITIZE_MEMORY
void DynamicAssertionHelper::IsNotSubstring(const E& needle,
const A& haystack) {
std::ostringstream ess, ass;
diff --git a/runtime/platform/memory_sanitizer.h b/runtime/platform/memory_sanitizer.h
index b9bd059..fe05ed1 100644
--- a/runtime/platform/memory_sanitizer.h
+++ b/runtime/platform/memory_sanitizer.h
@@ -13,11 +13,14 @@
#if __has_feature(memory_sanitizer)
extern "C" void __msan_unpoison(void *, size_t);
#define MSAN_UNPOISON(ptr, len) __msan_unpoison(ptr, len)
+#define NO_SANITIZE_MEMORY __attribute__((no_sanitize_memory))
#else // __has_feature(memory_sanitizer)
#define MSAN_UNPOISON(ptr, len) do {} while (false && (ptr) == 0 && (len) == 0)
+#define NO_SANITIZE_MEMORY
#endif // __has_feature(memory_sanitizer)
#else // defined(__has_feature)
#define MSAN_UNPOISON(ptr, len) do {} while (false && (ptr) == 0 && (len) == 0)
+#define NO_SANITIZE_MEMORY
#endif // defined(__has_feature)
#endif // PLATFORM_MEMORY_SANITIZER_H_
diff --git a/runtime/tools/gyp/runtime-configurations.gypi b/runtime/tools/gyp/runtime-configurations.gypi
index 0b993ca..95168b0 100644
--- a/runtime/tools/gyp/runtime-configurations.gypi
+++ b/runtime/tools/gyp/runtime-configurations.gypi
@@ -10,6 +10,7 @@
'dart_io_support%': 0,
'dart_io_secure_socket%': 1,
'asan%': 0,
+ 'msan%': 0,
# Intel VTune related variables.
'dart_vtune_support%': 0,
'conditions': [
diff --git a/runtime/vm/BUILD.gn b/runtime/vm/BUILD.gn
index 2f0a5ed..01dd5e9 100644
--- a/runtime/vm/BUILD.gn
+++ b/runtime/vm/BUILD.gn
@@ -3,23 +3,25 @@
# BSD-style license that can be found in the LICENSE file.
config("libdart_vm_config") {
- # TODO(zra, jamesr): This check can go away after some problems with the
- # fuchsia toolchain definition are fixed.
- if (!defined(is_fuchsia) || !is_fuchsia) {
- libs = [ "dl" ]
-
- if (!is_android) {
- libs += [ "pthread" ]
-
- if (is_linux) {
- libs += [ "rt" ]
- }
- }
- } else {
+ if (defined(is_fuchsia) && is_fuchsia) {
libs = [
"magenta",
"runtime",
]
+ } else if (is_win) {
+ libs = [
+ "advapi32.lib",
+ "shell32.lib",
+ "dbghelp.lib",
+ ]
+ } else {
+ libs = [ "dl" ]
+ if (!is_android) {
+ libs += [ "pthread"]
+ }
+ if (is_linux) {
+ libs += [ "rt" ]
+ }
}
}
@@ -71,6 +73,20 @@
}
+static_library("libdart_vm_noopt") {
+ configs += ["..:dart_config",
+ "..:dart_maybe_product_config",
+ "..:dart_precompiler_config",
+ "..:dart_maybe_precompiled_runtime_config"]
+ public_configs = [":libdart_vm_config"]
+ set_sources_assignment_filter(["*_test.cc", "*_test.h"])
+ sources = vm_sources_list.sources
+ include_dirs = [
+ "..",
+ ]
+}
+
+
static_library("libdart_vm_precompiled_runtime") {
configs += ["..:dart_config",
"..:dart_maybe_product_config",
diff --git a/runtime/vm/aot_optimizer.cc b/runtime/vm/aot_optimizer.cc
index 208a224..c938bc3 100644
--- a/runtime/vm/aot_optimizer.cc
+++ b/runtime/vm/aot_optimizer.cc
@@ -54,6 +54,42 @@
}
+// Returns named function that is a unique dynamic target, i.e.,
+// - the target is identified by its name alone, since it occurs only once.
+// - target's class has no subclasses, and neither is subclassed, i.e.,
+// the receiver type can be only the function's class.
+// Returns Function::null() if there is no unique dynamic target for
+// given 'fname'. 'fname' must be a symbol.
+static void GetUniqueDynamicTarget(Isolate* isolate,
+ const String& fname,
+ Object* function) {
+ UniqueFunctionsSet functions_set(
+ isolate->object_store()->unique_dynamic_targets());
+ ASSERT(fname.IsSymbol());
+ *function = functions_set.GetOrNull(fname);
+ ASSERT(functions_set.Release().raw() ==
+ isolate->object_store()->unique_dynamic_targets());
+}
+
+
+AotOptimizer::AotOptimizer(FlowGraph* flow_graph,
+ bool use_speculative_inlining,
+ GrowableArray<intptr_t>* inlining_black_list)
+ : FlowGraphVisitor(flow_graph->reverse_postorder()),
+ flow_graph_(flow_graph),
+ use_speculative_inlining_(use_speculative_inlining),
+ inlining_black_list_(inlining_black_list),
+ has_unique_no_such_method_(false) {
+ ASSERT(!use_speculative_inlining || (inlining_black_list != NULL));
+ Function& target_function = Function::Handle();
+ if (isolate()->object_store()->unique_dynamic_targets() != Array::null()) {
+ GetUniqueDynamicTarget(
+ isolate(), Symbols::NoSuchMethod(), &target_function);
+ has_unique_no_such_method_ = !target_function.IsNull();
+ }
+}
+
+
// Optimize instance calls using ICData.
void AotOptimizer::ApplyICData() {
VisitBlocks();
@@ -123,24 +159,6 @@
}
-// Returns named function that is a unique dynamic target, i.e.,
-// - the target is identified by its name alone, since it occurs only once.
-// - target's class has no subclasses, and neither is subclassed, i.e.,
-// the receiver type can be only the function's class.
-// Returns Function::null() if there is no unique dynamic target for
-// given 'fname'. 'fname' must be a symbol.
-static void GetUniqueDynamicTarget(Isolate* isolate,
- const String& fname,
- Object* function) {
- UniqueFunctionsSet functions_set(
- isolate->object_store()->unique_dynamic_targets());
- ASSERT(fname.IsSymbol());
- *function = functions_set.GetOrNull(fname);
- ASSERT(functions_set.Release().raw() ==
- isolate->object_store()->unique_dynamic_targets());
-}
-
-
bool AotOptimizer::TryCreateICData(InstanceCallInstr* call) {
ASSERT(call->HasICData());
if (call->ic_data()->NumberOfUsedChecks() > 0) {
@@ -227,12 +245,17 @@
!target_function.HasOptionalNamedParameters() &&
target_function.AreValidArgumentCounts(call->ArgumentCount(), 0,
/* error_message = */ NULL)) {
- const intptr_t cid = Class::Handle(Z, target_function.Owner()).id();
- const ICData& ic_data = ICData::ZoneHandle(Z,
- ICData::NewFrom(*call->ic_data(), 1));
- ic_data.AddReceiverCheck(cid, target_function);
- call->set_ic_data(&ic_data);
- return true;
+ const Class& cls = Class::Handle(Z, target_function.Owner());
+ if (!CHA::IsImplemented(cls) && !CHA::HasSubclasses(cls)) {
+ const ICData& ic_data = ICData::ZoneHandle(Z,
+ ICData::NewFrom(*call->ic_data(), 1));
+ ic_data.AddReceiverCheck(cls.id(), target_function);
+ call->set_ic_data(&ic_data);
+ if (has_unique_no_such_method_) {
+ call->set_has_unique_selector(true);
+ }
+ return true;
+ }
}
}
@@ -1995,6 +2018,32 @@
}
+void AotOptimizer::VisitPolymorphicInstanceCall(
+ PolymorphicInstanceCallInstr* call) {
+ if (call->with_checks()) {
+ const intptr_t receiver_cid =
+ call->PushArgumentAt(0)->value()->Type()->ToCid();
+ if (receiver_cid != kDynamicCid) {
+ const Class& receiver_class = Class::Handle(Z,
+ isolate()->class_table()->At(receiver_cid));
+
+ const Array& args_desc_array = Array::Handle(Z,
+ ArgumentsDescriptor::New(call->ArgumentCount(),
+ call->instance_call()->argument_names()));
+ ArgumentsDescriptor args_desc(args_desc_array);
+ const Function& function = Function::Handle(Z,
+ Resolver::ResolveDynamicForReceiverClass(
+ receiver_class,
+ call->instance_call()->function_name(),
+ args_desc));
+ if (!function.IsNull()) {
+ call->set_with_checks(false);
+ }
+ }
+ }
+}
+
+
void AotOptimizer::VisitStaticCall(StaticCallInstr* call) {
if (!IsAllowedForInlining(call->deopt_id())) {
// Inlining disabled after a speculative inlining attempt.
diff --git a/runtime/vm/aot_optimizer.h b/runtime/vm/aot_optimizer.h
index f35536c..6612d99 100644
--- a/runtime/vm/aot_optimizer.h
+++ b/runtime/vm/aot_optimizer.h
@@ -17,16 +17,9 @@
class AotOptimizer : public FlowGraphVisitor {
public:
- AotOptimizer(
- FlowGraph* flow_graph,
- bool use_speculative_inlining,
- GrowableArray<intptr_t>* inlining_black_list)
- : FlowGraphVisitor(flow_graph->reverse_postorder()),
- flow_graph_(flow_graph),
- use_speculative_inlining_(use_speculative_inlining),
- inlining_black_list_(inlining_black_list) {
- ASSERT(!use_speculative_inlining || (inlining_black_list != NULL));
- }
+ AotOptimizer(FlowGraph* flow_graph,
+ bool use_speculative_inlining,
+ GrowableArray<intptr_t>* inlining_black_list);
virtual ~AotOptimizer() {}
FlowGraph* flow_graph() const { return flow_graph_; }
@@ -45,6 +38,8 @@
virtual void VisitStaticCall(StaticCallInstr* instr);
virtual void VisitInstanceCall(InstanceCallInstr* instr);
+ virtual void VisitPolymorphicInstanceCall(
+ PolymorphicInstanceCallInstr* instr);
virtual void VisitLoadCodeUnits(LoadCodeUnitsInstr* instr);
void InsertBefore(Instruction* next,
@@ -142,6 +137,8 @@
GrowableArray<intptr_t>* inlining_black_list_;
+ bool has_unique_no_such_method_;
+
DISALLOW_COPY_AND_ASSIGN(AotOptimizer);
};
diff --git a/runtime/vm/assembler_arm.cc b/runtime/vm/assembler_arm.cc
index e768806..6599e59 100644
--- a/runtime/vm/assembler_arm.cc
+++ b/runtime/vm/assembler_arm.cc
@@ -3243,7 +3243,6 @@
buffer_.Reset();
bkpt(0);
bkpt(0);
- bkpt(0);
ASSERT(CodeSize() == Instructions::kCheckedEntryOffset);
}
@@ -3257,8 +3256,7 @@
Label miss;
Bind(&miss);
- ldr(CODE_REG, Address(THR, Thread::monomorphic_miss_stub_offset()));
- ldr(IP, FieldAddress(CODE_REG, Code::entry_point_offset()));
+ ldr(IP, Address(THR, Thread::monomorphic_miss_entry_offset()));
bx(IP);
Comment("MonomorphicCheckedEntry");
diff --git a/runtime/vm/assembler_arm64.cc b/runtime/vm/assembler_arm64.cc
index 72278e9..37e9ca3 100644
--- a/runtime/vm/assembler_arm64.cc
+++ b/runtime/vm/assembler_arm64.cc
@@ -1244,8 +1244,6 @@
brk(0);
brk(0);
brk(0);
- brk(0);
- brk(0);
ASSERT(CodeSize() == Instructions::kCheckedEntryOffset);
}
@@ -1257,10 +1255,8 @@
Label immediate, have_cid, miss;
Bind(&miss);
- ldr(CODE_REG, Address(THR, Thread::monomorphic_miss_stub_offset()));
- ldr(IP0, FieldAddress(CODE_REG, Code::entry_point_offset()));
+ ldr(IP0, Address(THR, Thread::monomorphic_miss_entry_offset()));
br(IP0);
- brk(0);
Bind(&immediate);
movz(R4, Immediate(kSmiCid), 0);
diff --git a/runtime/vm/assembler_mips.cc b/runtime/vm/assembler_mips.cc
index a85aa08..aa8905e 100644
--- a/runtime/vm/assembler_mips.cc
+++ b/runtime/vm/assembler_mips.cc
@@ -865,7 +865,6 @@
break_(0);
break_(0);
break_(0);
- break_(0);
ASSERT(CodeSize() == Instructions::kCheckedEntryOffset);
}
@@ -877,8 +876,7 @@
Label have_cid, miss;
Bind(&miss);
- lw(CODE_REG, Address(THR, Thread::monomorphic_miss_stub_offset()));
- lw(T9, FieldAddress(CODE_REG, Code::entry_point_offset()));
+ lw(T9, Address(THR, Thread::monomorphic_miss_entry_offset()));
jr(T9);
Comment("MonomorphicCheckedEntry");
diff --git a/runtime/vm/assembler_x64.cc b/runtime/vm/assembler_x64.cc
index 213b8cb..ea2c95d 100644
--- a/runtime/vm/assembler_x64.cc
+++ b/runtime/vm/assembler_x64.cc
@@ -3335,9 +3335,7 @@
void Assembler::MonomorphicCheckedEntry() {
Label immediate, have_cid, miss;
Bind(&miss);
- movq(CODE_REG, Address(THR, Thread::monomorphic_miss_stub_offset()));
- movq(RCX, FieldAddress(CODE_REG, Code::entry_point_offset()));
- jmp(RCX);
+ jmp(Address(THR, Thread::monomorphic_miss_entry_offset()));
Bind(&immediate);
movq(R10, Immediate(kSmiCid));
@@ -3354,6 +3352,7 @@
Bind(&have_cid);
cmpq(R10, RBX);
j(NOT_EQUAL, &miss, Assembler::kNearJump);
+ nop();
// Fall through to unchecked entry.
ASSERT(CodeSize() == Instructions::kUncheckedEntryOffset);
diff --git a/runtime/vm/benchmark_test.h b/runtime/vm/benchmark_test.h
index ab572e4..40f36a0 100644
--- a/runtime/vm/benchmark_test.h
+++ b/runtime/vm/benchmark_test.h
@@ -48,7 +48,7 @@
#define BENCHMARK(name) BENCHMARK_HELPER(name, "RunTime")
#define BENCHMARK_SIZE(name) BENCHMARK_HELPER(name, "CodeSize")
-#define BENCHMARK_MEMORY(name) BENCHMARK_HELPER(name, "Memory")
+#define BENCHMARK_MEMORY(name) BENCHMARK_HELPER(name, "MemoryUse")
inline Dart_Handle NewString(const char* str) {
return Dart_NewStringFromCString(str);
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index 3b1f79e..1799db8 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -522,6 +522,7 @@
s->Push(func->ptr()->code_);
} else if (s->kind() == Snapshot::kAppWithJIT) {
NOT_IN_PRECOMPILED(s->Push(func->ptr()->unoptimized_code_));
+ s->Push(func->ptr()->code_);
s->Push(func->ptr()->ic_data_array_);
}
}
@@ -550,6 +551,7 @@
s->WriteRef(func->ptr()->code_);
} else if (s->kind() == Snapshot::kAppWithJIT) {
NOT_IN_PRECOMPILED(s->WriteRef(func->ptr()->unoptimized_code_));
+ s->WriteRef(func->ptr()->code_);
s->WriteRef(func->ptr()->ic_data_array_);
}
@@ -624,6 +626,7 @@
} else if (kind == Snapshot::kAppWithJIT) {
NOT_IN_PRECOMPILED(func->ptr()->unoptimized_code_ =
reinterpret_cast<RawCode*>(d->ReadRef()));
+ func->ptr()->code_ = reinterpret_cast<RawCode*>(d->ReadRef());
func->ptr()->ic_data_array_ = reinterpret_cast<RawArray*>(d->ReadRef());
}
@@ -671,8 +674,8 @@
Code& code = Code::Handle(zone);
for (intptr_t i = start_index_; i < stop_index_; i++) {
func ^= refs.At(i);
- code ^= func.unoptimized_code();
- if (!code.IsNull()) {
+ code ^= func.CurrentCode();
+ if (func.HasCode() && !code.IsDisabled()) {
func.SetInstructions(code);
func.set_was_compiled(true);
} else {
@@ -899,6 +902,9 @@
// Write out the guarded list length.
s->Push(field->ptr()->guarded_list_length_);
}
+ if (kind == Snapshot::kAppWithJIT) {
+ s->Push(field->ptr()->dependent_code_);
+ }
}
void WriteAlloc(Serializer* s) {
@@ -946,6 +952,9 @@
// Write out the guarded list length.
s->WriteRef(field->ptr()->guarded_list_length_);
}
+ if (kind == Snapshot::kAppWithJIT) {
+ s->WriteRef(field->ptr()->dependent_code_);
+ }
if (kind != Snapshot::kAppNoJIT) {
s->WriteTokenPosition(field->ptr()->token_pos_);
@@ -1484,6 +1493,13 @@
s->Push(code->ptr()->exception_handlers_);
s->Push(code->ptr()->pc_descriptors_);
s->Push(code->ptr()->stackmaps_);
+
+ if (s->kind() == Snapshot::kAppWithJIT) {
+ s->Push(code->ptr()->deopt_info_array_);
+ s->Push(code->ptr()->static_calls_target_table_);
+ NOT_IN_PRODUCT(s->Push(code->ptr()->inlined_metadata_));
+ NOT_IN_PRODUCT(s->Push(code->ptr()->return_address_metadata_));
+ }
}
void WriteAlloc(Serializer* s) {
@@ -1511,21 +1527,19 @@
// No disabled code in precompilation.
NOT_IN_PRECOMPILED(ASSERT(
code->ptr()->instructions_ == code->ptr()->active_instructions_));
- } else {
- ASSERT(kind == Snapshot::kAppWithJIT);
- // We never include optimized code in JIT precompilation. Deoptimization
- // requires code patching and we cannot patch code that is shared
- // between isolates and should not mutate memory allocated by the
- // embedder.
- bool is_optimized = Code::PtrOffBits::decode(code->ptr()->state_bits_);
- if (is_optimized) {
- FATAL("Cannot include optimized code in a JIT snapshot");
- }
}
RawInstructions* instr = code->ptr()->instructions_;
int32_t text_offset = s->GetTextOffset(instr, code);
s->Write<int32_t>(text_offset);
+ if (s->kind() == Snapshot::kAppWithJIT) {
+ // TODO(rmacnak): Fix references to disabled code before serializing.
+ if (code->ptr()->active_instructions_ != code->ptr()->instructions_) {
+ instr = code->ptr()->active_instructions_;
+ text_offset = s->GetTextOffset(instr, code);
+ }
+ s->Write<int32_t>(text_offset);
+ }
s->WriteRef(code->ptr()->object_pool_);
s->WriteRef(code->ptr()->owner_);
@@ -1533,6 +1547,13 @@
s->WriteRef(code->ptr()->pc_descriptors_);
s->WriteRef(code->ptr()->stackmaps_);
+ if (s->kind() == Snapshot::kAppWithJIT) {
+ s->WriteRef(code->ptr()->deopt_info_array_);
+ s->WriteRef(code->ptr()->static_calls_target_table_);
+ NOT_IN_PRODUCT(s->WriteRef(code->ptr()->inlined_metadata_));
+ NOT_IN_PRODUCT(s->WriteRef(code->ptr()->return_address_metadata_));
+ }
+
s->Write<int32_t>(code->ptr()->state_bits_);
}
}
@@ -1575,6 +1596,19 @@
Instructions::CheckedEntryPoint(instr);
NOT_IN_PRECOMPILED(code->ptr()->active_instructions_ = instr);
code->ptr()->instructions_ = instr;
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ if (d->kind() == Snapshot::kAppWithJIT) {
+ int32_t text_offset = d->Read<int32_t>();
+ RawInstructions* instr = reinterpret_cast<RawInstructions*>(
+ d->GetInstructionsAt(text_offset) + kHeapObjectTag);
+ code->ptr()->active_instructions_ = instr;
+ code->ptr()->entry_point_ = Instructions::UncheckedEntryPoint(instr);
+ code->ptr()->checked_entry_point_ =
+ Instructions::CheckedEntryPoint(instr);
+ }
+#endif // !DART_PRECOMPILED_RUNTIME
+
code->ptr()->object_pool_ =
reinterpret_cast<RawObjectPool*>(d->ReadRef());
code->ptr()->owner_ = d->ReadRef();
@@ -1586,21 +1620,34 @@
reinterpret_cast<RawArray*>(d->ReadRef());
#if !defined(DART_PRECOMPILED_RUNTIME)
- code->ptr()->deopt_info_array_ = Array::null();
- code->ptr()->static_calls_target_table_ = Array::null();
+ if (d->kind() == Snapshot::kAppWithJIT) {
+ code->ptr()->deopt_info_array_ =
+ reinterpret_cast<RawArray*>(d->ReadRef());
+ code->ptr()->static_calls_target_table_ =
+ reinterpret_cast<RawArray*>(d->ReadRef());
+#if defined(PRODUCT)
+ code->ptr()->inlined_metadata_ = Array::null();
+ code->ptr()->return_address_metadata_ = Object::null();
+#else
+ code->ptr()->inlined_metadata_ =
+ reinterpret_cast<RawArray*>(d->ReadRef());
+ code->ptr()->return_address_metadata_ = d->ReadRef();
+#endif
+ } else {
+ code->ptr()->deopt_info_array_ = Array::null();
+ code->ptr()->static_calls_target_table_ = Array::null();
+ code->ptr()->inlined_metadata_ = Array::null();
+ code->ptr()->return_address_metadata_ = Object::null();
+ }
+
code->ptr()->var_descriptors_ = LocalVarDescriptors::null();
- code->ptr()->inlined_metadata_ = Array::null();
code->ptr()->code_source_map_ = CodeSourceMap::null();
code->ptr()->comments_ = Array::null();
- code->ptr()->return_address_metadata_ = Object::null();
code->ptr()->compile_timestamp_ = 0;
-#endif
+#endif // !DART_PRECOMPILED_RUNTIME
+
code->ptr()->state_bits_ = d->Read<int32_t>();
-#if !defined(DART_PRECOMPILED_RUNTIME)
- code->ptr()->lazy_deopt_return_pc_offset_ = -1;
- code->ptr()->lazy_deopt_throw_pc_offset_ = -1;
-#endif
}
}
};
@@ -2736,7 +2783,6 @@
}
s->Write<uint16_t>(prefix->ptr()->num_imports_);
s->Write<bool>(prefix->ptr()->is_deferred_load_);
- s->Write<bool>(prefix->ptr()->is_loaded_);
}
}
@@ -2778,7 +2824,7 @@
}
prefix->ptr()->num_imports_ = d->Read<uint16_t>();
prefix->ptr()->is_deferred_load_ = d->Read<bool>();
- prefix->ptr()->is_loaded_ = d->Read<bool>();
+ prefix->ptr()->is_loaded_ = !prefix->ptr()->is_deferred_load_;
}
}
};
@@ -3900,6 +3946,86 @@
#if !defined(DART_PRECOMPILED_RUNTIME)
+class WeakPropertySerializationCluster : public SerializationCluster {
+ public:
+ WeakPropertySerializationCluster() { }
+ virtual ~WeakPropertySerializationCluster() { }
+
+ void Trace(Serializer* s, RawObject* object) {
+ RawWeakProperty* property = WeakProperty::RawCast(object);
+ objects_.Add(property);
+
+ RawObject** from = property->from();
+ RawObject** to = property->to();
+ for (RawObject** p = from; p <= to; p++) {
+ s->Push(*p);
+ }
+ }
+
+ void WriteAlloc(Serializer* s) {
+ s->WriteCid(kWeakPropertyCid);
+ intptr_t count = objects_.length();
+ s->Write<int32_t>(count);
+ for (intptr_t i = 0; i < count; i++) {
+ RawWeakProperty* property = objects_[i];
+ s->AssignRef(property);
+ }
+ }
+
+ void WriteFill(Serializer* s) {
+ intptr_t count = objects_.length();
+ for (intptr_t i = 0; i < count; i++) {
+ RawWeakProperty* property = objects_[i];
+ RawObject** from = property->from();
+ RawObject** to = property->to();
+ for (RawObject** p = from; p <= to; p++) {
+ s->WriteRef(*p);
+ }
+ }
+ }
+
+ private:
+ GrowableArray<RawWeakProperty*> objects_;
+};
+#endif // !DART_PRECOMPILED_RUNTIME
+
+
+class WeakPropertyDeserializationCluster : public DeserializationCluster {
+ public:
+ WeakPropertyDeserializationCluster() { }
+ virtual ~WeakPropertyDeserializationCluster() { }
+
+ void ReadAlloc(Deserializer* d) {
+ start_index_ = d->next_index();
+ PageSpace* old_space = d->heap()->old_space();
+ intptr_t count = d->Read<int32_t>();
+ for (intptr_t i = 0; i < count; i++) {
+ d->AssignRef(AllocateUninitialized(old_space,
+ WeakProperty::InstanceSize()));
+ }
+ stop_index_ = d->next_index();
+ }
+
+ void ReadFill(Deserializer* d) {
+ bool is_vm_object = d->isolate() == Dart::vm_isolate();
+
+ for (intptr_t id = start_index_; id < stop_index_; id++) {
+ RawWeakProperty* property =
+ reinterpret_cast<RawWeakProperty*>(d->Ref(id));
+ Deserializer::InitializeHeader(property, kWeakPropertyCid,
+ WeakProperty::InstanceSize(),
+ is_vm_object);
+ RawObject** from = property->from();
+ RawObject** to = property->to();
+ for (RawObject** p = from; p <= to; p++) {
+ *p = d->ReadRef();
+ }
+ }
+ }
+};
+
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
class LinkedHashMapSerializationCluster : public SerializationCluster {
public:
LinkedHashMapSerializationCluster() { }
@@ -4375,6 +4501,7 @@
return new (Z) GrowableObjectArraySerializationCluster();
case kStacktraceCid: return new (Z) StacktraceSerializationCluster();
case kRegExpCid: return new (Z) RegExpSerializationCluster();
+ case kWeakPropertyCid: return new (Z) WeakPropertySerializationCluster();
case kLinkedHashMapCid: return new (Z) LinkedHashMapSerializationCluster();
case kArrayCid:
return new (Z) ArraySerializationCluster(kArrayCid);
@@ -4700,6 +4827,7 @@
return new (Z) GrowableObjectArrayDeserializationCluster();
case kStacktraceCid: return new (Z) StacktraceDeserializationCluster();
case kRegExpCid: return new (Z) RegExpDeserializationCluster();
+ case kWeakPropertyCid: return new (Z) WeakPropertyDeserializationCluster();
case kLinkedHashMapCid:
return new (Z) LinkedHashMapDeserializationCluster();
case kArrayCid:
@@ -5159,7 +5287,10 @@
WriteIsolateFullSnapshot(num_base_objects);
if (Snapshot::IncludesCode(kind_)) {
- instructions_writer_->Write();
+ instructions_writer_->Write(*vm_isolate_snapshot_buffer_,
+ vm_isolate_snapshot_size_,
+ *isolate_snapshot_buffer_,
+ isolate_snapshot_size_);
OS::Print("VMIsolate(CodeSize): %" Pd "\n", VmIsolateSnapshotSize());
OS::Print("Isolate(CodeSize): %" Pd "\n", IsolateSnapshotSize());
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index 6bfbdb8..1d101b9 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -1864,7 +1864,7 @@
ASSERT(isolate->background_compiler() != NULL);
isolate->background_compiler()->CompileOptimized(function);
// Continue in the same code.
- arguments.SetReturn(Code::Handle(zone, function.CurrentCode()));
+ arguments.SetReturn(function);
return;
}
}
@@ -1886,7 +1886,7 @@
const Code& optimized_code = Code::Handle(zone, function.CurrentCode());
ASSERT(!optimized_code.IsNull());
}
- arguments.SetReturn(Code::Handle(zone, function.CurrentCode()));
+ arguments.SetReturn(function);
#else
UNREACHABLE();
#endif // !DART_PRECOMPILED_RUNTIME
@@ -1935,6 +1935,7 @@
target_function.ToFullyQualifiedCString(),
current_target_code.UncheckedEntryPoint());
}
+ ASSERT(!current_target_code.IsDisabled());
arguments.SetReturn(current_target_code);
}
@@ -1996,15 +1997,10 @@
}
-void DeoptimizeAt(const Code& optimized_code, uword pc) {
+void DeoptimizeAt(const Code& optimized_code, StackFrame* frame) {
ASSERT(optimized_code.is_optimized());
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
- ICData::DeoptReasonId deopt_reason = ICData::kDeoptUnknown;
- uint32_t deopt_flags = 0;
- const TypedData& deopt_info = TypedData::Handle(zone,
- optimized_code.GetDeoptInfoAtPc(pc, &deopt_reason, &deopt_flags));
- ASSERT(!deopt_info.IsNull());
const Function& function = Function::Handle(zone, optimized_code.function());
const Error& error =
Error::Handle(zone, Compiler::EnsureUnoptimizedCode(thread, function));
@@ -2018,24 +2014,18 @@
if (function.HasOptimizedCode()) {
function.SwitchToUnoptimizedCode();
}
- // Patch call site (lazy deoptimization is quite rare, patching it twice
- // is not a performance issue).
- uword lazy_deopt_jump_return = optimized_code.GetLazyDeoptReturnPc();
- uword lazy_deopt_jump_throw = optimized_code.GetLazyDeoptThrowPc();
-#if !defined(TARGET_ARCH_DBC)
- ASSERT(lazy_deopt_jump_return != 0);
- ASSERT(lazy_deopt_jump_throw != 0);
-#endif
+
+#if defined(TARGET_ARCH_DBC)
const Instructions& instrs =
Instructions::Handle(zone, optimized_code.instructions());
{
WritableInstructionsScope writable(instrs.PayloadStart(), instrs.size());
- CodePatcher::InsertDeoptimizationCallAt(pc, lazy_deopt_jump_return);
+ CodePatcher::InsertDeoptimizationCallAt(frame->pc());
if (FLAG_trace_patching) {
const String& name = String::Handle(function.name());
OS::PrintErr(
- "InsertDeoptimizationCallAt: 0x%" Px " to 0x%" Px " for %s\n",
- pc, lazy_deopt_jump_return, name.ToCString());
+ "InsertDeoptimizationCallAt: 0x%" Px " for %s\n",
+ frame->pc(), name.ToCString());
}
const ExceptionHandlers& handlers =
ExceptionHandlers::Handle(zone, optimized_code.exception_handlers());
@@ -2043,12 +2033,38 @@
for (intptr_t i = 0; i < handlers.num_entries(); ++i) {
handlers.GetHandlerInfo(i, &info);
const uword patch_pc = instrs.PayloadStart() + info.handler_pc_offset;
- CodePatcher::InsertDeoptimizationCallAt(patch_pc, lazy_deopt_jump_throw);
+ CodePatcher::InsertDeoptimizationCallAt(patch_pc);
if (FLAG_trace_patching) {
OS::PrintErr(" at handler 0x%" Px "\n", patch_pc);
}
}
}
+#else // !DBC
+ if (frame->IsMarkedForLazyDeopt()) {
+ // Deopt already scheduled.
+ if (FLAG_trace_deoptimization) {
+ THR_Print("Lazy deopt already scheduled for fp=%" Pp "\n", frame->fp());
+ }
+ } else {
+ uword deopt_pc = frame->pc();
+ ASSERT(optimized_code.ContainsInstructionAt(deopt_pc));
+
+#if defined(DEBUG)
+ ValidateFrames();
+#endif
+
+ // N.B.: Update the pending deopt table before updating the frame. The
+ // profiler may attempt a stack walk in between.
+ thread->isolate()->AddPendingDeopt(frame->fp(), deopt_pc);
+ frame->MarkForLazyDeopt();
+
+ if (FLAG_trace_deoptimization) {
+ THR_Print("Lazy deopt scheduled for fp=%" Pp ", pc=%" Pp "\n",
+ frame->fp(), deopt_pc);
+ }
+ }
+#endif // !DBC
+
// Mark code as dead (do not GC its embedded objects).
optimized_code.set_is_alive(false);
}
@@ -2063,7 +2079,7 @@
while (frame != NULL) {
optimized_code = frame->LookupDartCode();
if (optimized_code.is_optimized()) {
- DeoptimizeAt(optimized_code, frame->pc());
+ DeoptimizeAt(optimized_code, frame);
}
frame = iterator.NextFrame();
}
@@ -2144,6 +2160,28 @@
is_lazy_deopt ? "lazy-deopt" : "");
}
+#if !defined(TARGET_ARCH_DBC)
+ if (is_lazy_deopt) {
+ uword deopt_pc = isolate->FindPendingDeopt(caller_frame->fp());
+ if (FLAG_trace_deoptimization) {
+ THR_Print("Lazy deopt fp=%" Pp " pc=%" Pp "\n",
+ caller_frame->fp(), deopt_pc);
+ }
+
+ // N.B.: Update frame before updating pending deopt table. The profiler
+ // may attempt a stack walk in between.
+ caller_frame->set_pc(deopt_pc);
+ ASSERT(caller_frame->pc() == deopt_pc);
+ ASSERT(optimized_code.ContainsInstructionAt(caller_frame->pc()));
+ isolate->ClearPendingDeoptsAtOrBelow(caller_frame->fp());
+ } else {
+ if (FLAG_trace_deoptimization) {
+ THR_Print("Eager deopt fp=%" Pp " pc=%" Pp "\n",
+ caller_frame->fp(), caller_frame->pc());
+ }
+ }
+#endif // !DBC
+
// Copy the saved registers from the stack.
fpu_register_t* fpu_registers;
intptr_t* cpu_registers;
@@ -2204,6 +2242,7 @@
deopt_context->set_dest_frame(caller_frame);
deopt_context->FillDestFrame();
+
#else
UNREACHABLE();
#endif // !DART_PRECOMPILED_RUNTIME
@@ -2222,11 +2261,7 @@
{
// We may rendezvous for a safepoint at entry or GC from the allocations
// below. Check the stack is walkable.
- StackFrameIterator frames_iterator(StackFrameIterator::kValidateFrames);
- StackFrame* frame = frames_iterator.NextFrame();
- while (frame != NULL) {
- frame = frames_iterator.NextFrame();
- }
+ ValidateFrames();
}
#endif
DeoptContext* deopt_context = isolate->deopt_context();
diff --git a/runtime/vm/code_generator.h b/runtime/vm/code_generator.h
index 62e8e23..e0c49b7 100644
--- a/runtime/vm/code_generator.h
+++ b/runtime/vm/code_generator.h
@@ -17,7 +17,7 @@
const char* DeoptReasonToCString(ICData::DeoptReasonId deopt_reason);
-void DeoptimizeAt(const Code& optimized_code, uword pc);
+void DeoptimizeAt(const Code& optimized_code, StackFrame* frame);
void DeoptimizeFunctionsOnStack();
double DartModulo(double a, double b);
diff --git a/runtime/vm/code_patcher.h b/runtime/vm/code_patcher.h
index bde916f..c342f5d 100644
--- a/runtime/vm/code_patcher.h
+++ b/runtime/vm/code_patcher.h
@@ -68,7 +68,7 @@
static intptr_t InstanceCallSizeInBytes();
- static void InsertDeoptimizationCallAt(uword start, uword target);
+ static void InsertDeoptimizationCallAt(uword start);
static void PatchPoolPointerCallAt(uword return_address,
const Code& code,
diff --git a/runtime/vm/code_patcher_arm.cc b/runtime/vm/code_patcher_arm.cc
index 62775bf..7640a5f 100644
--- a/runtime/vm/code_patcher_arm.cc
+++ b/runtime/vm/code_patcher_arm.cc
@@ -30,10 +30,8 @@
}
-void CodePatcher::InsertDeoptimizationCallAt(uword start, uword target) {
- // The inserted call should not overlap the lazy deopt jump code.
- ASSERT(start + CallPattern::DeoptCallPatternLengthInBytes() <= target);
- CallPattern::InsertDeoptCallAt(start, target);
+void CodePatcher::InsertDeoptimizationCallAt(uword start) {
+ UNREACHABLE();
}
diff --git a/runtime/vm/code_patcher_arm64.cc b/runtime/vm/code_patcher_arm64.cc
index 76b959b..658f406 100644
--- a/runtime/vm/code_patcher_arm64.cc
+++ b/runtime/vm/code_patcher_arm64.cc
@@ -70,10 +70,8 @@
}
-void CodePatcher::InsertDeoptimizationCallAt(uword start, uword target) {
- // The inserted call should not overlap the lazy deopt jump code.
- ASSERT(start + CallPattern::kDeoptCallLengthInBytes <= target);
- CallPattern::InsertDeoptCallAt(start, target);
+void CodePatcher::InsertDeoptimizationCallAt(uword start) {
+ UNREACHABLE();
}
diff --git a/runtime/vm/code_patcher_dbc.cc b/runtime/vm/code_patcher_dbc.cc
index 327b27f..b24c32f 100644
--- a/runtime/vm/code_patcher_dbc.cc
+++ b/runtime/vm/code_patcher_dbc.cc
@@ -30,9 +30,8 @@
}
-void CodePatcher::InsertDeoptimizationCallAt(uword start, uword target) {
- ASSERT(target == 0); // Always 0 on DBC.
- CallPattern::InsertDeoptCallAt(start, target);
+void CodePatcher::InsertDeoptimizationCallAt(uword start) {
+ CallPattern::InsertDeoptCallAt(start);
}
diff --git a/runtime/vm/code_patcher_ia32.cc b/runtime/vm/code_patcher_ia32.cc
index db04cdf..de3f74c 100644
--- a/runtime/vm/code_patcher_ia32.cc
+++ b/runtime/vm/code_patcher_ia32.cc
@@ -177,13 +177,8 @@
}
-void CodePatcher::InsertDeoptimizationCallAt(uword start, uword target) {
- // The inserted call should not overlap the lazy deopt jump code.
- ASSERT(start + CallPattern::pattern_length_in_bytes() <= target);
- *reinterpret_cast<uint8_t*>(start) = 0xE8;
- CallPattern call(start);
- call.SetTargetAddress(target);
- CPU::FlushICache(start, CallPattern::pattern_length_in_bytes());
+void CodePatcher::InsertDeoptimizationCallAt(uword start) {
+ UNREACHABLE();
}
diff --git a/runtime/vm/code_patcher_mips.cc b/runtime/vm/code_patcher_mips.cc
index a4d0433..3ed9af3 100644
--- a/runtime/vm/code_patcher_mips.cc
+++ b/runtime/vm/code_patcher_mips.cc
@@ -29,10 +29,8 @@
}
-void CodePatcher::InsertDeoptimizationCallAt(uword start, uword target) {
- // The inserted call should not overlap the lazy deopt jump code.
- ASSERT(start + CallPattern::kDeoptCallLengthInBytes <= target);
- CallPattern::InsertDeoptCallAt(start, target);
+void CodePatcher::InsertDeoptimizationCallAt(uword start) {
+ UNREACHABLE();
}
diff --git a/runtime/vm/code_patcher_x64.cc b/runtime/vm/code_patcher_x64.cc
index 0e18f6f..0426ae7 100644
--- a/runtime/vm/code_patcher_x64.cc
+++ b/runtime/vm/code_patcher_x64.cc
@@ -207,9 +207,9 @@
bool IsValid() const {
static int16_t pattern[kCallPatternSize] = {
- 0x49, 0x8b, 0x9f, -1, -1, -1, -1, // movq rbx, [PP + cache_offs]
0x4d, 0x8b, 0xa7, -1, -1, -1, -1, // movq r12, [PP + code_offs]
0x49, 0x8b, 0x4c, 0x24, 0x0f, // movq rcx, [r12 + entrypoint_off]
+ 0x49, 0x8b, 0x9f, -1, -1, -1, -1, // movq rbx, [PP + cache_offs]
0xff, 0xd1, // call rcx
};
ASSERT(ARRAY_SIZE(pattern) == kCallPatternSize);
@@ -217,10 +217,10 @@
}
intptr_t data_index() const {
- return IndexFromPPLoad(start_ + 3);
+ return IndexFromPPLoad(start_ + 15);
}
intptr_t target_index() const {
- return IndexFromPPLoad(start_ + 10);
+ return IndexFromPPLoad(start_ + 3);
}
RawObject* data() const {
@@ -293,13 +293,8 @@
}
-void CodePatcher::InsertDeoptimizationCallAt(uword start, uword target) {
- // The inserted call should not overlap the lazy deopt jump code.
- ASSERT(start + ShortCallPattern::pattern_length_in_bytes() <= target);
- *reinterpret_cast<uint8_t*>(start) = 0xE8;
- ShortCallPattern call(start);
- call.SetTargetAddress(target);
- CPU::FlushICache(start, ShortCallPattern::pattern_length_in_bytes());
+void CodePatcher::InsertDeoptimizationCallAt(uword start) {
+ UNREACHABLE();
}
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index 3972b33..dccb8c1 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -16,6 +16,8 @@
#include "vm/dart_entry.h"
#include "vm/debugger.h"
#include "vm/deopt_instructions.h"
+#include "vm/kernel.h"
+#include "vm/kernel_to_il.h"
#include "vm/disassembler.h"
#include "vm/exceptions.h"
#include "vm/flags.h"
@@ -84,9 +86,20 @@
#ifndef DART_PRECOMPILED_RUNTIME
+
+bool UseKernelFrontEndFor(ParsedFunction* parsed_function) {
+ const Function& function = parsed_function->function();
+ return (function.kernel_function() != NULL) ||
+ (function.kind() == RawFunction::kNoSuchMethodDispatcher) ||
+ (function.kind() == RawFunction::kInvokeFieldDispatcher);
+}
+
+
void DartCompilationPipeline::ParseFunction(ParsedFunction* parsed_function) {
- Parser::ParseFunction(parsed_function);
- parsed_function->AllocateVariables();
+ if (!UseKernelFrontEndFor(parsed_function)) {
+ Parser::ParseFunction(parsed_function);
+ parsed_function->AllocateVariables();
+ }
}
@@ -95,7 +108,15 @@
ParsedFunction* parsed_function,
const ZoneGrowableArray<const ICData*>& ic_data_array,
intptr_t osr_id) {
- // Build the flow graph.
+ if (UseKernelFrontEndFor(parsed_function)) {
+ kernel::TreeNode* node = static_cast<kernel::TreeNode*>(
+ parsed_function->function().kernel_function());
+ kernel::FlowGraphBuilder builder(
+ node, parsed_function, ic_data_array, NULL, osr_id);
+ FlowGraph* graph = builder.BuildGraph();
+ ASSERT(graph != NULL);
+ return graph;
+ }
FlowGraphBuilder builder(*parsed_function,
ic_data_array,
NULL, // NULL = not inlining.
@@ -1028,7 +1049,7 @@
// the deoptimization path.
AllocationSinking* sinking = NULL;
if (FLAG_allocation_sinking &&
- (flow_graph->graph_entry()->SuccessorCount() == 1)) {
+ (flow_graph->graph_entry()->SuccessorCount() == 1)) {
NOT_IN_PRODUCT(TimelineDurationScope tds2(
thread(), compiler_timeline, "AllocationSinking::Optimize"));
// TODO(fschneider): Support allocation sinking with try-catch.
@@ -1704,11 +1725,43 @@
}
)
- StackZone zone(thread);
- ParsedFunction* parsed_function =
- Parser::ParseStaticFieldInitializer(field);
+ StackZone stack_zone(thread);
+ Zone* zone = stack_zone.GetZone();
+ ParsedFunction* parsed_function;
- parsed_function->AllocateVariables();
+ // Create a one-time-use function to evaluate the initializer and invoke
+ // it immediately.
+ if (field.kernel_field() != NULL) {
+ // kImplicitStaticFinalGetter is used for both implicit static getters
+ // and static initializers. The Kernel graph builder will tell the
+ // difference by pattern matching on the name.
+ const String& name = String::Handle(zone,
+ Symbols::FromConcat(thread,
+ Symbols::InitPrefix(), String::Handle(zone, field.name())));
+ const Script& script = Script::Handle(zone, field.Script());
+ Object& owner = Object::Handle(zone, field.Owner());
+ owner = PatchClass::New(Class::Cast(owner), script);
+ const Function& function = Function::ZoneHandle(zone,
+ Function::New(name,
+ RawFunction::kImplicitStaticFinalGetter,
+ true, // is_static
+ false, // is_const
+ false, // is_abstract
+ false, // is_external
+ false, // is_native
+ owner,
+ TokenPosition::kNoSource));
+ function.set_kernel_function(field.kernel_field());
+ function.set_result_type(AbstractType::Handle(zone, field.type()));
+ function.set_is_reflectable(false);
+ function.set_is_debuggable(false);
+ function.set_is_inlinable(false);
+ parsed_function = new(zone) ParsedFunction(thread, function);
+ } else {
+ parsed_function = Parser::ParseStaticFieldInitializer(field);
+ parsed_function->AllocateVariables();
+ }
+
// Non-optimized code generator.
DartCompilationPipeline pipeline;
CompileParsedFunctionHelper helper(parsed_function, false, kNoOSRDeoptId);
@@ -2165,6 +2218,12 @@
#else // DART_PRECOMPILED_RUNTIME
+bool UseKernelFrontEndFor(ParsedFunction* parsed_function) {
+ UNREACHABLE();
+ return false;
+}
+
+
CompilationPipeline* CompilationPipeline::New(Zone* zone,
const Function& function) {
UNREACHABLE();
diff --git a/runtime/vm/compiler.h b/runtime/vm/compiler.h
index 4ec478f..4c059c9 100644
--- a/runtime/vm/compiler.h
+++ b/runtime/vm/compiler.h
@@ -27,6 +27,7 @@
class Script;
class SequenceNode;
+bool UseKernelFrontEndFor(ParsedFunction* parsed_function);
class CompilationPipeline : public ZoneAllocated {
public:
diff --git a/runtime/vm/constants_dbc.h b/runtime/vm/constants_dbc.h
index 44398aa..f274ebb 100644
--- a/runtime/vm/constants_dbc.h
+++ b/runtime/vm/constants_dbc.h
@@ -396,6 +396,12 @@
//
// Store value FP[rC] into object FP[rA] at offset (in words) B.
//
+// - StoreFieldExt rA, rD
+//
+// Store value FP[rD] into object FP[rA] at offset (in words)
+// stored in the following Nop instruction. Used to access fields with
+// large offsets.
+//
// - StoreFieldTOS D
//
// Store value SP[0] into object SP[-1] at offset (in words) D.
@@ -404,6 +410,12 @@
//
// Load value at offset (in words) C from object FP[rB] into FP[rA].
//
+// - LoadFieldExt rA, rD
+//
+// Load value from object FP[rD] at offset (in words) stored in the
+// following Nop instruction into FP[rA]. Used to access fields with
+// large offsets.
+//
// - LoadUntagged rA, rB, C
//
// Like LoadField, but assumes that FP[rB] is untagged.
@@ -514,10 +526,16 @@
// (A = 1) a subtype of SP[-1] using SubtypeTestCache SP[0], with result
// placed at top of stack.
//
-// - AssertAssignable D
+// - AssertAssignable A, D
//
// Assert that SP[-3] is assignable to variable named SP[0] of type
// SP[-1] with type arguments SP[-2] using SubtypeTestCache PP[D].
+// If A is 1, then the instance may be a Smi.
+//
+// - BadTypeError
+//
+// If SP[-3] is non-null, throws a BadType error by calling into the runtime.
+// Assumes that the stack is arranged the same as for AssertAssignable.
//
// - AssertBoolean A
//
@@ -729,7 +747,7 @@
V(IfEqNull, A, reg, ___, ___) \
V(IfNeNull, A, reg, ___, ___) \
V(CreateArrayTOS, 0, ___, ___, ___) \
- V(CreateArrayOpt, A_B_C, reg, reg, ___) \
+ V(CreateArrayOpt, A_B_C, reg, reg, reg) \
V(Allocate, D, lit, ___, ___) \
V(AllocateT, 0, ___, ___, ___) \
V(AllocateOpt, A_D, reg, lit, ___) \
@@ -758,8 +776,10 @@
V(LoadIndexedOneByteString, A_B_C, reg, reg, reg) \
V(LoadIndexedTwoByteString, A_B_C, reg, reg, reg) \
V(StoreField, A_B_C, reg, num, reg) \
+ V(StoreFieldExt, A_D, reg, reg, ___) \
V(StoreFieldTOS, D, num, ___, ___) \
V(LoadField, A_B_C, reg, reg, num) \
+ V(LoadFieldExt, A_D, reg, reg, ___) \
V(LoadUntagged, A_B_C, reg, reg, num) \
V(LoadFieldTOS, D, num, ___, ___) \
V(BooleanNegateTOS, 0, ___, ___, ___) \
@@ -777,7 +797,8 @@
V(InstantiateType, D, lit, ___, ___) \
V(InstantiateTypeArgumentsTOS, A_D, num, lit, ___) \
V(InstanceOf, A, num, ___, ___) \
- V(AssertAssignable, D, num, lit, ___) \
+ V(BadTypeError, 0, ___, ___, ___) \
+ V(AssertAssignable, A_D, num, lit, ___) \
V(AssertBoolean, A, num, ___, ___) \
V(TestSmi, A_D, reg, reg, ___) \
V(TestCids, A_D, reg, num, ___) \
@@ -785,7 +806,7 @@
V(CheckEitherNonSmi, A_D, reg, reg, ___) \
V(CheckClassId, A_D, reg, num, ___) \
V(CheckDenseSwitch, A_D, reg, num, ___) \
- V(CheckCids, A_B_C, reg, num, ___) \
+ V(CheckCids, A_B_C, reg, num, num) \
V(CheckStack, 0, ___, ___, ___) \
V(DebugStep, 0, ___, ___, ___) \
V(DebugBreak, A, num, ___, ___) \
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index f6f3ab8..7bef09e 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -17,6 +17,9 @@
#include "vm/dart_api_state.h"
#include "vm/dart_entry.h"
#include "vm/debugger.h"
+#if !defined(DART_PRECOMPILED_RUNTIME)
+#include "vm/kernel_reader.h"
+#endif
#include "vm/exceptions.h"
#include "vm/flags.h"
#include "vm/growable_array.h"
@@ -5392,6 +5395,41 @@
}
+DART_EXPORT Dart_Handle Dart_LoadKernel(const uint8_t* buffer,
+ intptr_t buffer_len) {
+ API_TIMELINE_DURATION;
+ DARTSCOPE(Thread::Current());
+ StackZone zone(T);
+
+#if defined(DART_PRECOMPILED_RUNTIME) && !defined(DART_PRECOMPILER)
+ return Api::NewError("%s: Can't load Kernel files from precompiled runtime.",
+ CURRENT_FUNC);
+#else
+ Isolate* I = T->isolate();
+
+ Library& library = Library::Handle(Z, I->object_store()->root_library());
+ if (!library.IsNull()) {
+ const String& library_url = String::Handle(Z, library.url());
+ return Api::NewError("%s: A script has already been loaded from '%s'.",
+ CURRENT_FUNC, library_url.ToCString());
+ }
+ CHECK_CALLBACK_STATE(T);
+ CHECK_COMPILATION_ALLOWED(I);
+
+ // TODO(27588): Memory leak!
+ kernel::KernelReader* reader = new kernel::KernelReader(buffer, buffer_len);
+ const Object& tmp = reader->ReadProgram();
+ if (tmp.IsError()) {
+ return Api::NewHandle(T, tmp.raw());
+ }
+ library ^= tmp.raw();
+ library.set_debuggable(false);
+ I->object_store()->set_root_library(library);
+ return Api::NewHandle(T, library.raw());
+#endif
+}
+
+
DART_EXPORT Dart_Handle Dart_RootLibrary() {
Thread* thread = Thread::Current();
Isolate* isolate = thread->isolate();
@@ -6323,10 +6361,6 @@
DART_EXPORT Dart_Handle Dart_CreatePrecompiledSnapshotAssembly(
- uint8_t** vm_isolate_snapshot_buffer,
- intptr_t* vm_isolate_snapshot_size,
- uint8_t** isolate_snapshot_buffer,
- intptr_t* isolate_snapshot_size,
uint8_t** assembly_buffer,
intptr_t* assembly_size) {
UNREACHABLE();
@@ -6378,10 +6412,6 @@
DART_EXPORT Dart_Handle Dart_CreatePrecompiledSnapshotAssembly(
- uint8_t** vm_isolate_snapshot_buffer,
- intptr_t* vm_isolate_snapshot_size,
- uint8_t** isolate_snapshot_buffer,
- intptr_t* isolate_snapshot_size,
uint8_t** assembly_buffer,
intptr_t* assembly_size) {
#if defined(TARGET_ARCH_IA32)
@@ -6397,18 +6427,6 @@
"Did you forget to call Dart_Precompile?");
}
ASSERT(FLAG_load_deferred_eagerly);
- if (vm_isolate_snapshot_buffer == NULL) {
- RETURN_NULL_ERROR(vm_isolate_snapshot_buffer);
- }
- if (vm_isolate_snapshot_size == NULL) {
- RETURN_NULL_ERROR(vm_isolate_snapshot_size);
- }
- if (isolate_snapshot_buffer == NULL) {
- RETURN_NULL_ERROR(isolate_snapshot_buffer);
- }
- if (isolate_snapshot_size == NULL) {
- RETURN_NULL_ERROR(isolate_snapshot_size);
- }
if (assembly_buffer == NULL) {
RETURN_NULL_ERROR(assembly_buffer);
}
@@ -6421,15 +6439,15 @@
AssemblyInstructionsWriter instructions_writer(assembly_buffer,
ApiReallocate,
2 * MB /* initial_size */);
+ uint8_t* vm_isolate_snapshot_buffer = NULL;
+ uint8_t* isolate_snapshot_buffer = NULL;
FullSnapshotWriter writer(Snapshot::kAppNoJIT,
- vm_isolate_snapshot_buffer,
- isolate_snapshot_buffer,
+ &vm_isolate_snapshot_buffer,
+ &isolate_snapshot_buffer,
ApiReallocate,
&instructions_writer);
writer.WriteFullSnapshot();
- *vm_isolate_snapshot_size = writer.VmIsolateSnapshotSize();
- *isolate_snapshot_size = writer.IsolateSnapshotSize();
*assembly_size = instructions_writer.AssemblySize();
return Api::Success();
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index d2016a4..d3245c9 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -6709,13 +6709,13 @@
const char* kSourceChars =
"part of library1_name;\n"
"external int foo([int x]);\n"
- "class Foo {\n"
+ "class Foo<T extends Foo> {\n"
" external static int addDefault10([int x, int y]);\n"
"}";
const char* kPatchChars =
"const _UNDEFINED = const Object();\n"
"@patch foo([x=_UNDEFINED]) => identical(x, _UNDEFINED) ? 42 : x;\n"
- "@patch class Foo {\n"
+ "@patch class Foo<T> {\n"
" static addDefault10([x=_UNDEFINED, y=_UNDEFINED]) {\n"
" if (identical(x, _UNDEFINED)) x = 10;\n"
" if (identical(y, _UNDEFINED)) y = 10;\n"
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index f78dc3c..12567e6 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -299,6 +299,14 @@
}
+intptr_t ArgumentsDescriptor::PositionAt(intptr_t index) const {
+ const intptr_t offset = kFirstNamedEntryIndex +
+ (index * kNamedEntrySize) +
+ kPositionOffset;
+ return Smi::Value(Smi::RawCast(array_.At(offset)));
+}
+
+
bool ArgumentsDescriptor::MatchesNameAt(intptr_t index,
const String& other) const {
return NameAt(index) == other.raw();
diff --git a/runtime/vm/dart_entry.h b/runtime/vm/dart_entry.h
index e52961b..13294a3 100644
--- a/runtime/vm/dart_entry.h
+++ b/runtime/vm/dart_entry.h
@@ -37,6 +37,7 @@
intptr_t PositionalCount() const;
intptr_t NamedCount() const { return Count() - PositionalCount(); }
RawString* NameAt(intptr_t i) const;
+ intptr_t PositionAt(intptr_t i) const;
bool MatchesNameAt(intptr_t i, const String& other) const;
// Generated code support.
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 51c6721..16bb50f 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -292,12 +292,22 @@
RawError* Debugger::PauseInterrupted() {
+ return PauseRequest(ServiceEvent::kPauseInterrupted);
+}
+
+
+RawError* Debugger::PausePostRequest() {
+ return PauseRequest(ServiceEvent::kPausePostRequest);
+}
+
+
+RawError* Debugger::PauseRequest(ServiceEvent::EventKind kind) {
if (ignore_breakpoints_ || IsPaused()) {
// We don't let the isolate get interrupted if we are already
// paused or ignoring breakpoints.
return Error::null();
}
- ServiceEvent event(isolate_, ServiceEvent::kPauseInterrupted);
+ ServiceEvent event(isolate_, kind);
DebuggerStackTrace* trace = CollectStackTrace();
if (trace->Length() > 0) {
event.set_top_frame(trace->FrameAt(0));
@@ -574,7 +584,8 @@
void ActivationFrame::GetVarDescriptors() {
if (var_descriptors_.IsNull()) {
- if (code().is_optimized()) {
+ Code& unoptimized_code = Code::Handle(function().unoptimized_code());
+ if (unoptimized_code.IsNull()) {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
const Error& error = Error::Handle(zone,
@@ -582,9 +593,10 @@
if (!error.IsNull()) {
Exceptions::PropagateError(error);
}
+ unoptimized_code ^= function().unoptimized_code();
}
- var_descriptors_ =
- Code::Handle(function().unoptimized_code()).GetLocalVarDescriptors();
+ ASSERT(!unoptimized_code.IsNull());
+ var_descriptors_ = unoptimized_code.GetLocalVarDescriptors();
ASSERT(!var_descriptors_.IsNull());
}
}
diff --git a/runtime/vm/debugger.h b/runtime/vm/debugger.h
index e78e839..f3536c7 100644
--- a/runtime/vm/debugger.h
+++ b/runtime/vm/debugger.h
@@ -495,6 +495,9 @@
// Pause execution due to isolate interrupt.
RawError* PauseInterrupted();
+ // Pause after a reload request.
+ RawError* PausePostRequest();
+
// Pause execution due to an uncaught exception.
void PauseException(const Instance& exc);
@@ -519,6 +522,8 @@
kSingleStep
};
+ RawError* PauseRequest(ServiceEvent::EventKind kind);
+
bool NeedsIsolateEvents();
bool NeedsDebugEvents();
void InvokeEventHandler(ServiceEvent* event);
diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc
index 18aa1a1..bc09820 100644
--- a/runtime/vm/deopt_instructions.cc
+++ b/runtime/vm/deopt_instructions.cc
@@ -123,10 +123,12 @@
if (FLAG_trace_deoptimization || FLAG_trace_deoptimization_verbose) {
THR_Print(
- "Deoptimizing (reason %d '%s') at pc %#" Px " '%s' (count %d)\n",
+ "Deoptimizing (reason %d '%s') at "
+ "pc=%" Pp " fp=%" Pp " '%s' (count %d)\n",
deopt_reason(),
DeoptReasonToCString(deopt_reason()),
frame->pc(),
+ frame->fp(),
function.ToFullyQualifiedCString(),
function.deoptimization_counter());
}
@@ -343,11 +345,11 @@
if (FLAG_trace_deoptimization_verbose) {
for (intptr_t i = 0; i < frame_size; i++) {
intptr_t* to_addr = GetDestFrameAddressAt(i);
- OS::PrintErr("*%" Pd ". [%p] 0x%" Px " [%s]\n",
- i,
- to_addr,
- *to_addr,
- deopt_instructions[i + (len - frame_size)]->ToCString());
+ THR_Print("*%" Pd ". [%p] 0x%" Px " [%s]\n",
+ i,
+ to_addr,
+ *to_addr,
+ deopt_instructions[i + (len - frame_size)]->ToCString());
}
}
}
@@ -398,12 +400,12 @@
intptr_t line, column;
script.GetTokenLocation(token_pos, &line, &column);
String& line_string = String::Handle(script.GetLine(line));
- OS::PrintErr(" Function: %s\n", top_function.ToFullyQualifiedCString());
+ THR_Print(" Function: %s\n", top_function.ToFullyQualifiedCString());
char line_buffer[80];
OS::SNPrint(line_buffer, sizeof(line_buffer), " Line %" Pd ": '%s'",
line, line_string.ToCString());
- OS::PrintErr("%s\n", line_buffer);
- OS::PrintErr(" Deopt args: %" Pd "\n", deopt_arg_count);
+ THR_Print("%s\n", line_buffer);
+ THR_Print(" Deopt args: %" Pd "\n", deopt_arg_count);
}
return deopt_arg_count;
diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc
index 7c9d71d..a0af67e 100644
--- a/runtime/vm/exceptions.cc
+++ b/runtime/vm/exceptions.cc
@@ -21,6 +21,7 @@
namespace dart {
+DECLARE_FLAG(bool, trace_deoptimization);
DEFINE_FLAG(bool, print_stacktrace_at_throw, false,
"Prints a stack trace everytime a throw occurs.");
@@ -128,6 +129,7 @@
while (frame != NULL) {
if (frame->IsDartFrame()) {
code = frame->LookupDartCode();
+ ASSERT(code.ContainsInstructionAt(frame->pc()));
offset = Smi::New(frame->pc() - code.PayloadStart());
builder->AddFrame(code, offset);
}
@@ -214,6 +216,64 @@
RawObject* raw_exception = exception_object.raw();
RawObject* raw_stacktrace = stacktrace_object.raw();
+#if !defined(TARGET_ARCH_DBC)
+ MallocGrowableArray<PendingLazyDeopt>* pending_deopts =
+ thread->isolate()->pending_deopts();
+ if (pending_deopts->length() > 0) {
+ // Check if the target frame is scheduled for lazy deopt.
+ for (intptr_t i = 0; i < pending_deopts->length(); i++) {
+ if ((*pending_deopts)[i].fp() == frame_pointer) {
+ // Deopt should now resume in the catch handler instead of after the
+ // call.
+ (*pending_deopts)[i].set_pc(program_counter);
+
+ // Jump to the deopt stub instead of the catch handler.
+ program_counter =
+ StubCode::DeoptimizeLazyFromThrow_entry()->EntryPoint();
+ if (FLAG_trace_deoptimization) {
+ THR_Print("Throwing to frame scheduled for lazy deopt fp=%" Pp "\n",
+ frame_pointer);
+ }
+ break;
+ }
+ }
+
+ // We may be jumping over frames scheduled for lazy deopt. Remove these
+ // frames from the pending deopt table, but only after unmarking them so
+ // any stack walk that happens before the stack is unwound will still work.
+ {
+ DartFrameIterator frames(thread);
+ StackFrame* frame = frames.NextFrame();
+ while ((frame != NULL) && (frame->fp() < frame_pointer)) {
+ if (frame->IsMarkedForLazyDeopt()) {
+ frame->UnmarkForLazyDeopt();
+ }
+ frame = frames.NextFrame();
+ }
+ }
+
+#if defined(DEBUG)
+ ValidateFrames();
+#endif
+
+ for (intptr_t i = 0; i < pending_deopts->length(); i++) {
+ if ((*pending_deopts)[i].fp() < frame_pointer) {
+ if (FLAG_trace_deoptimization) {
+ THR_Print("Lazy deopt skipped due to throw for "
+ "fp=%" Pp ", pc=%" Pp "\n",
+ (*pending_deopts)[i].fp(), (*pending_deopts)[i].pc());
+ }
+ pending_deopts->RemoveAt(i);
+ }
+ }
+
+#if defined(DEBUG)
+ ValidateFrames();
+#endif
+ }
+#endif // !DBC
+
+
#if defined(USING_SIMULATOR)
// Unwinding of the C++ frames and destroying of their stack resources is done
// by the simulator, because the target stack_pointer is a simulated stack
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index 3a54ca8..c8ceb68 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -170,8 +170,10 @@
"Trace isolate creation and shut down.") \
D(trace_handles, bool, false, \
"Traces allocation of handles.") \
+D(trace_kernel_binary, bool, false, \
+ "Trace Kernel reader/writer.") \
D(trace_optimization, bool, false, \
- "Print optimization details."); \
+ "Print optimization details.") \
R(trace_profiler, false, bool, false, \
"Profiler trace") \
D(trace_profiler_verbose, bool, false, \
diff --git a/runtime/vm/flow_graph_allocator.cc b/runtime/vm/flow_graph_allocator.cc
index 7b62e37..423e6c1 100644
--- a/runtime/vm/flow_graph_allocator.cc
+++ b/runtime/vm/flow_graph_allocator.cc
@@ -11,6 +11,7 @@
#include "vm/flow_graph_compiler.h"
#include "vm/log.h"
#include "vm/parser.h"
+#include "vm/stack_frame.h"
namespace dart {
@@ -612,10 +613,6 @@
} else if (block->IsCatchBlockEntry()) {
// Process initial definitions.
CatchBlockEntryInstr* catch_entry = block->AsCatchBlockEntry();
-#if defined(TARGET_ARCH_DBC)
- // TODO(vegorov) support try-catch/finally for DBC.
- flow_graph_.parsed_function().Bailout("FlowGraphAllocator", "Catch");
-#endif
ProcessEnvironmentUses(catch_entry, catch_entry); // For lazy deopt
@@ -631,10 +628,19 @@
// block start to until the end of the instruction so that they are
// preserved.
intptr_t start = catch_entry->start_pos();
- BlockLocation(Location::RegisterLocation(kExceptionObjectReg),
+#if !defined(TARGET_ARCH_DBC)
+ const Register exception_reg = kExceptionObjectReg;
+ const Register stacktrace_reg = kStackTraceObjectReg;
+#else
+ const intptr_t exception_reg =
+ LocalVarIndex(0, catch_entry->exception_var().index());
+ const intptr_t stacktrace_reg =
+ LocalVarIndex(0, catch_entry->stacktrace_var().index());
+#endif
+ BlockLocation(Location::RegisterLocation(exception_reg),
start,
ToInstructionEnd(start));
- BlockLocation(Location::RegisterLocation(kStackTraceObjectReg),
+ BlockLocation(Location::RegisterLocation(stacktrace_reg),
start,
ToInstructionEnd(start));
}
@@ -654,9 +660,52 @@
}
+void FlowGraphAllocator::SplitInitialDefinitionAt(LiveRange* range,
+ intptr_t pos) {
+ if (range->End() > pos) {
+ LiveRange* tail = range->SplitAt(pos);
+ CompleteRange(tail, Location::kRegister);
+ }
+}
+
+
void FlowGraphAllocator::ProcessInitialDefinition(Definition* defn,
LiveRange* range,
BlockEntryInstr* block) {
+#if defined(TARGET_ARCH_DBC)
+ if (block->IsCatchBlockEntry()) {
+ if (defn->IsParameter()) {
+ ParameterInstr* param = defn->AsParameter();
+ intptr_t slot_index = param->index();
+ AssignSafepoints(defn, range);
+ range->finger()->Initialize(range);
+ slot_index = kNumberOfCpuRegisters - 1 - slot_index;
+ range->set_assigned_location(Location::RegisterLocation(slot_index));
+ SplitInitialDefinitionAt(range, block->lifetime_position() + 2);
+ ConvertAllUses(range);
+ BlockLocation(Location::RegisterLocation(slot_index), 0, kMaxPosition);
+ } else {
+ ConstantInstr* constant = defn->AsConstant();
+ ASSERT(constant != NULL);
+ range->set_assigned_location(Location::Constant(constant));
+ range->set_spill_slot(Location::Constant(constant));
+ AssignSafepoints(defn, range);
+ range->finger()->Initialize(range);
+ UsePosition* use =
+ range->finger()->FirstRegisterBeneficialUse(block->start_pos());
+ if (use != NULL) {
+ LiveRange* tail =
+ SplitBetween(range, block->start_pos(), use->pos());
+ // Parameters and constants are tagged, so allocated to CPU registers.
+ ASSERT(constant->representation() == kTagged);
+ CompleteRange(tail, Location::kRegister);
+ }
+ ConvertAllUses(range);
+ }
+ return;
+ }
+#endif
+
// Save the range end because it may change below.
intptr_t range_end = range->End();
if (defn->IsParameter()) {
@@ -679,10 +728,7 @@
AssignSafepoints(defn, range);
range->finger()->Initialize(range);
range->set_assigned_location(Location::RegisterLocation(slot_index));
- if (range->End() > kNormalEntryPos) {
- LiveRange* tail = range->SplitAt(kNormalEntryPos);
- CompleteRange(tail, Location::kRegister);
- }
+ SplitInitialDefinitionAt(range, kNormalEntryPos);
ConvertAllUses(range);
return;
}
diff --git a/runtime/vm/flow_graph_allocator.h b/runtime/vm/flow_graph_allocator.h
index 7df1a6a..34804eb 100644
--- a/runtime/vm/flow_graph_allocator.h
+++ b/runtime/vm/flow_graph_allocator.h
@@ -248,6 +248,8 @@
return Location::MachineRegisterLocation(register_kind_, reg);
}
+ void SplitInitialDefinitionAt(LiveRange* range, intptr_t pos);
+
void PrintLiveRanges();
const FlowGraph& flow_graph_;
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index ffdf3de..333257f 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -1546,6 +1546,7 @@
return Bind(BuildAssertAssignable(token_pos, value, dst_type, dst_name));
}
+
static bool simpleInstanceOfType(const AbstractType& type) {
// Bail if the type is still uninstantiated at compile time.
if (!type.IsInstantiated()) return false;
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index 46a54562..b983754 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -225,8 +225,6 @@
LookupClass(Symbols::List()))),
parallel_move_resolver_(this),
pending_deoptimization_env_(NULL),
- lazy_deopt_return_pc_offset_(Code::kInvalidPc),
- lazy_deopt_throw_pc_offset_(Code::kInvalidPc),
deopt_id_to_ic_data_(NULL),
edge_counters_array_(Array::ZoneHandle()),
inlined_code_intervals_(Array::ZoneHandle(Object::empty_array().raw())),
@@ -672,8 +670,17 @@
if (flow_graph().captured_parameters()->Contains(i)) continue;
if ((*idefs)[i]->IsConstant()) continue; // Common constants
Location src = env->LocationAt(i);
+#if defined(TARGET_ARCH_DBC)
+ intptr_t dest_index = kNumberOfCpuRegisters - 1 - i;
+ Location dest = Location::RegisterLocation(dest_index);
+ // Update safepoint bitmap to indicate that the target location
+ // now contains a pointer. With DBC parameters are copied into
+ // the locals area.
+ instr->locs()->SetStackBit(dest_index);
+#else
intptr_t dest_index = i - num_non_copied_params;
Location dest = Location::StackSlot(dest_index);
+#endif
move_instr->AddMove(dest, src);
}
@@ -689,8 +696,13 @@
Location src = env->LocationAt(i);
ASSERT(!src.IsFpuRegister());
ASSERT(!src.IsDoubleStackSlot());
+#if defined(TARGET_ARCH_DBC)
+ intptr_t dest_index = kNumberOfCpuRegisters - 1 - i;
+ Location dest = Location::RegisterLocation(dest_index);
+#else
intptr_t dest_index = i - num_non_copied_params;
Location dest = Location::StackSlot(dest_index);
+#endif
move_instr->AddMove(dest, src);
// Update safepoint bitmap to indicate that the target location
// now contains a pointer.
@@ -847,12 +859,18 @@
// with the same instruction (and same location summary) sees a bitmap that
// is larger that StackSize(). It will never be larger than StackSize() +
// live_registers_size.
- ASSERT(bitmap->Length() <= (spill_area_size + live_registers_size));
// The first safepoint will grow the bitmap to be the size of
// spill_area_size but the second safepoint will truncate the bitmap and
// append the live registers to it again. The bitmap produced by both calls
// will be the same.
+#if !defined(TARGET_ARCH_DBC)
+ ASSERT(bitmap->Length() <= (spill_area_size + live_registers_size));
bitmap->SetLength(spill_area_size);
+#else
+ if (bitmap->Length() <= (spill_area_size + live_registers_size)) {
+ bitmap->SetLength(Utils::Maximum(bitmap->Length(), spill_area_size));
+ }
+#endif
// Mark the bits in the stack map in the same order we push registers in
// slow path code (see FlowGraphCompiler::SaveLiveRegisters).
@@ -1031,8 +1049,6 @@
pc_descriptors_list_->FinalizePcDescriptors(code.PayloadStart()));
if (!is_optimizing_) descriptors.Verify(parsed_function_.function());
code.set_pc_descriptors(descriptors);
- code.set_lazy_deopt_return_pc_offset(lazy_deopt_return_pc_offset_);
- code.set_lazy_deopt_throw_pc_offset(lazy_deopt_throw_pc_offset_);
}
@@ -1139,38 +1155,36 @@
// Intrinsification skips arguments checks, therefore disable if in checked
// mode.
if (FLAG_intrinsify && !isolate()->type_checks()) {
+ const Class& owner = Class::Handle(parsed_function().function().Owner());
+ String& name = String::Handle(parsed_function().function().name());
+
if (parsed_function().function().kind() == RawFunction::kImplicitGetter) {
- // An implicit getter must have a specific AST structure.
- const SequenceNode& sequence_node = *parsed_function().node_sequence();
- ASSERT(sequence_node.length() == 1);
- ASSERT(sequence_node.NodeAt(0)->IsReturnNode());
- const ReturnNode& return_node = *sequence_node.NodeAt(0)->AsReturnNode();
- ASSERT(return_node.value()->IsLoadInstanceFieldNode());
- const LoadInstanceFieldNode& load_node =
- *return_node.value()->AsLoadInstanceFieldNode();
+ // TODO(27590) Store Field object inside RawFunction::data_ if possible.
+ name = Field::NameFromGetter(name);
+ const Field& field = Field::Handle(owner.LookupFieldAllowPrivate(name));
+ ASSERT(!field.IsNull());
+
// Only intrinsify getter if the field cannot contain a mutable double.
// Reading from a mutable double box requires allocating a fresh double.
- if (FLAG_precompiled_mode ||
- !IsPotentialUnboxedField(load_node.field())) {
- GenerateInlinedGetter(load_node.field().Offset());
+ if (field.is_instance() &&
+ (FLAG_precompiled_mode || !IsPotentialUnboxedField(field))) {
+ GenerateInlinedGetter(field.Offset());
return !FLAG_use_field_guards;
}
return false;
}
if (parsed_function().function().kind() == RawFunction::kImplicitSetter) {
- // An implicit setter must have a specific AST structure.
- // Sequence node has one store node and one return NULL node.
- const SequenceNode& sequence_node = *parsed_function().node_sequence();
- ASSERT(sequence_node.length() == 2);
- ASSERT(sequence_node.NodeAt(0)->IsStoreInstanceFieldNode());
- ASSERT(sequence_node.NodeAt(1)->IsReturnNode());
- const StoreInstanceFieldNode& store_node =
- *sequence_node.NodeAt(0)->AsStoreInstanceFieldNode();
- if (FLAG_precompiled_mode ||
- (store_node.field().guarded_cid() == kDynamicCid)) {
- GenerateInlinedSetter(store_node.field().Offset());
+ // TODO(27590) Store Field object inside RawFunction::data_ if possible.
+ name = Field::NameFromSetter(name);
+ const Field& field = Field::Handle(owner.LookupFieldAllowPrivate(name));
+ ASSERT(!field.IsNull());
+
+ if (field.is_instance() &&
+ (FLAG_precompiled_mode || field.guarded_cid() == kDynamicCid)) {
+ GenerateInlinedSetter(field.Offset());
return !FLAG_use_field_guards;
}
+ return false;
}
}
@@ -1918,20 +1932,8 @@
deopt_id, token_pos, locs, true);
assembler()->Bind(&ok);
} else {
- // Instead of deoptimizing, do a megamorphic call when no matching
- // cid found.
- Label ok;
- MegamorphicSlowPath* slow_path =
- new MegamorphicSlowPath(ic_data, argument_count, deopt_id,
- token_pos, locs, CurrentTryIndex());
- AddSlowPathCode(slow_path);
- EmitTestAndCall(ic_data, argument_count, argument_names,
- slow_path->entry_label(), // No cid match.
- &ok, // Found cid.
- deopt_id, token_pos, locs, false);
-
- assembler()->Bind(slow_path->exit_label());
- assembler()->Bind(&ok);
+ EmitSwitchableInstanceCall(ic_data, argument_count,
+ deopt_id, token_pos, locs);
}
}
}
diff --git a/runtime/vm/flow_graph_compiler.h b/runtime/vm/flow_graph_compiler.h
index 796c1f2..165cded 100644
--- a/runtime/vm/flow_graph_compiler.h
+++ b/runtime/vm/flow_graph_compiler.h
@@ -213,37 +213,6 @@
};
-class MegamorphicSlowPath : public SlowPathCode {
- public:
- MegamorphicSlowPath(const ICData& ic_data,
- intptr_t argument_count,
- intptr_t deopt_id,
- TokenPosition token_pos,
- LocationSummary* locs,
- intptr_t try_index)
- : SlowPathCode(),
- ic_data_(ic_data),
- argument_count_(argument_count),
- deopt_id_(deopt_id),
- token_pos_(token_pos),
- locs_(locs),
- try_index_(try_index) {}
- virtual ~MegamorphicSlowPath() {}
-
- private:
- virtual void EmitNativeCode(FlowGraphCompiler* comp);
-
- const ICData& ic_data_;
- intptr_t argument_count_;
- intptr_t deopt_id_;
- TokenPosition token_pos_;
- LocationSummary* locs_;
- const intptr_t try_index_; // For try/catch ranges.
-
- DISALLOW_COPY_AND_ASSIGN(MegamorphicSlowPath);
-};
-
-
struct CidTarget {
intptr_t cid;
Function* target;
@@ -819,9 +788,6 @@
// In future AddDeoptStub should be moved out of the instruction template.
Environment* pending_deoptimization_env_;
- intptr_t lazy_deopt_return_pc_offset_;
- intptr_t lazy_deopt_throw_pc_offset_;
-
ZoneGrowableArray<const ICData*>* deopt_id_to_ic_data_;
Array& edge_counters_array_;
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index 0b7fd3d..488b475 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -29,18 +29,6 @@
DECLARE_FLAG(bool, enable_simd_inline);
-void MegamorphicSlowPath::EmitNativeCode(FlowGraphCompiler* compiler) {
- Assembler* assembler = compiler->assembler();
-#define __ assembler->
- __ Bind(entry_label());
- __ Comment("MegamorphicSlowPath");
- compiler->EmitMegamorphicInstanceCall(ic_data_, argument_count_, deopt_id_,
- token_pos_, locs_, try_index_);
- __ b(exit_label());
-#undef __
-}
-
-
FlowGraphCompiler::~FlowGraphCompiler() {
// BlockInfos are zone-allocated, so their destructors are not called.
// Verify the labels explicitly here.
@@ -1124,21 +1112,6 @@
__ bkpt(0);
ASSERT(assembler()->constant_pool_allowed());
GenerateDeferredCode();
-
- BeginCodeSourceRange();
- if (is_optimizing() && !FLAG_precompiled_mode) {
- // Leave enough space for patching in case of lazy deoptimization.
- for (intptr_t i = 0;
- i < CallPattern::DeoptCallPatternLengthInInstructions();
- ++i) {
- __ nop();
- }
- lazy_deopt_return_pc_offset_ = assembler()->CodeSize();
- __ Branch(*StubCode::DeoptimizeLazyFromReturn_entry());
- lazy_deopt_throw_pc_offset_ = assembler()->CodeSize();
- __ Branch(*StubCode::DeoptimizeLazyFromThrow_entry());
- }
- EndCodeSourceRange(TokenPosition::kDartCodeEpilogue);
}
@@ -1146,7 +1119,7 @@
const StubEntry& stub_entry,
RawPcDescriptors::Kind kind,
LocationSummary* locs) {
- __ BranchLinkPatchable(stub_entry);
+ __ BranchLink(stub_entry);
AddCurrentDescriptor(kind, Thread::kNoDeoptId, token_pos);
RecordSafepoint(locs);
}
@@ -1381,9 +1354,9 @@
__ Comment("SwitchableCall");
__ LoadFromOffset(kWord, R0, SP, (argument_count - 1) * kWordSize);
- __ LoadUniqueObject(R9, ic_data);
__ LoadUniqueObject(CODE_REG, initial_stub);
__ ldr(LR, FieldAddress(CODE_REG, Code::checked_entry_point_offset()));
+ __ LoadUniqueObject(R9, ic_data);
__ blx(LR);
AddCurrentDescriptor(RawPcDescriptors::kOther, Thread::kNoDeoptId, token_pos);
diff --git a/runtime/vm/flow_graph_compiler_arm64.cc b/runtime/vm/flow_graph_compiler_arm64.cc
index 10ff57f..e76bf3b 100644
--- a/runtime/vm/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/flow_graph_compiler_arm64.cc
@@ -27,18 +27,6 @@
DECLARE_FLAG(bool, enable_simd_inline);
-void MegamorphicSlowPath::EmitNativeCode(FlowGraphCompiler* compiler) {
- Assembler* assembler = compiler->assembler();
-#define __ assembler->
- __ Bind(entry_label());
- __ Comment("MegamorphicSlowPath");
- compiler->EmitMegamorphicInstanceCall(ic_data_, argument_count_, deopt_id_,
- token_pos_, locs_, try_index_);
- __ b(exit_label());
-#undef __
-}
-
-
FlowGraphCompiler::~FlowGraphCompiler() {
// BlockInfos are zone-allocated, so their destructors are not called.
// Verify the labels explicitly here.
@@ -1118,21 +1106,6 @@
__ brk(0);
ASSERT(assembler()->constant_pool_allowed());
GenerateDeferredCode();
-
- BeginCodeSourceRange();
- if (is_optimizing() && !FLAG_precompiled_mode) {
- // Leave enough space for patching in case of lazy deoptimization.
- for (intptr_t i = 0;
- i < CallPattern::kDeoptCallLengthInInstructions;
- ++i) {
- __ orr(R0, ZR, Operand(R0)); // nop
- }
- lazy_deopt_return_pc_offset_ = assembler()->CodeSize();
- __ BranchPatchable(*StubCode::DeoptimizeLazyFromReturn_entry());
- lazy_deopt_throw_pc_offset_ = assembler()->CodeSize();
- __ BranchPatchable(*StubCode::DeoptimizeLazyFromThrow_entry());
- }
- EndCodeSourceRange(TokenPosition::kDartCodeEpilogue);
}
@@ -1140,7 +1113,7 @@
const StubEntry& stub_entry,
RawPcDescriptors::Kind kind,
LocationSummary* locs) {
- __ BranchLinkPatchable(stub_entry);
+ __ BranchLink(stub_entry);
AddCurrentDescriptor(kind, Thread::kNoDeoptId, token_pos);
RecordSafepoint(locs);
}
@@ -1361,9 +1334,9 @@
__ Comment("SwitchableCall");
__ LoadFromOffset(R0, SP, (argument_count - 1) * kWordSize);
- __ LoadUniqueObject(R5, ic_data);
__ LoadUniqueObject(CODE_REG, initial_stub);
__ ldr(TMP, FieldAddress(CODE_REG, Code::checked_entry_point_offset()));
+ __ LoadUniqueObject(R5, ic_data);
__ blr(TMP);
AddCurrentDescriptor(RawPcDescriptors::kOther,
diff --git a/runtime/vm/flow_graph_compiler_dbc.cc b/runtime/vm/flow_graph_compiler_dbc.cc
index 69dd8ad..00fc026 100644
--- a/runtime/vm/flow_graph_compiler_dbc.cc
+++ b/runtime/vm/flow_graph_compiler_dbc.cc
@@ -29,11 +29,6 @@
DECLARE_FLAG(bool, enable_simd_inline);
DECLARE_FLAG(charp, optimization_filter);
-void MegamorphicSlowPath::EmitNativeCode(FlowGraphCompiler* compiler) {
- UNIMPLEMENTED();
-}
-
-
FlowGraphCompiler::~FlowGraphCompiler() {
// BlockInfos are zone-allocated, so their destructors are not called.
// Verify the labels explicitly here.
@@ -199,10 +194,12 @@
// hence the difference.
pending_deoptimization_env_->DropArguments(instr->ArgumentCount());
AddDeoptIndexAtCall(deopt_id_after);
+ // This descriptor is needed for exception handling in optimized code.
+ AddCurrentDescriptor(RawPcDescriptors::kOther,
+ deopt_id_after, instr->token_pos());
} else {
// Add deoptimization continuation point after the call and before the
// arguments are removed.
- // In optimized code this descriptor is needed for exception handling.
AddCurrentDescriptor(RawPcDescriptors::kDeopt,
deopt_id_after,
instr->token_pos());
@@ -227,6 +224,9 @@
SubtypeTestCache& test_cache = SubtypeTestCache::Handle();
if (!dst_type.IsVoidType() && dst_type.IsInstantiated()) {
test_cache = SubtypeTestCache::New();
+ } else if (!dst_type.IsInstantiated() &&
+ (dst_type.IsTypeParameter() || dst_type.IsType())) {
+ test_cache = SubtypeTestCache::New();
}
if (is_optimizing()) {
@@ -235,7 +235,26 @@
}
__ PushConstant(dst_type);
__ PushConstant(dst_name);
- __ AssertAssignable(__ AddConstant(test_cache));
+
+ if (dst_type.IsMalformedOrMalbounded()) {
+ __ BadTypeError();
+ } else {
+ bool may_be_smi = false;
+ if (!dst_type.IsVoidType() && dst_type.IsInstantiated()) {
+ const Class& type_class = Class::Handle(zone(), dst_type.type_class());
+ if (type_class.NumTypeArguments() == 0) {
+ const Class& smi_class = Class::Handle(zone(), Smi::Class());
+ may_be_smi = smi_class.IsSubtypeOf(TypeArguments::Handle(zone()),
+ type_class,
+ TypeArguments::Handle(zone()),
+ NULL,
+ NULL,
+ Heap::kOld);
+ }
+ }
+ __ AssertAssignable(may_be_smi ? 1 : 0, __ AddConstant(test_cache));
+ }
+
if (is_optimizing()) {
// Register allocator does not think that our first input (also used as
// output) needs to be kept alive across the call because that is how code
@@ -276,7 +295,13 @@
void FlowGraphCompiler::GenerateInlinedGetter(intptr_t offset) {
__ Move(0, -(1 + kParamEndSlotFromFp));
- __ LoadField(0, 0, offset / kWordSize);
+ ASSERT(offset % kWordSize == 0);
+ if (Utils::IsInt(8, offset/ kWordSize)) {
+ __ LoadField(0, 0, offset / kWordSize);
+ } else {
+ __ LoadFieldExt(0, 0);
+ __ Nop(offset / kWordSize);
+ }
__ Return(0);
}
@@ -284,7 +309,13 @@
void FlowGraphCompiler::GenerateInlinedSetter(intptr_t offset) {
__ Move(0, -(2 + kParamEndSlotFromFp));
__ Move(1, -(1 + kParamEndSlotFromFp));
- __ StoreField(0, offset / kWordSize, 1);
+ ASSERT(offset % kWordSize == 0);
+ if (Utils::IsInt(8, offset/ kWordSize)) {
+ __ StoreField(0, offset / kWordSize, 1);
+ } else {
+ __ StoreFieldExt(0, 1);
+ __ Nop(offset / kWordSize);
+ }
__ LoadConstant(0, Object::Handle());
__ Return(0);
}
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index 6d823d1..be480f1 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -31,18 +31,6 @@
DECLARE_FLAG(bool, enable_simd_inline);
-void MegamorphicSlowPath::EmitNativeCode(FlowGraphCompiler* compiler) {
- Assembler* assembler = compiler->assembler();
-#define __ assembler->
- __ Bind(entry_label());
- __ Comment("MegamorphicSlowPath");
- compiler->EmitMegamorphicInstanceCall(ic_data_, argument_count_, deopt_id_,
- token_pos_, locs_, try_index_);
- __ jmp(exit_label());
-#undef __
-}
-
-
FlowGraphCompiler::~FlowGraphCompiler() {
// BlockInfos are zone-allocated, so their destructors are not called.
// Verify the labels explicitly here.
@@ -1135,17 +1123,6 @@
__ int3();
GenerateDeferredCode();
-
- BeginCodeSourceRange();
- if (is_optimizing() && !FLAG_precompiled_mode) {
- // Leave enough space for patching in case of lazy deoptimization.
- __ nop(CallPattern::pattern_length_in_bytes());
- lazy_deopt_return_pc_offset_ = assembler()->CodeSize();
- __ Jmp(*StubCode::DeoptimizeLazyFromReturn_entry());
- lazy_deopt_throw_pc_offset_ = assembler()->CodeSize();
- __ Jmp(*StubCode::DeoptimizeLazyFromThrow_entry());
- }
- EndCodeSourceRange(TokenPosition::kDartCodeEpilogue);
}
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index 07117a2..9dd8859 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -25,18 +25,6 @@
DEFINE_FLAG(bool, trap_on_deoptimization, false, "Trap on deoptimization.");
-void MegamorphicSlowPath::EmitNativeCode(FlowGraphCompiler* compiler) {
- Assembler* assembler = compiler->assembler();
-#define __ assembler->
- __ Bind(entry_label());
- __ Comment("MegamorphicSlowPath");
- compiler->EmitMegamorphicInstanceCall(ic_data_, argument_count_, deopt_id_,
- token_pos_, locs_, try_index_);
- __ b(exit_label());
-#undef __
-}
-
-
FlowGraphCompiler::~FlowGraphCompiler() {
// BlockInfos are zone-allocated, so their destructors are not called.
// Verify the labels explicitly here.
@@ -1138,21 +1126,6 @@
__ break_(0);
GenerateDeferredCode();
-
- BeginCodeSourceRange();
- if (is_optimizing() && !FLAG_precompiled_mode) {
- // Leave enough space for patching in case of lazy deoptimization.
- for (intptr_t i = 0;
- i < CallPattern::kDeoptCallLengthInInstructions;
- ++i) {
- __ nop();
- }
- lazy_deopt_return_pc_offset_ = assembler()->CodeSize();
- __ Branch(*StubCode::DeoptimizeLazyFromReturn_entry());
- lazy_deopt_throw_pc_offset_ = assembler()->CodeSize();
- __ Branch(*StubCode::DeoptimizeLazyFromThrow_entry());
- }
- EndCodeSourceRange(TokenPosition::kDartCodeEpilogue);
}
@@ -1160,7 +1133,7 @@
const StubEntry& stub_entry,
RawPcDescriptors::Kind kind,
LocationSummary* locs) {
- __ BranchLinkPatchable(stub_entry);
+ __ BranchLink(stub_entry);
AddCurrentDescriptor(kind, Thread::kNoDeoptId, token_pos);
RecordSafepoint(locs);
}
@@ -1385,9 +1358,9 @@
__ Comment("SwitchableCall");
__ lw(T0, Address(SP, (argument_count - 1) * kWordSize));
- __ LoadUniqueObject(S5, ic_data);
__ LoadUniqueObject(CODE_REG, initial_stub);
__ lw(T9, FieldAddress(CODE_REG, Code::checked_entry_point_offset()));
+ __ LoadUniqueObject(S5, ic_data);
__ jalr(T9);
AddCurrentDescriptor(RawPcDescriptors::kOther,
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index 67223b5..bc7139c 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -27,18 +27,6 @@
DECLARE_FLAG(bool, enable_simd_inline);
-void MegamorphicSlowPath::EmitNativeCode(FlowGraphCompiler* compiler) {
- Assembler* assembler = compiler->assembler();
-#define __ assembler->
- __ Bind(entry_label());
- __ Comment("MegamorphicSlowPath");
- compiler->EmitMegamorphicInstanceCall(ic_data_, argument_count_, deopt_id_,
- token_pos_, locs_, try_index_);
- __ jmp(exit_label());
-#undef __
-}
-
-
FlowGraphCompiler::~FlowGraphCompiler() {
// BlockInfos are zone-allocated, so their destructors are not called.
// Verify the labels explicitly here.
@@ -1135,19 +1123,6 @@
__ int3();
ASSERT(assembler()->constant_pool_allowed());
GenerateDeferredCode();
- // Emit function patching code. This will be swapped with the first 13 bytes
- // at entry point.
-
- BeginCodeSourceRange();
- if (is_optimizing() && !FLAG_precompiled_mode) {
- // Leave enough space for patching in case of lazy deoptimization.
- __ nop(ShortCallPattern::pattern_length_in_bytes());
- lazy_deopt_return_pc_offset_ = assembler()->CodeSize();
- __ Jmp(*StubCode::DeoptimizeLazyFromReturn_entry(), PP);
- lazy_deopt_throw_pc_offset_ = assembler()->CodeSize();
- __ Jmp(*StubCode::DeoptimizeLazyFromThrow_entry(), PP);
- }
- EndCodeSourceRange(TokenPosition::kDartCodeEpilogue);
}
@@ -1385,9 +1360,9 @@
__ Comment("SwitchableCall");
__ movq(RDI, Address(RSP, (argument_count - 1) * kWordSize));
- __ LoadUniqueObject(RBX, ic_data);
__ LoadUniqueObject(CODE_REG, initial_stub);
__ movq(RCX, FieldAddress(CODE_REG, Code::checked_entry_point_offset()));
+ __ LoadUniqueObject(RBX, ic_data);
__ call(RCX);
AddCurrentDescriptor(RawPcDescriptors::kOther,
diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc
index b42bba5..726f6e8 100644
--- a/runtime/vm/flow_graph_inliner.cc
+++ b/runtime/vm/flow_graph_inliner.cc
@@ -8,6 +8,8 @@
#include "vm/block_scheduler.h"
#include "vm/branch_optimizer.h"
#include "vm/compiler.h"
+#include "vm/kernel.h"
+#include "vm/kernel_to_il.h"
#include "vm/flags.h"
#include "vm/flow_graph.h"
#include "vm/flow_graph_builder.h"
@@ -720,13 +722,6 @@
// Makes sure no classes are loaded during parsing in background.
const intptr_t loading_invalidation_gen_at_start =
isolate->loading_invalidation_gen();
- // Parse the callee function.
- bool in_cache;
- ParsedFunction* parsed_function;
- {
- CSTAT_TIMER_SCOPE(thread(), graphinliner_parse_timer);
- parsed_function = GetParsedFunction(function, &in_cache);
- }
if (Compiler::IsBackgroundCompilation()) {
if (isolate->IsTopLevelParsing() ||
@@ -750,18 +745,42 @@
"ICData cleared while inlining");
}
+ // Parse the callee function.
+ bool in_cache;
+ ParsedFunction* parsed_function;
+ {
+ CSTAT_TIMER_SCOPE(thread(), graphinliner_parse_timer);
+ parsed_function = GetParsedFunction(function, &in_cache);
+ }
+
// Build the callee graph.
InlineExitCollector* exit_collector =
new(Z) InlineExitCollector(caller_graph_, call);
- FlowGraphBuilder builder(*parsed_function,
- *ic_data_array,
- exit_collector,
- Compiler::kNoOSRDeoptId);
- builder.SetInitialBlockId(caller_graph_->max_block_id());
FlowGraph* callee_graph;
- {
- CSTAT_TIMER_SCOPE(thread(), graphinliner_build_timer);
- callee_graph = builder.BuildGraph();
+ if (UseKernelFrontEndFor(parsed_function)) {
+ kernel::TreeNode* node = static_cast<kernel::TreeNode*>(
+ parsed_function->function().kernel_function());
+
+ kernel::FlowGraphBuilder builder(node,
+ parsed_function,
+ *ic_data_array,
+ exit_collector,
+ Compiler::kNoOSRDeoptId,
+ caller_graph_->max_block_id() + 1);
+ {
+ CSTAT_TIMER_SCOPE(thread(), graphinliner_build_timer);
+ callee_graph = builder.BuildGraph();
+ }
+ } else {
+ FlowGraphBuilder builder(*parsed_function,
+ *ic_data_array,
+ exit_collector,
+ Compiler::kNoOSRDeoptId);
+ builder.SetInitialBlockId(caller_graph_->max_block_id());
+ {
+ CSTAT_TIMER_SCOPE(thread(), graphinliner_build_timer);
+ callee_graph = builder.BuildGraph();
+ }
}
// The parameter stubs are a copy of the actual arguments providing
@@ -1138,8 +1157,10 @@
*in_cache = false;
ParsedFunction* parsed_function =
new(Z) ParsedFunction(thread(), function);
- Parser::ParseFunction(parsed_function);
- parsed_function->AllocateVariables();
+ if (!UseKernelFrontEndFor(parsed_function)) {
+ Parser::ParseFunction(parsed_function);
+ parsed_function->AllocateVariables();
+ }
return parsed_function;
}
diff --git a/runtime/vm/flow_graph_type_propagator.cc b/runtime/vm/flow_graph_type_propagator.cc
index 2162cfe..d0dd61b 100644
--- a/runtime/vm/flow_graph_type_propagator.cc
+++ b/runtime/vm/flow_graph_type_propagator.cc
@@ -216,9 +216,8 @@
value->SetReachingType(type);
if (FLAG_support_il_printer && FLAG_trace_type_propagation) {
- THR_Print("reaching type to v%" Pd " for v%" Pd " is %s\n",
- value->instruction()->IsDefinition() ?
- value->instruction()->AsDefinition()->ssa_temp_index() : -1,
+ THR_Print("reaching type to %s for v%" Pd " is %s\n",
+ value->instruction()->ToCString(),
value->definition()->ssa_temp_index(),
type->ToCString());
}
@@ -263,6 +262,23 @@
}
+void FlowGraphTypePropagator::VisitInstanceCall(InstanceCallInstr* instr) {
+ if (instr->has_unique_selector()) {
+ SetCid(instr->ArgumentAt(0),
+ instr->ic_data()->GetReceiverClassIdAt(0));
+ }
+}
+
+
+void FlowGraphTypePropagator::VisitPolymorphicInstanceCall(
+ PolymorphicInstanceCallInstr* instr) {
+ if (instr->instance_call()->has_unique_selector()) {
+ SetCid(instr->ArgumentAt(0),
+ instr->ic_data().GetReceiverClassIdAt(0));
+ }
+}
+
+
void FlowGraphTypePropagator::VisitGuardFieldClass(
GuardFieldClassInstr* guard) {
const intptr_t cid = guard->field().guarded_cid();
diff --git a/runtime/vm/flow_graph_type_propagator.h b/runtime/vm/flow_graph_type_propagator.h
index 7a5e87e..84229c5 100644
--- a/runtime/vm/flow_graph_type_propagator.h
+++ b/runtime/vm/flow_graph_type_propagator.h
@@ -32,6 +32,9 @@
virtual void VisitCheckClassId(CheckClassIdInstr* instr);
virtual void VisitGuardFieldClass(GuardFieldClassInstr* instr);
virtual void VisitAssertAssignable(AssertAssignableInstr* instr);
+ virtual void VisitInstanceCall(InstanceCallInstr* instr);
+ virtual void VisitPolymorphicInstanceCall(
+ PolymorphicInstanceCallInstr* instr);
// Current reaching type of the definition. Valid only during dominator tree
// traversal.
diff --git a/runtime/vm/gc_marker.cc b/runtime/vm/gc_marker.cc
index ed6d4da..76cdd5e 100644
--- a/runtime/vm/gc_marker.cc
+++ b/runtime/vm/gc_marker.cc
@@ -677,10 +677,10 @@
template<class MarkingVisitorType>
void GCMarker::FinalizeResultsFrom(MarkingVisitorType* visitor) {
-#ifndef PRODUCT
{
MutexLocker ml(&stats_mutex_);
marked_bytes_ += visitor->marked_bytes();
+#ifndef PRODUCT
// Class heap stats are not themselves thread-safe yet, so we update the
// stats while holding stats_mutex_.
ClassTable* table = heap_->isolate()->class_table();
@@ -691,8 +691,8 @@
table->UpdateLiveOld(i, size, count);
}
}
- }
#endif // !PRODUCT
+ }
visitor->Finalize();
}
diff --git a/runtime/vm/hash_map.h b/runtime/vm/hash_map.h
index 64f8790..d703c0a 100644
--- a/runtime/vm/hash_map.h
+++ b/runtime/vm/hash_map.h
@@ -364,6 +364,27 @@
static inline bool IsKeyEqual(Pair kv, Key key) { return kv.first() == key; }
};
+
+template<typename K, typename V>
+class RawPointerKeyValueTrait {
+ public:
+ typedef K* Key;
+ typedef V Value;
+
+ struct Pair {
+ Key key;
+ Value value;
+ Pair() : key(NULL), value() {}
+ Pair(const Key key, const Value& value) : key(key), value(value) {}
+ Pair(const Pair& other) : key(other.key), value(other.value) {}
+ };
+
+ static Key KeyOf(Pair kv) { return kv.key; }
+ static Value ValueOf(Pair kv) { return kv.value; }
+ static intptr_t Hashcode(Key key) { return reinterpret_cast<intptr_t>(key); }
+ static bool IsKeyEqual(Pair kv, Key key) { return kv.key == key; }
+};
+
} // namespace dart
#endif // VM_HASH_MAP_H_
diff --git a/runtime/vm/heap.cc b/runtime/vm/heap.cc
index c3353d2..97a6da6 100644
--- a/runtime/vm/heap.cc
+++ b/runtime/vm/heap.cc
@@ -38,6 +38,7 @@
read_only_(false),
gc_new_space_in_progress_(false),
gc_old_space_in_progress_(false) {
+ UpdateGlobalMaxUsed();
for (int sel = 0;
sel < kNumWeakSelectors;
sel++) {
diff --git a/runtime/vm/instructions_arm.cc b/runtime/vm/instructions_arm.cc
index 0e5cfb2..a3abab8 100644
--- a/runtime/vm/instructions_arm.cc
+++ b/runtime/vm/instructions_arm.cc
@@ -32,21 +32,6 @@
}
-int CallPattern::DeoptCallPatternLengthInInstructions() {
- const ARMVersion version = TargetCPUFeatures::arm_version();
- if ((version == ARMv5TE) || (version == ARMv6)) {
- return 5;
- } else {
- ASSERT(version == ARMv7);
- return 3;
- }
-}
-
-int CallPattern::DeoptCallPatternLengthInBytes() {
- return DeoptCallPatternLengthInInstructions() * Instr::kInstrSize;
-}
-
-
NativeCallPattern::NativeCallPattern(uword pc, const Code& code)
: object_pool_(ObjectPool::Handle(code.GetObjectPool())),
end_(pc),
@@ -264,49 +249,6 @@
}
-void CallPattern::InsertDeoptCallAt(uword pc, uword target_address) {
- const ARMVersion version = TargetCPUFeatures::arm_version();
- if ((version == ARMv5TE) || (version == ARMv6)) {
- const uint32_t byte0 = (target_address & 0x000000ff);
- const uint32_t byte1 = (target_address & 0x0000ff00) >> 8;
- const uint32_t byte2 = (target_address & 0x00ff0000) >> 16;
- const uint32_t byte3 = (target_address & 0xff000000) >> 24;
-
- const uword mov_ip = 0xe3a0c400 | byte3; // mov ip, (byte3 rot 4)
- const uword or1_ip = 0xe38cc800 | byte2; // orr ip, ip, (byte2 rot 8)
- const uword or2_ip = 0xe38ccc00 | byte1; // orr ip, ip, (byte1 rot 12)
- const uword or3_ip = 0xe38cc000 | byte0; // orr ip, ip, byte0
- const uword blx_ip = 0xe12fff3c;
-
- *reinterpret_cast<uword*>(pc + (0 * Instr::kInstrSize)) = mov_ip;
- *reinterpret_cast<uword*>(pc + (1 * Instr::kInstrSize)) = or1_ip;
- *reinterpret_cast<uword*>(pc + (2 * Instr::kInstrSize)) = or2_ip;
- *reinterpret_cast<uword*>(pc + (3 * Instr::kInstrSize)) = or3_ip;
- *reinterpret_cast<uword*>(pc + (4 * Instr::kInstrSize)) = blx_ip;
-
- ASSERT(DeoptCallPatternLengthInBytes() == 5 * Instr::kInstrSize);
- CPU::FlushICache(pc, DeoptCallPatternLengthInBytes());
- } else {
- ASSERT(version == ARMv7);
- const uint16_t target_lo = target_address & 0xffff;
- const uint16_t target_hi = target_address >> 16;
-
- const uword movw_ip =
- 0xe300c000 | ((target_lo >> 12) << 16) | (target_lo & 0xfff);
- const uword movt_ip =
- 0xe340c000 | ((target_hi >> 12) << 16) | (target_hi & 0xfff);
- const uword blx_ip = 0xe12fff3c;
-
- *reinterpret_cast<uword*>(pc + (0 * Instr::kInstrSize)) = movw_ip;
- *reinterpret_cast<uword*>(pc + (1 * Instr::kInstrSize)) = movt_ip;
- *reinterpret_cast<uword*>(pc + (2 * Instr::kInstrSize)) = blx_ip;
-
- ASSERT(DeoptCallPatternLengthInBytes() == 3 * Instr::kInstrSize);
- CPU::FlushICache(pc, DeoptCallPatternLengthInBytes());
- }
-}
-
-
SwitchableCallPattern::SwitchableCallPattern(uword pc, const Code& code)
: object_pool_(ObjectPool::Handle(code.GetObjectPool())),
data_pool_index_(-1),
@@ -316,15 +258,15 @@
ASSERT(*(reinterpret_cast<uword*>(pc) - 1) == 0xe12fff3e);
Register reg;
- uword stub_load_end =
- InstructionPattern::DecodeLoadWordFromPool(pc - 2 * Instr::kInstrSize,
+ uword data_load_end =
+ InstructionPattern::DecodeLoadWordFromPool(pc - Instr::kInstrSize,
®,
- &target_pool_index_);
- ASSERT(reg == CODE_REG);
- InstructionPattern::DecodeLoadWordFromPool(stub_load_end,
- ®,
- &data_pool_index_);
+ &data_pool_index_);
ASSERT(reg == R9);
+ InstructionPattern::DecodeLoadWordFromPool(data_load_end - Instr::kInstrSize,
+ ®,
+ &target_pool_index_);
+ ASSERT(reg == CODE_REG);
}
diff --git a/runtime/vm/instructions_arm.h b/runtime/vm/instructions_arm.h
index 86d81a7..687cf7e 100644
--- a/runtime/vm/instructions_arm.h
+++ b/runtime/vm/instructions_arm.h
@@ -57,13 +57,6 @@
RawCode* TargetCode() const;
void SetTargetCode(const Code& code) const;
- // This constant length is only valid for inserted call patterns used for
- // lazy deoptimization. Regular call pattern may vary in length.
- static int DeoptCallPatternLengthInBytes();
- static int DeoptCallPatternLengthInInstructions();
-
- static void InsertDeoptCallAt(uword pc, uword target_address);
-
private:
const ObjectPool& object_pool_;
diff --git a/runtime/vm/instructions_arm64.cc b/runtime/vm/instructions_arm64.cc
index 60ef9bf..674e68a 100644
--- a/runtime/vm/instructions_arm64.cc
+++ b/runtime/vm/instructions_arm64.cc
@@ -333,30 +333,6 @@
}
-void CallPattern::InsertDeoptCallAt(uword pc, uword target_address) {
- Instr* movz0 = Instr::At(pc + (0 * Instr::kInstrSize));
- Instr* movk1 = Instr::At(pc + (1 * Instr::kInstrSize));
- Instr* movk2 = Instr::At(pc + (2 * Instr::kInstrSize));
- Instr* movk3 = Instr::At(pc + (3 * Instr::kInstrSize));
- Instr* blr = Instr::At(pc + (4 * Instr::kInstrSize));
- const uint32_t w0 = Utils::Low32Bits(target_address);
- const uint32_t w1 = Utils::High32Bits(target_address);
- const uint16_t h0 = Utils::Low16Bits(w0);
- const uint16_t h1 = Utils::High16Bits(w0);
- const uint16_t h2 = Utils::Low16Bits(w1);
- const uint16_t h3 = Utils::High16Bits(w1);
-
- movz0->SetMoveWideBits(MOVZ, IP0, h0, 0, kDoubleWord);
- movk1->SetMoveWideBits(MOVK, IP0, h1, 1, kDoubleWord);
- movk2->SetMoveWideBits(MOVK, IP0, h2, 2, kDoubleWord);
- movk3->SetMoveWideBits(MOVK, IP0, h3, 3, kDoubleWord);
- blr->SetUnconditionalBranchRegBits(BLR, IP0);
-
- ASSERT(kDeoptCallLengthInBytes == 5 * Instr::kInstrSize);
- CPU::FlushICache(pc, kDeoptCallLengthInBytes);
-}
-
-
SwitchableCallPattern::SwitchableCallPattern(uword pc, const Code& code)
: object_pool_(ObjectPool::Handle(code.GetObjectPool())),
data_pool_index_(-1),
@@ -366,15 +342,15 @@
ASSERT(*(reinterpret_cast<uint32_t*>(pc) - 1) == 0xd63f0200);
Register reg;
- uword stub_load_end =
- InstructionPattern::DecodeLoadWordFromPool(pc - 2 * Instr::kInstrSize,
+ uword data_load_end =
+ InstructionPattern::DecodeLoadWordFromPool(pc - Instr::kInstrSize,
®,
- &target_pool_index_);
- ASSERT(reg == CODE_REG);
- InstructionPattern::DecodeLoadWordFromPool(stub_load_end,
- ®,
- &data_pool_index_);
+ &data_pool_index_);
ASSERT(reg == R5);
+ InstructionPattern::DecodeLoadWordFromPool(data_load_end - Instr::kInstrSize,
+ ®,
+ &target_pool_index_);
+ ASSERT(reg == CODE_REG);
}
diff --git a/runtime/vm/instructions_arm64.h b/runtime/vm/instructions_arm64.h
index 80de324..e3c1d4d 100644
--- a/runtime/vm/instructions_arm64.h
+++ b/runtime/vm/instructions_arm64.h
@@ -64,14 +64,6 @@
RawCode* TargetCode() const;
void SetTargetCode(const Code& target) const;
- // This constant length is only valid for inserted call patterns used for
- // lazy deoptimization. Regular call pattern may vary in length.
- static const int kDeoptCallLengthInInstructions = 5;
- static const int kDeoptCallLengthInBytes =
- kDeoptCallLengthInInstructions * Instr::kInstrSize;
-
- static void InsertDeoptCallAt(uword pc, uword target_address);
-
private:
const ObjectPool& object_pool_;
diff --git a/runtime/vm/instructions_dbc.cc b/runtime/vm/instructions_dbc.cc
index 7d8dab7..b3f50ad 100644
--- a/runtime/vm/instructions_dbc.cc
+++ b/runtime/vm/instructions_dbc.cc
@@ -67,18 +67,6 @@
}
-int CallPattern::DeoptCallPatternLengthInInstructions() {
- UNIMPLEMENTED();
- return 0;
-}
-
-
-int CallPattern::DeoptCallPatternLengthInBytes() {
- UNIMPLEMENTED();
- return 0;
-}
-
-
NativeCallPattern::NativeCallPattern(uword pc, const Code& code)
: object_pool_(ObjectPool::Handle(code.GetObjectPool())),
end_(pc),
@@ -181,7 +169,7 @@
}
-void CallPattern::InsertDeoptCallAt(uword pc, uword target_address) {
+void CallPattern::InsertDeoptCallAt(uword pc) {
const uint8_t argc = Bytecode::IsCallOpcode(Bytecode::At(pc)) ?
Bytecode::DecodeArgc(Bytecode::At(pc)) : 0;
*reinterpret_cast<Instr*>(pc) = Bytecode::Encode(Bytecode::kDeopt, argc, 0);
diff --git a/runtime/vm/instructions_dbc.h b/runtime/vm/instructions_dbc.h
index 6db5205..a10dcc0 100644
--- a/runtime/vm/instructions_dbc.h
+++ b/runtime/vm/instructions_dbc.h
@@ -57,12 +57,7 @@
RawCode* TargetCode() const;
void SetTargetCode(const Code& code) const;
- // This constant length is only valid for inserted call patterns used for
- // lazy deoptimization. Regular call pattern may vary in length.
- static int DeoptCallPatternLengthInBytes();
- static int DeoptCallPatternLengthInInstructions();
-
- static void InsertDeoptCallAt(uword pc, uword target_address);
+ static void InsertDeoptCallAt(uword pc);
private:
const ObjectPool& object_pool_;
diff --git a/runtime/vm/instructions_mips.cc b/runtime/vm/instructions_mips.cc
index 70fff9d..cc51a3d 100644
--- a/runtime/vm/instructions_mips.cc
+++ b/runtime/vm/instructions_mips.cc
@@ -217,24 +217,6 @@
}
-void CallPattern::InsertDeoptCallAt(uword pc, uword target_address) {
- Instr* lui = Instr::At(pc + (0 * Instr::kInstrSize));
- Instr* ori = Instr::At(pc + (1 * Instr::kInstrSize));
- Instr* jr = Instr::At(pc + (2 * Instr::kInstrSize));
- Instr* nop = Instr::At(pc + (3 * Instr::kInstrSize));
- uint16_t target_lo = target_address & 0xffff;
- uint16_t target_hi = target_address >> 16;
-
- lui->SetImmInstrBits(LUI, ZR, T9, target_hi);
- ori->SetImmInstrBits(ORI, T9, T9, target_lo);
- jr->SetSpecialInstrBits(JALR, T9, ZR, RA);
- nop->SetInstructionBits(Instr::kNopInstruction);
-
- ASSERT(kDeoptCallLengthInBytes == 4 * Instr::kInstrSize);
- CPU::FlushICache(pc, kDeoptCallLengthInBytes);
-}
-
-
SwitchableCallPattern::SwitchableCallPattern(uword pc, const Code& code)
: object_pool_(ObjectPool::Handle(code.GetObjectPool())),
data_pool_index_(-1),
@@ -245,15 +227,15 @@
ASSERT(*(reinterpret_cast<uword*>(pc) - 2) == 0x0320f809);
Register reg;
- uword stub_load_end =
- InstructionPattern::DecodeLoadWordFromPool(pc - 3 * Instr::kInstrSize,
+ uword data_load_end =
+ InstructionPattern::DecodeLoadWordFromPool(pc - 2 * Instr::kInstrSize,
®,
- &target_pool_index_);
- ASSERT(reg == CODE_REG);
- InstructionPattern::DecodeLoadWordFromPool(stub_load_end,
- ®,
- &data_pool_index_);
+ &data_pool_index_);
ASSERT(reg == S5);
+ InstructionPattern::DecodeLoadWordFromPool(data_load_end - Instr::kInstrSize,
+ ®,
+ &target_pool_index_);
+ ASSERT(reg == CODE_REG);
}
diff --git a/runtime/vm/instructions_mips.h b/runtime/vm/instructions_mips.h
index a5a398f..95f04f7 100644
--- a/runtime/vm/instructions_mips.h
+++ b/runtime/vm/instructions_mips.h
@@ -57,12 +57,6 @@
RawCode* TargetCode() const;
void SetTargetCode(const Code& target) const;
- static const int kDeoptCallLengthInInstructions = 4;
- static const int kDeoptCallLengthInBytes =
- kDeoptCallLengthInInstructions * Instr::kInstrSize;
-
- static void InsertDeoptCallAt(uword pc, uword target_address);
-
private:
const ObjectPool& object_pool_;
diff --git a/runtime/vm/instructions_x64.cc b/runtime/vm/instructions_x64.cc
index 950fd16..fe0c6ef 100644
--- a/runtime/vm/instructions_x64.cc
+++ b/runtime/vm/instructions_x64.cc
@@ -12,13 +12,6 @@
namespace dart {
-void ShortCallPattern::SetTargetAddress(uword target) const {
- ASSERT(IsValid());
- *reinterpret_cast<uint32_t*>(start() + 1) = target - start() - kLengthInBytes;
- CPU::FlushICache(start() + 1, kWordSize);
-}
-
-
bool DecodeLoadObjectFromPoolOrThread(uword pc,
const Code& code,
Object* obj) {
diff --git a/runtime/vm/instructions_x64.h b/runtime/vm/instructions_x64.h
index 8f1c073..97c52e9 100644
--- a/runtime/vm/instructions_x64.h
+++ b/runtime/vm/instructions_x64.h
@@ -66,25 +66,6 @@
};
-// 5 byte call instruction.
-class ShortCallPattern : public InstructionPattern<ShortCallPattern> {
- public:
- explicit ShortCallPattern(uword pc) : InstructionPattern(pc) {}
-
- void SetTargetAddress(uword new_target) const;
-
- static int pattern_length_in_bytes() { return kLengthInBytes; }
- static const int* pattern() {
- static const int kCallPattern[kLengthInBytes] = {0xE8, -1, -1, -1, -1};
- return kCallPattern;
- }
-
- private:
- static const int kLengthInBytes = 5;
- DISALLOW_COPY_AND_ASSIGN(ShortCallPattern);
-};
-
-
class ReturnPattern : public InstructionPattern<ReturnPattern> {
public:
explicit ReturnPattern(uword pc) : InstructionPattern(pc) {}
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 102f6b8..1fe4377 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -1566,7 +1566,8 @@
const LocalVariable& exception_var,
const LocalVariable& stacktrace_var,
bool needs_stacktrace,
- intptr_t deopt_id)
+ intptr_t deopt_id,
+ bool should_restore_closure_context = false)
: BlockEntryInstr(block_id, try_index),
graph_entry_(graph_entry),
predecessor_(NULL),
@@ -1574,7 +1575,8 @@
catch_try_index_(catch_try_index),
exception_var_(exception_var),
stacktrace_var_(stacktrace_var),
- needs_stacktrace_(needs_stacktrace) {
+ needs_stacktrace_(needs_stacktrace),
+ should_restore_closure_context_(should_restore_closure_context) {
deopt_id_ = deopt_id;
}
@@ -1615,6 +1617,12 @@
predecessor_ = predecessor;
}
+ bool should_restore_closure_context() const {
+ ASSERT(exception_var_.is_captured() == stacktrace_var_.is_captured());
+ ASSERT(!exception_var_.is_captured() || should_restore_closure_context_);
+ return should_restore_closure_context_;
+ }
+
GraphEntryInstr* graph_entry_;
BlockEntryInstr* predecessor_;
const Array& catch_handler_types_;
@@ -1623,6 +1631,7 @@
const LocalVariable& exception_var_;
const LocalVariable& stacktrace_var_;
const bool needs_stacktrace_;
+ const bool should_restore_closure_context_;
DISALLOW_COPY_AND_ASSIGN(CatchBlockEntryInstr);
};
@@ -2777,17 +2786,27 @@
ClosureCallNode* node,
ZoneGrowableArray<PushArgumentInstr*>* arguments)
: TemplateDefinition(Thread::Current()->GetNextDeoptId()),
- ast_node_(*node),
+ argument_names_(node->arguments()->names()),
+ token_pos_(node->token_pos()),
+ arguments_(arguments) {
+ SetInputAt(0, function);
+ }
+
+ ClosureCallInstr(Value* function,
+ ZoneGrowableArray<PushArgumentInstr*>* arguments,
+ const Array& argument_names,
+ TokenPosition token_pos)
+ : TemplateDefinition(Thread::Current()->GetNextDeoptId()),
+ argument_names_(argument_names),
+ token_pos_(token_pos),
arguments_(arguments) {
SetInputAt(0, function);
}
DECLARE_INSTRUCTION(ClosureCall)
- const Array& argument_names() const { return ast_node_.arguments()->names(); }
- virtual TokenPosition token_pos() const {
- return ast_node_.token_pos();
- }
+ const Array& argument_names() const { return argument_names_; }
+ virtual TokenPosition token_pos() const { return token_pos_; }
virtual intptr_t ArgumentCount() const { return arguments_->length(); }
virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const {
@@ -2804,7 +2823,8 @@
PRINT_OPERANDS_TO_SUPPORT
private:
- const ClosureCallNode& ast_node_;
+ const Array& argument_names_;
+ TokenPosition token_pos_;
ZoneGrowableArray<PushArgumentInstr*>* arguments_;
DISALLOW_COPY_AND_ASSIGN(ClosureCallInstr);
@@ -2827,7 +2847,8 @@
token_kind_(token_kind),
arguments_(arguments),
argument_names_(argument_names),
- checked_argument_count_(checked_argument_count) {
+ checked_argument_count_(checked_argument_count),
+ has_unique_selector_(false) {
ic_data_ = GetICData(ic_data_array);
ASSERT(function_name.IsNotTemporaryScopedHandle());
ASSERT(!arguments->is_empty());
@@ -2864,6 +2885,11 @@
const Array& argument_names() const { return argument_names_; }
intptr_t checked_argument_count() const { return checked_argument_count_; }
+ bool has_unique_selector() const { return has_unique_selector_; }
+ void set_has_unique_selector(bool b) {
+ has_unique_selector_ = b;
+ }
+
virtual bool CanDeoptimize() const { return true; }
virtual bool CanBecomeDeoptimizationTarget() const {
@@ -2888,6 +2914,7 @@
ZoneGrowableArray<PushArgumentInstr*>* const arguments_;
const Array& argument_names_;
const intptr_t checked_argument_count_;
+ bool has_unique_selector_;
DISALLOW_COPY_AND_ASSIGN(InstanceCallInstr);
};
@@ -2910,6 +2937,7 @@
InstanceCallInstr* instance_call() const { return instance_call_; }
bool with_checks() const { return with_checks_; }
+ void set_with_checks(bool b) { with_checks_ = b; }
bool complete() const { return complete_; }
virtual TokenPosition token_pos() const {
return instance_call_->token_pos();
@@ -2941,7 +2969,7 @@
private:
InstanceCallInstr* instance_call_;
const ICData& ic_data_;
- const bool with_checks_;
+ bool with_checks_;
const bool complete_;
DISALLOW_COPY_AND_ASSIGN(PolymorphicInstanceCallInstr);
@@ -3264,6 +3292,7 @@
identity_(AliasIdentity::Unknown()) {
ic_data_ = GetICData(ic_data_array);
ASSERT(function.IsZoneHandle());
+ ASSERT(!function.IsNull());
ASSERT(argument_names.IsZoneHandle() || argument_names.InVMHeap());
}
@@ -3282,6 +3311,7 @@
is_known_list_constructor_(false),
identity_(AliasIdentity::Unknown()) {
ASSERT(function.IsZoneHandle());
+ ASSERT(!function.IsNull());
ASSERT(argument_names.IsZoneHandle() || argument_names.InVMHeap());
}
@@ -3483,33 +3513,32 @@
class NativeCallInstr : public TemplateDefinition<0, Throws> {
public:
explicit NativeCallInstr(NativeBodyNode* node)
- : ast_node_(*node),
+ : native_name_(&node->native_c_function_name()),
+ function_(&node->function()),
native_c_function_(NULL),
- is_bootstrap_native_(false) { }
+ is_bootstrap_native_(false),
+ link_lazily_(node->link_lazily()),
+ token_pos_(node->token_pos()) { }
+
+ NativeCallInstr(const String* name,
+ const Function* function,
+ bool link_lazily,
+ TokenPosition position)
+ : native_name_(name),
+ function_(function),
+ native_c_function_(NULL),
+ is_bootstrap_native_(false),
+ link_lazily_(link_lazily),
+ token_pos_(position) { }
DECLARE_INSTRUCTION(NativeCall)
- virtual TokenPosition token_pos() const {
- return ast_node_.token_pos();
- }
-
- const Function& function() const { return ast_node_.function(); }
-
- const String& native_name() const {
- return ast_node_.native_c_function_name();
- }
-
- NativeFunction native_c_function() const {
- return native_c_function_;
- }
-
- bool is_bootstrap_native() const {
- return is_bootstrap_native_;
- }
-
- bool link_lazily() const {
- return ast_node_.link_lazily();
- }
+ const String& native_name() const { return *native_name_; }
+ const Function& function() const { return *function_; }
+ NativeFunction native_c_function() const { return native_c_function_; }
+ bool is_bootstrap_native() const { return is_bootstrap_native_; }
+ bool link_lazily() const { return link_lazily_; }
+ virtual TokenPosition token_pos() const { return token_pos_; }
virtual bool CanDeoptimize() const { return false; }
@@ -3526,9 +3555,12 @@
void set_is_bootstrap_native(bool value) { is_bootstrap_native_ = value; }
- const NativeBodyNode& ast_node_;
+ const String* native_name_;
+ const Function* function_;
NativeFunction native_c_function_;
bool is_bootstrap_native_;
+ bool link_lazily_;
+ const TokenPosition token_pos_;
DISALLOW_COPY_AND_ASSIGN(NativeCallInstr);
};
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
index 9827a4d..f92bbf4 100644
--- a/runtime/vm/intermediate_language_arm.cc
+++ b/runtime/vm/intermediate_language_arm.cc
@@ -2837,14 +2837,6 @@
void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- // Ensure space for patching return sites for lazy deopt.
- if (!FLAG_precompiled_mode && compiler->is_optimizing()) {
- for (intptr_t i = 0;
- i < CallPattern::DeoptCallPatternLengthInInstructions();
- ++i) {
- __ nop();
- }
- }
__ Bind(compiler->GetJumpLabel(this));
compiler->AddExceptionHandler(catch_try_index(),
try_index(),
@@ -2872,12 +2864,39 @@
ASSERT(fp_sp_dist <= 0);
__ AddImmediate(SP, FP, fp_sp_dist);
- // Restore stack and initialize the two exception variables:
- // exception and stack trace variables.
- __ StoreToOffset(kWord, kExceptionObjectReg,
- FP, exception_var().index() * kWordSize);
- __ StoreToOffset(kWord, kStackTraceObjectReg,
- FP, stacktrace_var().index() * kWordSize);
+ // Auxiliary variables introduced by the try catch can be captured if we are
+ // inside a function with yield/resume points. In this case we first need
+ // to restore the context to match the context at entry into the closure.
+ if (should_restore_closure_context()) {
+ const ParsedFunction& parsed_function = compiler->parsed_function();
+ ASSERT(parsed_function.function().IsClosureFunction());
+ LocalScope* scope = parsed_function.node_sequence()->scope();
+
+ LocalVariable* closure_parameter = scope->VariableAt(0);
+ ASSERT(!closure_parameter->is_captured());
+ __ ldr(CTX, Address(FP, closure_parameter->index() * kWordSize));
+ __ ldr(CTX, FieldAddress(CTX, Closure::context_offset()));
+
+ const intptr_t context_index =
+ parsed_function.current_context_var()->index();
+ __ StoreToOffset(kWord, CTX, FP, context_index * kWordSize);
+ }
+
+ // Initialize exception and stack trace variables.
+ if (exception_var().is_captured()) {
+ ASSERT(stacktrace_var().is_captured());
+ __ StoreIntoObjectOffset(CTX,
+ Context::variable_offset(exception_var().index()),
+ kExceptionObjectReg);
+ __ StoreIntoObjectOffset(CTX,
+ Context::variable_offset(stacktrace_var().index()),
+ kStackTraceObjectReg);
+ } else {
+ __ StoreToOffset(kWord, kExceptionObjectReg,
+ FP, exception_var().index() * kWordSize);
+ __ StoreToOffset(kWord, kStackTraceObjectReg,
+ FP, stacktrace_var().index() * kWordSize);
+ }
}
@@ -3168,17 +3187,10 @@
case Token::kLTE:
case Token::kGT:
case Token::kGTE: {
- Label true_label, false_label, done;
- BranchLabels labels = { &true_label, &false_label, &false_label };
Condition true_condition =
EmitSmiComparisonOp(compiler, locs(), op_kind());
- EmitBranchOnCondition(compiler, true_condition, labels);
- __ Bind(&false_label);
- __ LoadObject(result, Bool::False());
- __ b(&done);
- __ Bind(&true_label);
- __ LoadObject(result, Bool::True());
- __ Bind(&done);
+ __ LoadObject(result, Bool::True(), true_condition);
+ __ LoadObject(result, Bool::False(), NegateCondition(true_condition));
break;
}
default:
@@ -6972,8 +6984,9 @@
void DebugStepCheckInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
ASSERT(!compiler->is_optimizing());
- compiler->GenerateCall(
- token_pos(), *StubCode::DebugStepCheck_entry(), stub_kind_, locs());
+ __ BranchLinkPatchable(*StubCode::DebugStepCheck_entry());
+ compiler->AddCurrentDescriptor(stub_kind_, Thread::kNoDeoptId, token_pos());
+ compiler->RecordSafepoint(locs());
}
diff --git a/runtime/vm/intermediate_language_arm64.cc b/runtime/vm/intermediate_language_arm64.cc
index af9f56d..1eabe23 100644
--- a/runtime/vm/intermediate_language_arm64.cc
+++ b/runtime/vm/intermediate_language_arm64.cc
@@ -2554,14 +2554,6 @@
void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- // Ensure space for patching return sites for lazy deopt.
- if (!FLAG_precompiled_mode && compiler->is_optimizing()) {
- for (intptr_t i = 0;
- i < CallPattern::kDeoptCallLengthInInstructions;
- ++i) {
- __ orr(R0, ZR, Operand(R0)); // nop
- }
- }
__ Bind(compiler->GetJumpLabel(this));
compiler->AddExceptionHandler(catch_try_index(),
try_index(),
@@ -5759,8 +5751,9 @@
void DebugStepCheckInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
ASSERT(!compiler->is_optimizing());
- compiler->GenerateCall(
- token_pos(), *StubCode::DebugStepCheck_entry(), stub_kind_, locs());
+ __ BranchLinkPatchable(*StubCode::DebugStepCheck_entry());
+ compiler->AddCurrentDescriptor(stub_kind_, Thread::kNoDeoptId, token_pos());
+ compiler->RecordSafepoint(locs());
}
diff --git a/runtime/vm/intermediate_language_dbc.cc b/runtime/vm/intermediate_language_dbc.cc
index aca13bd..6bde28b 100644
--- a/runtime/vm/intermediate_language_dbc.cc
+++ b/runtime/vm/intermediate_language_dbc.cc
@@ -454,7 +454,7 @@
}
} else {
ASSERT(true_condition == NEXT_IS_FALSE);
- // NEXT_IS_FALSE indicates that the preceeing test has been flipped and
+ // NEXT_IS_FALSE indicates that the preceeding test has been flipped and
// expects the false case to be in the subsequent instruction, which it
// skips if the test succeeds.
__ Jump(labels.false_label);
@@ -479,7 +479,7 @@
condition = NEXT_IS_TRUE;
comparison = kind();
} else {
- // Flip comparision to save a jump.
+ // Flip comparison to save a jump.
condition = NEXT_IS_FALSE;
comparison = (kind() == Token::kEQ_STRICT) ? Token::kNE_STRICT
: Token::kEQ_STRICT;
@@ -1028,7 +1028,12 @@
if (compiler->is_optimizing()) {
const Register value = locs()->in(1).reg();
const Register instance = locs()->in(0).reg();
- __ StoreField(instance, offset_in_bytes() / kWordSize, value);
+ if (Utils::IsInt(8, offset_in_bytes() / kWordSize)) {
+ __ StoreField(instance, offset_in_bytes() / kWordSize, value);
+ } else {
+ __ StoreFieldExt(instance, value);
+ __ Nop(offset_in_bytes() / kWordSize);
+ }
} else {
__ StoreFieldTOS(offset_in_bytes() / kWordSize);
}
@@ -1040,7 +1045,12 @@
if (compiler->is_optimizing()) {
const Register result = locs()->out(0).reg();
const Register instance = locs()->in(0).reg();
- __ LoadField(result, instance, offset_in_bytes() / kWordSize);
+ if (Utils::IsInt(8, offset_in_bytes() / kWordSize)) {
+ __ LoadField(result, instance, offset_in_bytes() / kWordSize);
+ } else {
+ __ LoadFieldExt(result, instance);
+ __ Nop(offset_in_bytes() / kWordSize);
+ }
} else {
__ LoadFieldTOS(offset_in_bytes() / kWordSize);
}
@@ -1119,10 +1129,27 @@
compiler->assembler()->CodeSize(),
catch_handler_types_,
needs_stacktrace());
- __ MoveSpecial(-exception_var().index()-1,
- Simulator::kExceptionSpecialIndex);
- __ MoveSpecial(-stacktrace_var().index()-1,
- Simulator::kStacktraceSpecialIndex);
+
+ if (HasParallelMove()) {
+ compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
+ }
+ if (compiler->is_optimizing()) {
+ // In optimized code, variables at the catch block entry reside at the top
+ // of the allocatable register range.
+ const intptr_t num_non_copied_params =
+ compiler->flow_graph().num_non_copied_params();
+ const intptr_t exception_reg = kNumberOfCpuRegisters -
+ (-exception_var().index() + num_non_copied_params);
+ const intptr_t stacktrace_reg = kNumberOfCpuRegisters -
+ (-stacktrace_var().index() + num_non_copied_params);
+ __ MoveSpecial(exception_reg, Simulator::kExceptionSpecialIndex);
+ __ MoveSpecial(stacktrace_reg, Simulator::kStacktraceSpecialIndex);
+ } else {
+ __ MoveSpecial(LocalVarIndex(0, exception_var().index()),
+ Simulator::kExceptionSpecialIndex);
+ __ MoveSpecial(LocalVarIndex(0, stacktrace_var().index()),
+ Simulator::kStacktraceSpecialIndex);
+ }
__ SetFrame(compiler->StackSize());
}
@@ -1400,10 +1427,15 @@
(unary_checks().NumberOfChecks() > 1));
const intptr_t may_be_smi =
(unary_checks().GetReceiverClassIdAt(0) == kSmiCid) ? 1 : 0;
+ bool is_dense_switch = false;
+ intptr_t cid_mask = 0;
if (IsDenseSwitch()) {
ASSERT(cids_[0] < cids_[cids_.length() - 1]);
+ cid_mask = ComputeCidMask();
+ is_dense_switch = Smi::IsValid(cid_mask);
+ }
+ if (is_dense_switch) {
const intptr_t low_cid = cids_[0];
- const intptr_t cid_mask = ComputeCidMask();
__ CheckDenseSwitch(value, may_be_smi);
__ Nop(compiler->ToEmbeddableCid(low_cid, this));
__ Nop(__ AddConstant(Smi::Handle(Smi::New(cid_mask))));
@@ -1788,15 +1820,12 @@
const Register left = locs->in(0).reg();
const Register right = locs->in(1).reg();
Token::Kind comparison = kind;
+ // For double comparisons we can't flip the condition like with smi
+ // comparisons because of NaN which will compare false for all except !=
+ // operations.
+ // TODO(fschneider): Change the block order instead in DBC so that the
+ // false block in always the fall-through block.
Condition condition = NEXT_IS_TRUE;
- if (labels.fall_through != labels.false_label) {
- // If we aren't falling through to the false label, we can save a Jump
- // instruction in the case that the true case is the fall through by
- // flipping the sense of the test such that the instruction following the
- // test is the Jump to the false label.
- condition = NEXT_IS_FALSE;
- comparison = FlipCondition(kind);
- }
__ Emit(Bytecode::Encode(OpcodeForDoubleCondition(comparison), left, right));
return condition;
}
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index 597fd43..5002712 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -2548,10 +2548,6 @@
void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- // Ensure space for patching return sites for lazy deopt.
- if (!FLAG_precompiled_mode && compiler->is_optimizing()) {
- __ nop(CallPattern::pattern_length_in_bytes());
- }
__ Bind(compiler->GetJumpLabel(this));
compiler->AddExceptionHandler(catch_try_index(),
try_index(),
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc
index 6ec28cc..e824df1 100644
--- a/runtime/vm/intermediate_language_mips.cc
+++ b/runtime/vm/intermediate_language_mips.cc
@@ -2668,14 +2668,6 @@
void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- // Ensure space for patching return sites for lazy deopt.
- if (!FLAG_precompiled_mode && compiler->is_optimizing()) {
- for (intptr_t i = 0;
- i < CallPattern::kDeoptCallLengthInInstructions;
- ++i) {
- __ nop();
- }
- }
__ Bind(compiler->GetJumpLabel(this));
compiler->AddExceptionHandler(catch_try_index(),
try_index(),
@@ -5763,8 +5755,9 @@
void DebugStepCheckInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
ASSERT(!compiler->is_optimizing());
- compiler->GenerateCall(
- token_pos(), *StubCode::DebugStepCheck_entry(), stub_kind_, locs());
+ __ BranchLinkPatchable(*StubCode::DebugStepCheck_entry());
+ compiler->AddCurrentDescriptor(stub_kind_, Thread::kNoDeoptId, token_pos());
+ compiler->RecordSafepoint(locs());
}
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index b8a57bb..6e17709 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -2564,10 +2564,6 @@
void CatchBlockEntryInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
- // Ensure space for patching return sites for lazy deopt.
- if (!FLAG_precompiled_mode && compiler->is_optimizing()) {
- __ nop(ShortCallPattern::pattern_length_in_bytes());
- }
__ Bind(compiler->GetJumpLabel(this));
compiler->AddExceptionHandler(catch_try_index(),
try_index(),
@@ -2595,12 +2591,50 @@
ASSERT(fp_sp_dist <= 0);
__ leaq(RSP, Address(RBP, fp_sp_dist));
- // Restore stack and initialize the two exception variables:
- // exception and stack trace variables.
- __ movq(Address(RBP, exception_var().index() * kWordSize),
- kExceptionObjectReg);
- __ movq(Address(RBP, stacktrace_var().index() * kWordSize),
- kStackTraceObjectReg);
+ // Auxiliary variables introduced by the try catch can be captured if we are
+ // inside a function with yield/resume points. In this case we first need
+ // to restore the context to match the context at entry into the closure.
+ if (should_restore_closure_context()) {
+ const ParsedFunction& parsed_function = compiler->parsed_function();
+ ASSERT(parsed_function.function().IsClosureFunction());
+ LocalScope* scope = parsed_function.node_sequence()->scope();
+
+ LocalVariable* closure_parameter = scope->VariableAt(0);
+ ASSERT(!closure_parameter->is_captured());
+ __ movq(CTX, Address(RBP, closure_parameter->index() * kWordSize));
+ __ movq(CTX, FieldAddress(CTX, Closure::context_offset()));
+
+#ifdef DEBUG
+ Label ok;
+ __ LoadClassId(RBX, CTX);
+ __ cmpq(RBX, Immediate(kContextCid));
+ __ j(EQUAL, &ok, Assembler::kNearJump);
+ __ Stop("Incorrect context at entry");
+ __ Bind(&ok);
+#endif
+
+ const intptr_t context_index =
+ parsed_function.current_context_var()->index();
+ __ movq(Address(RBP, context_index * kWordSize), CTX);
+ }
+
+ // Initialize exception and stack trace variables.
+ if (exception_var().is_captured()) {
+ ASSERT(stacktrace_var().is_captured());
+ __ StoreIntoObject(
+ CTX,
+ FieldAddress(CTX, Context::variable_offset(exception_var().index())),
+ kExceptionObjectReg);
+ __ StoreIntoObject(
+ CTX,
+ FieldAddress(CTX, Context::variable_offset(stacktrace_var().index())),
+ kStackTraceObjectReg);
+ } else {
+ __ movq(Address(RBP, exception_var().index() * kWordSize),
+ kExceptionObjectReg);
+ __ movq(Address(RBP, stacktrace_var().index() * kWordSize),
+ kStackTraceObjectReg);
+ }
}
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 908f0f2..7ede2f5 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -813,6 +813,7 @@
gc_prologue_callback_(NULL),
gc_epilogue_callback_(NULL),
defer_finalization_count_(0),
+ pending_deopts_(new MallocGrowableArray<PendingLazyDeopt>),
deopt_context_(NULL),
is_service_isolate_(false),
stacktrace_(NULL),
@@ -838,11 +839,16 @@
boxed_field_list_(GrowableObjectArray::null()),
spawn_count_monitor_(new Monitor()),
spawn_count_(0),
+#define ISOLATE_METRIC_CONSTRUCTORS(type, variable, name, unit) \
+ metric_##variable##_(),
+ ISOLATE_METRIC_LIST(ISOLATE_METRIC_CONSTRUCTORS)
+#undef ISOLATE_METRIC_CONSTRUCTORS
has_attempted_reload_(false),
no_reload_scope_depth_(0),
reload_every_n_stack_overflow_checks_(FLAG_reload_every),
reload_context_(NULL),
- last_reload_timestamp_(OS::GetCurrentTimeMillis()) {
+ last_reload_timestamp_(OS::GetCurrentTimeMillis()),
+ should_pause_post_service_request_(false) {
NOT_IN_PRODUCT(FlagsCopyFrom(api_flags));
// TODO(asiva): A Thread is not available here, need to figure out
// how the vm_tag (kEmbedderTagId) can be set, these tags need to
@@ -878,6 +884,8 @@
constant_canonicalization_mutex_ = NULL;
delete megamorphic_lookup_mutex_;
megamorphic_lookup_mutex_ = NULL;
+ delete pending_deopts_;
+ pending_deopts_ = NULL;
delete message_handler_;
message_handler_ = NULL; // Fail fast if we send messages to a dead isolate.
ASSERT(deopt_context_ == NULL); // No deopt in progress when isolate deleted.
@@ -1041,6 +1049,26 @@
}
+bool Isolate::IsPaused() const {
+ return (debugger_ != NULL) && (debugger_->PauseEvent() != NULL);
+}
+
+
+void Isolate::PausePostRequest() {
+ if (!FLAG_support_debugger) {
+ return;
+ }
+ if (debugger_ == NULL) {
+ return;
+ }
+ ASSERT(!IsPaused());
+ const Error& error = Error::Handle(debugger_->PausePostRequest());
+ if (!error.IsNull()) {
+ Exceptions::PropagateError(error);
+ }
+}
+
+
void Isolate::BuildName(const char* name_prefix) {
ASSERT(name_ == NULL);
if (name_prefix == NULL) {
@@ -1900,6 +1928,45 @@
}
+void Isolate::AddPendingDeopt(uword fp, uword pc) {
+ // GrowableArray::Add is not atomic and may be interrupt by a profiler
+ // stack walk.
+ MallocGrowableArray<PendingLazyDeopt>* old_pending_deopts = pending_deopts_;
+ MallocGrowableArray<PendingLazyDeopt>* new_pending_deopts
+ = new MallocGrowableArray<PendingLazyDeopt>(
+ old_pending_deopts->length() + 1);
+ for (intptr_t i = 0; i < old_pending_deopts->length(); i++) {
+ ASSERT((*old_pending_deopts)[i].fp() != fp);
+ new_pending_deopts->Add((*old_pending_deopts)[i]);
+ }
+ PendingLazyDeopt deopt(fp, pc);
+ new_pending_deopts->Add(deopt);
+
+ pending_deopts_ = new_pending_deopts;
+ delete old_pending_deopts;
+}
+
+
+uword Isolate::FindPendingDeopt(uword fp) const {
+ for (intptr_t i = 0; i < pending_deopts_->length(); i++) {
+ if ((*pending_deopts_)[i].fp() == fp) {
+ return (*pending_deopts_)[i].pc();
+ }
+ }
+ FATAL("Missing pending deopt entry");
+ return 0;
+}
+
+
+void Isolate::ClearPendingDeoptsAtOrBelow(uword fp) const {
+ for (intptr_t i = pending_deopts_->length() - 1; i >= 0; i--) {
+ if ((*pending_deopts_)[i].fp() <= fp) {
+ pending_deopts_->RemoveAt(i);
+ }
+ }
+}
+
+
#ifndef PRODUCT
static const char* ExceptionPauseInfoToServiceEnum(Dart_ExceptionPauseInfo pi) {
switch (pi) {
@@ -1956,8 +2023,8 @@
ASSERT((debugger() == NULL) || (debugger()->PauseEvent() == NULL));
ServiceEvent pause_event(this, ServiceEvent::kPauseStart);
jsobj.AddProperty("pauseEvent", &pause_event);
- } else if (message_handler()->is_paused_on_exit()) {
- ASSERT((debugger() == NULL) || (debugger()->PauseEvent() == NULL));
+ } else if (message_handler()->is_paused_on_exit() &&
+ ((debugger() == NULL) || (debugger()->PauseEvent() == NULL))) {
ServiceEvent pause_event(this, ServiceEvent::kPauseExit);
jsobj.AddProperty("pauseEvent", &pause_event);
} else if ((debugger() != NULL) &&
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 12dd5fa..98b4188 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -19,6 +19,7 @@
#include "vm/os_thread.h"
#include "vm/timer.h"
#include "vm/token_position.h"
+#include "vm/growable_array.h"
namespace dart {
@@ -70,6 +71,19 @@
class UserTag;
+class PendingLazyDeopt {
+ public:
+ PendingLazyDeopt(uword fp, uword pc) : fp_(fp), pc_(pc) { }
+ uword fp() { return fp_; }
+ uword pc() { return pc_; }
+ void set_pc(uword pc) { pc_ = pc; }
+
+ private:
+ uword fp_;
+ uword pc_;
+};
+
+
class IsolateVisitor {
public:
IsolateVisitor() {}
@@ -390,6 +404,12 @@
return object_id_ring_;
}
+ void AddPendingDeopt(uword fp, uword pc);
+ uword FindPendingDeopt(uword fp) const;
+ void ClearPendingDeoptsAtOrBelow(uword fp) const;
+ MallocGrowableArray<PendingLazyDeopt>* pending_deopts() const {
+ return pending_deopts_;
+ }
bool IsDeoptimizing() const { return deopt_context_ != NULL; }
DeoptContext* deopt_context() const { return deopt_context_; }
void set_deopt_context(DeoptContext* value) {
@@ -490,6 +510,18 @@
return last_reload_timestamp_;
}
+ bool IsPaused() const;
+
+ bool should_pause_post_service_request() const {
+ return should_pause_post_service_request_;
+ }
+ void set_should_pause_post_service_request(
+ bool should_pause_post_service_request) {
+ should_pause_post_service_request_ = should_pause_post_service_request;
+ }
+
+ void PausePostRequest();
+
uword user_tag() const {
return user_tag_;
}
@@ -740,6 +772,7 @@
Dart_GcPrologueCallback gc_prologue_callback_;
Dart_GcEpilogueCallback gc_epilogue_callback_;
intptr_t defer_finalization_count_;
+ MallocGrowableArray<PendingLazyDeopt>* pending_deopts_;
DeoptContext* deopt_context_;
bool is_service_isolate_;
@@ -821,6 +854,11 @@
Monitor* spawn_count_monitor_;
intptr_t spawn_count_;
+#define ISOLATE_METRIC_VARIABLE(type, variable, name, unit) \
+ type metric_##variable##_;
+ ISOLATE_METRIC_LIST(ISOLATE_METRIC_VARIABLE);
+#undef ISOLATE_METRIC_VARIABLE
+
// Has a reload ever been attempted?
bool has_attempted_reload_;
intptr_t no_reload_scope_depth_; // we can only reload when this is 0.
@@ -828,12 +866,8 @@
intptr_t reload_every_n_stack_overflow_checks_;
IsolateReloadContext* reload_context_;
int64_t last_reload_timestamp_;
-
-#define ISOLATE_METRIC_VARIABLE(type, variable, name, unit) \
- type metric_##variable##_;
- ISOLATE_METRIC_LIST(ISOLATE_METRIC_VARIABLE);
-#undef ISOLATE_METRIC_VARIABLE
-
+ // Should we pause in the debug message loop after this request?
+ bool should_pause_post_service_request_;
static Dart_IsolateCreateCallback create_callback_;
static Dart_IsolateShutdownCallback shutdown_callback_;
diff --git a/runtime/vm/isolate_reload_test.cc b/runtime/vm/isolate_reload_test.cc
index 4543baa..e33cb97 100644
--- a/runtime/vm/isolate_reload_test.cc
+++ b/runtime/vm/isolate_reload_test.cc
@@ -1536,7 +1536,7 @@
TestCase::SetReloadTestScript(kReloadScript);
- EXPECT_STREQ("4 Class 'C' has no instance getter 'y'.",
+ EXPECT_STREQ("4 NoSuchMethodError: Class 'C' has no instance getter 'y'.",
SimpleInvokeStr(lib, "main"));
lib = TestCase::GetReloadErrorOrRootLibrary();
@@ -1595,8 +1595,8 @@
TestCase::SetReloadTestScript(kReloadScript);
- EXPECT_STREQ("4 No static getter 'y' declared in class 'C'.",
- SimpleInvokeStr(lib, "main"));
+ EXPECT_STREQ("4 NoSuchMethodError: No static getter 'y' declared "
+ "in class 'C'.", SimpleInvokeStr(lib, "main"));
lib = TestCase::GetReloadErrorOrRootLibrary();
EXPECT_VALID(lib);
@@ -1653,7 +1653,7 @@
TestCase::SetReloadTestScript(kScript); // Root library does not change.
- EXPECT_STREQ("4 No top-level getter 'y' declared.",
+ EXPECT_STREQ("4 NoSuchMethodError: No top-level getter 'y' declared.",
SimpleInvokeStr(lib, "main"));
lib = TestCase::GetReloadErrorOrRootLibrary();
@@ -1710,7 +1710,7 @@
TestCase::SetReloadTestScript(kReloadScript);
- EXPECT_STREQ("null Class 'C' has no instance setter 'y='.",
+ EXPECT_STREQ("null NoSuchMethodError: Class 'C' has no instance setter 'y='.",
SimpleInvokeStr(lib, "main"));
lib = TestCase::GetReloadErrorOrRootLibrary();
@@ -1769,8 +1769,8 @@
TestCase::SetReloadTestScript(kReloadScript);
- EXPECT_STREQ("5 No static setter 'y=' declared in class 'C'.",
- SimpleInvokeStr(lib, "main"));
+ EXPECT_STREQ("5 NoSuchMethodError: No static setter 'y=' declared in "
+ "class 'C'.", SimpleInvokeStr(lib, "main"));
lib = TestCase::GetReloadErrorOrRootLibrary();
EXPECT_VALID(lib);
@@ -1827,7 +1827,7 @@
TestCase::SetReloadTestScript(kScript); // Root library does not change.
- EXPECT_STREQ("5 No top-level setter 'y=' declared.",
+ EXPECT_STREQ("5 NoSuchMethodError: No top-level setter 'y=' declared.",
SimpleInvokeStr(lib, "main"));
lib = TestCase::GetReloadErrorOrRootLibrary();
@@ -1883,8 +1883,8 @@
TestCase::SetReloadTestScript(kReloadScript);
- EXPECT_STREQ("1 Class 'C' has no instance method 'foo' with matching"
- " arguments.", SimpleInvokeStr(lib, "main"));
+ EXPECT_STREQ("1 NoSuchMethodError: Class 'C' has no instance method "
+ "'foo' with matching arguments.", SimpleInvokeStr(lib, "main"));
lib = TestCase::GetReloadErrorOrRootLibrary();
EXPECT_VALID(lib);
@@ -1937,8 +1937,8 @@
TestCase::SetReloadTestScript(kReloadScript);
- EXPECT_STREQ("1 Closure call with mismatched arguments: function 'C.foo'",
- SimpleInvokeStr(lib, "main"));
+ EXPECT_STREQ("1 NoSuchMethodError: Closure call with mismatched arguments: "
+ "function 'C.foo'", SimpleInvokeStr(lib, "main"));
lib = TestCase::GetReloadErrorOrRootLibrary();
EXPECT_VALID(lib);
diff --git a/runtime/vm/kernel.cc b/runtime/vm/kernel.cc
new file mode 100644
index 0000000..340b60d
--- /dev/null
+++ b/runtime/vm/kernel.cc
@@ -0,0 +1,1205 @@
+// 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.
+
+#include "vm/kernel.h"
+
+namespace dart {
+
+namespace kernel {
+
+
+template <typename T>
+void VisitList(List<T>* list, Visitor* visitor) {
+ for (int i = 0; i < list->length(); ++i) {
+ (*list)[i]->AcceptVisitor(visitor);
+ }
+}
+
+
+Node::~Node() {}
+
+
+TreeNode::~TreeNode() {}
+
+
+void TreeNode::AcceptVisitor(Visitor* visitor) { AcceptTreeVisitor(visitor); }
+
+
+Library::~Library() {}
+
+
+void Library::AcceptTreeVisitor(TreeVisitor* visitor) {
+ visitor->VisitLibrary(this);
+}
+
+
+void Library::VisitChildren(Visitor* visitor) {
+ VisitList(&classes(), visitor);
+ VisitList(&procedures(), visitor);
+ VisitList(&fields(), visitor);
+}
+
+
+Class::~Class() {}
+
+
+void Class::AcceptTreeVisitor(TreeVisitor* visitor) {
+ AcceptClassVisitor(visitor);
+}
+
+
+NormalClass::~NormalClass() {}
+
+
+void NormalClass::AcceptClassVisitor(ClassVisitor* visitor) {
+ visitor->VisitNormalClass(this);
+}
+
+
+void NormalClass::AcceptReferenceVisitor(ClassReferenceVisitor* visitor) {
+ visitor->VisitNormalClassReference(this);
+}
+
+
+void NormalClass::VisitChildren(Visitor* visitor) {
+ VisitList(&type_parameters(), visitor);
+ if (super_class() != NULL) visitor->VisitInterfaceType(super_class());
+ VisitList(&implemented_classes(), visitor);
+ VisitList(&constructors(), visitor);
+ VisitList(&procedures(), visitor);
+ VisitList(&fields(), visitor);
+}
+
+
+MixinClass::~MixinClass() {}
+
+
+void MixinClass::AcceptClassVisitor(ClassVisitor* visitor) {
+ visitor->VisitMixinClass(this);
+}
+
+
+void MixinClass::AcceptReferenceVisitor(ClassReferenceVisitor* visitor) {
+ visitor->VisitMixinClassReference(this);
+}
+
+
+void MixinClass::VisitChildren(Visitor* visitor) {
+ VisitList(&type_parameters(), visitor);
+ visitor->VisitInterfaceType(first());
+ visitor->VisitInterfaceType(second());
+ VisitList(&implemented_classes(), visitor);
+ VisitList(&constructors(), visitor);
+}
+
+
+Member::~Member() {}
+
+
+void Member::AcceptTreeVisitor(TreeVisitor* visitor) {
+ AcceptMemberVisitor(visitor);
+}
+
+
+Field::~Field() {}
+
+
+void Field::AcceptMemberVisitor(MemberVisitor* visitor) {
+ visitor->VisitField(this);
+}
+
+
+void Field::AcceptReferenceVisitor(MemberReferenceVisitor* visitor) {
+ visitor->VisitFieldReference(this);
+}
+
+
+void Field::VisitChildren(Visitor* visitor) {
+ type()->AcceptDartTypeVisitor(visitor);
+ visitor->VisitName(name());
+ if (initializer() != NULL) initializer()->AcceptExpressionVisitor(visitor);
+}
+
+
+Constructor::~Constructor() {}
+
+
+void Constructor::AcceptMemberVisitor(MemberVisitor* visitor) {
+ visitor->VisitConstructor(this);
+}
+
+
+void Constructor::AcceptReferenceVisitor(MemberReferenceVisitor* visitor) {
+ visitor->VisitConstructorReference(this);
+}
+
+
+void Constructor::VisitChildren(Visitor* visitor) {
+ visitor->VisitName(name());
+ visitor->VisitFunctionNode(function());
+ VisitList(&initializers(), visitor);
+}
+
+
+Procedure::~Procedure() {}
+
+
+void Procedure::AcceptMemberVisitor(MemberVisitor* visitor) {
+ visitor->VisitProcedure(this);
+}
+
+
+void Procedure::AcceptReferenceVisitor(MemberReferenceVisitor* visitor) {
+ visitor->VisitProcedureReference(this);
+}
+
+
+void Procedure::VisitChildren(Visitor* visitor) {
+ visitor->VisitName(name());
+ if (function() != NULL) visitor->VisitFunctionNode(function());
+}
+
+
+Initializer::~Initializer() {}
+
+
+void Initializer::AcceptTreeVisitor(TreeVisitor* visitor) {
+ AcceptInitializerVisitor(visitor);
+}
+
+
+InvalidInitializer::~InvalidInitializer() {}
+
+
+void InvalidInitializer::AcceptInitializerVisitor(InitializerVisitor* visitor) {
+ visitor->VisitInvalidInitializer(this);
+}
+
+
+void InvalidInitializer::VisitChildren(Visitor* visitor) {}
+
+
+FieldInitializer::~FieldInitializer() {}
+
+
+void FieldInitializer::AcceptInitializerVisitor(InitializerVisitor* visitor) {
+ visitor->VisitFieldInitializer(this);
+}
+
+
+void FieldInitializer::VisitChildren(Visitor* visitor) {
+ visitor->VisitFieldReference(field());
+ value()->AcceptExpressionVisitor(visitor);
+}
+
+
+SuperInitializer::~SuperInitializer() {}
+
+
+void SuperInitializer::AcceptInitializerVisitor(InitializerVisitor* visitor) {
+ visitor->VisitSuperInitializer(this);
+}
+
+
+void SuperInitializer::VisitChildren(Visitor* visitor) {
+ visitor->VisitConstructorReference(target());
+ visitor->VisitArguments(arguments());
+}
+
+
+RedirectingInitializer::~RedirectingInitializer() {}
+
+
+void RedirectingInitializer::AcceptInitializerVisitor(
+ InitializerVisitor* visitor) {
+ visitor->VisitRedirectingInitializer(this);
+}
+
+
+void RedirectingInitializer::VisitChildren(Visitor* visitor) {
+ visitor->VisitConstructorReference(target());
+ visitor->VisitArguments(arguments());
+}
+
+
+LocalInitializer::~LocalInitializer() {}
+
+
+void LocalInitializer::AcceptInitializerVisitor(InitializerVisitor* visitor) {
+ visitor->VisitLocalInitializer(this);
+}
+
+
+void LocalInitializer::VisitChildren(Visitor* visitor) {
+ visitor->VisitVariableDeclaration(variable());
+}
+
+
+FunctionNode::~FunctionNode() {}
+
+
+void FunctionNode::AcceptTreeVisitor(TreeVisitor* visitor) {
+ visitor->VisitFunctionNode(this);
+}
+
+
+void FunctionNode::VisitChildren(Visitor* visitor) {
+ VisitList(&type_parameters(), visitor);
+ VisitList(&positional_parameters(), visitor);
+ VisitList(&named_parameters(), visitor);
+ if (return_type() != NULL) return_type()->AcceptDartTypeVisitor(visitor);
+ if (body() != NULL) body()->AcceptStatementVisitor(visitor);
+}
+
+
+Expression::~Expression() {}
+
+
+void Expression::AcceptTreeVisitor(TreeVisitor* visitor) {
+ AcceptExpressionVisitor(visitor);
+}
+
+
+InvalidExpression::~InvalidExpression() {}
+
+
+void InvalidExpression::AcceptExpressionVisitor(ExpressionVisitor* visitor) {
+ visitor->VisitInvalidExpression(this);
+}
+
+
+void InvalidExpression::VisitChildren(Visitor* visitor) {}
+
+
+VariableGet::~VariableGet() {}
+
+
+void VariableGet::AcceptExpressionVisitor(ExpressionVisitor* visitor) {
+ visitor->VisitVariableGet(this);
+}
+
+
+void VariableGet::VisitChildren(Visitor* visitor) {}
+
+
+VariableSet::~VariableSet() {}
+
+
+void VariableSet::AcceptExpressionVisitor(ExpressionVisitor* visitor) {
+ visitor->VisitVariableSet(this);
+}
+
+
+void VariableSet::VisitChildren(Visitor* visitor) {
+ expression()->AcceptExpressionVisitor(visitor);
+}
+
+
+PropertyGet::~PropertyGet() {}
+
+
+void PropertyGet::AcceptExpressionVisitor(ExpressionVisitor* visitor) {
+ visitor->VisitPropertyGet(this);
+}
+
+
+void PropertyGet::VisitChildren(Visitor* visitor) {
+ receiver()->AcceptExpressionVisitor(visitor);
+ visitor->VisitName(name());
+}
+
+
+PropertySet::~PropertySet() {}
+
+
+void PropertySet::AcceptExpressionVisitor(ExpressionVisitor* visitor) {
+ visitor->VisitPropertySet(this);
+}
+
+
+void PropertySet::VisitChildren(Visitor* visitor) {
+ receiver()->AcceptExpressionVisitor(visitor);
+ visitor->VisitName(name());
+ value()->AcceptExpressionVisitor(visitor);
+}
+
+
+DirectPropertyGet::~DirectPropertyGet() {}
+
+
+void DirectPropertyGet::AcceptExpressionVisitor(ExpressionVisitor* visitor) {
+ visitor->VisitDirectPropertyGet(this);
+}
+
+
+void DirectPropertyGet::VisitChildren(Visitor* visitor) {
+ receiver()->AcceptExpressionVisitor(visitor);
+ target()->AcceptReferenceVisitor(visitor);
+}
+
+
+DirectPropertySet::~DirectPropertySet() {}
+
+
+void DirectPropertySet::AcceptExpressionVisitor(ExpressionVisitor* visitor) {
+ visitor->VisitDirectPropertySet(this);
+}
+
+
+void DirectPropertySet::VisitChildren(Visitor* visitor) {
+ receiver()->AcceptExpressionVisitor(visitor);
+ target()->AcceptReferenceVisitor(visitor);
+ value()->AcceptExpressionVisitor(visitor);
+}
+
+
+StaticGet::~StaticGet() {}
+
+
+void StaticGet::AcceptExpressionVisitor(ExpressionVisitor* visitor) {
+ visitor->VisitStaticGet(this);
+}
+
+
+void StaticGet::VisitChildren(Visitor* visitor) {
+ target()->AcceptReferenceVisitor(visitor);
+}
+
+
+StaticSet::~StaticSet() {}
+
+
+void StaticSet::AcceptExpressionVisitor(ExpressionVisitor* visitor) {
+ visitor->VisitStaticSet(this);
+}
+
+
+void StaticSet::VisitChildren(Visitor* visitor) {
+ target()->AcceptReferenceVisitor(visitor);
+ expression()->AcceptExpressionVisitor(visitor);
+}
+
+
+Arguments::~Arguments() {}
+
+
+void Arguments::AcceptTreeVisitor(TreeVisitor* visitor) {
+ visitor->VisitArguments(this);
+}
+
+
+void Arguments::VisitChildren(Visitor* visitor) {
+ VisitList(&types(), visitor);
+ VisitList(&positional(), visitor);
+ VisitList(&named(), visitor);
+}
+
+
+NamedExpression::~NamedExpression() {}
+
+
+void NamedExpression::AcceptTreeVisitor(TreeVisitor* visitor) {
+ visitor->VisitNamedExpression(this);
+}
+
+
+void NamedExpression::VisitChildren(Visitor* visitor) {
+ expression()->AcceptExpressionVisitor(visitor);
+}
+
+
+MethodInvocation::~MethodInvocation() {}
+
+
+void MethodInvocation::AcceptExpressionVisitor(ExpressionVisitor* visitor) {
+ visitor->VisitMethodInvocation(this);
+}
+
+
+void MethodInvocation::VisitChildren(Visitor* visitor) {
+ receiver()->AcceptExpressionVisitor(visitor);
+ visitor->VisitName(name());
+ visitor->VisitArguments(arguments());
+}
+
+
+DirectMethodInvocation::~DirectMethodInvocation() {}
+
+
+void DirectMethodInvocation::AcceptExpressionVisitor(
+ ExpressionVisitor* visitor) {
+ visitor->VisitDirectMethodInvocation(this);
+}
+
+
+void DirectMethodInvocation::VisitChildren(Visitor* visitor) {
+ receiver()->AcceptExpressionVisitor(visitor);
+ visitor->VisitProcedureReference(target());
+ visitor->VisitArguments(arguments());
+}
+
+
+StaticInvocation::~StaticInvocation() {}
+
+
+void StaticInvocation::AcceptExpressionVisitor(ExpressionVisitor* visitor) {
+ visitor->VisitStaticInvocation(this);
+}
+
+
+void StaticInvocation::VisitChildren(Visitor* visitor) {
+ visitor->VisitProcedureReference(procedure());
+ visitor->VisitArguments(arguments());
+}
+
+
+ConstructorInvocation::~ConstructorInvocation() {}
+
+
+void ConstructorInvocation::AcceptExpressionVisitor(
+ ExpressionVisitor* visitor) {
+ visitor->VisitConstructorInvocation(this);
+}
+
+
+void ConstructorInvocation::VisitChildren(Visitor* visitor) {
+ visitor->VisitConstructorReference(target());
+ visitor->VisitArguments(arguments());
+}
+
+
+Not::~Not() {}
+
+
+void Not::AcceptExpressionVisitor(ExpressionVisitor* visitor) {
+ visitor->VisitNot(this);
+}
+
+
+void Not::VisitChildren(Visitor* visitor) {
+ expression()->AcceptExpressionVisitor(visitor);
+}
+
+
+LogicalExpression::~LogicalExpression() {}
+
+
+void LogicalExpression::AcceptExpressionVisitor(ExpressionVisitor* visitor) {
+ visitor->VisitLogicalExpression(this);
+}
+
+
+void LogicalExpression::VisitChildren(Visitor* visitor) {
+ left()->AcceptExpressionVisitor(visitor);
+ right()->AcceptExpressionVisitor(visitor);
+}
+
+
+ConditionalExpression::~ConditionalExpression() {}
+
+
+void ConditionalExpression::AcceptExpressionVisitor(
+ ExpressionVisitor* visitor) {
+ visitor->VisitConditionalExpression(this);
+}
+
+
+void ConditionalExpression::VisitChildren(Visitor* visitor) {
+ condition()->AcceptExpressionVisitor(visitor);
+ then()->AcceptExpressionVisitor(visitor);
+ otherwise()->AcceptExpressionVisitor(visitor);
+}
+
+
+StringConcatenation::~StringConcatenation() {}
+
+
+void StringConcatenation::AcceptExpressionVisitor(ExpressionVisitor* visitor) {
+ visitor->VisitStringConcatenation(this);
+}
+
+
+void StringConcatenation::VisitChildren(Visitor* visitor) {
+ VisitList(&expressions(), visitor);
+}
+
+
+IsExpression::~IsExpression() {}
+
+
+void IsExpression::AcceptExpressionVisitor(ExpressionVisitor* visitor) {
+ visitor->VisitIsExpression(this);
+}
+
+
+void IsExpression::VisitChildren(Visitor* visitor) {
+ operand()->AcceptExpressionVisitor(visitor);
+ type()->AcceptDartTypeVisitor(visitor);
+}
+
+
+AsExpression::~AsExpression() {}
+
+
+void AsExpression::AcceptExpressionVisitor(ExpressionVisitor* visitor) {
+ visitor->VisitAsExpression(this);
+}
+
+
+void AsExpression::VisitChildren(Visitor* visitor) {
+ operand()->AcceptExpressionVisitor(visitor);
+ type()->AcceptDartTypeVisitor(visitor);
+}
+
+
+BasicLiteral::~BasicLiteral() {}
+
+
+void BasicLiteral::VisitChildren(Visitor* visitor) {}
+
+
+StringLiteral::~StringLiteral() {}
+
+
+void StringLiteral::AcceptExpressionVisitor(ExpressionVisitor* visitor) {
+ visitor->VisitStringLiteral(this);
+}
+
+
+BigintLiteral::~BigintLiteral() {}
+
+
+void BigintLiteral::AcceptExpressionVisitor(ExpressionVisitor* visitor) {
+ visitor->VisitBigintLiteral(this);
+}
+
+
+IntLiteral::~IntLiteral() {}
+
+
+void IntLiteral::AcceptExpressionVisitor(ExpressionVisitor* visitor) {
+ visitor->VisitIntLiteral(this);
+}
+
+
+DoubleLiteral::~DoubleLiteral() {}
+
+
+void DoubleLiteral::AcceptExpressionVisitor(ExpressionVisitor* visitor) {
+ visitor->VisitDoubleLiteral(this);
+}
+
+
+BoolLiteral::~BoolLiteral() {}
+
+
+void BoolLiteral::AcceptExpressionVisitor(ExpressionVisitor* visitor) {
+ visitor->VisitBoolLiteral(this);
+}
+
+
+NullLiteral::~NullLiteral() {}
+
+
+void NullLiteral::AcceptExpressionVisitor(ExpressionVisitor* visitor) {
+ visitor->VisitNullLiteral(this);
+}
+
+
+SymbolLiteral::~SymbolLiteral() {}
+
+
+void SymbolLiteral::AcceptExpressionVisitor(ExpressionVisitor* visitor) {
+ visitor->VisitSymbolLiteral(this);
+}
+
+
+void SymbolLiteral::VisitChildren(Visitor* visitor) {}
+
+
+TypeLiteral::~TypeLiteral() {}
+
+
+void TypeLiteral::AcceptExpressionVisitor(ExpressionVisitor* visitor) {
+ visitor->VisitTypeLiteral(this);
+}
+
+
+void TypeLiteral::VisitChildren(Visitor* visitor) {
+ type()->AcceptDartTypeVisitor(visitor);
+}
+
+
+ThisExpression::~ThisExpression() {}
+
+
+void ThisExpression::AcceptExpressionVisitor(ExpressionVisitor* visitor) {
+ visitor->VisitThisExpression(this);
+}
+
+
+void ThisExpression::VisitChildren(Visitor* visitor) {}
+
+
+Rethrow::~Rethrow() {}
+
+
+void Rethrow::AcceptExpressionVisitor(ExpressionVisitor* visitor) {
+ visitor->VisitRethrow(this);
+}
+
+
+void Rethrow::VisitChildren(Visitor* visitor) {}
+
+
+Throw::~Throw() {}
+
+
+void Throw::AcceptExpressionVisitor(ExpressionVisitor* visitor) {
+ visitor->VisitThrow(this);
+}
+
+
+void Throw::VisitChildren(Visitor* visitor) {
+ expression()->AcceptExpressionVisitor(visitor);
+}
+
+
+ListLiteral::~ListLiteral() {}
+
+
+void ListLiteral::AcceptExpressionVisitor(ExpressionVisitor* visitor) {
+ visitor->VisitListLiteral(this);
+}
+
+
+void ListLiteral::VisitChildren(Visitor* visitor) {
+ type()->AcceptDartTypeVisitor(visitor);
+ VisitList(&expressions(), visitor);
+}
+
+
+MapLiteral::~MapLiteral() {}
+
+
+void MapLiteral::AcceptExpressionVisitor(ExpressionVisitor* visitor) {
+ visitor->VisitMapLiteral(this);
+}
+
+
+void MapLiteral::VisitChildren(Visitor* visitor) {
+ key_type()->AcceptDartTypeVisitor(visitor);
+ value_type()->AcceptDartTypeVisitor(visitor);
+ VisitList(&entries(), visitor);
+}
+
+
+MapEntry::~MapEntry() {}
+
+
+void MapEntry::AcceptTreeVisitor(TreeVisitor* visitor) {
+ visitor->VisitMapEntry(this);
+}
+
+
+void MapEntry::VisitChildren(Visitor* visitor) {
+ key()->AcceptExpressionVisitor(visitor);
+ value()->AcceptExpressionVisitor(visitor);
+}
+
+
+AwaitExpression::~AwaitExpression() {}
+
+
+void AwaitExpression::AcceptExpressionVisitor(ExpressionVisitor* visitor) {
+ visitor->VisitAwaitExpression(this);
+}
+
+
+void AwaitExpression::VisitChildren(Visitor* visitor) {
+ operand()->AcceptExpressionVisitor(visitor);
+}
+
+
+FunctionExpression::~FunctionExpression() {}
+
+
+void FunctionExpression::AcceptExpressionVisitor(ExpressionVisitor* visitor) {
+ visitor->VisitFunctionExpression(this);
+}
+
+
+void FunctionExpression::VisitChildren(Visitor* visitor) {
+ visitor->VisitFunctionNode(function());
+}
+
+
+Let::~Let() {}
+
+
+void Let::AcceptExpressionVisitor(ExpressionVisitor* visitor) {
+ visitor->VisitLet(this);
+}
+
+
+void Let::VisitChildren(Visitor* visitor) {
+ visitor->VisitVariableDeclaration(variable());
+ body()->AcceptExpressionVisitor(visitor);
+}
+
+
+BlockExpression::~BlockExpression() {}
+
+
+void BlockExpression::AcceptExpressionVisitor(ExpressionVisitor* visitor) {
+ visitor->VisitBlockExpression(this);
+}
+
+
+void BlockExpression::VisitChildren(Visitor* visitor) {
+ visitor->VisitBlock(body());
+ value()->AcceptExpressionVisitor(visitor);
+}
+
+
+Statement::~Statement() {}
+
+
+void Statement::AcceptTreeVisitor(TreeVisitor* visitor) {
+ AcceptStatementVisitor(visitor);
+}
+
+
+InvalidStatement::~InvalidStatement() {}
+
+
+void InvalidStatement::AcceptStatementVisitor(StatementVisitor* visitor) {
+ visitor->VisitInvalidStatement(this);
+}
+
+
+void InvalidStatement::VisitChildren(Visitor* visitor) {}
+
+
+ExpressionStatement::~ExpressionStatement() {}
+
+
+void ExpressionStatement::AcceptStatementVisitor(StatementVisitor* visitor) {
+ visitor->VisitExpressionStatement(this);
+}
+
+
+void ExpressionStatement::VisitChildren(Visitor* visitor) {
+ expression()->AcceptExpressionVisitor(visitor);
+}
+
+
+Block::~Block() {}
+
+
+void Block::AcceptStatementVisitor(StatementVisitor* visitor) {
+ visitor->VisitBlock(this);
+}
+
+
+void Block::VisitChildren(Visitor* visitor) {
+ VisitList(&statements(), visitor);
+}
+
+
+EmptyStatement::~EmptyStatement() {}
+
+
+void EmptyStatement::AcceptStatementVisitor(StatementVisitor* visitor) {
+ visitor->VisitEmptyStatement(this);
+}
+
+
+void EmptyStatement::VisitChildren(Visitor* visitor) {}
+
+
+AssertStatement::~AssertStatement() {}
+
+
+void AssertStatement::AcceptStatementVisitor(StatementVisitor* visitor) {
+ visitor->VisitAssertStatement(this);
+}
+
+
+void AssertStatement::VisitChildren(Visitor* visitor) {
+ condition()->AcceptExpressionVisitor(visitor);
+ if (message() != NULL) message()->AcceptExpressionVisitor(visitor);
+}
+
+
+LabeledStatement::~LabeledStatement() {}
+
+
+void LabeledStatement::AcceptStatementVisitor(StatementVisitor* visitor) {
+ visitor->VisitLabeledStatement(this);
+}
+
+
+void LabeledStatement::VisitChildren(Visitor* visitor) {
+ body()->AcceptStatementVisitor(visitor);
+}
+
+
+BreakStatement::~BreakStatement() {}
+
+
+void BreakStatement::AcceptStatementVisitor(StatementVisitor* visitor) {
+ visitor->VisitBreakStatement(this);
+}
+
+
+void BreakStatement::VisitChildren(Visitor* visitor) {}
+
+
+WhileStatement::~WhileStatement() {}
+
+
+void WhileStatement::AcceptStatementVisitor(StatementVisitor* visitor) {
+ visitor->VisitWhileStatement(this);
+}
+
+
+void WhileStatement::VisitChildren(Visitor* visitor) {
+ condition()->AcceptExpressionVisitor(visitor);
+ body()->AcceptStatementVisitor(visitor);
+}
+
+
+DoStatement::~DoStatement() {}
+
+
+void DoStatement::AcceptStatementVisitor(StatementVisitor* visitor) {
+ visitor->VisitDoStatement(this);
+}
+
+
+void DoStatement::VisitChildren(Visitor* visitor) {
+ body()->AcceptStatementVisitor(visitor);
+ condition()->AcceptExpressionVisitor(visitor);
+}
+
+
+ForStatement::~ForStatement() {}
+
+
+void ForStatement::AcceptStatementVisitor(StatementVisitor* visitor) {
+ visitor->VisitForStatement(this);
+}
+
+
+void ForStatement::VisitChildren(Visitor* visitor) {
+ VisitList(&variables(), visitor);
+ if (condition() != NULL) condition()->AcceptExpressionVisitor(visitor);
+ VisitList(&updates(), visitor);
+ body()->AcceptStatementVisitor(visitor);
+}
+
+
+ForInStatement::~ForInStatement() {}
+
+
+void ForInStatement::AcceptStatementVisitor(StatementVisitor* visitor) {
+ visitor->VisitForInStatement(this);
+}
+
+
+void ForInStatement::VisitChildren(Visitor* visitor) {
+ visitor->VisitVariableDeclaration(variable());
+ iterable()->AcceptExpressionVisitor(visitor);
+ body()->AcceptStatementVisitor(visitor);
+}
+
+
+SwitchStatement::~SwitchStatement() {}
+
+
+void SwitchStatement::AcceptStatementVisitor(StatementVisitor* visitor) {
+ visitor->VisitSwitchStatement(this);
+}
+
+
+void SwitchStatement::VisitChildren(Visitor* visitor) {
+ condition()->AcceptExpressionVisitor(visitor);
+ VisitList(&cases(), visitor);
+}
+
+
+SwitchCase::~SwitchCase() {}
+
+
+void SwitchCase::AcceptTreeVisitor(TreeVisitor* visitor) {
+ visitor->VisitSwitchCase(this);
+}
+
+
+void SwitchCase::VisitChildren(Visitor* visitor) {
+ VisitList(&expressions(), visitor);
+ body()->AcceptStatementVisitor(visitor);
+}
+
+
+ContinueSwitchStatement::~ContinueSwitchStatement() {}
+
+
+void ContinueSwitchStatement::AcceptStatementVisitor(
+ StatementVisitor* visitor) {
+ visitor->VisitContinueSwitchStatement(this);
+}
+
+
+void ContinueSwitchStatement::VisitChildren(Visitor* visitor) {}
+
+
+IfStatement::~IfStatement() {}
+
+
+void IfStatement::AcceptStatementVisitor(StatementVisitor* visitor) {
+ visitor->VisitIfStatement(this);
+}
+
+
+void IfStatement::VisitChildren(Visitor* visitor) {
+ condition()->AcceptExpressionVisitor(visitor);
+ then()->AcceptStatementVisitor(visitor);
+ otherwise()->AcceptStatementVisitor(visitor);
+}
+
+
+ReturnStatement::~ReturnStatement() {}
+
+
+void ReturnStatement::AcceptStatementVisitor(StatementVisitor* visitor) {
+ visitor->VisitReturnStatement(this);
+}
+
+
+void ReturnStatement::VisitChildren(Visitor* visitor) {
+ if (expression() != NULL) expression()->AcceptExpressionVisitor(visitor);
+}
+
+
+TryCatch::~TryCatch() {}
+
+
+void TryCatch::AcceptStatementVisitor(StatementVisitor* visitor) {
+ visitor->VisitTryCatch(this);
+}
+
+
+void TryCatch::VisitChildren(Visitor* visitor) {
+ body()->AcceptStatementVisitor(visitor);
+ VisitList(&catches(), visitor);
+}
+
+
+Catch::~Catch() {}
+
+
+void Catch::AcceptTreeVisitor(TreeVisitor* visitor) {
+ visitor->VisitCatch(this);
+}
+
+
+void Catch::VisitChildren(Visitor* visitor) {
+ if (guard() != NULL) guard()->AcceptDartTypeVisitor(visitor);
+ if (exception() != NULL) visitor->VisitVariableDeclaration(exception());
+ if (stack_trace() != NULL) visitor->VisitVariableDeclaration(stack_trace());
+ body()->AcceptStatementVisitor(visitor);
+}
+
+
+TryFinally::~TryFinally() {}
+
+
+void TryFinally::AcceptStatementVisitor(StatementVisitor* visitor) {
+ visitor->VisitTryFinally(this);
+}
+
+
+void TryFinally::VisitChildren(Visitor* visitor) {
+ body()->AcceptStatementVisitor(visitor);
+ finalizer()->AcceptStatementVisitor(visitor);
+}
+
+
+YieldStatement::~YieldStatement() {}
+
+
+void YieldStatement::AcceptStatementVisitor(StatementVisitor* visitor) {
+ visitor->VisitYieldStatement(this);
+}
+
+
+void YieldStatement::VisitChildren(Visitor* visitor) {
+ expression()->AcceptExpressionVisitor(visitor);
+}
+
+
+VariableDeclaration::~VariableDeclaration() {}
+
+
+void VariableDeclaration::AcceptStatementVisitor(StatementVisitor* visitor) {
+ visitor->VisitVariableDeclaration(this);
+}
+
+
+void VariableDeclaration::VisitChildren(Visitor* visitor) {
+ if (type() != NULL) type()->AcceptDartTypeVisitor(visitor);
+ if (initializer() != NULL) initializer()->AcceptExpressionVisitor(visitor);
+}
+
+
+FunctionDeclaration::~FunctionDeclaration() {}
+
+
+void FunctionDeclaration::AcceptStatementVisitor(StatementVisitor* visitor) {
+ visitor->VisitFunctionDeclaration(this);
+}
+
+
+void FunctionDeclaration::VisitChildren(Visitor* visitor) {
+ visitor->VisitVariableDeclaration(variable());
+ visitor->VisitFunctionNode(function());
+}
+
+
+Name::~Name() {}
+
+
+void Name::AcceptVisitor(Visitor* visitor) { visitor->VisitName(this); }
+
+
+void Name::VisitChildren(Visitor* visitor) {}
+
+
+InferredValue::~InferredValue() {}
+
+
+void InferredValue::AcceptVisitor(Visitor* visitor) {
+ visitor->VisitInferredValue(this);
+}
+
+
+void InferredValue::VisitChildren(Visitor* visitor) {}
+
+
+DartType::~DartType() {}
+
+
+void DartType::AcceptVisitor(Visitor* visitor) {
+ AcceptDartTypeVisitor(visitor);
+}
+
+
+InvalidType::~InvalidType() {}
+
+
+void InvalidType::AcceptDartTypeVisitor(DartTypeVisitor* visitor) {
+ visitor->VisitInvalidType(this);
+}
+
+
+void InvalidType::VisitChildren(Visitor* visitor) {}
+
+
+DynamicType::~DynamicType() {}
+
+
+void DynamicType::AcceptDartTypeVisitor(DartTypeVisitor* visitor) {
+ visitor->VisitDynamicType(this);
+}
+
+
+void DynamicType::VisitChildren(Visitor* visitor) {}
+
+
+VoidType::~VoidType() {}
+
+
+void VoidType::AcceptDartTypeVisitor(DartTypeVisitor* visitor) {
+ visitor->VisitVoidType(this);
+}
+
+
+void VoidType::VisitChildren(Visitor* visitor) {}
+
+
+InterfaceType::~InterfaceType() {}
+
+
+void InterfaceType::AcceptDartTypeVisitor(DartTypeVisitor* visitor) {
+ visitor->VisitInterfaceType(this);
+}
+
+
+void InterfaceType::VisitChildren(Visitor* visitor) {
+ klass()->AcceptReferenceVisitor(visitor);
+ VisitList(&type_arguments(), visitor);
+}
+
+
+FunctionType::~FunctionType() {}
+
+
+void FunctionType::AcceptDartTypeVisitor(DartTypeVisitor* visitor) {
+ visitor->VisitFunctionType(this);
+}
+
+
+void FunctionType::VisitChildren(Visitor* visitor) {
+ VisitList(&type_parameters(), visitor);
+ VisitList(&positional_parameters(), visitor);
+ for (int i = 0; i < named_parameters().length(); ++i) {
+ named_parameters()[i]->second()->AcceptDartTypeVisitor(visitor);
+ }
+ return_type()->AcceptDartTypeVisitor(visitor);
+}
+
+
+TypeParameterType::~TypeParameterType() {}
+
+
+void TypeParameterType::AcceptDartTypeVisitor(DartTypeVisitor* visitor) {
+ visitor->VisitTypeParameterType(this);
+}
+
+
+void TypeParameterType::VisitChildren(Visitor* visitor) {}
+
+
+TypeParameter::~TypeParameter() {}
+
+
+void TypeParameter::AcceptTreeVisitor(TreeVisitor* visitor) {
+ visitor->VisitTypeParameter(this);
+}
+
+
+void TypeParameter::VisitChildren(Visitor* visitor) {
+ bound()->AcceptDartTypeVisitor(visitor);
+}
+
+
+Program::~Program() {}
+
+
+void Program::AcceptTreeVisitor(TreeVisitor* visitor) {
+ visitor->VisitProgram(this);
+}
+
+
+void Program::VisitChildren(Visitor* visitor) {
+ VisitList(&libraries(), visitor);
+ visitor->VisitProcedureReference(main_method());
+}
+
+
+} // namespace kernel
+
+} // namespace dart
diff --git a/runtime/vm/kernel.h b/runtime/vm/kernel.h
new file mode 100644
index 0000000..b6038fc
--- /dev/null
+++ b/runtime/vm/kernel.h
@@ -0,0 +1,3243 @@
+// 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.
+
+#ifndef VM_KERNEL_H_
+#define VM_KERNEL_H_
+
+#include "platform/assert.h"
+#include "vm/allocation.h"
+#include "vm/globals.h"
+
+#define KERNEL_NODES_DO(M) \
+ M(Name) \
+ M(InferredValue) \
+ M(DartType) \
+ M(InvalidType) \
+ M(DynamicType) \
+ M(VoidType) \
+ M(InterfaceType) \
+ M(FunctionType) \
+ M(TypeParameterType)
+
+#define KERNEL_TREE_NODES_DO(M) \
+ M(Library) \
+ M(Class) \
+ M(NormalClass) \
+ M(MixinClass) \
+ M(Member) \
+ M(Field) \
+ M(Constructor) \
+ M(Procedure) \
+ M(Initializer) \
+ M(InvalidInitializer) \
+ M(FieldInitializer) \
+ M(SuperInitializer) \
+ M(RedirectingInitializer) \
+ M(LocalInitializer) \
+ M(FunctionNode) \
+ M(Expression) \
+ M(InvalidExpression) \
+ M(VariableGet) \
+ M(VariableSet) \
+ M(PropertyGet) \
+ M(PropertySet) \
+ M(DirectPropertyGet) \
+ M(DirectPropertySet) \
+ M(StaticGet) \
+ M(StaticSet) \
+ M(Arguments) \
+ M(NamedExpression) \
+ M(MethodInvocation) \
+ M(DirectMethodInvocation) \
+ M(StaticInvocation) \
+ M(ConstructorInvocation) \
+ M(Not) \
+ M(LogicalExpression) \
+ M(ConditionalExpression) \
+ M(StringConcatenation) \
+ M(IsExpression) \
+ M(AsExpression) \
+ M(BasicLiteral) \
+ M(StringLiteral) \
+ M(BigintLiteral) \
+ M(IntLiteral) \
+ M(DoubleLiteral) \
+ M(BoolLiteral) \
+ M(NullLiteral) \
+ M(SymbolLiteral) \
+ M(TypeLiteral) \
+ M(ThisExpression) \
+ M(Rethrow) \
+ M(Throw) \
+ M(ListLiteral) \
+ M(MapLiteral) \
+ M(MapEntry) \
+ M(AwaitExpression) \
+ M(FunctionExpression) \
+ M(Let) \
+ M(BlockExpression) \
+ M(Statement) \
+ M(InvalidStatement) \
+ M(ExpressionStatement) \
+ M(Block) \
+ M(EmptyStatement) \
+ M(AssertStatement) \
+ M(LabeledStatement) \
+ M(BreakStatement) \
+ M(WhileStatement) \
+ M(DoStatement) \
+ M(ForStatement) \
+ M(ForInStatement) \
+ M(SwitchStatement) \
+ M(SwitchCase) \
+ M(ContinueSwitchStatement) \
+ M(IfStatement) \
+ M(ReturnStatement) \
+ M(TryCatch) \
+ M(Catch) \
+ M(TryFinally) \
+ M(YieldStatement) \
+ M(VariableDeclaration) \
+ M(FunctionDeclaration) \
+ M(TypeParameter) \
+ M(Program)
+
+#define KERNEL_ALL_NODES_DO(M) \
+ M(Node) \
+ KERNEL_NODES_DO(M) \
+ M(TreeNode) \
+ KERNEL_TREE_NODES_DO(M)
+
+#define KERNEL_VISITORS_DO(M) \
+ M(ExpressionVisitor) \
+ M(StatementVisitor) \
+ M(MemberVisitor) \
+ M(ClassVisitor) \
+ M(InitializerVisitor) \
+ M(DartTypeVisitor) \
+ M(ClassReferenceVisitor) \
+ M(MemberReferenceVisitor) \
+ M(TreeVisitor) \
+ M(Visitor)
+
+namespace dart {
+
+namespace kernel {
+
+
+class Reader;
+class TreeNode;
+class TypeParameter;
+class Writer;
+
+// Boxes a value of type `T*` and `delete`s it on destruction.
+template <typename T>
+class Child {
+ public:
+ Child() : pointer_(NULL) {}
+ explicit Child(T* value) : pointer_(value) {}
+
+ ~Child() { delete pointer_; }
+
+ // Support `Child<T> box = T* obj`.
+ T*& operator=(T* value) {
+ ASSERT(pointer_ == NULL);
+ return pointer_ = value;
+ }
+
+ // Implicitly convert `Child<T>` to `T*`.
+ operator T*&() { return pointer_; }
+
+ T* operator->() { return pointer_; }
+
+ private:
+ T* pointer_;
+};
+
+// Boxes a value of type `T*` (only used to mark a member as a weak reference).
+template <typename T>
+class Ref {
+ public:
+ Ref() : pointer_(NULL) {}
+ explicit Ref(T* value) : pointer_(value) {}
+
+ // Support `Ref<T> box = T* obj`.
+ T*& operator=(T* value) {
+ ASSERT(pointer_ == NULL);
+ return pointer_ = value;
+ }
+
+ // Implicitly convert `Ref<T>` to `T*`.
+ operator T*&() { return pointer_; }
+
+ T* operator->() { return pointer_; }
+
+ private:
+ T* pointer_;
+};
+
+
+template <typename T>
+class List {
+ public:
+ List() : array_(NULL), length_(0) {}
+ ~List();
+
+ template <typename IT>
+ void ReadFrom(Reader* reader);
+
+ template <typename IT>
+ void ReadFrom(Reader* reader, TreeNode* parent);
+
+ template <typename IT>
+ void ReadFromStatic(Reader* reader);
+
+ void WriteTo(Writer* writer);
+
+ template <typename IT>
+ void WriteToStatic(Writer* writer);
+
+ // Extends the array to at least be able to hold [length] elements.
+ //
+ // Free places will be filled with `NULL` values.
+ void EnsureInitialized(int length);
+
+ // Returns element at [index].
+ //
+ // If the array is not big enough, it will be grown via `EnsureInitialized`.
+ // If the element doesn't exist, it will be created via `new IT()`.
+ template <typename IT>
+ IT* GetOrCreate(int index);
+
+ template <typename IT, typename PT>
+ IT* GetOrCreate(int index, PT* parent);
+
+ // Returns element at [index].
+ T*& operator[](int index) {
+ ASSERT(index < length_);
+ return array_[index];
+ }
+
+ int length() { return length_; }
+
+ T** raw_array() { return array_; }
+
+ private:
+ T** array_;
+ int length_;
+
+ DISALLOW_COPY_AND_ASSIGN(List);
+};
+
+
+class TypeParameterList : public List<TypeParameter> {
+ public:
+ void ReadFrom(Reader* reader);
+ void WriteTo(Writer* writer);
+};
+
+
+template <typename A, typename B>
+class Tuple {
+ public:
+ static Tuple<A, B>* ReadFrom(Reader* reader);
+ void WriteTo(Writer* writer);
+
+ Tuple(A* a, B* b) : first_(a), second_(b) {}
+
+ A* first() { return first_; }
+ B* second() { return second_; }
+
+ private:
+ Tuple() {}
+
+ Ref<A> first_;
+ Child<B> second_;
+
+ DISALLOW_COPY_AND_ASSIGN(Tuple);
+};
+
+
+class String {
+ public:
+ static String* ReadFrom(Reader* reader);
+ static String* ReadFromImpl(Reader* reader);
+ void WriteTo(Writer* writer);
+ void WriteToImpl(Writer* writer);
+
+ String(const uint8_t* utf8, int length) {
+ buffer_ = new uint8_t[length];
+ size_ = length;
+ memmove(buffer_, utf8, length);
+ }
+ ~String() { delete[] buffer_; }
+
+ uint8_t* buffer() { return buffer_; }
+ int size() { return size_; }
+
+ bool is_empty() { return size_ == 0; }
+
+ private:
+ uint8_t* buffer_;
+ int size_;
+
+ DISALLOW_COPY_AND_ASSIGN(String);
+};
+
+
+class StringTable {
+ public:
+ void ReadFrom(Reader* reader);
+ void WriteTo(Writer* writer);
+
+ List<String>& strings() { return strings_; }
+
+ private:
+ StringTable() {}
+
+ friend class Program;
+
+ List<String> strings_;
+
+ DISALLOW_COPY_AND_ASSIGN(StringTable);
+};
+
+
+class LineStartingTable {
+ public:
+ void ReadFrom(Reader* reader, intptr_t length);
+ void WriteTo(Writer* writer);
+ ~LineStartingTable() {
+ for (intptr_t i = 0; i < size_; ++i) {
+ delete[] values_[i];
+ }
+ delete[] values_;
+ }
+
+ intptr_t size() { return size_; }
+ intptr_t* valuesFor(int i) { return values_[i]; }
+
+ private:
+ LineStartingTable() : values_(NULL), size_(0) {}
+
+ friend class Program;
+
+ intptr_t** values_;
+ intptr_t size_;
+
+ DISALLOW_COPY_AND_ASSIGN(LineStartingTable);
+};
+
+// Forward declare all classes.
+#define DO(name) class name;
+KERNEL_ALL_NODES_DO(DO)
+KERNEL_VISITORS_DO(DO)
+#undef DO
+
+
+#define DEFINE_CASTING_OPERATIONS(klass) \
+ virtual bool Is##klass() { return true; } \
+ \
+ static klass* Cast(Node* node) { \
+ ASSERT(node == NULL || node->Is##klass()); \
+ return static_cast<klass*>(node); \
+ } \
+ \
+ virtual Node::NodeType Type() { return Node::kType##klass; }
+
+#define DEFINE_IS_OPERATION(klass) \
+ virtual bool Is##klass() { return false; }
+
+#define DEFINE_ALL_IS_OPERATIONS() \
+ KERNEL_NODES_DO(DEFINE_IS_OPERATION) \
+ DEFINE_IS_OPERATION(TreeNode) \
+ KERNEL_TREE_NODES_DO(DEFINE_IS_OPERATION)
+
+
+class Node {
+ public:
+ virtual ~Node();
+
+ enum NodeType {
+#define DO(name) kType##name,
+ KERNEL_ALL_NODES_DO(DO)
+#undef DO
+
+ kNumTypes
+ };
+
+ DEFINE_ALL_IS_OPERATIONS();
+ DEFINE_CASTING_OPERATIONS(Node);
+
+ virtual void AcceptVisitor(Visitor* visitor) = 0;
+ virtual void VisitChildren(Visitor* visitor) = 0;
+
+ protected:
+ Node() { }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Node);
+};
+
+
+class TreeNode : public Node {
+ public:
+ virtual ~TreeNode();
+
+ DEFINE_CASTING_OPERATIONS(TreeNode);
+
+ virtual void AcceptVisitor(Visitor* visitor);
+ virtual void AcceptTreeVisitor(TreeVisitor* visitor) = 0;
+
+ protected:
+ TreeNode() {}
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(TreeNode);
+};
+
+
+class Library : public TreeNode {
+ public:
+ Library* ReadFrom(Reader* reader);
+ void WriteTo(Writer* writer);
+
+ virtual ~Library();
+
+ DEFINE_CASTING_OPERATIONS(Library);
+
+ virtual void AcceptTreeVisitor(TreeVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ String* import_uri() { return import_uri_; }
+ String* name() { return name_; }
+ List<Class>& classes() { return classes_; }
+ List<Field>& fields() { return fields_; }
+ List<Procedure>& procedures() { return procedures_; }
+
+ bool IsCorelibrary() {
+ static const char* dart_library = "dart:";
+ static intptr_t dart_library_length = strlen(dart_library);
+ static const char* patch_library = "dart:_patch";
+ static intptr_t patch_library_length = strlen(patch_library);
+
+ if (name_->size() < 5) return false;
+
+ // Check for dart: prefix.
+ char* buffer = reinterpret_cast<char*>(import_uri_->buffer());
+ if (strncmp(buffer, dart_library, dart_library_length) != 0) {
+ return false;
+ }
+
+ // Rasta emits dart:_patch and we should treat it as a user library.
+ if (name_->size() == patch_library_length &&
+ strncmp(buffer, patch_library, patch_library_length) == 0) {
+ return false;
+ }
+ return true;
+ }
+
+ private:
+ Library() : name_(NULL) {}
+
+ template <typename T>
+ friend class List;
+
+ Ref<String> name_;
+ Ref<String> import_uri_;
+ List<Class> classes_;
+ List<Field> fields_;
+ List<Procedure> procedures_;
+
+ DISALLOW_COPY_AND_ASSIGN(Library);
+};
+
+
+class Class : public TreeNode {
+ public:
+ Class* ReadFrom(Reader* reader);
+ void WriteTo(Writer* writer);
+
+ virtual ~Class();
+
+ DEFINE_CASTING_OPERATIONS(Class);
+
+ virtual void AcceptTreeVisitor(TreeVisitor* visitor);
+ virtual void AcceptClassVisitor(ClassVisitor* visitor) = 0;
+ virtual void AcceptReferenceVisitor(ClassReferenceVisitor* visitor) = 0;
+
+ Library* parent() { return parent_; }
+ String* name() { return name_; }
+ bool is_abstract() { return is_abstract_; }
+ List<Expression>& annotations() { return annotations_; }
+
+ virtual List<TypeParameter>& type_parameters() = 0;
+ virtual List<InterfaceType>& implemented_classes() = 0;
+ virtual List<Field>& fields() = 0;
+ virtual List<Constructor>& constructors() = 0;
+ virtual List<Procedure>& procedures() = 0;
+
+ protected:
+ Class() : is_abstract_(false) {}
+
+ private:
+ template <typename T>
+ friend class List;
+
+ Ref<Library> parent_;
+ Ref<String> name_;
+ bool is_abstract_;
+ List<Expression> annotations_;
+
+ DISALLOW_COPY_AND_ASSIGN(Class);
+};
+
+
+class NormalClass : public Class {
+ public:
+ NormalClass* ReadFrom(Reader* reader);
+ void WriteTo(Writer* writer);
+
+ virtual ~NormalClass();
+
+ DEFINE_CASTING_OPERATIONS(NormalClass);
+
+ virtual void AcceptClassVisitor(ClassVisitor* visitor);
+ virtual void AcceptReferenceVisitor(ClassReferenceVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ virtual TypeParameterList& type_parameters() { return type_parameters_; }
+ InterfaceType* super_class() { return super_class_; }
+ virtual List<InterfaceType>& implemented_classes() {
+ return implemented_classes_;
+ }
+ virtual List<Constructor>& constructors() { return constructors_; }
+ virtual List<Procedure>& procedures() { return procedures_; }
+ virtual List<Field>& fields() { return fields_; }
+
+ private:
+ NormalClass() {}
+
+ template <typename T>
+ friend class List;
+
+ TypeParameterList type_parameters_;
+ Child<InterfaceType> super_class_;
+ List<InterfaceType> implemented_classes_;
+ List<Constructor> constructors_;
+ List<Procedure> procedures_;
+ List<Field> fields_;
+
+ DISALLOW_COPY_AND_ASSIGN(NormalClass);
+};
+
+
+class MixinClass : public Class {
+ public:
+ MixinClass* ReadFrom(Reader* reader);
+ void WriteTo(Writer* writer);
+
+ virtual ~MixinClass();
+
+ DEFINE_CASTING_OPERATIONS(MixinClass);
+
+ virtual void AcceptClassVisitor(ClassVisitor* visitor);
+ virtual void AcceptReferenceVisitor(ClassReferenceVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ virtual TypeParameterList& type_parameters() { return type_parameters_; }
+ InterfaceType* first() { return first_; }
+ InterfaceType* second() { return second_; }
+ virtual List<InterfaceType>& implemented_classes() {
+ return implemented_classes_;
+ }
+ virtual List<Constructor>& constructors() { return constructors_; }
+ virtual List<Field>& fields() { return fields_; }
+ virtual List<Procedure>& procedures() { return procedures_; }
+
+ private:
+ MixinClass() {}
+
+ template <typename T>
+ friend class List;
+
+ TypeParameterList type_parameters_;
+ Child<InterfaceType> first_;
+ Child<InterfaceType> second_;
+ List<InterfaceType> implemented_classes_;
+ List<Constructor> constructors_;
+
+ // Dummy instances which are empty lists.
+ List<Field> fields_;
+ List<Procedure> procedures_;
+
+ DISALLOW_COPY_AND_ASSIGN(MixinClass);
+};
+
+
+class Member : public TreeNode {
+ public:
+ virtual ~Member();
+
+ DEFINE_CASTING_OPERATIONS(Member);
+
+ virtual void AcceptTreeVisitor(TreeVisitor* visitor);
+ virtual void AcceptMemberVisitor(MemberVisitor* visitor) = 0;
+ virtual void AcceptReferenceVisitor(MemberReferenceVisitor* visitor) = 0;
+
+ TreeNode* parent() { return parent_; }
+ Name* name() { return name_; }
+ List<Expression>& annotations() { return annotations_; }
+
+ protected:
+ Member() { }
+
+ template <typename T>
+ friend class List;
+
+ Ref<TreeNode> parent_;
+ Child<Name> name_;
+ List<Expression> annotations_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Member);
+};
+
+
+class Field : public Member {
+ public:
+ enum Flags {
+ kFlagFinal = 1 << 0,
+ kFlagConst = 1 << 1,
+ kFlagStatic = 1 << 2,
+ };
+
+ Field* ReadFrom(Reader* reader);
+ void WriteTo(Writer* writer);
+
+ virtual ~Field();
+
+ DEFINE_CASTING_OPERATIONS(Field);
+
+ virtual void AcceptMemberVisitor(MemberVisitor* visitor);
+ virtual void AcceptReferenceVisitor(MemberReferenceVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ bool IsConst() { return (flags_ & kFlagConst) == kFlagConst; }
+ bool IsFinal() { return (flags_ & kFlagFinal) == kFlagFinal; }
+ bool IsStatic() { return (flags_ & kFlagStatic) == kFlagStatic; }
+
+ DartType* type() { return type_; }
+ InferredValue* inferred_value() { return inferred_value_; }
+ Expression* initializer() { return initializer_; }
+
+ private:
+ Field() {}
+
+ template <typename T>
+ friend class List;
+
+ word flags_;
+ Child<DartType> type_;
+ Child<InferredValue> inferred_value_;
+ Child<Expression> initializer_;
+
+ DISALLOW_COPY_AND_ASSIGN(Field);
+};
+
+
+class Constructor : public Member {
+ public:
+ enum Flags {
+ kFlagConst = 1 << 0,
+ kFlagExternal = 1 << 1,
+ };
+
+ Constructor* ReadFrom(Reader* reader);
+ void WriteTo(Writer* writer);
+
+ virtual ~Constructor();
+
+ DEFINE_CASTING_OPERATIONS(Constructor);
+
+ virtual void AcceptMemberVisitor(MemberVisitor* visitor);
+ virtual void AcceptReferenceVisitor(MemberReferenceVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ bool IsExternal() { return (flags_ & kFlagExternal) == kFlagExternal; }
+ bool IsConst() { return (flags_ & kFlagConst) == kFlagConst; }
+
+ FunctionNode* function() { return function_; }
+ List<Initializer>& initializers() { return initializers_; }
+
+ private:
+ template <typename T>
+ friend class List;
+
+ Constructor() {}
+
+ uint8_t flags_;
+ Child<FunctionNode> function_;
+ List<Initializer> initializers_;
+
+ DISALLOW_COPY_AND_ASSIGN(Constructor);
+};
+
+
+class Procedure : public Member {
+ public:
+ enum Flags {
+ kFlagStatic = 1 << 0,
+ kFlagAbstract = 1 << 1,
+ kFlagExternal = 1 << 2,
+ kFlagConst = 1 << 3, // Only for external const factories.
+ };
+
+ // Keep in sync with package:dynamo/lib/ast.dart:ProcedureKind
+ enum ProcedureKind {
+ kMethod,
+ kGetter,
+ kSetter,
+ kOperator,
+ kFactory,
+
+ kIncompleteProcedure = 255
+ };
+
+ Procedure* ReadFrom(Reader* reader);
+ void WriteTo(Writer* writer);
+
+ virtual ~Procedure();
+
+ DEFINE_CASTING_OPERATIONS(Procedure);
+
+ virtual void AcceptMemberVisitor(MemberVisitor* visitor);
+ virtual void AcceptReferenceVisitor(MemberReferenceVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ ProcedureKind kind() { return kind_; }
+ FunctionNode* function() { return function_; }
+
+ bool IsStatic() { return (flags_ & kFlagStatic) == kFlagStatic; }
+ bool IsAbstract() { return (flags_ & kFlagAbstract) == kFlagAbstract; }
+ bool IsExternal() { return (flags_ & kFlagExternal) == kFlagExternal; }
+ bool IsConst() { return (flags_ & kFlagConst) == kFlagConst; }
+
+ private:
+ Procedure() : kind_(kIncompleteProcedure), flags_(0), function_(NULL) {}
+
+ template <typename T>
+ friend class List;
+
+ ProcedureKind kind_;
+ word flags_;
+ Child<FunctionNode> function_;
+
+ DISALLOW_COPY_AND_ASSIGN(Procedure);
+};
+
+
+class Initializer : public TreeNode {
+ public:
+ static Initializer* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer) = 0;
+
+ virtual ~Initializer();
+
+ DEFINE_CASTING_OPERATIONS(Initializer);
+
+ virtual void AcceptTreeVisitor(TreeVisitor* visitor);
+ virtual void AcceptInitializerVisitor(InitializerVisitor* visitor) = 0;
+
+ protected:
+ Initializer() { }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Initializer);
+};
+
+
+class InvalidInitializer : public Initializer {
+ public:
+ static InvalidInitializer* ReadFromImpl(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~InvalidInitializer();
+
+ DEFINE_CASTING_OPERATIONS(InvalidInitializer);
+ virtual void AcceptInitializerVisitor(InitializerVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ private:
+ InvalidInitializer() { }
+
+ DISALLOW_COPY_AND_ASSIGN(InvalidInitializer);
+};
+
+
+class FieldInitializer : public Initializer {
+ public:
+ static FieldInitializer* ReadFromImpl(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~FieldInitializer();
+
+ DEFINE_CASTING_OPERATIONS(FieldInitializer);
+
+ virtual void AcceptInitializerVisitor(InitializerVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ Field* field() { return field_; }
+ Expression* value() { return value_; }
+
+ private:
+ FieldInitializer() {}
+
+ Ref<Field> field_;
+ Child<Expression> value_;
+
+ DISALLOW_COPY_AND_ASSIGN(FieldInitializer);
+};
+
+
+class SuperInitializer : public Initializer {
+ public:
+ static SuperInitializer* ReadFromImpl(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~SuperInitializer();
+
+ DEFINE_CASTING_OPERATIONS(SuperInitializer);
+
+ virtual void AcceptInitializerVisitor(InitializerVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ Constructor* target() { return target_; }
+ Arguments* arguments() { return arguments_; }
+
+ private:
+ SuperInitializer() {}
+
+ Ref<Constructor> target_;
+ Child<Arguments> arguments_;
+
+ DISALLOW_COPY_AND_ASSIGN(SuperInitializer);
+};
+
+
+class RedirectingInitializer : public Initializer {
+ public:
+ static RedirectingInitializer* ReadFromImpl(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~RedirectingInitializer();
+
+ DEFINE_CASTING_OPERATIONS(RedirectingInitializer);
+
+ virtual void AcceptInitializerVisitor(InitializerVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ Constructor* target() { return target_; }
+ Arguments* arguments() { return arguments_; }
+
+ private:
+ RedirectingInitializer() {}
+
+ Ref<Constructor> target_;
+ Child<Arguments> arguments_;
+
+ DISALLOW_COPY_AND_ASSIGN(RedirectingInitializer);
+};
+
+
+class LocalInitializer : public Initializer {
+ public:
+ static LocalInitializer* ReadFromImpl(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~LocalInitializer();
+
+ DEFINE_CASTING_OPERATIONS(LocalInitializer);
+
+ virtual void AcceptInitializerVisitor(InitializerVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ VariableDeclaration* variable() { return variable_; }
+
+ private:
+ LocalInitializer() {}
+
+ Child<VariableDeclaration> variable_;
+
+ DISALLOW_COPY_AND_ASSIGN(LocalInitializer);
+};
+
+
+class FunctionNode : public TreeNode {
+ public:
+ enum AsyncMarker {
+ kSync = 0,
+ kSyncStar = 1,
+ kAsync = 2,
+ kAsyncStar = 3,
+ kSyncYielding = 4,
+ };
+
+ static FunctionNode* ReadFrom(Reader* reader);
+ void WriteTo(Writer* writer);
+
+ virtual ~FunctionNode();
+
+ DEFINE_CASTING_OPERATIONS(FunctionNode);
+
+ virtual void AcceptTreeVisitor(TreeVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ AsyncMarker async_marker() { return async_marker_; }
+ TypeParameterList& type_parameters() { return type_parameters_; }
+ int required_parameter_count() { return required_parameter_count_; }
+ List<VariableDeclaration>& positional_parameters() {
+ return positional_parameters_;
+ }
+ List<VariableDeclaration>& named_parameters() { return named_parameters_; }
+ DartType* return_type() { return return_type_; }
+ InferredValue* inferred_return_value() { return inferred_return_value_; }
+ Statement* body() { return body_; }
+
+ private:
+ FunctionNode() {}
+
+ AsyncMarker async_marker_;
+ TypeParameterList type_parameters_;
+ int required_parameter_count_;
+ List<VariableDeclaration> positional_parameters_;
+ List<VariableDeclaration> named_parameters_;
+ Child<DartType> return_type_;
+ Child<InferredValue> inferred_return_value_;
+ Child<Statement> body_;
+
+ DISALLOW_COPY_AND_ASSIGN(FunctionNode);
+};
+
+
+class Expression : public TreeNode {
+ public:
+ static Expression* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer) = 0;
+
+ virtual ~Expression();
+
+ DEFINE_CASTING_OPERATIONS(Expression);
+
+ virtual void AcceptTreeVisitor(TreeVisitor* visitor);
+ virtual void AcceptExpressionVisitor(ExpressionVisitor* visitor) = 0;
+
+ protected:
+ Expression() { }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Expression);
+};
+
+
+class InvalidExpression : public Expression {
+ public:
+ static InvalidExpression* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~InvalidExpression();
+ virtual void VisitChildren(Visitor* visitor);
+
+ DEFINE_CASTING_OPERATIONS(InvalidExpression);
+
+ virtual void AcceptExpressionVisitor(ExpressionVisitor* visitor);
+
+ private:
+ InvalidExpression() { }
+
+ DISALLOW_COPY_AND_ASSIGN(InvalidExpression);
+};
+
+
+class VariableGet : public Expression {
+ public:
+ static VariableGet* ReadFrom(Reader* reader);
+ static VariableGet* ReadFrom(Reader* reader, uint8_t payload);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~VariableGet();
+
+ DEFINE_CASTING_OPERATIONS(VariableGet);
+
+ virtual void AcceptExpressionVisitor(ExpressionVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ VariableDeclaration* variable() { return variable_; }
+
+ private:
+ VariableGet() {}
+
+ Ref<VariableDeclaration> variable_;
+
+ DISALLOW_COPY_AND_ASSIGN(VariableGet);
+};
+
+
+class VariableSet : public Expression {
+ public:
+ static VariableSet* ReadFrom(Reader* reader);
+ static VariableSet* ReadFrom(Reader* reader, uint8_t payload);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~VariableSet();
+
+ DEFINE_CASTING_OPERATIONS(VariableSet);
+
+ virtual void AcceptExpressionVisitor(ExpressionVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ VariableDeclaration* variable() { return variable_; }
+ Expression* expression() { return expression_; }
+
+ private:
+ VariableSet() {}
+
+ Ref<VariableDeclaration> variable_;
+ Child<Expression> expression_;
+
+ DISALLOW_COPY_AND_ASSIGN(VariableSet);
+};
+
+
+class PropertyGet : public Expression {
+ public:
+ static PropertyGet* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~PropertyGet();
+
+ DEFINE_CASTING_OPERATIONS(PropertyGet);
+
+ virtual void AcceptExpressionVisitor(ExpressionVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ Expression* receiver() { return receiver_; }
+ Name* name() { return name_; }
+
+ private:
+ PropertyGet() {}
+
+ Child<Expression> receiver_;
+ Child<Name> name_;
+ Ref<Member> interfaceTarget_;
+
+ DISALLOW_COPY_AND_ASSIGN(PropertyGet);
+};
+
+
+class PropertySet : public Expression {
+ public:
+ static PropertySet* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~PropertySet();
+
+ DEFINE_CASTING_OPERATIONS(PropertySet);
+
+ virtual void AcceptExpressionVisitor(ExpressionVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ Expression* receiver() { return receiver_; }
+ Name* name() { return name_; }
+ Expression* value() { return value_; }
+
+ private:
+ PropertySet() {}
+
+ Child<Expression> receiver_;
+ Child<Name> name_;
+ Child<Expression> value_;
+ Ref<Member> interfaceTarget_;
+
+ DISALLOW_COPY_AND_ASSIGN(PropertySet);
+};
+
+
+class DirectPropertyGet : public Expression {
+ public:
+ static DirectPropertyGet* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~DirectPropertyGet();
+
+ DEFINE_CASTING_OPERATIONS(DirectPropertyGet);
+
+ virtual void AcceptExpressionVisitor(ExpressionVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ Expression* receiver() { return receiver_; }
+ Member* target() { return target_; }
+
+ private:
+ DirectPropertyGet() {}
+
+ Child<Expression> receiver_;
+ Ref<Member> target_;
+
+ DISALLOW_COPY_AND_ASSIGN(DirectPropertyGet);
+};
+
+
+class DirectPropertySet : public Expression {
+ public:
+ static DirectPropertySet* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~DirectPropertySet();
+
+ DEFINE_CASTING_OPERATIONS(DirectPropertySet);
+
+ virtual void AcceptExpressionVisitor(ExpressionVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ Expression* receiver() { return receiver_; }
+ Member* target() { return target_; }
+ Expression* value() { return value_; }
+
+ private:
+ DirectPropertySet() {}
+
+ Child<Expression> receiver_;
+ Ref<Member> target_;
+ Child<Expression> value_;
+
+ DISALLOW_COPY_AND_ASSIGN(DirectPropertySet);
+};
+
+
+class StaticGet : public Expression {
+ public:
+ static StaticGet* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~StaticGet();
+
+ DEFINE_CASTING_OPERATIONS(StaticGet);
+
+ virtual void AcceptExpressionVisitor(ExpressionVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ Member* target() { return target_; }
+
+ private:
+ StaticGet() {}
+
+ Ref<Member> target_;
+
+ DISALLOW_COPY_AND_ASSIGN(StaticGet);
+};
+
+
+class StaticSet : public Expression {
+ public:
+ static StaticSet* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~StaticSet();
+
+ DEFINE_CASTING_OPERATIONS(StaticSet);
+
+ virtual void AcceptExpressionVisitor(ExpressionVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ Member* target() { return target_; }
+ Expression* expression() { return expression_; }
+
+ private:
+ StaticSet() {}
+
+ Ref<Member> target_;
+ Child<Expression> expression_;
+
+ DISALLOW_COPY_AND_ASSIGN(StaticSet);
+};
+
+
+class Arguments : public TreeNode {
+ public:
+ static Arguments* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~Arguments();
+
+ DEFINE_CASTING_OPERATIONS(Arguments);
+
+ virtual void AcceptTreeVisitor(TreeVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ List<DartType>& types() { return types_; }
+ List<Expression>& positional() { return positional_; }
+ List<NamedExpression>& named() { return named_; }
+
+ int count() { return positional_.length() + named_.length(); }
+
+ private:
+ Arguments() {}
+
+ List<DartType> types_;
+ List<Expression> positional_;
+ List<NamedExpression> named_;
+
+ DISALLOW_COPY_AND_ASSIGN(Arguments);
+};
+
+
+class NamedExpression : public TreeNode {
+ public:
+ static NamedExpression* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ NamedExpression(String* name, Expression* expr)
+ : name_(name), expression_(expr) {}
+ virtual ~NamedExpression();
+
+ DEFINE_CASTING_OPERATIONS(NamedExpression);
+
+ virtual void AcceptTreeVisitor(TreeVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ String* name() { return name_; }
+ Expression* expression() { return expression_; }
+
+ private:
+ NamedExpression() {}
+
+ Ref<String> name_;
+ Child<Expression> expression_;
+
+ DISALLOW_COPY_AND_ASSIGN(NamedExpression);
+};
+
+
+class MethodInvocation : public Expression {
+ public:
+ static MethodInvocation* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~MethodInvocation();
+
+ DEFINE_CASTING_OPERATIONS(MethodInvocation);
+
+ virtual void AcceptExpressionVisitor(ExpressionVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ Expression* receiver() { return receiver_; }
+ Name* name() { return name_; }
+ Arguments* arguments() { return arguments_; }
+
+ private:
+ MethodInvocation() {}
+
+ Child<Expression> receiver_;
+ Child<Name> name_;
+ Child<Arguments> arguments_;
+ Ref<Member> interfaceTarget_;
+
+ DISALLOW_COPY_AND_ASSIGN(MethodInvocation);
+};
+
+
+class DirectMethodInvocation : public Expression {
+ public:
+ static DirectMethodInvocation* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~DirectMethodInvocation();
+
+ DEFINE_CASTING_OPERATIONS(DirectMethodInvocation);
+
+ virtual void AcceptExpressionVisitor(ExpressionVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ Expression* receiver() { return receiver_; }
+ Procedure* target() { return target_; }
+ Arguments* arguments() { return arguments_; }
+
+ private:
+ DirectMethodInvocation() {}
+
+ Child<Expression> receiver_;
+ Ref<Procedure> target_;
+ Child<Arguments> arguments_;
+
+ DISALLOW_COPY_AND_ASSIGN(DirectMethodInvocation);
+};
+
+
+class StaticInvocation : public Expression {
+ public:
+ static StaticInvocation* ReadFrom(Reader* reader, bool is_const);
+ virtual void WriteTo(Writer* writer);
+
+ explicit StaticInvocation(Procedure* procedure, Arguments* args,
+ bool is_const)
+ : procedure_(procedure), arguments_(args), is_const_(is_const) {}
+ ~StaticInvocation();
+
+ virtual void AcceptExpressionVisitor(ExpressionVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ Procedure* procedure() { return procedure_; }
+ Arguments* arguments() { return arguments_; }
+ bool is_const() { return is_const_; }
+
+ private:
+ StaticInvocation() {}
+
+ Ref<Procedure> procedure_;
+ Child<Arguments> arguments_;
+ bool is_const_;
+
+ DISALLOW_COPY_AND_ASSIGN(StaticInvocation);
+};
+
+
+class ConstructorInvocation : public Expression {
+ public:
+ static ConstructorInvocation* ReadFrom(Reader* reader, bool is_const);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~ConstructorInvocation();
+
+ DEFINE_CASTING_OPERATIONS(ConstructorInvocation);
+
+ virtual void AcceptExpressionVisitor(ExpressionVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ bool is_const() { return is_const_; }
+ Constructor* target() { return target_; }
+ Arguments* arguments() { return arguments_; }
+
+ private:
+ ConstructorInvocation() {}
+
+ bool is_const_;
+ Ref<Constructor> target_;
+ Child<Arguments> arguments_;
+
+ DISALLOW_COPY_AND_ASSIGN(ConstructorInvocation);
+};
+
+
+class Not : public Expression {
+ public:
+ static Not* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~Not();
+
+ DEFINE_CASTING_OPERATIONS(Not);
+
+ virtual void AcceptExpressionVisitor(ExpressionVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ Expression* expression() { return expression_; }
+
+ private:
+ Not() {}
+
+ Child<Expression> expression_;
+
+ DISALLOW_COPY_AND_ASSIGN(Not);
+};
+
+
+class LogicalExpression : public Expression {
+ public:
+ enum Operator { kAnd, kOr };
+
+ static LogicalExpression* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~LogicalExpression();
+
+ DEFINE_CASTING_OPERATIONS(LogicalExpression);
+
+ virtual void AcceptExpressionVisitor(ExpressionVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ Expression* left() { return left_; }
+ Operator op() { return operator_; }
+ Expression* right() { return right_; }
+
+ private:
+ LogicalExpression() {}
+
+ Child<Expression> left_;
+ Operator operator_;
+ Child<Expression> right_;
+
+ DISALLOW_COPY_AND_ASSIGN(LogicalExpression);
+};
+
+
+class ConditionalExpression : public Expression {
+ public:
+ static ConditionalExpression* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~ConditionalExpression();
+
+ DEFINE_CASTING_OPERATIONS(ConditionalExpression);
+
+ virtual void AcceptExpressionVisitor(ExpressionVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ Expression* condition() { return condition_; }
+ Expression* then() { return then_; }
+ Expression* otherwise() { return otherwise_; }
+
+ private:
+ ConditionalExpression() {}
+
+ Child<Expression> condition_;
+ Child<Expression> then_;
+ Child<Expression> otherwise_;
+
+ DISALLOW_COPY_AND_ASSIGN(ConditionalExpression);
+};
+
+
+class StringConcatenation : public Expression {
+ public:
+ static StringConcatenation* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~StringConcatenation();
+
+ DEFINE_CASTING_OPERATIONS(StringConcatenation);
+
+ virtual void AcceptExpressionVisitor(ExpressionVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ List<Expression>& expressions() { return expressions_; }
+
+ private:
+ StringConcatenation() {}
+
+ List<Expression> expressions_;
+
+ DISALLOW_COPY_AND_ASSIGN(StringConcatenation);
+};
+
+
+class IsExpression : public Expression {
+ public:
+ static IsExpression* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~IsExpression();
+
+ DEFINE_CASTING_OPERATIONS(IsExpression);
+
+ virtual void AcceptExpressionVisitor(ExpressionVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ Expression* operand() { return operand_; }
+ DartType* type() { return type_; }
+
+ private:
+ IsExpression() {}
+
+ Child<Expression> operand_;
+ Child<DartType> type_;
+
+ DISALLOW_COPY_AND_ASSIGN(IsExpression);
+};
+
+
+class AsExpression : public Expression {
+ public:
+ static AsExpression* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~AsExpression();
+
+ DEFINE_CASTING_OPERATIONS(AsExpression);
+
+ virtual void AcceptExpressionVisitor(ExpressionVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ Expression* operand() { return operand_; }
+ DartType* type() { return type_; }
+
+ private:
+ AsExpression() {}
+
+ Child<Expression> operand_;
+ Child<DartType> type_;
+
+ DISALLOW_COPY_AND_ASSIGN(AsExpression);
+};
+
+
+class BasicLiteral : public Expression {
+ public:
+ virtual ~BasicLiteral();
+
+ DEFINE_CASTING_OPERATIONS(BasicLiteral);
+
+ virtual void VisitChildren(Visitor* visitor);
+};
+
+
+class StringLiteral : public BasicLiteral {
+ public:
+ static StringLiteral* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual void AcceptExpressionVisitor(ExpressionVisitor* visitor);
+
+ explicit StringLiteral(String* string) : value_(string) {}
+ virtual ~StringLiteral();
+
+ DEFINE_CASTING_OPERATIONS(StringLiteral);
+
+ String* value() { return value_; }
+
+ protected:
+ StringLiteral() {}
+
+ Ref<String> value_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(StringLiteral);
+};
+
+
+class BigintLiteral : public StringLiteral {
+ public:
+ static BigintLiteral* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual void AcceptExpressionVisitor(ExpressionVisitor* visitor);
+
+ explicit BigintLiteral(String* string) : StringLiteral(string) {}
+ virtual ~BigintLiteral();
+
+ DEFINE_CASTING_OPERATIONS(BigintLiteral);
+
+ private:
+ BigintLiteral() {}
+
+ DISALLOW_COPY_AND_ASSIGN(BigintLiteral);
+};
+
+
+class IntLiteral : public BasicLiteral {
+ public:
+ static IntLiteral* ReadFrom(Reader* reader, bool is_negative);
+ static IntLiteral* ReadFrom(Reader* reader, uint8_t payload);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~IntLiteral();
+
+ DEFINE_CASTING_OPERATIONS(IntLiteral);
+
+ virtual void AcceptExpressionVisitor(ExpressionVisitor* visitor);
+
+ int64_t value() { return value_; }
+
+ private:
+ IntLiteral() {}
+
+ int64_t value_;
+
+ DISALLOW_COPY_AND_ASSIGN(IntLiteral);
+};
+
+
+class DoubleLiteral : public BasicLiteral {
+ public:
+ static DoubleLiteral* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~DoubleLiteral();
+
+ DEFINE_CASTING_OPERATIONS(DoubleLiteral);
+
+ virtual void AcceptExpressionVisitor(ExpressionVisitor* visitor);
+
+ String* value() { return value_; }
+
+ private:
+ DoubleLiteral() {}
+
+ Ref<String> value_;
+
+ DISALLOW_COPY_AND_ASSIGN(DoubleLiteral);
+};
+
+
+class BoolLiteral : public BasicLiteral {
+ public:
+ static BoolLiteral* ReadFrom(Reader* reader, bool value);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~BoolLiteral();
+
+ DEFINE_CASTING_OPERATIONS(BoolLiteral);
+
+ virtual void AcceptExpressionVisitor(ExpressionVisitor* visitor);
+
+ bool value() { return value_; }
+
+ private:
+ BoolLiteral() {}
+
+ bool value_;
+
+ DISALLOW_COPY_AND_ASSIGN(BoolLiteral);
+};
+
+
+class NullLiteral : public BasicLiteral {
+ public:
+ static NullLiteral* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~NullLiteral();
+
+ DEFINE_CASTING_OPERATIONS(NullLiteral);
+
+ virtual void AcceptExpressionVisitor(ExpressionVisitor* visitor);
+
+ private:
+ NullLiteral() { }
+
+ DISALLOW_COPY_AND_ASSIGN(NullLiteral);
+};
+
+
+class SymbolLiteral : public Expression {
+ public:
+ static SymbolLiteral* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~SymbolLiteral();
+
+ DEFINE_CASTING_OPERATIONS(SymbolLiteral);
+
+ virtual void AcceptExpressionVisitor(ExpressionVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ String* value() { return value_; }
+
+ private:
+ SymbolLiteral() {}
+
+ Ref<String> value_;
+
+ DISALLOW_COPY_AND_ASSIGN(SymbolLiteral);
+};
+
+
+class TypeLiteral : public Expression {
+ public:
+ static TypeLiteral* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~TypeLiteral();
+
+ DEFINE_CASTING_OPERATIONS(TypeLiteral);
+
+ virtual void AcceptExpressionVisitor(ExpressionVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ DartType* type() { return type_; }
+
+ private:
+ TypeLiteral() {}
+
+ Child<DartType> type_;
+
+ DISALLOW_COPY_AND_ASSIGN(TypeLiteral);
+};
+
+
+class ThisExpression : public Expression {
+ public:
+ static ThisExpression* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~ThisExpression();
+
+ DEFINE_CASTING_OPERATIONS(ThisExpression);
+
+ virtual void AcceptExpressionVisitor(ExpressionVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ private:
+ ThisExpression() { }
+
+ DISALLOW_COPY_AND_ASSIGN(ThisExpression);
+};
+
+
+class Rethrow : public Expression {
+ public:
+ static Rethrow* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~Rethrow();
+
+ DEFINE_CASTING_OPERATIONS(Rethrow);
+
+ virtual void AcceptExpressionVisitor(ExpressionVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ private:
+ Rethrow() { }
+
+ DISALLOW_COPY_AND_ASSIGN(Rethrow);
+};
+
+
+class Throw : public Expression {
+ public:
+ static Throw* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~Throw();
+
+ DEFINE_CASTING_OPERATIONS(Throw);
+
+ virtual void AcceptExpressionVisitor(ExpressionVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ Expression* expression() { return expression_; }
+
+ private:
+ Throw() {}
+
+ Child<Expression> expression_;
+
+ DISALLOW_COPY_AND_ASSIGN(Throw);
+};
+
+
+class ListLiteral : public Expression {
+ public:
+ static ListLiteral* ReadFrom(Reader* reader, bool is_const);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~ListLiteral();
+
+ DEFINE_CASTING_OPERATIONS(ListLiteral);
+
+ virtual void AcceptExpressionVisitor(ExpressionVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ bool is_const() { return is_const_; }
+ DartType* type() { return type_; }
+ List<Expression>& expressions() { return expressions_; }
+
+ private:
+ ListLiteral() {}
+
+ bool is_const_;
+ Child<DartType> type_;
+ List<Expression> expressions_;
+
+ DISALLOW_COPY_AND_ASSIGN(ListLiteral);
+};
+
+
+class MapLiteral : public Expression {
+ public:
+ static MapLiteral* ReadFrom(Reader* reader, bool is_const);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~MapLiteral();
+
+ DEFINE_CASTING_OPERATIONS(MapLiteral);
+
+ virtual void AcceptExpressionVisitor(ExpressionVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ bool is_const() { return is_const_; }
+ DartType* key_type() { return key_type_; }
+ DartType* value_type() { return value_type_; }
+ List<MapEntry>& entries() { return entries_; }
+
+ private:
+ MapLiteral() {}
+
+ bool is_const_;
+ Child<DartType> key_type_;
+ Child<DartType> value_type_;
+ List<MapEntry> entries_;
+
+ DISALLOW_COPY_AND_ASSIGN(MapLiteral);
+};
+
+
+class MapEntry : public TreeNode {
+ public:
+ static MapEntry* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~MapEntry();
+
+ DEFINE_CASTING_OPERATIONS(MapEntry);
+
+ virtual void AcceptTreeVisitor(TreeVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ Expression* key() { return key_; }
+ Expression* value() { return value_; }
+
+ private:
+ MapEntry() {}
+
+ template <typename T>
+ friend class List;
+
+ Child<Expression> key_;
+ Child<Expression> value_;
+
+ DISALLOW_COPY_AND_ASSIGN(MapEntry);
+};
+
+
+class AwaitExpression : public Expression {
+ public:
+ static AwaitExpression* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~AwaitExpression();
+
+ DEFINE_CASTING_OPERATIONS(AwaitExpression);
+
+ virtual void AcceptExpressionVisitor(ExpressionVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ Expression* operand() { return operand_; }
+
+ private:
+ AwaitExpression() {}
+
+ Child<Expression> operand_;
+
+ DISALLOW_COPY_AND_ASSIGN(AwaitExpression);
+};
+
+
+class FunctionExpression : public Expression {
+ public:
+ static FunctionExpression* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~FunctionExpression();
+
+ DEFINE_CASTING_OPERATIONS(FunctionExpression);
+
+ virtual void AcceptExpressionVisitor(ExpressionVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ FunctionNode* function() { return function_; }
+
+ private:
+ FunctionExpression() {}
+
+ Child<FunctionNode> function_;
+
+ DISALLOW_COPY_AND_ASSIGN(FunctionExpression);
+};
+
+
+class Let : public Expression {
+ public:
+ static Let* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~Let();
+
+ DEFINE_CASTING_OPERATIONS(Let);
+
+ virtual void AcceptExpressionVisitor(ExpressionVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ VariableDeclaration* variable() { return variable_; }
+ Expression* body() { return body_; }
+
+ private:
+ Let() {}
+
+ Child<VariableDeclaration> variable_;
+ Child<Expression> body_;
+
+ DISALLOW_COPY_AND_ASSIGN(Let);
+};
+
+
+class BlockExpression : public Expression {
+ public:
+ static BlockExpression* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~BlockExpression();
+
+ DEFINE_CASTING_OPERATIONS(BlockExpression);
+
+ virtual void AcceptExpressionVisitor(ExpressionVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ Block* body() { return body_; }
+ Expression* value() { return value_; }
+
+ private:
+ BlockExpression() {}
+
+ Child<Block> body_;
+ Child<Expression> value_;
+
+ DISALLOW_COPY_AND_ASSIGN(BlockExpression);
+};
+
+
+class Statement : public TreeNode {
+ public:
+ static Statement* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer) = 0;
+
+ virtual ~Statement();
+
+ DEFINE_CASTING_OPERATIONS(Statement);
+
+ virtual void AcceptTreeVisitor(TreeVisitor* visitor);
+ virtual void AcceptStatementVisitor(StatementVisitor* visitor) = 0;
+
+ protected:
+ Statement() { }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(Statement);
+};
+
+
+class InvalidStatement : public Statement {
+ public:
+ static InvalidStatement* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~InvalidStatement();
+
+ DEFINE_CASTING_OPERATIONS(InvalidStatement);
+
+ virtual void AcceptStatementVisitor(StatementVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ private:
+ InvalidStatement() { }
+
+ DISALLOW_COPY_AND_ASSIGN(InvalidStatement);
+};
+
+
+class ExpressionStatement : public Statement {
+ public:
+ static ExpressionStatement* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ explicit ExpressionStatement(Expression* exp) : expression_(exp) {}
+ virtual ~ExpressionStatement();
+
+ DEFINE_CASTING_OPERATIONS(ExpressionStatement);
+
+ virtual void AcceptStatementVisitor(StatementVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ Expression* expression() { return expression_; }
+
+ private:
+ ExpressionStatement() {}
+
+ Child<Expression> expression_;
+
+ DISALLOW_COPY_AND_ASSIGN(ExpressionStatement);
+};
+
+
+class Block : public Statement {
+ public:
+ static Block* ReadFromImpl(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+ void WriteToImpl(Writer* writer);
+
+ virtual ~Block();
+
+ DEFINE_CASTING_OPERATIONS(Block);
+
+ virtual void AcceptStatementVisitor(StatementVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ List<Statement>& statements() { return statements_; }
+
+ private:
+ Block() {}
+
+ List<Statement> statements_;
+
+ DISALLOW_COPY_AND_ASSIGN(Block);
+};
+
+
+class EmptyStatement : public Statement {
+ public:
+ static EmptyStatement* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~EmptyStatement();
+
+ DEFINE_CASTING_OPERATIONS(EmptyStatement);
+
+ virtual void AcceptStatementVisitor(StatementVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ private:
+ EmptyStatement() { }
+
+ DISALLOW_COPY_AND_ASSIGN(EmptyStatement);
+};
+
+
+class AssertStatement : public Statement {
+ public:
+ static AssertStatement* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~AssertStatement();
+
+ DEFINE_CASTING_OPERATIONS(AssertStatement);
+
+ virtual void AcceptStatementVisitor(StatementVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ Expression* condition() { return condition_; }
+ Expression* message() { return message_; }
+
+ private:
+ AssertStatement() {}
+
+ Child<Expression> condition_;
+ Child<Expression> message_;
+
+ DISALLOW_COPY_AND_ASSIGN(AssertStatement);
+};
+
+
+class LabeledStatement : public Statement {
+ public:
+ static LabeledStatement* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~LabeledStatement();
+
+ DEFINE_CASTING_OPERATIONS(LabeledStatement);
+
+ virtual void AcceptStatementVisitor(StatementVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ Statement* body() { return body_; }
+
+ private:
+ LabeledStatement() {}
+
+ Child<Statement> body_;
+
+ DISALLOW_COPY_AND_ASSIGN(LabeledStatement);
+};
+
+
+class BreakStatement : public Statement {
+ public:
+ static BreakStatement* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~BreakStatement();
+
+ DEFINE_CASTING_OPERATIONS(BreakStatement);
+
+ virtual void AcceptStatementVisitor(StatementVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ LabeledStatement* target() { return target_; }
+
+ private:
+ BreakStatement() {}
+
+ Ref<LabeledStatement> target_;
+
+ DISALLOW_COPY_AND_ASSIGN(BreakStatement);
+};
+
+
+class WhileStatement : public Statement {
+ public:
+ static WhileStatement* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~WhileStatement();
+
+ DEFINE_CASTING_OPERATIONS(WhileStatement);
+
+ virtual void AcceptStatementVisitor(StatementVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ Expression* condition() { return condition_; }
+ Statement* body() { return body_; }
+
+ private:
+ WhileStatement() {}
+
+ Child<Expression> condition_;
+ Child<Statement> body_;
+
+ DISALLOW_COPY_AND_ASSIGN(WhileStatement);
+};
+
+
+class DoStatement : public Statement {
+ public:
+ static DoStatement* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~DoStatement();
+
+ DEFINE_CASTING_OPERATIONS(DoStatement);
+
+ virtual void AcceptStatementVisitor(StatementVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ Expression* condition() { return condition_; }
+ Statement* body() { return body_; }
+
+ private:
+ DoStatement() {}
+
+ Child<Expression> condition_;
+ Child<Statement> body_;
+
+ DISALLOW_COPY_AND_ASSIGN(DoStatement);
+};
+
+
+class ForStatement : public Statement {
+ public:
+ static ForStatement* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~ForStatement();
+
+ DEFINE_CASTING_OPERATIONS(ForStatement);
+
+ virtual void AcceptStatementVisitor(StatementVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ List<VariableDeclaration>& variables() { return variables_; }
+ Expression* condition() { return condition_; }
+ List<Expression>& updates() { return updates_; }
+ Statement* body() { return body_; }
+
+ private:
+ ForStatement() {}
+
+ List<VariableDeclaration> variables_;
+ Child<Expression> condition_;
+ List<Expression> updates_;
+ Child<Statement> body_;
+
+ DISALLOW_COPY_AND_ASSIGN(ForStatement);
+};
+
+
+class ForInStatement : public Statement {
+ public:
+ static ForInStatement* ReadFrom(Reader* reader, bool is_async);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~ForInStatement();
+
+ DEFINE_CASTING_OPERATIONS(ForInStatement);
+
+ virtual void AcceptStatementVisitor(StatementVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ VariableDeclaration* variable() { return variable_; }
+ Expression* iterable() { return iterable_; }
+ Statement* body() { return body_; }
+ bool is_async() { return is_async_; }
+
+ private:
+ ForInStatement() {}
+
+ Child<VariableDeclaration> variable_;
+ Child<Expression> iterable_;
+ Child<Statement> body_;
+ bool is_async_;
+
+ DISALLOW_COPY_AND_ASSIGN(ForInStatement);
+};
+
+
+class SwitchStatement : public Statement {
+ public:
+ static SwitchStatement* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~SwitchStatement();
+
+ DEFINE_CASTING_OPERATIONS(SwitchStatement);
+
+ virtual void AcceptStatementVisitor(StatementVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ Expression* condition() { return condition_; }
+ List<SwitchCase>& cases() { return cases_; }
+
+ private:
+ SwitchStatement() {}
+
+ Child<Expression> condition_;
+ List<SwitchCase> cases_;
+
+ DISALLOW_COPY_AND_ASSIGN(SwitchStatement);
+};
+
+
+class SwitchCase : public TreeNode {
+ public:
+ SwitchCase* ReadFrom(Reader* reader);
+ void WriteTo(Writer* writer);
+
+ virtual ~SwitchCase();
+
+ DEFINE_CASTING_OPERATIONS(SwitchCase);
+
+ virtual void AcceptTreeVisitor(TreeVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ List<Expression>& expressions() { return expressions_; }
+ bool is_default() { return is_default_; }
+ Statement* body() { return body_; }
+
+ private:
+ SwitchCase() {}
+
+ template <typename T>
+ friend class List;
+
+ List<Expression> expressions_;
+ bool is_default_;
+ Child<Statement> body_;
+
+ DISALLOW_COPY_AND_ASSIGN(SwitchCase);
+};
+
+
+class ContinueSwitchStatement : public Statement {
+ public:
+ static ContinueSwitchStatement* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~ContinueSwitchStatement();
+
+ DEFINE_CASTING_OPERATIONS(ContinueSwitchStatement);
+
+ virtual void AcceptStatementVisitor(StatementVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ SwitchCase* target() { return target_; }
+
+ private:
+ ContinueSwitchStatement() {}
+
+ Ref<SwitchCase> target_;
+
+ DISALLOW_COPY_AND_ASSIGN(ContinueSwitchStatement);
+};
+
+
+class IfStatement : public Statement {
+ public:
+ static IfStatement* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~IfStatement();
+
+ DEFINE_CASTING_OPERATIONS(IfStatement);
+
+ virtual void AcceptStatementVisitor(StatementVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ Expression* condition() { return condition_; }
+ Statement* then() { return then_; }
+ Statement* otherwise() { return otherwise_; }
+
+ private:
+ IfStatement() {}
+
+ Child<Expression> condition_;
+ Child<Statement> then_;
+ Child<Statement> otherwise_;
+
+ DISALLOW_COPY_AND_ASSIGN(IfStatement);
+};
+
+
+class ReturnStatement : public Statement {
+ public:
+ static ReturnStatement* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~ReturnStatement();
+
+ DEFINE_CASTING_OPERATIONS(ReturnStatement);
+
+ virtual void AcceptStatementVisitor(StatementVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ Expression* expression() { return expression_; }
+
+ private:
+ ReturnStatement() {}
+
+ Child<Expression> expression_;
+
+ DISALLOW_COPY_AND_ASSIGN(ReturnStatement);
+};
+
+
+class TryCatch : public Statement {
+ public:
+ static TryCatch* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~TryCatch();
+
+ DEFINE_CASTING_OPERATIONS(TryCatch);
+
+ virtual void AcceptStatementVisitor(StatementVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ Statement* body() { return body_; }
+ List<Catch>& catches() { return catches_; }
+
+ private:
+ TryCatch() {}
+
+ Child<Statement> body_;
+ List<Catch> catches_;
+
+ DISALLOW_COPY_AND_ASSIGN(TryCatch);
+};
+
+
+class Catch : public TreeNode {
+ public:
+ static Catch* ReadFrom(Reader* reader);
+ void WriteTo(Writer* writer);
+
+ virtual ~Catch();
+
+ DEFINE_CASTING_OPERATIONS(Catch);
+
+ virtual void AcceptTreeVisitor(TreeVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ DartType* guard() { return guard_; }
+ VariableDeclaration* exception() { return exception_; }
+ VariableDeclaration* stack_trace() { return stack_trace_; }
+ Statement* body() { return body_; }
+
+ private:
+ Catch() {}
+
+ template <typename T>
+ friend class List;
+
+ Child<DartType> guard_;
+ Child<VariableDeclaration> exception_;
+ Child<VariableDeclaration> stack_trace_;
+ Child<Statement> body_;
+
+ DISALLOW_COPY_AND_ASSIGN(Catch);
+};
+
+
+class TryFinally : public Statement {
+ public:
+ static TryFinally* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~TryFinally();
+
+ DEFINE_CASTING_OPERATIONS(TryFinally);
+
+ virtual void AcceptStatementVisitor(StatementVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ Statement* body() { return body_; }
+ Statement* finalizer() { return finalizer_; }
+
+ private:
+ TryFinally() {}
+
+ Child<Statement> body_;
+ Child<Statement> finalizer_;
+
+ DISALLOW_COPY_AND_ASSIGN(TryFinally);
+};
+
+
+class YieldStatement : public Statement {
+ public:
+ enum {
+ kFlagYieldStar = 1 << 0,
+ kFlagNative = 1 << 1,
+ };
+ static YieldStatement* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~YieldStatement();
+
+ DEFINE_CASTING_OPERATIONS(YieldStatement);
+
+ virtual void AcceptStatementVisitor(StatementVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ bool is_yield_start() { return (flags_ & kFlagYieldStar) == kFlagYieldStar; }
+ bool is_native() { return (flags_ & kFlagNative) == kFlagNative; }
+ Expression* expression() { return expression_; }
+
+ private:
+ YieldStatement() {}
+
+ word flags_;
+ Child<Expression> expression_;
+
+ DISALLOW_COPY_AND_ASSIGN(YieldStatement);
+};
+
+
+class VariableDeclaration : public Statement {
+ public:
+ enum Flags {
+ kFlagFinal = 1 << 0,
+ kFlagConst = 1 << 1,
+ };
+
+ static VariableDeclaration* ReadFrom(Reader* reader);
+ static VariableDeclaration* ReadFromImpl(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+ void WriteToImpl(Writer* writer);
+
+ virtual ~VariableDeclaration();
+
+ DEFINE_CASTING_OPERATIONS(VariableDeclaration);
+
+ virtual void AcceptStatementVisitor(StatementVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ bool IsConst() { return (flags_ & kFlagConst) == kFlagConst; }
+ bool IsFinal() { return (flags_ & kFlagFinal) == kFlagFinal; }
+
+ String* name() { return name_; }
+ DartType* type() { return type_; }
+ InferredValue* inferred_value() { return inferred_value_; }
+ Expression* initializer() { return initializer_; }
+
+ private:
+ VariableDeclaration() {}
+
+ template <typename T>
+ friend class List;
+
+ word flags_;
+ Ref<String> name_;
+ Child<DartType> type_;
+ Child<InferredValue> inferred_value_;
+ Child<Expression> initializer_;
+
+ DISALLOW_COPY_AND_ASSIGN(VariableDeclaration);
+};
+
+
+class FunctionDeclaration : public Statement {
+ public:
+ static FunctionDeclaration* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer);
+
+ virtual ~FunctionDeclaration();
+
+ DEFINE_CASTING_OPERATIONS(FunctionDeclaration);
+
+ virtual void AcceptStatementVisitor(StatementVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ VariableDeclaration* variable() { return variable_; }
+ FunctionNode* function() { return function_; }
+
+ private:
+ FunctionDeclaration() {}
+
+ Child<VariableDeclaration> variable_;
+ Child<FunctionNode> function_;
+
+ DISALLOW_COPY_AND_ASSIGN(FunctionDeclaration);
+};
+
+
+class Name : public Node {
+ public:
+ static Name* ReadFrom(Reader* reader);
+ void WriteTo(Writer* writer);
+
+ virtual ~Name();
+
+ DEFINE_CASTING_OPERATIONS(Name);
+
+ virtual void AcceptVisitor(Visitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ String* string() { return string_; }
+ Library* library() { return library_; }
+
+ private:
+ Name(String* string, Library* library) : string_(string), library_(library) {}
+
+ Ref<String> string_;
+ Ref<Library> library_;
+
+ DISALLOW_COPY_AND_ASSIGN(Name);
+};
+
+
+class InferredValue : public Node {
+ public:
+ static const uint8_t kNull = 1 << 0;
+ static const uint8_t kInteger = 1 << 1;
+ static const uint8_t kDouble = 1 << 2;
+ static const uint8_t kString = 1 << 3;
+ static const uint8_t kOther = 1 << 4;
+
+ enum BaseClassKind {
+ kNone,
+ kExact,
+ kSubclass,
+ kSubtype,
+ };
+
+ static InferredValue* ReadFrom(Reader* reader);
+ void WriteTo(Writer* writer);
+
+ virtual ~InferredValue();
+
+ DEFINE_CASTING_OPERATIONS(InferredValue);
+
+ virtual void AcceptVisitor(Visitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ bool IsInterfaceType() { return kind_ == kSubtype; }
+ bool IsExactClass() { return kind_ == kExact; }
+ bool IsSubclass() { return kind_ == kSubclass; }
+
+ bool CanBeNull() { return (value_bits_ & kNull) != 0; }
+ bool CanBeInteger() { return (value_bits_ & kInteger) != 0; }
+ bool CanBeDouble() { return (value_bits_ & kDouble) != 0; }
+ bool CanBeString() { return (value_bits_ & kString) != 0; }
+
+ bool IsAlwaysNull() { return value_bits_ == kNull; }
+ bool IsAlwaysInteger() { return value_bits_ == kInteger; }
+ bool IsAlwaysDouble() { return value_bits_ == kDouble; }
+ bool IsAlwaysString() { return value_bits_ == kString; }
+
+ Class* klass() { return klass_; }
+ BaseClassKind kind() { return kind_; }
+ uint8_t value_bits() { return value_bits_; }
+
+ private:
+ InferredValue() { }
+
+ Ref<Class> klass_;
+ BaseClassKind kind_;
+ uint8_t value_bits_;
+
+ DISALLOW_COPY_AND_ASSIGN(InferredValue);
+};
+
+
+class DartType : public Node {
+ public:
+ static DartType* ReadFrom(Reader* reader);
+ virtual void WriteTo(Writer* writer) = 0;
+
+ virtual ~DartType();
+
+ DEFINE_CASTING_OPERATIONS(DartType);
+
+ virtual void AcceptVisitor(Visitor* visitor);
+ virtual void AcceptDartTypeVisitor(DartTypeVisitor* visitor) = 0;
+
+ protected:
+ DartType() { }
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(DartType);
+};
+
+
+class InvalidType : public DartType {
+ public:
+ static InvalidType* ReadFrom(Reader* reader);
+ void WriteTo(Writer* writer);
+
+ virtual ~InvalidType();
+
+ DEFINE_CASTING_OPERATIONS(InvalidType);
+
+ virtual void AcceptDartTypeVisitor(DartTypeVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ private:
+ InvalidType() { }
+
+ DISALLOW_COPY_AND_ASSIGN(InvalidType);
+};
+
+
+class DynamicType : public DartType {
+ public:
+ static DynamicType* ReadFrom(Reader* reader);
+ void WriteTo(Writer* writer);
+
+ virtual ~DynamicType();
+
+ DEFINE_CASTING_OPERATIONS(DynamicType);
+
+ virtual void AcceptDartTypeVisitor(DartTypeVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ private:
+ DynamicType() { }
+
+ DISALLOW_COPY_AND_ASSIGN(DynamicType);
+};
+
+
+class VoidType : public DartType {
+ public:
+ static VoidType* ReadFrom(Reader* reader);
+ void WriteTo(Writer* writer);
+
+ virtual ~VoidType();
+
+ DEFINE_CASTING_OPERATIONS(VoidType);
+
+ virtual void AcceptDartTypeVisitor(DartTypeVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ private:
+ VoidType() { }
+
+ DISALLOW_COPY_AND_ASSIGN(VoidType);
+};
+
+
+class InterfaceType : public DartType {
+ public:
+ static InterfaceType* ReadFrom(Reader* reader);
+ static InterfaceType* ReadFrom(Reader* reader, bool _without_type_arguments_);
+ void WriteTo(Writer* writer);
+
+ explicit InterfaceType(Class* klass) : klass_(klass) {}
+ virtual ~InterfaceType();
+
+ DEFINE_CASTING_OPERATIONS(InterfaceType);
+
+ virtual void AcceptDartTypeVisitor(DartTypeVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ Class* klass() { return klass_; }
+ List<DartType>& type_arguments() { return type_arguments_; }
+
+ private:
+ InterfaceType() {}
+
+ Ref<Class> klass_;
+ List<DartType> type_arguments_;
+
+ DISALLOW_COPY_AND_ASSIGN(InterfaceType);
+};
+
+
+class FunctionType : public DartType {
+ public:
+ static FunctionType* ReadFrom(Reader* reader);
+ static FunctionType* ReadFrom(Reader* reader, bool _without_type_arguments_);
+ void WriteTo(Writer* writer);
+
+ virtual ~FunctionType();
+
+ DEFINE_CASTING_OPERATIONS(FunctionType);
+
+ virtual void AcceptDartTypeVisitor(DartTypeVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ TypeParameterList& type_parameters() { return type_parameters_; }
+ int required_parameter_count() { return required_parameter_count_; }
+ List<DartType>& positional_parameters() { return positional_parameters_; }
+ List<Tuple<String, DartType> >& named_parameters() {
+ return named_parameters_;
+ }
+ DartType* return_type() { return return_type_; }
+
+ private:
+ FunctionType() {}
+
+ TypeParameterList type_parameters_;
+ int required_parameter_count_;
+ List<DartType> positional_parameters_;
+ List<Tuple<String, DartType> > named_parameters_;
+ Child<DartType> return_type_;
+
+ DISALLOW_COPY_AND_ASSIGN(FunctionType);
+};
+
+
+class TypeParameterType : public DartType {
+ public:
+ static TypeParameterType* ReadFrom(Reader* reader);
+ void WriteTo(Writer* writer);
+
+ virtual ~TypeParameterType();
+
+ DEFINE_CASTING_OPERATIONS(TypeParameterType);
+
+ virtual void AcceptDartTypeVisitor(DartTypeVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ TypeParameter* parameter() { return parameter_; }
+
+ private:
+ TypeParameterType() {}
+
+ Ref<TypeParameter> parameter_;
+
+ DISALLOW_COPY_AND_ASSIGN(TypeParameterType);
+};
+
+
+class TypeParameter : public TreeNode {
+ public:
+ TypeParameter* ReadFrom(Reader* reader);
+ void WriteTo(Writer* writer);
+
+ virtual ~TypeParameter();
+
+ DEFINE_CASTING_OPERATIONS(TypeParameter);
+
+ virtual void AcceptTreeVisitor(TreeVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ String* name() { return name_; }
+ DartType* bound() { return bound_; }
+
+ private:
+ TypeParameter() {}
+
+ template <typename T>
+ friend class List;
+ friend class TypeParameterList;
+
+ Ref<String> name_;
+ Child<DartType> bound_;
+
+ DISALLOW_COPY_AND_ASSIGN(TypeParameter);
+};
+
+
+class Program : public TreeNode {
+ public:
+ static Program* ReadFrom(Reader* reader);
+ void WriteTo(Writer* writer);
+
+ virtual ~Program();
+
+ DEFINE_CASTING_OPERATIONS(Program);
+
+ virtual void AcceptTreeVisitor(TreeVisitor* visitor);
+ virtual void VisitChildren(Visitor* visitor);
+
+ StringTable& string_table() { return string_table_; }
+ List<Library>& libraries() { return libraries_; }
+ Procedure* main_method() { return main_method_; }
+
+ private:
+ Program() {}
+
+ List<Library> libraries_;
+ Ref<Procedure> main_method_;
+ StringTable string_table_;
+
+ DISALLOW_COPY_AND_ASSIGN(Program);
+};
+
+
+class Reference : public AllStatic {
+ public:
+ static Member* ReadMemberFrom(Reader* reader, bool allow_null = false);
+ static void WriteMemberTo(Writer* writer, Member* member,
+ bool allow_null = false);
+
+ static Class* ReadClassFrom(Reader* reader, bool allow_null = false);
+ static void WriteClassTo(Writer* writer, Class* klass,
+ bool allow_null = false);
+
+ static String* ReadStringFrom(Reader* reader);
+ static void WriteStringTo(Writer* writer, String* string); // NOLINT
+};
+
+
+class ExpressionVisitor {
+ public:
+ virtual ~ExpressionVisitor() {}
+
+ virtual void VisitDefaultExpression(Expression* node) = 0;
+ virtual void VisitDefaultBasicLiteral(BasicLiteral* node) {
+ VisitDefaultExpression(node);
+ }
+ virtual void VisitInvalidExpression(InvalidExpression* node) {
+ VisitDefaultExpression(node);
+ }
+ virtual void VisitVariableGet(VariableGet* node) {
+ VisitDefaultExpression(node);
+ }
+ virtual void VisitVariableSet(VariableSet* node) {
+ VisitDefaultExpression(node);
+ }
+ virtual void VisitPropertyGet(PropertyGet* node) {
+ VisitDefaultExpression(node);
+ }
+ virtual void VisitPropertySet(PropertySet* node) {
+ VisitDefaultExpression(node);
+ }
+ virtual void VisitDirectPropertyGet(DirectPropertyGet* node) {
+ VisitDefaultExpression(node);
+ }
+ virtual void VisitDirectPropertySet(DirectPropertySet* node) {
+ VisitDefaultExpression(node);
+ }
+ virtual void VisitStaticGet(StaticGet* node) { VisitDefaultExpression(node); }
+ virtual void VisitStaticSet(StaticSet* node) { VisitDefaultExpression(node); }
+ virtual void VisitMethodInvocation(MethodInvocation* node) {
+ VisitDefaultExpression(node);
+ }
+ virtual void VisitDirectMethodInvocation(DirectMethodInvocation* node) {
+ VisitDefaultExpression(node);
+ }
+ virtual void VisitStaticInvocation(StaticInvocation* node) {
+ VisitDefaultExpression(node);
+ }
+ virtual void VisitConstructorInvocation(ConstructorInvocation* node) {
+ VisitDefaultExpression(node);
+ }
+ virtual void VisitNot(Not* node) { VisitDefaultExpression(node); }
+ virtual void VisitLogicalExpression(LogicalExpression* node) {
+ VisitDefaultExpression(node);
+ }
+ virtual void VisitConditionalExpression(ConditionalExpression* node) {
+ VisitDefaultExpression(node);
+ }
+ virtual void VisitStringConcatenation(StringConcatenation* node) {
+ VisitDefaultExpression(node);
+ }
+ virtual void VisitIsExpression(IsExpression* node) {
+ VisitDefaultExpression(node);
+ }
+ virtual void VisitAsExpression(AsExpression* node) {
+ VisitDefaultExpression(node);
+ }
+ virtual void VisitSymbolLiteral(SymbolLiteral* node) {
+ VisitDefaultExpression(node);
+ }
+ virtual void VisitTypeLiteral(TypeLiteral* node) {
+ VisitDefaultExpression(node);
+ }
+ virtual void VisitThisExpression(ThisExpression* node) {
+ VisitDefaultExpression(node);
+ }
+ virtual void VisitRethrow(Rethrow* node) { VisitDefaultExpression(node); }
+ virtual void VisitThrow(Throw* node) { VisitDefaultExpression(node); }
+ virtual void VisitListLiteral(ListLiteral* node) {
+ VisitDefaultExpression(node);
+ }
+ virtual void VisitMapLiteral(MapLiteral* node) {
+ VisitDefaultExpression(node);
+ }
+ virtual void VisitAwaitExpression(AwaitExpression* node) {
+ VisitDefaultExpression(node);
+ }
+ virtual void VisitFunctionExpression(FunctionExpression* node) {
+ VisitDefaultExpression(node);
+ }
+ virtual void VisitStringLiteral(StringLiteral* node) {
+ VisitDefaultBasicLiteral(node);
+ }
+ virtual void VisitBigintLiteral(BigintLiteral* node) {
+ VisitDefaultBasicLiteral(node);
+ }
+ virtual void VisitIntLiteral(IntLiteral* node) {
+ VisitDefaultBasicLiteral(node);
+ }
+ virtual void VisitDoubleLiteral(DoubleLiteral* node) {
+ VisitDefaultBasicLiteral(node);
+ }
+ virtual void VisitBoolLiteral(BoolLiteral* node) {
+ VisitDefaultBasicLiteral(node);
+ }
+ virtual void VisitNullLiteral(NullLiteral* node) {
+ VisitDefaultBasicLiteral(node);
+ }
+ virtual void VisitLet(Let* node) { VisitDefaultExpression(node); }
+ virtual void VisitBlockExpression(BlockExpression* node) {
+ VisitDefaultExpression(node);
+ }
+};
+
+
+class StatementVisitor {
+ public:
+ virtual ~StatementVisitor() {}
+
+ virtual void VisitDefaultStatement(Statement* node) = 0;
+ virtual void VisitInvalidStatement(InvalidStatement* node) {
+ VisitDefaultStatement(node);
+ }
+ virtual void VisitExpressionStatement(ExpressionStatement* node) {
+ VisitDefaultStatement(node);
+ }
+ virtual void VisitBlock(Block* node) { VisitDefaultStatement(node); }
+ virtual void VisitEmptyStatement(EmptyStatement* node) {
+ VisitDefaultStatement(node);
+ }
+ virtual void VisitAssertStatement(AssertStatement* node) {
+ VisitDefaultStatement(node);
+ }
+ virtual void VisitLabeledStatement(LabeledStatement* node) {
+ VisitDefaultStatement(node);
+ }
+ virtual void VisitBreakStatement(BreakStatement* node) {
+ VisitDefaultStatement(node);
+ }
+ virtual void VisitWhileStatement(WhileStatement* node) {
+ VisitDefaultStatement(node);
+ }
+ virtual void VisitDoStatement(DoStatement* node) {
+ VisitDefaultStatement(node);
+ }
+ virtual void VisitForStatement(ForStatement* node) {
+ VisitDefaultStatement(node);
+ }
+ virtual void VisitForInStatement(ForInStatement* node) {
+ VisitDefaultStatement(node);
+ }
+ virtual void VisitSwitchStatement(SwitchStatement* node) {
+ VisitDefaultStatement(node);
+ }
+ virtual void VisitContinueSwitchStatement(ContinueSwitchStatement* node) {
+ VisitDefaultStatement(node);
+ }
+ virtual void VisitIfStatement(IfStatement* node) {
+ VisitDefaultStatement(node);
+ }
+ virtual void VisitReturnStatement(ReturnStatement* node) {
+ VisitDefaultStatement(node);
+ }
+ virtual void VisitTryCatch(TryCatch* node) { VisitDefaultStatement(node); }
+ virtual void VisitTryFinally(TryFinally* node) {
+ VisitDefaultStatement(node);
+ }
+ virtual void VisitYieldStatement(YieldStatement* node) {
+ VisitDefaultStatement(node);
+ }
+ virtual void VisitVariableDeclaration(VariableDeclaration* node) {
+ VisitDefaultStatement(node);
+ }
+ virtual void VisitFunctionDeclaration(FunctionDeclaration* node) {
+ VisitDefaultStatement(node);
+ }
+};
+
+
+class MemberVisitor {
+ public:
+ virtual ~MemberVisitor() {}
+
+ virtual void VisitDefaultMember(Member* node) = 0;
+ virtual void VisitConstructor(Constructor* node) { VisitDefaultMember(node); }
+ virtual void VisitProcedure(Procedure* node) { VisitDefaultMember(node); }
+ virtual void VisitField(Field* node) { VisitDefaultMember(node); }
+};
+
+
+class ClassVisitor {
+ public:
+ virtual ~ClassVisitor() {}
+
+ virtual void VisitDefaultClass(Class* node) = 0;
+ virtual void VisitNormalClass(NormalClass* node) { VisitDefaultClass(node); }
+ virtual void VisitMixinClass(MixinClass* node) { VisitDefaultClass(node); }
+};
+
+
+class InitializerVisitor {
+ public:
+ virtual ~InitializerVisitor() {}
+
+ virtual void VisitDefaultInitializer(Initializer* node) = 0;
+ virtual void VisitInvalidInitializer(InvalidInitializer* node) {
+ VisitDefaultInitializer(node);
+ }
+ virtual void VisitFieldInitializer(FieldInitializer* node) {
+ VisitDefaultInitializer(node);
+ }
+ virtual void VisitSuperInitializer(SuperInitializer* node) {
+ VisitDefaultInitializer(node);
+ }
+ virtual void VisitRedirectingInitializer(RedirectingInitializer* node) {
+ VisitDefaultInitializer(node);
+ }
+ virtual void VisitLocalInitializer(LocalInitializer* node) {
+ VisitDefaultInitializer(node);
+ }
+};
+
+
+class DartTypeVisitor {
+ public:
+ virtual ~DartTypeVisitor() {}
+
+ virtual void VisitDefaultDartType(DartType* node) = 0;
+ virtual void VisitInvalidType(InvalidType* node) {
+ VisitDefaultDartType(node);
+ }
+ virtual void VisitDynamicType(DynamicType* node) {
+ VisitDefaultDartType(node);
+ }
+ virtual void VisitVoidType(VoidType* node) { VisitDefaultDartType(node); }
+ virtual void VisitInterfaceType(InterfaceType* node) {
+ VisitDefaultDartType(node);
+ }
+ virtual void VisitFunctionType(FunctionType* node) {
+ VisitDefaultDartType(node);
+ }
+ virtual void VisitTypeParameterType(TypeParameterType* node) {
+ VisitDefaultDartType(node);
+ }
+};
+
+
+class ClassReferenceVisitor {
+ public:
+ virtual ~ClassReferenceVisitor() {}
+
+ virtual void VisitDefaultClassReference(Class* node) = 0;
+ virtual void VisitNormalClassReference(NormalClass* node) {
+ VisitDefaultClassReference(node);
+ }
+ virtual void VisitMixinClassReference(MixinClass* node) {
+ VisitDefaultClassReference(node);
+ }
+};
+
+
+class MemberReferenceVisitor {
+ public:
+ virtual ~MemberReferenceVisitor() {}
+
+ virtual void VisitDefaultMemberReference(Member* node) = 0;
+ virtual void VisitFieldReference(Field* node) {
+ VisitDefaultMemberReference(node);
+ }
+ virtual void VisitConstructorReference(Constructor* node) {
+ VisitDefaultMemberReference(node);
+ }
+ virtual void VisitProcedureReference(Procedure* node) {
+ VisitDefaultMemberReference(node);
+ }
+};
+
+
+class TreeVisitor : public ExpressionVisitor,
+ public StatementVisitor,
+ public MemberVisitor,
+ public ClassVisitor,
+ public InitializerVisitor {
+ public:
+ virtual ~TreeVisitor() {}
+
+ virtual void VisitDefaultTreeNode(TreeNode* node) = 0;
+ virtual void VisitDefaultStatement(Statement* node) {
+ VisitDefaultTreeNode(node);
+ }
+ virtual void VisitDefaultExpression(Expression* node) {
+ VisitDefaultTreeNode(node);
+ }
+ virtual void VisitDefaultMember(Member* node) { VisitDefaultTreeNode(node); }
+ virtual void VisitDefaultClass(Class* node) { VisitDefaultTreeNode(node); }
+ virtual void VisitDefaultInitializer(Initializer* node) {
+ VisitDefaultTreeNode(node);
+ }
+
+ virtual void VisitLibrary(Library* node) { VisitDefaultTreeNode(node); }
+ virtual void VisitTypeParameter(TypeParameter* node) {
+ VisitDefaultTreeNode(node);
+ }
+ virtual void VisitFunctionNode(FunctionNode* node) {
+ VisitDefaultTreeNode(node);
+ }
+ virtual void VisitArguments(Arguments* node) { VisitDefaultTreeNode(node); }
+ virtual void VisitNamedExpression(NamedExpression* node) {
+ VisitDefaultTreeNode(node);
+ }
+ virtual void VisitSwitchCase(SwitchCase* node) { VisitDefaultTreeNode(node); }
+ virtual void VisitCatch(Catch* node) { VisitDefaultTreeNode(node); }
+ virtual void VisitMapEntry(MapEntry* node) { VisitDefaultTreeNode(node); }
+ virtual void VisitProgram(Program* node) { VisitDefaultTreeNode(node); }
+};
+
+
+class Visitor : public TreeVisitor,
+ public DartTypeVisitor,
+ public ClassReferenceVisitor,
+ public MemberReferenceVisitor {
+ public:
+ virtual ~Visitor() {}
+
+ virtual void VisitDefaultNode(Node* node) = 0;
+ virtual void VisitInferredValue(InferredValue* node) {
+ VisitDefaultNode(node);
+ }
+ virtual void VisitDefaultTreeNode(TreeNode* node) { VisitDefaultNode(node); }
+ virtual void VisitDefaultDartType(DartType* node) { VisitDefaultNode(node); }
+ virtual void VisitName(Name* node) { VisitDefaultNode(node); }
+ virtual void VisitDefaultClassReference(Class* node) {
+ VisitDefaultNode(node);
+ }
+ virtual void VisitDefaultMemberReference(Member* node) {
+ VisitDefaultNode(node);
+ }
+};
+
+
+class RecursiveVisitor : public Visitor {
+ public:
+ virtual ~RecursiveVisitor() {}
+
+ virtual void VisitDefaultNode(Node* node) { node->VisitChildren(this); }
+
+ virtual void VisitDefaultClassReference(Class* node) {}
+ virtual void VisitDefaultMemberReference(Member* node) {}
+};
+
+
+template <typename T>
+List<T>::~List() {
+ for (int i = 0; i < length_; i++) {
+ delete array_[i];
+ }
+ delete[] array_;
+}
+
+
+template <typename T>
+void List<T>::EnsureInitialized(int length) {
+ if (length < length_) return;
+
+ T** old_array = array_;
+ int old_length = length_;
+
+ // TODO(27590) Maybe we should use double-growth instead to avoid running
+ // into the quadratic case.
+ length_ = length;
+ array_ = new T*[length_];
+
+ // Move old elements at the start (if necessary).
+ int offset = 0;
+ if (old_array != NULL) {
+ for (; offset < old_length; offset++) {
+ array_[offset] = old_array[offset];
+ }
+ }
+
+ // Set the rest to NULL.
+ for (; offset < length_; offset++) {
+ array_[offset] = NULL;
+ }
+
+ delete[] old_array;
+}
+
+
+template <typename T>
+template <typename IT>
+IT* List<T>::GetOrCreate(int index) {
+ EnsureInitialized(index + 1);
+
+ T* member = array_[index];
+ if (member == NULL) {
+ member = array_[index] = new IT();
+ }
+ return IT::Cast(member);
+}
+
+
+template <typename T>
+template <typename IT, typename PT>
+IT* List<T>::GetOrCreate(int index, PT* parent) {
+ EnsureInitialized(index + 1);
+
+ T* member = array_[index];
+ if (member == NULL) {
+ member = array_[index] = new IT();
+ member->parent_ = parent;
+ } else {
+ ASSERT(member->parent_ == parent);
+ }
+ return IT::Cast(member);
+}
+
+} // namespace kernel
+
+kernel::Program* ReadPrecompiledKernelFromBuffer(const uint8_t* buffer,
+ intptr_t buffer_length);
+
+class ByteWriter {
+ public:
+ virtual ~ByteWriter();
+
+ virtual void WriteByte(uint8_t byte) = 0;
+
+ virtual void WriteBytes(uint8_t* buffer, int count) = 0;
+};
+
+
+void WritePrecompiledKernel(ByteWriter* out, kernel::Program* program);
+
+
+} // namespace dart
+
+#endif // VM_KERNEL_H_
diff --git a/runtime/vm/kernel_binary.cc b/runtime/vm/kernel_binary.cc
new file mode 100644
index 0000000..407e1a6
--- /dev/null
+++ b/runtime/vm/kernel_binary.cc
@@ -0,0 +1,2902 @@
+// 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.
+
+#include <map>
+#include <vector>
+
+#include "vm/flags.h"
+#include "vm/kernel.h"
+#include "vm/os.h"
+
+#if defined(DEBUG)
+#define TRACE_READ_OFFSET() do { \
+ if (FLAG_trace_kernel_binary) \
+ reader->DumpOffset(__PRETTY_FUNCTION__); \
+ } while (0)
+#define TRACE_WRITE_OFFSET() do { \
+ if (FLAG_trace_kernel_binary) \
+ writer->DumpOffset(__PRETTY_FUNCTION__); \
+ } while (0)
+#else
+#define TRACE_READ_OFFSET()
+#define TRACE_WRITE_OFFSET()
+#endif
+
+namespace dart {
+
+
+ByteWriter::~ByteWriter() {}
+
+
+namespace kernel {
+
+
+static const uint32_t kMagicProgramFile = 0x90ABCDEFu;
+
+
+// Keep in sync with package:dynamo/lib/binary/tag.dart
+enum Tag {
+ kNothing = 0,
+ kSomething = 1,
+
+ kNormalClass = 2,
+ kMixinClass = 3,
+
+ kField = 4,
+ kConstructor = 5,
+ kProcedure = 6,
+
+ kInvalidInitializer = 7,
+ kFieldInitializer = 8,
+ kSuperInitializer = 9,
+ kRedirectingInitializer = 10,
+ kLocalInitializer = 11,
+
+ kDirectPropertyGet = 15,
+ kDirectPropertySet = 16,
+ kDirectMethodInvocation = 17,
+ kConstStaticInvocation = 18,
+ kInvalidExpression = 19,
+ kVariableGet = 20,
+ kVariableSet = 21,
+ kPropertyGet = 22,
+ kPropertySet = 23,
+ kSuperPropertyGet = 24,
+ kSuperPropertySet = 25,
+ kStaticGet = 26,
+ kStaticSet = 27,
+ kMethodInvocation = 28,
+ kSuperMethodInvocation = 29,
+ kStaticInvocation = 30,
+ kConstructorInvocation = 31,
+ kConstConstructorInvocation = 32,
+ kNot = 33,
+ kLogicalExpression = 34,
+ kConditionalExpression = 35,
+ kStringConcatenation = 36,
+ kIsExpression = 37,
+ kAsExpression = 38,
+ kStringLiteral = 39,
+ kDoubleLiteral = 40,
+ kTrueLiteral = 41,
+ kFalseLiteral = 42,
+ kNullLiteral = 43,
+ kSymbolLiteral = 44,
+ kTypeLiteral = 45,
+ kThisExpression = 46,
+ kRethrow = 47,
+ kThrow = 48,
+ kListLiteral = 49,
+ kMapLiteral = 50,
+ kAwaitExpression = 51,
+ kFunctionExpression = 52,
+ kLet = 53,
+ kBlockExpression = 54,
+
+ kPositiveIntLiteral = 55,
+ kNegativeIntLiteral = 56,
+ kBigIntLiteral = 57,
+ kConstListLiteral = 58,
+ kConstMapLiteral = 59,
+
+ kInvalidStatement = 60,
+ kExpressionStatement = 61,
+ kBlock = 62,
+ kEmptyStatement = 63,
+ kAssertStatement = 64,
+ kLabeledStatement = 65,
+ kBreakStatement = 66,
+ kWhileStatement = 67,
+ kDoStatement = 68,
+ kForStatement = 69,
+ kForInStatement = 70,
+ kSwitchStatement = 71,
+ kContinueSwitchStatement = 72,
+ kIfStatement = 73,
+ kReturnStatement = 74,
+ kTryCatch = 75,
+ kTryFinally = 76,
+ kYieldStatement = 77,
+ kVariableDeclaration = 78,
+ kFunctionDeclaration = 79,
+ kAsyncForInStatement = 80,
+
+ kInvalidType = 90,
+ kDynamicType = 91,
+ kVoidType = 92,
+ kInterfaceType = 93,
+ kFunctionType = 94,
+ kTypeParameterType = 95,
+ kSimpleInterfaceType = 96,
+ kSimpleFunctionType = 97,
+
+ kNullReference = 99,
+ kNormalClassReference = 100,
+ kMixinClassReference = 101,
+
+ kLibraryFieldReference = 102,
+ kClassFieldReference = 103,
+ kClassConstructorReference = 104,
+ kLibraryProcedureReference = 105,
+ kClassProcedureReference = 106,
+
+ kSpecializedTagHighBit = 0x80, // 10000000
+ kSpecializedTagMask = 0xF8, // 11111000
+ kSpecializedPayloadMask = 0x7, // 00000111
+
+ kSpecializedVariableGet = 128,
+ kSpecializedVariableSet = 136,
+ kSpecialIntLiteral = 144,
+};
+
+
+static const int SpecializedIntLiteralBias = 3;
+
+
+template <typename T>
+class BlockStack {
+ public:
+ BlockStack() : current_count_(0) {}
+
+ void EnterScope() {
+ variable_count_.push_back(current_count_);
+ current_count_ = 0;
+ }
+
+ void LeaveScope() {
+ variables_.resize(variables_.size() - current_count_);
+ current_count_ = variable_count_[variable_count_.size() - 1];
+ variable_count_.pop_back();
+ }
+
+ T* Lookup(int index) {
+ ASSERT(static_cast<unsigned>(index) < variables_.size());
+ return variables_[index];
+ }
+
+ void Push(T* v) {
+ variables_.push_back(v);
+ current_count_++;
+ }
+
+ void Push(List<T>* decl) {
+ for (int i = 0; i < decl->length(); i++) {
+ variables_.push_back(decl[i]);
+ current_count_++;
+ }
+ }
+
+ void Pop(T* decl) {
+ variables_.resize(variables_.size() - 1);
+ current_count_--;
+ }
+
+ void Pop(List<T>* decl) {
+ variables_.resize(variables_.size() - decl->length());
+ current_count_ -= decl->length();
+ }
+
+ private:
+ int current_count_;
+ std::vector<T*> variables_;
+ std::vector<int> variable_count_;
+};
+
+
+template <typename T>
+class BlockMap {
+ public:
+ BlockMap() : current_count_(0), stack_height_(0) {}
+
+ void EnterScope() {
+ variable_count_.push_back(current_count_);
+ current_count_ = 0;
+ }
+
+ void LeaveScope() {
+ stack_height_ -= current_count_;
+ current_count_ = variable_count_[variable_count_.size() - 1];
+ variable_count_.pop_back();
+ }
+
+ int Lookup(T* object) {
+ ASSERT(variables_.find(object) != variables_.end());
+ if (variables_.find(object) == variables_.end()) FATAL("lookup failure");
+ return variables_[object];
+ }
+
+ void Push(T* v) {
+ int index = stack_height_++;
+ variables_[v] = index;
+ current_count_++;
+ }
+
+ void Set(T* v, int index) { variables_[v] = index; }
+
+ void Push(List<T>* decl) {
+ for (int i = 0; i < decl->length(); i++) {
+ Push(decl[i]);
+ }
+ }
+
+ void Pop(T* v) {
+ current_count_--;
+ stack_height_--;
+ }
+
+ private:
+ int current_count_;
+ int stack_height_;
+ std::map<T*, int> variables_;
+ std::vector<int> variable_count_;
+};
+
+
+template <typename T>
+class VariableScope {
+ public:
+ explicit VariableScope(T* builder) : builder_(builder) {
+ builder_->variables().EnterScope();
+ }
+ ~VariableScope() { builder_->variables().LeaveScope(); }
+
+ private:
+ T* builder_;
+};
+
+
+template <typename T>
+class TypeParameterScope {
+ public:
+ explicit TypeParameterScope(T* builder) : builder_(builder) {
+ builder_->type_parameters().EnterScope();
+ }
+ ~TypeParameterScope() { builder_->type_parameters().LeaveScope(); }
+
+ private:
+ T* builder_;
+};
+
+
+template <typename T>
+class SwitchCaseScope {
+ public:
+ explicit SwitchCaseScope(T* builder) : builder_(builder) {
+ builder_->switch_cases().EnterScope();
+ }
+ ~SwitchCaseScope() { builder_->switch_cases().LeaveScope(); }
+
+ private:
+ T* builder_;
+};
+
+
+class ReaderHelper {
+ public:
+ ReaderHelper() : program_(NULL) {}
+ ~ReaderHelper() {}
+
+ Program* program() { return program_; }
+ void set_program(Program* program) { program_ = program; }
+
+ BlockStack<VariableDeclaration>& variables() { return scope_; }
+ BlockStack<TypeParameter>& type_parameters() { return type_parameters_; }
+ BlockStack<LabeledStatement>& lables() { return labels_; }
+ BlockStack<SwitchCase>& switch_cases() { return switch_cases_; }
+
+ private:
+ Program* program_;
+ BlockStack<VariableDeclaration> scope_;
+ BlockStack<TypeParameter> type_parameters_;
+ BlockStack<LabeledStatement> labels_;
+ BlockStack<SwitchCase> switch_cases_;
+};
+
+
+class Reader {
+ public:
+ Reader(const uint8_t* buffer, int64_t size)
+ : buffer_(buffer), size_(size), offset_(0) {}
+
+ uint32_t ReadUInt32() {
+ ASSERT(offset_ + 4 <= size_);
+
+ uint32_t value = (buffer_[offset_ + 0] << 24) |
+ (buffer_[offset_ + 1] << 16) |
+ (buffer_[offset_ + 2] << 8) | (buffer_[offset_ + 3] << 0);
+ offset_ += 4;
+ return value;
+ }
+
+ uint32_t ReadUInt() {
+ ASSERT(offset_ + 1 <= size_);
+ uint8_t byte0 = buffer_[offset_];
+ if ((byte0 & 0x80) == 0) {
+ // 0...
+ offset_++;
+ return byte0;
+ } else if ((byte0 & 0xc0) == 0x80) {
+ // 10...
+ ASSERT(offset_ + 2 <= size_);
+ uint32_t value = ((byte0 & ~0x80) << 8) | (buffer_[offset_ + 1]);
+ offset_ += 2;
+ return value;
+ } else {
+ // 11...
+ ASSERT(offset_ + 4 <= size_);
+ uint32_t value = ((byte0 & ~0xc0) << 24) | (buffer_[offset_ + 1] << 16) |
+ (buffer_[offset_ + 2] << 8) |
+ (buffer_[offset_ + 3] << 0);
+ offset_ += 4;
+ return value;
+ }
+ }
+
+ intptr_t ReadListLength() { return ReadUInt(); }
+
+ uint8_t ReadByte() { return buffer_[offset_++]; }
+
+ bool ReadBool() { return (ReadByte() & 1) == 1; }
+
+ word ReadFlags() { return ReadByte(); }
+
+ Tag ReadTag(uint8_t* payload = NULL) {
+ uint8_t byte = ReadByte();
+ bool has_payload = (byte & kSpecializedTagHighBit) != 0;
+ if (has_payload) {
+ if (payload != NULL) {
+ *payload = byte & kSpecializedPayloadMask;
+ }
+ return static_cast<Tag>(byte & kSpecializedTagMask);
+ } else {
+ return static_cast<Tag>(byte);
+ }
+ }
+
+ const uint8_t* Consume(int count) {
+ ASSERT(offset_ + count <= size_);
+ const uint8_t* old = buffer_ + offset_;
+ offset_ += count;
+ return old;
+ }
+
+ void EnsureEnd() {
+ if (offset_ != size_) {
+ FATAL2(
+ "Reading Kernel file: Expected to be at EOF "
+ "(offset: %" Pd64 ", size: %" Pd64 ")",
+ offset_, size_);
+ }
+ }
+
+ void DumpOffset(const char* str) {
+ OS::PrintErr("@%" Pd64 " %s\n", offset_, str);
+ }
+
+ template <typename T, typename RT>
+ T* ReadOptional() {
+ Tag tag = ReadTag();
+ if (tag == kNothing) {
+ return NULL;
+ }
+ ASSERT(tag == kSomething);
+ return RT::ReadFrom(this);
+ }
+
+ template <typename T>
+ T* ReadOptional() {
+ return ReadOptional<T, T>();
+ }
+
+ ReaderHelper* helper() { return &builder_; }
+
+ private:
+ const uint8_t* buffer_;
+ int64_t size_;
+ int64_t offset_;
+ ReaderHelper builder_;
+};
+
+
+class WriterHelper {
+ public:
+ void SetProgram(Program* program) {
+ program_ = program;
+ for (int i = 0; i < program->libraries().length(); i++) {
+ Library* lib = program->libraries()[i];
+ libraries_.Set(lib, i);
+
+ for (int j = 0; j < lib->classes().length(); j++) {
+ Class* klass = lib->classes()[j];
+ classes_.Set(klass, j);
+
+ for (int k = 0; k < klass->fields().length(); k++) {
+ Field* field = klass->fields()[k];
+ fields_.Set(field, k);
+ }
+ for (int k = 0; k < klass->constructors().length(); k++) {
+ Constructor* constructor = klass->constructors()[k];
+ constructors_.Set(constructor, k);
+ }
+ for (int k = 0; k < klass->procedures().length(); k++) {
+ Procedure* procedure = klass->procedures()[k];
+ procedures_.Set(procedure, k);
+ }
+ }
+
+ for (int k = 0; k < lib->fields().length(); k++) {
+ Field* field = lib->fields()[k];
+ fields_.Set(field, k);
+ }
+
+ for (int k = 0; k < lib->procedures().length(); k++) {
+ Procedure* procedure = lib->procedures()[k];
+ procedures_.Set(procedure, k);
+ }
+ }
+ }
+
+ Program* program() { return program_; }
+
+ BlockMap<String>& strings() { return strings_; }
+ BlockMap<Library>& libraries() { return libraries_; }
+ BlockMap<Class>& classes() { return classes_; }
+ BlockMap<Field>& fields() { return fields_; }
+ BlockMap<Procedure>& procedures() { return procedures_; }
+ BlockMap<Constructor>& constructors() { return constructors_; }
+
+ BlockMap<VariableDeclaration>& variables() { return scope_; }
+ BlockMap<TypeParameter>& type_parameters() { return type_parameters_; }
+ BlockMap<LabeledStatement>& lables() { return labels_; }
+ BlockMap<SwitchCase>& switch_cases() { return switch_cases_; }
+
+ private:
+ Program* program_;
+
+ BlockMap<String> strings_;
+ BlockMap<Library> libraries_;
+ BlockMap<Class> classes_;
+ BlockMap<Field> fields_;
+ BlockMap<Procedure> procedures_;
+ BlockMap<Constructor> constructors_;
+
+ BlockMap<VariableDeclaration> scope_;
+ BlockMap<TypeParameter> type_parameters_;
+ BlockMap<LabeledStatement> labels_;
+ BlockMap<SwitchCase> switch_cases_;
+};
+
+
+class Writer {
+ public:
+ explicit Writer(ByteWriter* writer) : out_(writer), offset_(0) {}
+
+ void WriteUInt32(uint32_t value) {
+ uint8_t buffer[4] = {
+ static_cast<uint8_t>((value >> 24) & 0xff),
+ static_cast<uint8_t>((value >> 16) & 0xff),
+ static_cast<uint8_t>((value >> 8) & 0xff),
+ static_cast<uint8_t>((value >> 0) & 0xff),
+ };
+ WriteBytes(buffer, 4);
+ }
+
+ void WriteUInt(uint32_t value) {
+ if (value < 0x80) {
+ // 0...
+ WriteByte(static_cast<uint8_t>(value));
+ } else if (value < 0x4000) {
+ // 10...
+ WriteByte(static_cast<uint8_t>(((value >> 8) & 0x3f) | 0x80));
+ WriteByte(static_cast<uint8_t>(value & 0xff));
+ } else {
+ // 11...
+ // Ensure the highest 2 bits is not used for anything (we use it to for
+ // encoding).
+ ASSERT(static_cast<uint8_t>((value >> 24) & 0xc0) == 0);
+ uint8_t buffer[4] = {
+ static_cast<uint8_t>(((value >> 24) & 0x7f) | 0xc0),
+ static_cast<uint8_t>((value >> 16) & 0xff),
+ static_cast<uint8_t>((value >> 8) & 0xff),
+ static_cast<uint8_t>((value >> 0) & 0xff),
+ };
+ WriteBytes(buffer, 4);
+ }
+ }
+
+ void WriteListLength(intptr_t value) { return WriteUInt(value); }
+
+ void WriteByte(uint8_t value) {
+ out_->WriteByte(value);
+ offset_++;
+ }
+
+ void WriteBool(bool value) { WriteByte(value ? 1 : 0); }
+
+ void WriteFlags(uint8_t value) { WriteByte(value); }
+
+ void WriteTag(Tag tag) { WriteByte(static_cast<uint8_t>(tag)); }
+
+ void WriteTag(Tag tag, uint8_t payload) {
+ ASSERT((payload & ~kSpecializedPayloadMask) == 0);
+ WriteByte(kSpecializedTagHighBit | static_cast<uint8_t>(tag) | payload);
+ }
+
+ void WriteBytes(uint8_t* bytes, int length) {
+ out_->WriteBytes(bytes, length);
+ offset_ += length;
+ }
+
+ template <typename T>
+ void WriteOptional(T* object) {
+ if (object == NULL) {
+ WriteTag(kNothing);
+ } else {
+ WriteTag(kSomething);
+ object->WriteTo(this);
+ }
+ }
+
+ template <typename T, typename WT>
+ void WriteOptionalStatic(T* object) {
+ if (object == NULL) {
+ WriteTag(kNothing);
+ } else {
+ WriteTag(kSomething);
+ WT::WriteTo(this, object);
+ }
+ }
+
+ template <typename T>
+ void WriteOptionalStatic(T* object) {
+ return WriteOptionalStatic<T, T>(object);
+ }
+
+ void DumpOffset(const char* str) {
+ OS::PrintErr("@%" Pd64 " %s\n", offset_, str);
+ }
+
+ WriterHelper* helper() { return &helper_; }
+
+ private:
+ ByteWriter* out_;
+ WriterHelper helper_;
+ int64_t offset_;
+};
+
+
+template <typename T>
+template <typename IT>
+void List<T>::ReadFrom(Reader* reader, TreeNode* parent) {
+ TRACE_READ_OFFSET();
+ ASSERT(parent != NULL);
+ int length = reader->ReadListLength();
+ EnsureInitialized(length);
+
+ for (int i = 0; i < length_; i++) {
+ IT* object = GetOrCreate<IT>(i, parent);
+ object->ReadFrom(reader);
+ }
+}
+
+
+template <typename T>
+template <typename IT>
+void List<T>::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ int length = reader->ReadListLength();
+ EnsureInitialized(length);
+
+ for (int i = 0; i < length_; i++) {
+ GetOrCreate<IT>(i)->ReadFrom(reader);
+ }
+}
+
+
+template <typename T>
+template <typename IT>
+void List<T>::ReadFromStatic(Reader* reader) {
+ TRACE_READ_OFFSET();
+ int length = reader->ReadListLength();
+ EnsureInitialized(length);
+
+ for (int i = 0; i < length_; i++) {
+ ASSERT(array_[i] == NULL);
+ array_[i] = IT::ReadFrom(reader);
+ }
+}
+
+
+template <typename T>
+void List<T>::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+
+ // NOTE: We only support dense lists.
+ writer->WriteListLength(length_);
+ for (int i = 0; i < length_; i++) {
+ T* object = array_[i];
+ ASSERT(object != NULL);
+ object->WriteTo(writer);
+ }
+}
+
+
+template <typename T>
+template <typename IT>
+void List<T>::WriteToStatic(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+
+ // NOTE: We only support dense lists.
+ writer->WriteListLength(length_);
+ for (int i = 0; i < length_; i++) {
+ T* object = array_[i];
+ ASSERT(object != NULL);
+ IT::WriteTo(writer, object);
+ }
+}
+
+
+void TypeParameterList::ReadFrom(Reader* reader) {
+ // It is possible for the bound of the first type parameter to refer to
+ // the second type parameter. This means we need to create [TypeParameter]
+ // objects before reading the bounds.
+ int length = reader->ReadListLength();
+ EnsureInitialized(length);
+
+ // Make all [TypeParameter]s available in scope.
+ for (int i = 0; i < length; i++) {
+ TypeParameter* parameter = (*this)[i] = new TypeParameter();
+ reader->helper()->type_parameters().Push(parameter);
+ }
+
+ // Read all [TypeParameter]s and their bounds.
+ for (int i = 0; i < length; i++) {
+ (*this)[i]->ReadFrom(reader);
+ }
+}
+
+
+void TypeParameterList::WriteTo(Writer* writer) {
+ writer->WriteListLength(length());
+
+ // Make all [TypeParameter]s available in scope.
+ for (int i = 0; i < length(); i++) {
+ TypeParameter* parameter = (*this)[i];
+ writer->helper()->type_parameters().Push(parameter);
+ }
+
+ // Write all [TypeParameter]s and their bounds.
+ for (int i = 0; i < length(); i++) {
+ TypeParameter* parameter = (*this)[i];
+ parameter->WriteTo(writer);
+ }
+}
+
+
+template <typename A, typename B>
+Tuple<A, B>* Tuple<A, B>::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ A* first = A::ReadFrom(reader);
+ B* second = B::ReadFrom(reader);
+ return new Tuple<A, B>(first, second);
+}
+
+
+template <typename A, typename B>
+void Tuple<A, B>::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ first_->WriteTo(writer);
+ second_->WriteTo(writer);
+}
+
+
+template <typename B, typename S>
+class DowncastReader {
+ public:
+ static S* ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ return S::Cast(B::ReadFrom(reader));
+ }
+};
+
+
+class StringImpl {
+ public:
+ static String* ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ return String::ReadFromImpl(reader);
+ }
+
+ static void WriteTo(Writer* writer, String* string) {
+ TRACE_WRITE_OFFSET();
+ string->WriteToImpl(writer);
+ }
+};
+
+
+class VariableDeclarationImpl {
+ public:
+ static VariableDeclaration* ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ return VariableDeclaration::ReadFromImpl(reader);
+ }
+
+ static void WriteTo(Writer* writer, VariableDeclaration* d) {
+ TRACE_WRITE_OFFSET();
+ d->WriteToImpl(writer);
+ }
+};
+
+
+String* String::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ return Reference::ReadStringFrom(reader);
+}
+
+
+String* String::ReadFromImpl(Reader* reader) {
+ TRACE_READ_OFFSET();
+ uint32_t bytes = reader->ReadUInt();
+ String* string = new String(reader->Consume(bytes), bytes);
+ return string;
+}
+
+
+void String::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ Reference::WriteStringTo(writer, this);
+}
+
+
+void String::WriteToImpl(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteUInt(size_);
+ writer->WriteBytes(buffer_, size_);
+}
+
+
+void StringTable::ReadFrom(Reader* reader) {
+ strings_.ReadFromStatic<StringImpl>(reader);
+}
+
+
+void StringTable::WriteTo(Writer* writer) {
+ strings_.WriteToStatic<StringImpl>(writer);
+
+ // Build up the "String* -> index" table.
+ WriterHelper* helper = writer->helper();
+ for (int i = 0; i < strings_.length(); i++) {
+ helper->strings().Push(strings_[i]);
+ }
+}
+
+
+void LineStartingTable::ReadFrom(Reader* reader, intptr_t length) {
+ size_ = length;
+ values_ = new intptr_t*[size_];
+ for (intptr_t i = 0; i < size_; ++i) {
+ intptr_t line_count = reader->ReadUInt();
+ intptr_t* line_starts = new intptr_t[line_count + 1];
+ line_starts[0] = line_count;
+ intptr_t previous_line_start = 0;
+ for (intptr_t j = 0; j < line_count; ++j) {
+ intptr_t lineStart = reader->ReadUInt() + previous_line_start;
+ line_starts[j + 1] = lineStart;
+ previous_line_start = lineStart;
+ }
+ values_[i] = line_starts;
+ }
+}
+
+
+void LineStartingTable::WriteTo(Writer* writer) {
+ for (intptr_t i = 0; i < size_; ++i) {
+ intptr_t* line_starts = values_[i];
+ intptr_t line_count = line_starts[0];
+ writer->WriteUInt(line_count);
+
+ intptr_t previous_line_start = 0;
+ for (intptr_t j = 0; j < line_count; ++j) {
+ intptr_t line_start = line_starts[j + 1];
+ writer->WriteUInt(line_start - previous_line_start);
+ previous_line_start = line_start;
+ }
+ }
+}
+
+
+Library* Library::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ int flags = reader->ReadFlags();
+ ASSERT(flags == 0); // external libraries not supported
+ name_ = Reference::ReadStringFrom(reader);
+ import_uri_ = Reference::ReadStringFrom(reader);
+ reader->ReadUInt();
+
+ int num_classes = reader->ReadUInt();
+ classes().EnsureInitialized(num_classes);
+ for (int i = 0; i < num_classes; i++) {
+ Tag tag = reader->ReadTag();
+ if (tag == kNormalClass) {
+ NormalClass* klass = classes().GetOrCreate<NormalClass>(i, this);
+ klass->ReadFrom(reader);
+ } else {
+ ASSERT(tag == kMixinClass);
+ MixinClass* klass = classes().GetOrCreate<MixinClass>(i, this);
+ klass->ReadFrom(reader);
+ }
+ }
+
+ fields().ReadFrom<Field>(reader, this);
+ procedures().ReadFrom<Procedure>(reader, this);
+ return this;
+}
+
+
+void Library::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ name_->WriteTo(writer);
+ import_uri_->WriteTo(writer);
+ writer->WriteUInt(0);
+
+ writer->WriteUInt(classes_.length());
+ for (int i = 0; i < classes_.length(); i++) {
+ Class* klass = classes_[i];
+ if (klass->IsNormalClass()) {
+ writer->WriteTag(kNormalClass);
+ NormalClass::Cast(klass)->WriteTo(writer);
+ } else {
+ writer->WriteTag(kMixinClass);
+ MixinClass::Cast(klass)->WriteTo(writer);
+ }
+ }
+ fields().WriteTo(writer);
+ procedures().WriteTo(writer);
+}
+
+
+Class* Class::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+
+ is_abstract_ = reader->ReadBool();
+ name_ = Reference::ReadStringFrom(reader);
+ reader->ReadUInt();
+ annotations_.ReadFromStatic<Expression>(reader);
+
+ return this;
+}
+
+
+void Class::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteBool(is_abstract_);
+ name_->WriteTo(writer);
+ writer->WriteUInt(0);
+ annotations_.WriteTo(writer);
+}
+
+
+NormalClass* NormalClass::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ Class::ReadFrom(reader);
+ TypeParameterScope<ReaderHelper> scope(reader->helper());
+
+ type_parameters_.ReadFrom(reader);
+ DartType* type = reader->ReadOptional<DartType>();
+
+ super_class_ = InterfaceType::Cast(type);
+ implemented_classes_.ReadFromStatic<DowncastReader<DartType, InterfaceType> >(
+ reader);
+ fields_.ReadFrom<Field>(reader, this);
+ constructors_.ReadFrom<Constructor>(reader, this);
+ procedures_.ReadFrom<Procedure>(reader, this);
+
+ return this;
+}
+
+
+void NormalClass::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ Class::WriteTo(writer);
+ TypeParameterScope<WriterHelper> scope(writer->helper());
+
+ type_parameters().WriteTo(writer);
+ writer->WriteOptional<DartType>(super_class_);
+ implemented_classes().WriteTo(writer);
+ fields_.WriteTo(writer);
+ constructors_.WriteTo(writer);
+ procedures_.WriteTo(writer);
+}
+
+
+MixinClass* MixinClass::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ TypeParameterScope<ReaderHelper> scope(reader->helper());
+
+ Class::ReadFrom(reader);
+ type_parameters_.ReadFrom(reader);
+ first_ = InterfaceType::Cast(DartType::ReadFrom(reader));
+ second_ = InterfaceType::Cast(DartType::ReadFrom(reader));
+ implemented_classes_.ReadFromStatic<DowncastReader<DartType, InterfaceType> >(
+ reader);
+ constructors_.ReadFrom<Constructor>(reader, this);
+ return this;
+}
+
+
+void MixinClass::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ TypeParameterScope<WriterHelper> scope(writer->helper());
+
+ Class::WriteTo(writer);
+ type_parameters_.WriteTo(writer);
+ first_->WriteTo(writer);
+ second_->WriteTo(writer);
+ implemented_classes_.WriteTo(writer);
+ constructors_.WriteTo(writer);
+}
+
+
+Member* Reference::ReadMemberFrom(Reader* reader, bool allow_null) {
+ TRACE_READ_OFFSET();
+
+ Program* program = reader->helper()->program();
+ Tag tag = reader->ReadTag();
+ switch (tag) {
+ case kLibraryFieldReference: {
+ int library_idx = reader->ReadUInt();
+ int field_idx = reader->ReadUInt();
+ Library* library = program->libraries().GetOrCreate<Library>(library_idx);
+ return library->fields().GetOrCreate<Field>(field_idx, library);
+ }
+ case kLibraryProcedureReference: {
+ int library_idx = reader->ReadUInt();
+ int procedure_idx = reader->ReadUInt();
+ Library* library = program->libraries().GetOrCreate<Library>(library_idx);
+ return library->procedures().GetOrCreate<Procedure>(procedure_idx,
+ library);
+ }
+ case kClassFieldReference:
+ case kClassConstructorReference:
+ case kClassProcedureReference: {
+ Class* klass = Reference::ReadClassFrom(reader);
+ if (tag == kClassFieldReference) {
+ int field_idx = reader->ReadUInt();
+ return klass->fields().GetOrCreate<Field>(field_idx, klass);
+ } else if (tag == kClassConstructorReference) {
+ int constructor_idx = reader->ReadUInt();
+ return klass->constructors().GetOrCreate<Constructor>(constructor_idx,
+ klass);
+ } else {
+ ASSERT(tag == kClassProcedureReference);
+ int procedure_idx = reader->ReadUInt();
+ return klass->procedures().GetOrCreate<Procedure>(procedure_idx, klass);
+ }
+ }
+ case kNullReference:
+ if (allow_null) {
+ return NULL;
+ } else {
+ FATAL("Expected a valid member reference, but got `null`");
+ }
+ default:
+ UNREACHABLE();
+ break;
+ }
+
+ UNREACHABLE();
+ return NULL;
+}
+
+
+void Reference::WriteMemberTo(Writer* writer, Member* member, bool allow_null) {
+ TRACE_WRITE_OFFSET();
+ if (member == NULL) {
+ if (allow_null) {
+ writer->WriteTag(kNullReference);
+ return;
+ } else {
+ FATAL("Expected a valid member reference but got `null`");
+ }
+ }
+ TreeNode* node = member->parent();
+
+ WriterHelper* helper = writer->helper();
+
+ if (node->IsLibrary()) {
+ Library* library = Library::Cast(node);
+ if (member->IsField()) {
+ Field* field = Field::Cast(member);
+ writer->WriteTag(kLibraryFieldReference);
+ writer->WriteUInt(helper->libraries().Lookup(library));
+ writer->WriteUInt(helper->fields().Lookup(field));
+ } else {
+ Procedure* procedure = Procedure::Cast(member);
+ writer->WriteTag(kLibraryProcedureReference);
+ writer->WriteUInt(helper->libraries().Lookup(library));
+ writer->WriteUInt(helper->procedures().Lookup(procedure));
+ }
+ } else {
+ Class* klass = Class::Cast(node);
+
+ if (member->IsField()) {
+ Field* field = Field::Cast(member);
+ writer->WriteTag(kClassFieldReference);
+ Reference::WriteClassTo(writer, klass);
+ writer->WriteUInt(helper->fields().Lookup(field));
+ } else if (member->IsConstructor()) {
+ Constructor* constructor = Constructor::Cast(member);
+ writer->WriteTag(kClassConstructorReference);
+ Reference::WriteClassTo(writer, klass);
+ writer->WriteUInt(helper->constructors().Lookup(constructor));
+ } else {
+ Procedure* procedure = Procedure::Cast(member);
+ writer->WriteTag(kClassProcedureReference);
+ Reference::WriteClassTo(writer, klass);
+ writer->WriteUInt(helper->procedures().Lookup(procedure));
+ }
+ }
+}
+
+
+Class* Reference::ReadClassFrom(Reader* reader, bool allow_null) {
+ TRACE_READ_OFFSET();
+ Program* program = reader->helper()->program();
+
+ Tag klass_member_tag = reader->ReadTag();
+ if (klass_member_tag == kNullReference) {
+ if (allow_null) {
+ return NULL;
+ } else {
+ FATAL("Expected a valid class reference but got `null`.");
+ }
+ }
+ int library_idx = reader->ReadUInt();
+ int class_idx = reader->ReadUInt();
+
+ Library* library = program->libraries().GetOrCreate<Library>(library_idx);
+ Class* klass;
+ if (klass_member_tag == kNormalClassReference) {
+ klass = library->classes().GetOrCreate<NormalClass>(class_idx, library);
+ } else {
+ ASSERT(klass_member_tag == kMixinClassReference);
+ klass = library->classes().GetOrCreate<MixinClass>(class_idx, library);
+ }
+ return klass;
+}
+
+
+void Reference::WriteClassTo(Writer* writer, Class* klass, bool allow_null) {
+ TRACE_WRITE_OFFSET();
+ if (klass == NULL) {
+ if (allow_null) {
+ writer->WriteTag(kNullReference);
+ return;
+ } else {
+ FATAL("Expected a valid class reference but got `null`.");
+ }
+ }
+ if (klass->IsNormalClass()) {
+ writer->WriteTag(kNormalClassReference);
+ } else {
+ ASSERT(klass->IsMixinClass());
+ writer->WriteTag(kMixinClassReference);
+ }
+
+ writer->WriteUInt(writer->helper()->libraries().Lookup(klass->parent()));
+ writer->WriteUInt(writer->helper()->classes().Lookup(klass));
+}
+
+
+String* Reference::ReadStringFrom(Reader* reader) {
+ int index = reader->ReadUInt();
+ return reader->helper()->program()->string_table().strings()[index];
+}
+
+
+void Reference::WriteStringTo(Writer* writer, String* string) {
+ int index = writer->helper()->strings().Lookup(string);
+ writer->WriteUInt(index);
+}
+
+
+Field* Field::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ Tag tag = reader->ReadTag();
+ ASSERT(tag == kField);
+
+ reader->ReadUInt();
+ flags_ = reader->ReadFlags();
+ name_ = Name::ReadFrom(reader);
+ reader->ReadUInt();
+ annotations_.ReadFromStatic<Expression>(reader);
+ type_ = DartType::ReadFrom(reader);
+ inferred_value_ = reader->ReadOptional<InferredValue>();
+ initializer_ = reader->ReadOptional<Expression>();
+ return this;
+}
+
+
+void Field::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kField);
+ writer->WriteUInt(0);
+ writer->WriteFlags(flags_);
+ name_->WriteTo(writer);
+ writer->WriteUInt(0);
+ annotations_.WriteTo(writer);
+ type_->WriteTo(writer);
+ writer->WriteOptional<InferredValue>(inferred_value_);
+ writer->WriteOptional<Expression>(initializer_);
+}
+
+
+Constructor* Constructor::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ Tag tag = reader->ReadTag();
+ ASSERT(tag == kConstructor);
+
+ VariableScope<ReaderHelper> parameters(reader->helper());
+ flags_ = reader->ReadFlags();
+ name_ = Name::ReadFrom(reader);
+ annotations_.ReadFromStatic<Expression>(reader);
+ function_ = FunctionNode::ReadFrom(reader);
+ initializers_.ReadFromStatic<Initializer>(reader);
+ return this;
+}
+
+
+void Constructor::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kConstructor);
+
+ VariableScope<WriterHelper> parameters(writer->helper());
+ writer->WriteFlags(flags_);
+ name_->WriteTo(writer);
+ annotations_.WriteTo(writer);
+ function_->WriteTo(writer);
+ initializers_.WriteTo(writer);
+}
+
+
+Procedure* Procedure::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ Tag tag = reader->ReadTag();
+ ASSERT(tag == kProcedure);
+
+ VariableScope<ReaderHelper> parameters(reader->helper());
+ kind_ = static_cast<ProcedureKind>(reader->ReadByte());
+ flags_ = reader->ReadFlags();
+ name_ = Name::ReadFrom(reader);
+ reader->ReadUInt();
+ annotations_.ReadFromStatic<Expression>(reader);
+ function_ = reader->ReadOptional<FunctionNode>();
+ return this;
+}
+
+
+void Procedure::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kProcedure);
+
+ VariableScope<WriterHelper> parameters(writer->helper());
+ writer->WriteByte(kind_);
+ writer->WriteFlags(flags_);
+ name_->WriteTo(writer);
+ writer->WriteUInt(0);
+ annotations_.WriteTo(writer);
+ writer->WriteOptional<FunctionNode>(function_);
+}
+
+
+Initializer* Initializer::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ Tag tag = reader->ReadTag();
+ switch (tag) {
+ case kInvalidInitializer:
+ return InvalidInitializer::ReadFromImpl(reader);
+ case kFieldInitializer:
+ return FieldInitializer::ReadFromImpl(reader);
+ case kSuperInitializer:
+ return SuperInitializer::ReadFromImpl(reader);
+ case kRedirectingInitializer:
+ return RedirectingInitializer::ReadFromImpl(reader);
+ case kLocalInitializer:
+ return LocalInitializer::ReadFromImpl(reader);
+ default:
+ UNREACHABLE();
+ }
+ return NULL;
+}
+
+
+InvalidInitializer* InvalidInitializer::ReadFromImpl(Reader* reader) {
+ TRACE_READ_OFFSET();
+ return new InvalidInitializer();
+}
+
+
+void InvalidInitializer::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kInvalidInitializer);
+}
+
+
+FieldInitializer* FieldInitializer::ReadFromImpl(Reader* reader) {
+ TRACE_READ_OFFSET();
+ FieldInitializer* initializer = new FieldInitializer();
+ initializer->field_ = Field::Cast(Reference::ReadMemberFrom(reader));
+ initializer->value_ = Expression::ReadFrom(reader);
+ return initializer;
+}
+
+
+void FieldInitializer::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kFieldInitializer);
+ Reference::WriteMemberTo(writer, field_);
+ value_->WriteTo(writer);
+}
+
+
+SuperInitializer* SuperInitializer::ReadFromImpl(Reader* reader) {
+ TRACE_READ_OFFSET();
+ SuperInitializer* init = new SuperInitializer();
+ init->target_ = Constructor::Cast(Reference::ReadMemberFrom(reader));
+ init->arguments_ = Arguments::ReadFrom(reader);
+ return init;
+}
+
+
+void SuperInitializer::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kSuperInitializer);
+ Reference::WriteMemberTo(writer, target_);
+ arguments_->WriteTo(writer);
+}
+
+
+RedirectingInitializer* RedirectingInitializer::ReadFromImpl(Reader* reader) {
+ TRACE_READ_OFFSET();
+ RedirectingInitializer* init = new RedirectingInitializer();
+ init->target_ = Constructor::Cast(Reference::ReadMemberFrom(reader));
+ init->arguments_ = Arguments::ReadFrom(reader);
+ return init;
+}
+
+
+void RedirectingInitializer::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kRedirectingInitializer);
+ Reference::WriteMemberTo(writer, target_);
+ arguments_->WriteTo(writer);
+}
+
+
+LocalInitializer* LocalInitializer::ReadFromImpl(Reader* reader) {
+ TRACE_READ_OFFSET();
+ LocalInitializer* init = new LocalInitializer();
+ init->variable_ = VariableDeclaration::ReadFromImpl(reader);
+ return init;
+}
+
+
+void LocalInitializer::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kLocalInitializer);
+ variable_->WriteToImpl(writer);
+}
+
+
+Expression* Expression::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ uint8_t payload = 0;
+ Tag tag = reader->ReadTag(&payload);
+ switch (tag) {
+ case kInvalidExpression:
+ return InvalidExpression::ReadFrom(reader);
+ case kVariableGet:
+ return VariableGet::ReadFrom(reader);
+ case kSpecializedVariableGet:
+ return VariableGet::ReadFrom(reader, payload);
+ case kVariableSet:
+ return VariableSet::ReadFrom(reader);
+ case kSpecializedVariableSet:
+ return VariableSet::ReadFrom(reader, payload);
+ case kPropertyGet:
+ return PropertyGet::ReadFrom(reader);
+ case kPropertySet:
+ return PropertySet::ReadFrom(reader);
+ case kDirectPropertyGet:
+ return DirectPropertyGet::ReadFrom(reader);
+ case kDirectPropertySet:
+ return DirectPropertySet::ReadFrom(reader);
+ case kStaticGet:
+ return StaticGet::ReadFrom(reader);
+ case kStaticSet:
+ return StaticSet::ReadFrom(reader);
+ case kMethodInvocation:
+ return MethodInvocation::ReadFrom(reader);
+ case kDirectMethodInvocation:
+ return DirectMethodInvocation::ReadFrom(reader);
+ case kStaticInvocation:
+ return StaticInvocation::ReadFrom(reader, false);
+ case kConstStaticInvocation:
+ return StaticInvocation::ReadFrom(reader, true);
+ case kConstructorInvocation:
+ return ConstructorInvocation::ReadFrom(reader, false);
+ case kConstConstructorInvocation:
+ return ConstructorInvocation::ReadFrom(reader, true);
+ case kNot:
+ return Not::ReadFrom(reader);
+ case kLogicalExpression:
+ return LogicalExpression::ReadFrom(reader);
+ case kConditionalExpression:
+ return ConditionalExpression::ReadFrom(reader);
+ case kStringConcatenation:
+ return StringConcatenation::ReadFrom(reader);
+ case kIsExpression:
+ return IsExpression::ReadFrom(reader);
+ case kAsExpression:
+ return AsExpression::ReadFrom(reader);
+ case kSymbolLiteral:
+ return SymbolLiteral::ReadFrom(reader);
+ case kTypeLiteral:
+ return TypeLiteral::ReadFrom(reader);
+ case kThisExpression:
+ return ThisExpression::ReadFrom(reader);
+ case kRethrow:
+ return Rethrow::ReadFrom(reader);
+ case kThrow:
+ return Throw::ReadFrom(reader);
+ case kListLiteral:
+ return ListLiteral::ReadFrom(reader, false);
+ case kConstListLiteral:
+ return ListLiteral::ReadFrom(reader, true);
+ case kMapLiteral:
+ return MapLiteral::ReadFrom(reader, false);
+ case kConstMapLiteral:
+ return MapLiteral::ReadFrom(reader, true);
+ case kAwaitExpression:
+ return AwaitExpression::ReadFrom(reader);
+ case kFunctionExpression:
+ return FunctionExpression::ReadFrom(reader);
+ case kLet:
+ return Let::ReadFrom(reader);
+ case kBlockExpression:
+ return BlockExpression::ReadFrom(reader);
+ case kBigIntLiteral:
+ return BigintLiteral::ReadFrom(reader);
+ case kStringLiteral:
+ return StringLiteral::ReadFrom(reader);
+ case kSpecialIntLiteral:
+ return IntLiteral::ReadFrom(reader, payload);
+ case kNegativeIntLiteral:
+ return IntLiteral::ReadFrom(reader, true);
+ case kPositiveIntLiteral:
+ return IntLiteral::ReadFrom(reader, false);
+ case kDoubleLiteral:
+ return DoubleLiteral::ReadFrom(reader);
+ case kTrueLiteral:
+ return BoolLiteral::ReadFrom(reader, true);
+ case kFalseLiteral:
+ return BoolLiteral::ReadFrom(reader, false);
+ case kNullLiteral:
+ return NullLiteral::ReadFrom(reader);
+ default:
+ UNREACHABLE();
+ }
+ return NULL;
+}
+
+
+InvalidExpression* InvalidExpression::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ return new InvalidExpression();
+}
+
+
+void InvalidExpression::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kInvalidExpression);
+}
+
+
+VariableGet* VariableGet::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ VariableGet* get = new VariableGet();
+ get->variable_ = reader->helper()->variables().Lookup(reader->ReadUInt());
+ reader->ReadOptional<DartType>(); // Unused promoted type.
+ return get;
+}
+
+
+VariableGet* VariableGet::ReadFrom(Reader* reader, uint8_t payload) {
+ TRACE_READ_OFFSET();
+ VariableGet* get = new VariableGet();
+ get->variable_ = reader->helper()->variables().Lookup(payload);
+ return get;
+}
+
+
+void VariableGet::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ int index = writer->helper()->variables().Lookup(variable_);
+ if ((index & kSpecializedPayloadMask) == index) {
+ writer->WriteTag(kSpecializedVariableGet, static_cast<uint8_t>(index));
+ } else {
+ writer->WriteTag(kVariableGet);
+ writer->WriteUInt(index);
+ writer->WriteOptional<DartType>(NULL);
+ }
+}
+
+
+VariableSet* VariableSet::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ VariableSet* set = new VariableSet();
+ set->variable_ = reader->helper()->variables().Lookup(reader->ReadUInt());
+ set->expression_ = Expression::ReadFrom(reader);
+ return set;
+}
+
+
+VariableSet* VariableSet::ReadFrom(Reader* reader, uint8_t payload) {
+ TRACE_READ_OFFSET();
+ VariableSet* set = new VariableSet();
+ set->variable_ = reader->helper()->variables().Lookup(payload);
+ set->expression_ = Expression::ReadFrom(reader);
+ return set;
+}
+
+
+void VariableSet::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ int index = writer->helper()->variables().Lookup(variable_);
+ if ((index & kSpecializedPayloadMask) == index) {
+ writer->WriteTag(kSpecializedVariableSet, static_cast<uint8_t>(index));
+ } else {
+ writer->WriteTag(kVariableSet);
+ writer->WriteUInt(index);
+ }
+ expression_->WriteTo(writer);
+}
+
+
+PropertyGet* PropertyGet::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ PropertyGet* get = new PropertyGet();
+ reader->ReadUInt();
+ get->receiver_ = Expression::ReadFrom(reader);
+ get->name_ = Name::ReadFrom(reader);
+ get->interfaceTarget_ = Reference::ReadMemberFrom(reader, true);
+ return get;
+}
+
+
+void PropertyGet::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kPropertyGet);
+ writer->WriteUInt(0);
+ receiver_->WriteTo(writer);
+ name_->WriteTo(writer);
+ Reference::WriteMemberTo(writer, interfaceTarget_, true);
+}
+
+
+PropertySet* PropertySet::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ PropertySet* set = new PropertySet();
+ reader->ReadUInt();
+ set->receiver_ = Expression::ReadFrom(reader);
+ set->name_ = Name::ReadFrom(reader);
+ set->value_ = Expression::ReadFrom(reader);
+ set->interfaceTarget_ = Reference::ReadMemberFrom(reader, true);
+ return set;
+}
+
+
+void PropertySet::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kPropertySet);
+ writer->WriteUInt(0);
+ receiver_->WriteTo(writer);
+ name_->WriteTo(writer);
+ value_->WriteTo(writer);
+ Reference::WriteMemberTo(writer, interfaceTarget_, true);
+}
+
+
+DirectPropertyGet* DirectPropertyGet::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ DirectPropertyGet* get = new DirectPropertyGet();
+ get->receiver_ = Expression::ReadFrom(reader);
+ get->target_ = Reference::ReadMemberFrom(reader);
+ return get;
+}
+
+
+void DirectPropertyGet::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kDirectPropertyGet);
+ receiver_->WriteTo(writer);
+ Reference::WriteMemberTo(writer, target_);
+}
+
+
+DirectPropertySet* DirectPropertySet::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ DirectPropertySet* set = new DirectPropertySet();
+ set->receiver_ = Expression::ReadFrom(reader);
+ set->target_ = Reference::ReadMemberFrom(reader);
+ set->value_ = Expression::ReadFrom(reader);
+ return set;
+}
+
+
+void DirectPropertySet::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kDirectPropertySet);
+ receiver_->WriteTo(writer);
+ Reference::WriteMemberTo(writer, target_);
+ value_->WriteTo(writer);
+}
+
+
+StaticGet* StaticGet::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ StaticGet* get = new StaticGet();
+ reader->ReadUInt();
+ get->target_ = Reference::ReadMemberFrom(reader);
+ return get;
+}
+
+
+void StaticGet::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kStaticGet);
+ writer->WriteUInt(0);
+ Reference::WriteMemberTo(writer, target_);
+}
+
+
+StaticSet* StaticSet::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ StaticSet* set = new StaticSet();
+ set->target_ = Reference::ReadMemberFrom(reader);
+ set->expression_ = Expression::ReadFrom(reader);
+ return set;
+}
+
+
+void StaticSet::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kStaticSet);
+ Reference::WriteMemberTo(writer, target_);
+ expression_->WriteTo(writer);
+}
+
+
+Arguments* Arguments::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ Arguments* arguments = new Arguments();
+ arguments->types().ReadFromStatic<DartType>(reader);
+ arguments->positional().ReadFromStatic<Expression>(reader);
+ arguments->named().ReadFromStatic<NamedExpression>(reader);
+ return arguments;
+}
+
+
+void Arguments::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ types().WriteTo(writer);
+ positional().WriteTo(writer);
+ named().WriteTo(writer);
+}
+
+
+NamedExpression* NamedExpression::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ String* name = Reference::ReadStringFrom(reader);
+ Expression* expression = Expression::ReadFrom(reader);
+ return new NamedExpression(name, expression);
+}
+
+
+void NamedExpression::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ name_->WriteTo(writer);
+ expression_->WriteTo(writer);
+}
+
+
+MethodInvocation* MethodInvocation::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ MethodInvocation* invocation = new MethodInvocation();
+ reader->ReadUInt();
+ invocation->receiver_ = Expression::ReadFrom(reader);
+ invocation->name_ = Name::ReadFrom(reader);
+ invocation->arguments_ = Arguments::ReadFrom(reader);
+ invocation->interfaceTarget_ = Reference::ReadMemberFrom(reader, true);
+ return invocation;
+}
+
+
+void MethodInvocation::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kMethodInvocation);
+ writer->WriteUInt(0);
+ receiver_->WriteTo(writer);
+ name_->WriteTo(writer);
+ arguments_->WriteTo(writer);
+ Reference::WriteMemberTo(writer, interfaceTarget_, true);
+}
+
+
+DirectMethodInvocation* DirectMethodInvocation::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ DirectMethodInvocation* invocation = new DirectMethodInvocation();
+ invocation->receiver_ = Expression::ReadFrom(reader);
+ invocation->target_ = Procedure::Cast(Reference::ReadMemberFrom(reader));
+ invocation->arguments_ = Arguments::ReadFrom(reader);
+ return invocation;
+}
+
+
+void DirectMethodInvocation::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kDirectMethodInvocation);
+ receiver_->WriteTo(writer);
+ Reference::WriteMemberTo(writer, target_);
+ arguments_->WriteTo(writer);
+}
+
+
+StaticInvocation* StaticInvocation::ReadFrom(Reader* reader, bool is_const) {
+ TRACE_READ_OFFSET();
+
+ reader->ReadUInt();
+ Member* member = Reference::ReadMemberFrom(reader);
+ Arguments* args = Arguments::ReadFrom(reader);
+
+ return new StaticInvocation(Procedure::Cast(member), args, is_const);
+}
+
+
+void StaticInvocation::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(is_const_ ? kConstStaticInvocation : kStaticInvocation);
+ writer->WriteUInt(0);
+ Reference::WriteMemberTo(writer, procedure_);
+ arguments_->WriteTo(writer);
+}
+
+
+ConstructorInvocation* ConstructorInvocation::ReadFrom(Reader* reader,
+ bool is_const) {
+ TRACE_READ_OFFSET();
+ ConstructorInvocation* invocation = new ConstructorInvocation();
+ invocation->is_const_ = is_const;
+ reader->ReadUInt();
+ invocation->target_ = Constructor::Cast(Reference::ReadMemberFrom(reader));
+ invocation->arguments_ = Arguments::ReadFrom(reader);
+ return invocation;
+}
+
+
+void ConstructorInvocation::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(is_const_ ? kConstConstructorInvocation
+ : kConstructorInvocation);
+ writer->WriteUInt(0);
+ Reference::WriteMemberTo(writer, target_);
+ arguments_->WriteTo(writer);
+}
+
+
+Not* Not::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ Not* n = new Not();
+ n->expression_ = Expression::ReadFrom(reader);
+ return n;
+}
+
+
+void Not::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kNot);
+ expression_->WriteTo(writer);
+}
+
+
+LogicalExpression* LogicalExpression::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ LogicalExpression* expr = new LogicalExpression();
+ expr->left_ = Expression::ReadFrom(reader);
+ expr->operator_ = static_cast<Operator>(reader->ReadByte());
+ expr->right_ = Expression::ReadFrom(reader);
+ return expr;
+}
+
+
+void LogicalExpression::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kLogicalExpression);
+ left_->WriteTo(writer);
+ writer->WriteByte(operator_);
+ right_->WriteTo(writer);
+}
+
+
+ConditionalExpression* ConditionalExpression::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ ConditionalExpression* expr = new ConditionalExpression();
+ expr->condition_ = Expression::ReadFrom(reader);
+ expr->then_ = Expression::ReadFrom(reader);
+ expr->otherwise_ = Expression::ReadFrom(reader);
+ reader->ReadOptional<DartType>(); // Unused static type.
+ return expr;
+}
+
+
+void ConditionalExpression::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kConditionalExpression);
+ condition_->WriteTo(writer);
+ then_->WriteTo(writer);
+ otherwise_->WriteTo(writer);
+ writer->WriteOptional<DartType>(NULL); // Unused static type.
+}
+
+
+StringConcatenation* StringConcatenation::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ StringConcatenation* concat = new StringConcatenation();
+ concat->expressions_.ReadFromStatic<Expression>(reader);
+ return concat;
+}
+
+
+void StringConcatenation::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kStringConcatenation);
+ expressions_.WriteTo(writer);
+}
+
+
+IsExpression* IsExpression::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ IsExpression* expr = new IsExpression();
+ expr->operand_ = Expression::ReadFrom(reader);
+ expr->type_ = DartType::ReadFrom(reader);
+ return expr;
+}
+
+
+void IsExpression::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kIsExpression);
+ operand_->WriteTo(writer);
+ type_->WriteTo(writer);
+}
+
+
+AsExpression* AsExpression::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ AsExpression* expr = new AsExpression();
+ expr->operand_ = Expression::ReadFrom(reader);
+ expr->type_ = DartType::ReadFrom(reader);
+ return expr;
+}
+
+
+void AsExpression::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kAsExpression);
+ operand_->WriteTo(writer);
+ type_->WriteTo(writer);
+}
+
+
+StringLiteral* StringLiteral::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ return new StringLiteral(Reference::ReadStringFrom(reader));
+}
+
+
+void StringLiteral::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kStringLiteral);
+ value_->WriteTo(writer);
+}
+
+
+BigintLiteral* BigintLiteral::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ return new BigintLiteral(Reference::ReadStringFrom(reader));
+}
+
+
+void BigintLiteral::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kBigIntLiteral);
+ value_->WriteTo(writer);
+}
+
+
+IntLiteral* IntLiteral::ReadFrom(Reader* reader, bool is_negative) {
+ TRACE_READ_OFFSET();
+ IntLiteral* literal = new IntLiteral();
+ literal->value_ = is_negative ? -static_cast<int64_t>(reader->ReadUInt())
+ : reader->ReadUInt();
+ return literal;
+}
+
+
+IntLiteral* IntLiteral::ReadFrom(Reader* reader, uint8_t payload) {
+ TRACE_READ_OFFSET();
+ IntLiteral* literal = new IntLiteral();
+ literal->value_ = static_cast<int32_t>(payload) - SpecializedIntLiteralBias;
+ return literal;
+}
+
+
+void IntLiteral::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ int64_t payload = value_ + SpecializedIntLiteralBias;
+ if ((payload & kSpecializedPayloadMask) == payload) {
+ writer->WriteTag(kSpecialIntLiteral, static_cast<uint8_t>(payload));
+ } else {
+ writer->WriteTag(value_ < 0 ? kNegativeIntLiteral : kPositiveIntLiteral);
+ writer->WriteUInt(static_cast<uint32_t>(value_ < 0 ? -value_ : value_));
+ }
+}
+
+
+DoubleLiteral* DoubleLiteral::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ DoubleLiteral* literal = new DoubleLiteral();
+ literal->value_ = Reference::ReadStringFrom(reader);
+ return literal;
+}
+
+
+void DoubleLiteral::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kDoubleLiteral);
+ value_->WriteTo(writer);
+}
+
+
+BoolLiteral* BoolLiteral::ReadFrom(Reader* reader, bool value) {
+ TRACE_READ_OFFSET();
+ BoolLiteral* lit = new BoolLiteral();
+ lit->value_ = value;
+ return lit;
+}
+
+
+void BoolLiteral::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(value_ ? kTrueLiteral : kFalseLiteral);
+}
+
+
+NullLiteral* NullLiteral::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ return new NullLiteral();
+}
+
+
+void NullLiteral::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kNullLiteral);
+}
+
+
+SymbolLiteral* SymbolLiteral::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ SymbolLiteral* lit = new SymbolLiteral();
+ lit->value_ = Reference::ReadStringFrom(reader);
+ return lit;
+}
+
+
+void SymbolLiteral::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kSymbolLiteral);
+ value_->WriteTo(writer);
+}
+
+
+TypeLiteral* TypeLiteral::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ TypeLiteral* literal = new TypeLiteral();
+ literal->type_ = DartType::ReadFrom(reader);
+ return literal;
+}
+
+
+void TypeLiteral::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kTypeLiteral);
+ type_->WriteTo(writer);
+}
+
+
+ThisExpression* ThisExpression::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ return new ThisExpression();
+}
+
+
+void ThisExpression::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kThisExpression);
+}
+
+
+Rethrow* Rethrow::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ return new Rethrow();
+}
+
+
+void Rethrow::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kRethrow);
+}
+
+
+Throw* Throw::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ Throw* t = new Throw();
+ reader->ReadUInt();
+ t->expression_ = Expression::ReadFrom(reader);
+ return t;
+}
+
+
+void Throw::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kThrow);
+ writer->WriteUInt(0);
+ expression_->WriteTo(writer);
+}
+
+
+ListLiteral* ListLiteral::ReadFrom(Reader* reader, bool is_const) {
+ TRACE_READ_OFFSET();
+ ListLiteral* literal = new ListLiteral();
+ literal->is_const_ = is_const;
+ literal->type_ = DartType::ReadFrom(reader);
+ literal->expressions_.ReadFromStatic<Expression>(reader);
+ return literal;
+}
+
+
+void ListLiteral::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(is_const_ ? kConstListLiteral : kListLiteral);
+ type_->WriteTo(writer);
+ expressions_.WriteTo(writer);
+}
+
+
+MapLiteral* MapLiteral::ReadFrom(Reader* reader, bool is_const) {
+ TRACE_READ_OFFSET();
+ MapLiteral* literal = new MapLiteral();
+ literal->is_const_ = is_const;
+ literal->key_type_ = DartType::ReadFrom(reader);
+ literal->value_type_ = DartType::ReadFrom(reader);
+ literal->entries_.ReadFromStatic<MapEntry>(reader);
+ return literal;
+}
+
+
+void MapLiteral::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(is_const_ ? kConstMapLiteral : kMapLiteral);
+ key_type_->WriteTo(writer);
+ value_type_->WriteTo(writer);
+ entries_.WriteTo(writer);
+}
+
+
+MapEntry* MapEntry::ReadFrom(Reader* reader) {
+ MapEntry* entry = new MapEntry();
+ entry->key_ = Expression::ReadFrom(reader);
+ entry->value_ = Expression::ReadFrom(reader);
+ return entry;
+}
+
+
+void MapEntry::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ key_->WriteTo(writer);
+ value_->WriteTo(writer);
+}
+
+
+AwaitExpression* AwaitExpression::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ AwaitExpression* await = new AwaitExpression();
+ await->operand_ = Expression::ReadFrom(reader);
+ return await;
+}
+
+
+void AwaitExpression::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kAwaitExpression);
+ operand_->WriteTo(writer);
+}
+
+
+FunctionExpression* FunctionExpression::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ VariableScope<ReaderHelper> parameters(reader->helper());
+ FunctionExpression* expr = new FunctionExpression();
+ expr->function_ = FunctionNode::ReadFrom(reader);
+ return expr;
+}
+
+
+void FunctionExpression::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ VariableScope<WriterHelper> parameters(writer->helper());
+ writer->WriteTag(kFunctionExpression);
+ function_->WriteTo(writer);
+}
+
+
+Let* Let::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ VariableScope<ReaderHelper> vars(reader->helper());
+ Let* let = new Let();
+ let->variable_ = VariableDeclaration::ReadFromImpl(reader);
+ let->body_ = Expression::ReadFrom(reader);
+ return let;
+}
+
+
+void Let::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ VariableScope<WriterHelper> vars(writer->helper());
+ writer->WriteTag(kLet);
+ variable_->WriteToImpl(writer);
+ body_->WriteTo(writer);
+}
+
+
+BlockExpression* BlockExpression::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ BlockExpression* be = new BlockExpression();
+ be->body_ = Block::ReadFromImpl(reader);
+ be->value_ = Expression::ReadFrom(reader);
+ return be;
+}
+
+
+void BlockExpression::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kBlockExpression);
+ body_->WriteToImpl(writer);
+ value_->WriteTo(writer);
+}
+
+
+Statement* Statement::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ Tag tag = reader->ReadTag();
+ switch (tag) {
+ case kInvalidStatement:
+ return InvalidStatement::ReadFrom(reader);
+ case kExpressionStatement:
+ return ExpressionStatement::ReadFrom(reader);
+ case kBlock:
+ return Block::ReadFromImpl(reader);
+ case kEmptyStatement:
+ return EmptyStatement::ReadFrom(reader);
+ case kAssertStatement:
+ return AssertStatement::ReadFrom(reader);
+ case kLabeledStatement:
+ return LabeledStatement::ReadFrom(reader);
+ case kBreakStatement:
+ return BreakStatement::ReadFrom(reader);
+ case kWhileStatement:
+ return WhileStatement::ReadFrom(reader);
+ case kDoStatement:
+ return DoStatement::ReadFrom(reader);
+ case kForStatement:
+ return ForStatement::ReadFrom(reader);
+ case kForInStatement:
+ return ForInStatement::ReadFrom(reader, false);
+ case kAsyncForInStatement:
+ return ForInStatement::ReadFrom(reader, true);
+ case kSwitchStatement:
+ return SwitchStatement::ReadFrom(reader);
+ case kContinueSwitchStatement:
+ return ContinueSwitchStatement::ReadFrom(reader);
+ case kIfStatement:
+ return IfStatement::ReadFrom(reader);
+ case kReturnStatement:
+ return ReturnStatement::ReadFrom(reader);
+ case kTryCatch:
+ return TryCatch::ReadFrom(reader);
+ case kTryFinally:
+ return TryFinally::ReadFrom(reader);
+ case kYieldStatement:
+ return YieldStatement::ReadFrom(reader);
+ case kVariableDeclaration:
+ return VariableDeclaration::ReadFromImpl(reader);
+ case kFunctionDeclaration:
+ return FunctionDeclaration::ReadFrom(reader);
+ default:
+ UNREACHABLE();
+ }
+ return NULL;
+}
+
+
+InvalidStatement* InvalidStatement::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ return new InvalidStatement();
+}
+
+
+void InvalidStatement::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kInvalidStatement);
+}
+
+
+ExpressionStatement* ExpressionStatement::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ return new ExpressionStatement(Expression::ReadFrom(reader));
+}
+
+
+void ExpressionStatement::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kExpressionStatement);
+ expression_->WriteTo(writer);
+}
+
+
+Block* Block::ReadFromImpl(Reader* reader) {
+ TRACE_READ_OFFSET();
+ VariableScope<ReaderHelper> vars(reader->helper());
+ Block* block = new Block();
+ block->statements().ReadFromStatic<Statement>(reader);
+ return block;
+}
+
+
+void Block::WriteTo(Writer* writer) {
+ writer->WriteTag(kBlock);
+ WriteToImpl(writer);
+}
+
+
+void Block::WriteToImpl(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ VariableScope<WriterHelper> vars(writer->helper());
+ statements_.WriteTo(writer);
+}
+
+
+EmptyStatement* EmptyStatement::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ return new EmptyStatement();
+}
+
+
+void EmptyStatement::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kEmptyStatement);
+}
+
+
+AssertStatement* AssertStatement::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ AssertStatement* stmt = new AssertStatement();
+ stmt->condition_ = Expression::ReadFrom(reader);
+ stmt->message_ = reader->ReadOptional<Expression>();
+ return stmt;
+}
+
+
+void AssertStatement::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kAssertStatement);
+ condition_->WriteTo(writer);
+ writer->WriteOptional<Expression>(message_);
+}
+
+
+LabeledStatement* LabeledStatement::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ LabeledStatement* stmt = new LabeledStatement();
+ reader->helper()->lables().Push(stmt);
+ stmt->body_ = Statement::ReadFrom(reader);
+ reader->helper()->lables().Pop(stmt);
+ return stmt;
+}
+
+
+void LabeledStatement::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kLabeledStatement);
+ writer->helper()->lables().Push(this);
+ body_->WriteTo(writer);
+ writer->helper()->lables().Pop(this);
+}
+
+
+BreakStatement* BreakStatement::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ BreakStatement* stmt = new BreakStatement();
+ stmt->target_ = reader->helper()->lables().Lookup(reader->ReadUInt());
+ return stmt;
+}
+
+
+void BreakStatement::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kBreakStatement);
+ writer->WriteUInt(writer->helper()->lables().Lookup(target_));
+}
+
+
+WhileStatement* WhileStatement::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ WhileStatement* stmt = new WhileStatement();
+ stmt->condition_ = Expression::ReadFrom(reader);
+ stmt->body_ = Statement::ReadFrom(reader);
+ return stmt;
+}
+
+
+void WhileStatement::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kWhileStatement);
+ condition_->WriteTo(writer);
+ body_->WriteTo(writer);
+}
+
+
+DoStatement* DoStatement::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ DoStatement* dostmt = new DoStatement();
+ dostmt->body_ = Statement::ReadFrom(reader);
+ dostmt->condition_ = Expression::ReadFrom(reader);
+ return dostmt;
+}
+
+
+void DoStatement::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kDoStatement);
+ body_->WriteTo(writer);
+ condition_->WriteTo(writer);
+}
+
+
+ForStatement* ForStatement::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ VariableScope<ReaderHelper> vars(reader->helper());
+ ForStatement* forstmt = new ForStatement();
+ forstmt->variables_.ReadFromStatic<VariableDeclarationImpl>(reader);
+ forstmt->condition_ = reader->ReadOptional<Expression>();
+ forstmt->updates_.ReadFromStatic<Expression>(reader);
+ forstmt->body_ = Statement::ReadFrom(reader);
+ return forstmt;
+}
+
+
+void ForStatement::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kForStatement);
+ VariableScope<WriterHelper> vars(writer->helper());
+ variables_.WriteToStatic<VariableDeclarationImpl>(writer);
+ writer->WriteOptional<Expression>(condition_);
+ updates_.WriteTo(writer);
+ body_->WriteTo(writer);
+}
+
+
+ForInStatement* ForInStatement::ReadFrom(Reader* reader, bool is_async) {
+ TRACE_READ_OFFSET();
+ VariableScope<ReaderHelper> vars(reader->helper());
+ ForInStatement* forinstmt = new ForInStatement();
+ forinstmt->is_async_ = is_async;
+ forinstmt->variable_ = VariableDeclaration::ReadFromImpl(reader);
+ forinstmt->iterable_ = Expression::ReadFrom(reader);
+ forinstmt->body_ = Statement::ReadFrom(reader);
+ return forinstmt;
+}
+
+
+void ForInStatement::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(is_async_ ? kAsyncForInStatement : kForInStatement);
+ VariableScope<WriterHelper> vars(writer->helper());
+ variable_->WriteToImpl(writer);
+ iterable_->WriteTo(writer);
+ body_->WriteTo(writer);
+}
+
+
+SwitchStatement* SwitchStatement::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ SwitchCaseScope<ReaderHelper> scope(reader->helper());
+ SwitchStatement* stmt = new SwitchStatement();
+ stmt->condition_ = Expression::ReadFrom(reader);
+ // We need to explicitly create empty [SwitchCase]s first in order to add them
+ // to the [SwitchCaseScope]. This is necessary since a [Statement] in a switch
+ // case can refer to one defined later on.
+ int count = reader->ReadUInt();
+ for (int i = 0; i < count; i++) {
+ SwitchCase* sc = stmt->cases_.GetOrCreate<SwitchCase>(i);
+ reader->helper()->switch_cases().Push(sc);
+ }
+ for (int i = 0; i < count; i++) {
+ SwitchCase* sc = stmt->cases_[i];
+ sc->ReadFrom(reader);
+ }
+ return stmt;
+}
+
+
+void SwitchStatement::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ SwitchCaseScope<WriterHelper> scope(writer->helper());
+ writer->WriteTag(kSwitchStatement);
+ condition_->WriteTo(writer);
+ for (int i = 0; i < cases_.length(); i++) {
+ writer->helper()->switch_cases().Push(cases_[i]);
+ }
+ cases_.WriteTo(writer);
+}
+
+
+SwitchCase* SwitchCase::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ expressions_.ReadFromStatic<Expression>(reader);
+ is_default_ = reader->ReadBool();
+ body_ = Statement::ReadFrom(reader);
+ return this;
+}
+
+
+void SwitchCase::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ expressions_.WriteTo(writer);
+ writer->WriteBool(is_default_);
+ body_->WriteTo(writer);
+}
+
+
+ContinueSwitchStatement* ContinueSwitchStatement::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ ContinueSwitchStatement* stmt = new ContinueSwitchStatement();
+ stmt->target_ = reader->helper()->switch_cases().Lookup(reader->ReadUInt());
+ return stmt;
+}
+
+
+void ContinueSwitchStatement::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kContinueSwitchStatement);
+ writer->WriteUInt(writer->helper()->switch_cases().Lookup(target_));
+}
+
+
+IfStatement* IfStatement::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ IfStatement* ifstmt = new IfStatement();
+ ifstmt->condition_ = Expression::ReadFrom(reader);
+ ifstmt->then_ = Statement::ReadFrom(reader);
+ ifstmt->otherwise_ = Statement::ReadFrom(reader);
+ return ifstmt;
+}
+
+
+void IfStatement::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kIfStatement);
+ condition_->WriteTo(writer);
+ then_->WriteTo(writer);
+ otherwise_->WriteTo(writer);
+}
+
+
+ReturnStatement* ReturnStatement::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ ReturnStatement* ret = new ReturnStatement();
+ ret->expression_ = reader->ReadOptional<Expression>();
+ return ret;
+}
+
+
+void ReturnStatement::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kReturnStatement);
+ writer->WriteOptional<Expression>(expression_);
+}
+
+
+TryCatch* TryCatch::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ TryCatch* tc = new TryCatch();
+ tc->body_ = Statement::ReadFrom(reader);
+ tc->catches_.ReadFromStatic<Catch>(reader);
+ return tc;
+}
+
+
+void TryCatch::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kTryCatch);
+ body_->WriteTo(writer);
+ catches_.WriteTo(writer);
+}
+
+
+Catch* Catch::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ VariableScope<ReaderHelper> vars(reader->helper());
+ Catch* c = new Catch();
+ c->guard_ = DartType::ReadFrom(reader);
+ c->exception_ =
+ reader->ReadOptional<VariableDeclaration, VariableDeclarationImpl>();
+ c->stack_trace_ =
+ reader->ReadOptional<VariableDeclaration, VariableDeclarationImpl>();
+ c->body_ = Statement::ReadFrom(reader);
+ return c;
+}
+
+
+void Catch::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ VariableScope<WriterHelper> vars(writer->helper());
+ guard_->WriteTo(writer);
+ writer->WriteOptionalStatic<VariableDeclaration, VariableDeclarationImpl>(
+ exception_);
+ writer->WriteOptionalStatic<VariableDeclaration, VariableDeclarationImpl>(
+ stack_trace_);
+ body_->WriteTo(writer);
+}
+
+
+TryFinally* TryFinally::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ TryFinally* tf = new TryFinally();
+ tf->body_ = Statement::ReadFrom(reader);
+ tf->finalizer_ = Statement::ReadFrom(reader);
+ return tf;
+}
+
+
+void TryFinally::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kTryFinally);
+ body_->WriteTo(writer);
+ finalizer_->WriteTo(writer);
+}
+
+
+YieldStatement* YieldStatement::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ YieldStatement* stmt = new YieldStatement();
+ stmt->flags_ = reader->ReadByte();
+ stmt->expression_ = Expression::ReadFrom(reader);
+ return stmt;
+}
+
+
+void YieldStatement::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kYieldStatement);
+ writer->WriteByte(flags_);
+ expression_->WriteTo(writer);
+}
+
+
+VariableDeclaration* VariableDeclaration::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ Tag tag = reader->ReadTag();
+ ASSERT(tag == kVariableDeclaration);
+ return VariableDeclaration::ReadFromImpl(reader);
+}
+
+
+VariableDeclaration* VariableDeclaration::ReadFromImpl(Reader* reader) {
+ TRACE_READ_OFFSET();
+ VariableDeclaration* decl = new VariableDeclaration();
+ decl->flags_ = reader->ReadFlags();
+ decl->name_ = Reference::ReadStringFrom(reader);
+ decl->type_ = DartType::ReadFrom(reader);
+ decl->inferred_value_ = reader->ReadOptional<InferredValue>();
+ decl->initializer_ = reader->ReadOptional<Expression>();
+ reader->helper()->variables().Push(decl);
+ return decl;
+}
+
+
+void VariableDeclaration::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kVariableDeclaration);
+ WriteToImpl(writer);
+}
+
+
+void VariableDeclaration::WriteToImpl(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteFlags(flags_);
+ name_->WriteTo(writer);
+ type_->WriteTo(writer);
+ writer->WriteOptional<InferredValue>(inferred_value_);
+ writer->WriteOptional<Expression>(initializer_);
+ writer->helper()->variables().Push(this);
+}
+
+
+FunctionDeclaration* FunctionDeclaration::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ FunctionDeclaration* decl = new FunctionDeclaration();
+ decl->variable_ = VariableDeclaration::ReadFromImpl(reader);
+ VariableScope<ReaderHelper> parameters(reader->helper());
+ decl->function_ = FunctionNode::ReadFrom(reader);
+ return decl;
+}
+
+
+void FunctionDeclaration::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kFunctionDeclaration);
+ variable_->WriteToImpl(writer);
+ VariableScope<WriterHelper> parameters(writer->helper());
+ function_->WriteTo(writer);
+}
+
+
+Name* Name::ReadFrom(Reader* reader) {
+ String* string = Reference::ReadStringFrom(reader);
+ if (string->size() >= 1 && string->buffer()[0] == '_') {
+ int lib_index = reader->ReadUInt();
+ Library* library =
+ reader->helper()->program()->libraries().GetOrCreate<Library>(
+ lib_index);
+ return new Name(string, library);
+ } else {
+ return new Name(string, NULL);
+ }
+}
+
+
+void Name::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ string_->WriteTo(writer);
+ Library* library = library_;
+ bool is_private = library != NULL;
+ if (is_private) {
+ writer->WriteUInt(writer->helper()->libraries().Lookup(library_));
+ }
+}
+
+
+InferredValue* InferredValue::ReadFrom(Reader* reader) {
+ InferredValue* type = new InferredValue();
+ type->klass_ = Reference::ReadClassFrom(reader, true);
+ type->kind_ = static_cast<BaseClassKind>(reader->ReadByte());
+ type->value_bits_ = reader->ReadByte();
+ return type;
+}
+
+
+void InferredValue::WriteTo(Writer* writer) {
+ Reference::WriteClassTo(writer, klass_, true);
+ writer->WriteByte(static_cast<uint8_t>(kind_));
+ writer->WriteByte(value_bits_);
+}
+
+
+DartType* DartType::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ Tag tag = reader->ReadTag();
+ switch (tag) {
+ case kInvalidType:
+ return InvalidType::ReadFrom(reader);
+ case kDynamicType:
+ return DynamicType::ReadFrom(reader);
+ case kVoidType:
+ return VoidType::ReadFrom(reader);
+ case kInterfaceType:
+ return InterfaceType::ReadFrom(reader);
+ case kSimpleInterfaceType:
+ return InterfaceType::ReadFrom(reader, true);
+ case kFunctionType:
+ return FunctionType::ReadFrom(reader);
+ case kSimpleFunctionType:
+ return FunctionType::ReadFrom(reader, true);
+ case kTypeParameterType:
+ return TypeParameterType::ReadFrom(reader);
+ default:
+ UNREACHABLE();
+ }
+ UNREACHABLE();
+ return NULL;
+}
+
+
+InvalidType* InvalidType::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ return new InvalidType();
+}
+
+
+void InvalidType::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kInvalidType);
+}
+
+
+DynamicType* DynamicType::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ return new DynamicType();
+}
+
+
+void DynamicType::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kDynamicType);
+}
+
+
+VoidType* VoidType::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ return new VoidType();
+}
+
+
+void VoidType::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kVoidType);
+}
+
+
+InterfaceType* InterfaceType::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ Class* klass = Reference::ReadClassFrom(reader);
+ InterfaceType* type = new InterfaceType(klass);
+ type->type_arguments().ReadFromStatic<DartType>(reader);
+ return type;
+}
+
+
+InterfaceType* InterfaceType::ReadFrom(Reader* reader,
+ bool _without_type_arguments_) {
+ TRACE_READ_OFFSET();
+ Class* klass = Reference::ReadClassFrom(reader);
+ InterfaceType* type = new InterfaceType(klass);
+ ASSERT(_without_type_arguments_);
+ return type;
+}
+
+
+void InterfaceType::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ if (type_arguments_.length() == 0) {
+ writer->WriteTag(kSimpleInterfaceType);
+ Reference::WriteClassTo(writer, klass_);
+ } else {
+ writer->WriteTag(kInterfaceType);
+ Reference::WriteClassTo(writer, klass_);
+ type_arguments_.WriteTo(writer);
+ }
+}
+
+
+FunctionType* FunctionType::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ FunctionType* type = new FunctionType();
+ TypeParameterScope<ReaderHelper> scope(reader->helper());
+ type->type_parameters().ReadFrom(reader);
+ type->required_parameter_count_ = reader->ReadUInt();
+ type->positional_parameters().ReadFromStatic<DartType>(reader);
+ type->named_parameters().ReadFromStatic<Tuple<String, DartType> >(reader);
+ type->return_type_ = DartType::ReadFrom(reader);
+ return type;
+}
+
+
+FunctionType* FunctionType::ReadFrom(Reader* reader, bool _is_simple_) {
+ TRACE_READ_OFFSET();
+ FunctionType* type = new FunctionType();
+ ASSERT(_is_simple_);
+ type->positional_parameters().ReadFromStatic<DartType>(reader);
+ type->required_parameter_count_ = type->positional_parameters().length();
+ type->return_type_ = DartType::ReadFrom(reader);
+ return type;
+}
+
+
+void FunctionType::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+
+ bool is_simple =
+ positional_parameters_.length() == required_parameter_count_ &&
+ type_parameters_.length() == 0 && named_parameters_.length() == 0;
+ if (is_simple) {
+ writer->WriteTag(kSimpleFunctionType);
+ positional_parameters_.WriteTo(writer);
+ return_type_->WriteTo(writer);
+ } else {
+ TypeParameterScope<WriterHelper> scope(writer->helper());
+ writer->WriteTag(kFunctionType);
+ type_parameters_.WriteTo(writer);
+ writer->WriteUInt(required_parameter_count_);
+ positional_parameters_.WriteTo(writer);
+ named_parameters_.WriteTo(writer);
+ return_type_->WriteTo(writer);
+ }
+}
+
+
+TypeParameterType* TypeParameterType::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ TypeParameterType* type = new TypeParameterType();
+ type->parameter_ =
+ reader->helper()->type_parameters().Lookup(reader->ReadUInt());
+ return type;
+}
+
+
+void TypeParameterType::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ writer->WriteTag(kTypeParameterType);
+ writer->WriteUInt(writer->helper()->type_parameters().Lookup(parameter_));
+}
+
+
+Program* Program::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ uint32_t magic = reader->ReadUInt32();
+ if (magic != kMagicProgramFile) FATAL("Invalid magic identifier");
+
+ Program* program = new Program();
+ reader->helper()->set_program(program);
+
+ program->string_table_.ReadFrom(reader);
+ StringTable dummy1;
+ dummy1.ReadFrom(reader);
+ LineStartingTable dummy2;
+ dummy2.ReadFrom(reader, dummy1.strings_.length());
+
+ int libraries = reader->ReadUInt();
+ program->libraries().EnsureInitialized(libraries);
+ for (int i = 0; i < libraries; i++) {
+ program->libraries().GetOrCreate<Library>(i)->ReadFrom(reader);
+ }
+
+ program->main_method_ = Procedure::Cast(Reference::ReadMemberFrom(reader));
+
+ return program;
+}
+
+
+void Program::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+
+ writer->helper()->SetProgram(this);
+
+ writer->WriteUInt32(kMagicProgramFile);
+
+ // NOTE: Currently we don't GC strings and we require that all referenced
+ // strings in nodes are present in [string_table_].
+ string_table_.WriteTo(writer);
+ StringTable dummy1;
+ dummy1.WriteTo(writer);
+ LineStartingTable dummy2;
+ dummy2.WriteTo(writer);
+
+ libraries_.WriteTo(writer);
+ Reference::WriteMemberTo(writer, main_method_);
+}
+
+
+FunctionNode* FunctionNode::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ TypeParameterScope<ReaderHelper> scope(reader->helper());
+
+ FunctionNode* function = new FunctionNode();
+ function->async_marker_ =
+ static_cast<FunctionNode::AsyncMarker>(reader->ReadByte());
+ function->type_parameters().ReadFrom(reader);
+ function->required_parameter_count_ = reader->ReadUInt();
+ function->positional_parameters().ReadFromStatic<VariableDeclarationImpl>(
+ reader);
+ function->named_parameters().ReadFromStatic<VariableDeclarationImpl>(reader);
+ function->return_type_ = DartType::ReadFrom(reader);
+ function->inferred_return_value_ = reader->ReadOptional<InferredValue>();
+
+ VariableScope<ReaderHelper> vars(reader->helper());
+ function->body_ = reader->ReadOptional<Statement>();
+ return function;
+}
+
+
+void FunctionNode::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ TypeParameterScope<WriterHelper> scope(writer->helper());
+
+ writer->WriteByte(static_cast<uint8_t>(async_marker_));
+ type_parameters().WriteTo(writer);
+ writer->WriteUInt(required_parameter_count());
+ positional_parameters().WriteToStatic<VariableDeclarationImpl>(writer);
+ named_parameters().WriteToStatic<VariableDeclarationImpl>(writer);
+ return_type_->WriteTo(writer);
+ writer->WriteOptional<InferredValue>(inferred_return_value_);
+
+ VariableScope<WriterHelper> vars(writer->helper());
+ writer->WriteOptional<Statement>(body_);
+}
+
+
+TypeParameter* TypeParameter::ReadFrom(Reader* reader) {
+ TRACE_READ_OFFSET();
+ name_ = Reference::ReadStringFrom(reader);
+ bound_ = DartType::ReadFrom(reader);
+ return this;
+}
+
+
+void TypeParameter::WriteTo(Writer* writer) {
+ TRACE_WRITE_OFFSET();
+ name_->WriteTo(writer);
+ bound_->WriteTo(writer);
+}
+
+
+} // namespace kernel
+
+
+kernel::Program* ReadPrecompiledKernelFromBuffer(const uint8_t* buffer,
+ intptr_t buffer_length) {
+ kernel::Reader reader(buffer, buffer_length);
+ return kernel::Program::ReadFrom(&reader);
+}
+
+
+void WritePrecompiledKernel(ByteWriter* byte_writer, kernel::Program* program) {
+ ASSERT(byte_writer != NULL);
+
+ kernel::Writer writer(byte_writer);
+ program->WriteTo(&writer);
+}
+
+
+} // namespace dart
diff --git a/runtime/vm/kernel_reader.cc b/runtime/vm/kernel_reader.cc
new file mode 100644
index 0000000..4eb6001
--- /dev/null
+++ b/runtime/vm/kernel_reader.cc
@@ -0,0 +1,716 @@
+// 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.
+
+#include "vm/kernel_reader.h"
+
+#include <string.h>
+
+#include "vm/dart_api_impl.h"
+#include "vm/longjump.h"
+#include "vm/object_store.h"
+#include "vm/parser.h"
+#include "vm/symbols.h"
+
+namespace dart {
+namespace kernel {
+
+#define Z (zone_)
+#define I (isolate_)
+#define T (type_translator_)
+#define H (translation_helper_)
+
+class SimpleExpressionConverter : public ExpressionVisitor {
+ public:
+ SimpleExpressionConverter(Thread* thread, Zone* zone)
+ : translation_helper_(thread, zone, NULL),
+ zone_(zone),
+ is_simple_(false),
+ simple_value_(NULL) {}
+
+ virtual void VisitDefaultExpression(Expression* node) { is_simple_ = false; }
+
+ virtual void VisitIntLiteral(IntLiteral* node) {
+ is_simple_ = true;
+ simple_value_ =
+ &Integer::ZoneHandle(Z, Integer::New(node->value(), Heap::kOld));
+ *simple_value_ = H.Canonicalize(*simple_value_);
+ }
+
+ virtual void VisitBigintLiteral(BigintLiteral* node) {
+ is_simple_ = true;
+ simple_value_ = &Integer::ZoneHandle(
+ Z, Integer::New(H.DartString(node->value(), Heap::kOld)));
+ *simple_value_ = H.Canonicalize(*simple_value_);
+ }
+
+ virtual void VisitDoubleLiteral(DoubleLiteral* node) {
+ is_simple_ = true;
+ simple_value_ = &Double::ZoneHandle(
+ Z, Double::New(H.DartString(node->value()), Heap::kOld));
+ *simple_value_ = H.Canonicalize(*simple_value_);
+ }
+
+ virtual void VisitBoolLiteral(BoolLiteral* node) {
+ is_simple_ = true;
+ simple_value_ = &Bool::Handle(Z, Bool::Get(node->value()).raw());
+ }
+
+ virtual void VisitNullLiteral(NullLiteral* node) {
+ is_simple_ = true;
+ simple_value_ = &dart::Instance::ZoneHandle(Z, dart::Instance::null());
+ }
+
+ virtual void VisitStringLiteral(StringLiteral* node) {
+ is_simple_ = true;
+ simple_value_ = &H.DartSymbol(node->value());
+ }
+
+ bool IsSimple(Expression* expression) {
+ expression->AcceptExpressionVisitor(this);
+ return is_simple_;
+ }
+
+ const dart::Instance& SimpleValue() { return *simple_value_; }
+ dart::Zone* zone() const { return zone_; }
+
+ private:
+ TranslationHelper translation_helper_;
+ dart::Zone* zone_;
+ bool is_simple_;
+ dart::Instance* simple_value_;
+};
+
+void BuildingTranslationHelper::SetFinalize(bool finalize) {
+ reader_->finalize_ = finalize;
+}
+
+RawLibrary* BuildingTranslationHelper::LookupLibraryByKernelLibrary(
+ Library* library) {
+ return reader_->LookupLibrary(library).raw();
+}
+
+RawClass* BuildingTranslationHelper::LookupClassByKernelClass(Class* klass) {
+ return reader_->LookupClass(klass).raw();
+}
+
+Object& KernelReader::ReadProgram() {
+ ASSERT(!bootstrapping_);
+ Program* program = ReadPrecompiledKernelFromBuffer(buffer_, buffer_length_);
+ if (program == NULL) {
+ const dart::String& error = H.DartString("Failed to read .kernell file");
+ return Object::Handle(Z, ApiError::New(error));
+ }
+
+ LongJumpScope jump;
+ if (setjmp(*jump.Set()) == 0) {
+ Procedure* main = program->main_method();
+ Library* kernel_main_library = Library::Cast(main->parent());
+
+ intptr_t length = program->libraries().length();
+ for (intptr_t i = 0; i < length; i++) {
+ Library* kernel_library = program->libraries()[i];
+ ReadLibrary(kernel_library);
+ }
+
+ // We finalize classes after we've constructed all classes since we
+ // currently don't construct them in pre-order of the class hierarchy (and
+ // finalization of a class needs all of its superclasses to be finalized).
+ dart::String& name = dart::String::Handle(Z);
+ for (intptr_t i = 0; i < length; i++) {
+ Library* kernel_library = program->libraries()[i];
+ dart::Library& library = LookupLibrary(kernel_library);
+ name = library.url();
+
+ // TODO(27590) unskip this library when we fix underlying issue.
+ if (name.Equals("dart:vmservice_io")) {
+ continue;
+ }
+
+ if (!library.Loaded()) {
+ dart::Class& klass = dart::Class::Handle(Z);
+ for (intptr_t i = 0; i < kernel_library->classes().length(); i++) {
+ klass = LookupClass(kernel_library->classes()[i]).raw();
+ ClassFinalizer::FinalizeTypesInClass(klass);
+ ClassFinalizer::FinalizeClass(klass);
+ }
+ library.SetLoaded();
+ }
+ }
+
+ dart::Library& library = LookupLibrary(kernel_main_library);
+
+ // Sanity check that we can find the main entrypoint.
+ Object& main_obj = Object::Handle(
+ Z, library.LookupObjectAllowPrivate(H.DartSymbol("main")));
+ ASSERT(!main_obj.IsNull());
+ return library;
+ } else {
+ // Everything else is a compile-time error. We don't use the [error] since
+ // it sometimes causes the higher-level error handling to try to read the
+ // script and token position (which we don't have) to produce a nice error
+ // message.
+ Error& error = Error::Handle(Z);
+ error = thread_->sticky_error();
+ thread_->clear_sticky_error();
+
+ // Instead we simply make a non-informative error message.
+ const dart::String& error_message =
+ H.DartString("Failed to read .kernell file => CompileTimeError.");
+ return Object::Handle(Z, LanguageError::New(error_message));
+ }
+}
+
+void KernelReader::ReadLibrary(Library* kernel_library) {
+ dart::Library& library = LookupLibrary(kernel_library);
+ if (library.Loaded()) return;
+
+ // The bootstrapper will take care of creating the native wrapper classes, but
+ // we will add the synthetic constructors to them here.
+ if (library.name() ==
+ Symbols::Symbol(Symbols::kDartNativeWrappersLibNameId).raw()) {
+ ASSERT(library.LoadInProgress());
+ } else {
+ library.SetLoadInProgress();
+ }
+ // Setup toplevel class (which contains library fields/procedures).
+
+ // TODO(27590): Figure out why we need this script stuff here.
+ Script& script = Script::Handle(
+ Z,
+ Script::New(H.DartString(""), H.DartString(""), RawScript::kScriptTag));
+ script.SetLocationOffset(0, 0);
+ script.Tokenize(H.DartString("nop() {}"));
+ dart::Class& toplevel_class = dart::Class::Handle(Z, dart::Class::New(
+ library, Symbols::TopLevel(), script, TokenPosition::kNoSource));
+ toplevel_class.set_is_cycle_free();
+ library.set_toplevel_class(toplevel_class);
+ if (bootstrapping_) {
+ GrowableObjectArray::Handle(Z, I->object_store()->pending_classes())
+ .Add(toplevel_class, Heap::kOld);
+ }
+
+ ActiveClassScope active_class_scope(&active_class_, NULL, &toplevel_class);
+ // Load toplevel fields.
+ for (intptr_t i = 0; i < kernel_library->fields().length(); i++) {
+ Field* kernel_field = kernel_library->fields()[i];
+
+ ActiveMemberScope active_member_scope(&active_class_, kernel_field);
+ const dart::String& name = H.DartFieldName(kernel_field->name());
+ dart::Field& field = dart::Field::Handle(
+ Z, dart::Field::NewTopLevel(name, kernel_field->IsFinal(),
+ kernel_field->IsConst(), toplevel_class,
+ TokenPosition::kNoSource));
+ field.set_kernel_field(kernel_field);
+ const AbstractType& type = T.TranslateType(kernel_field->type());
+ field.SetFieldType(type);
+ field.set_has_initializer(kernel_field->initializer() != NULL);
+ GenerateFieldAccessors(toplevel_class, field, kernel_field);
+ toplevel_class.AddField(field);
+ library.AddObject(field, name);
+ }
+
+ // Load toplevel procedures.
+ for (intptr_t i = 0; i < kernel_library->procedures().length(); i++) {
+ Procedure* kernel_procedure = kernel_library->procedures()[i];
+ ReadProcedure(library, toplevel_class, kernel_procedure);
+ }
+
+ // Load all classes.
+ for (intptr_t i = 0; i < kernel_library->classes().length(); i++) {
+ Class* kernel_klass = kernel_library->classes()[i];
+ ReadClass(library, kernel_klass);
+ }
+}
+
+void KernelReader::ReadPreliminaryClass(dart::Class* klass,
+ Class* kernel_klass) {
+ ActiveClassScope active_class_scope(&active_class_, kernel_klass, klass);
+
+ // First setup the type parameters, so if any of the following code uses it
+ // (in a recursive way) we're fine.
+ TypeArguments& type_parameters =
+ TypeArguments::Handle(Z, TypeArguments::null());
+ intptr_t num_type_parameters = kernel_klass->type_parameters().length();
+ if (num_type_parameters > 0) {
+ dart::TypeParameter& parameter = dart::TypeParameter::Handle(Z);
+ Type& null_bound = Type::Handle(Z, Type::null());
+
+ // Step a) Create array of [TypeParameter] objects (without bound).
+ type_parameters = TypeArguments::New(num_type_parameters);
+ for (intptr_t i = 0; i < num_type_parameters; i++) {
+ parameter = dart::TypeParameter::New(
+ *klass, Function::Handle(Z), i,
+ H.DartSymbol(kernel_klass->type_parameters()[i]->name()), null_bound,
+ TokenPosition::kNoSource);
+ type_parameters.SetTypeAt(i, parameter);
+ }
+ klass->set_type_parameters(type_parameters);
+
+ // Step b) Fill in the bounds of all [TypeParameter]s.
+ for (intptr_t i = 0; i < num_type_parameters; i++) {
+ TypeParameter* kernel_parameter = kernel_klass->type_parameters()[i];
+ // There is no dynamic bound, only Object.
+ // TODO(27590): Should we fix this in the kernel IR generator?
+ if (kernel_parameter->bound()->IsDynamicType()) {
+ parameter ^= type_parameters.TypeAt(i);
+ parameter.set_bound(Type::Handle(Z, I->object_store()->object_type()));
+ } else {
+ AbstractType& bound =
+ T.TranslateTypeWithoutFinalization(kernel_parameter->bound());
+ if (bound.IsMalformedOrMalbounded()) {
+ bound = I->object_store()->object_type();
+ }
+
+ parameter ^= type_parameters.TypeAt(i);
+ parameter.set_bound(bound);
+ }
+ }
+ }
+
+ if (kernel_klass->IsNormalClass()) {
+ NormalClass* kernel_normal_class = NormalClass::Cast(kernel_klass);
+
+ // Set super type. Some classes (e.g., Object) do not have one.
+ if (kernel_normal_class->super_class() != NULL) {
+ AbstractType& super_type = T.TranslateTypeWithoutFinalization(
+ kernel_normal_class->super_class());
+ if (super_type.IsMalformed()) H.ReportError("Malformed super type");
+ klass->set_super_type(super_type);
+ }
+ } else {
+ MixinClass* kernel_mixin = MixinClass::Cast(kernel_klass);
+
+ // Set super type.
+ AbstractType& super_type =
+ T.TranslateTypeWithoutFinalization(kernel_mixin->first());
+ if (super_type.IsMalformed()) H.ReportError("Malformed super type.");
+ klass->set_super_type(super_type);
+
+ // Tell the rest of the system there is nothing to resolve.
+ super_type.SetIsResolved();
+
+ // Set mixin type.
+ AbstractType& mixin_type =
+ T.TranslateTypeWithoutFinalization(kernel_mixin->second());
+ if (mixin_type.IsMalformed()) H.ReportError("Malformed mixin type.");
+ klass->set_mixin(Type::Cast(mixin_type));
+ }
+
+ // Build implemented interface types
+ intptr_t interface_count = kernel_klass->implemented_classes().length();
+ const dart::Array& interfaces =
+ dart::Array::Handle(Z, dart::Array::New(interface_count));
+ dart::Class& interface_class = dart::Class::Handle(Z);
+ for (intptr_t i = 0; i < interface_count; i++) {
+ InterfaceType* kernel_interface_type =
+ kernel_klass->implemented_classes()[i];
+ const AbstractType& type =
+ T.TranslateTypeWithoutFinalization(kernel_interface_type);
+ if (type.IsMalformed()) H.ReportError("Malformed interface type.");
+ interfaces.SetAt(i, type);
+
+ // NOTE: Normally the DartVM keeps a list of pending classes and iterates
+ // through them later on using `ClassFinalizer::ProcessPendingClasses()`.
+ // This involes calling `ClassFinalizer::ResolveSuperTypeAndInterfaces()`
+ // which does a lot of error validation (e.g. cycle checks) which we don't
+ // need here. But we do need to do one thing which this resolving phase
+ // normally does for us: set the `is_implemented` boolean.
+
+ // TODO(27590): Maybe we can do this differently once we have
+ // "bootstrapping from kernel"-support.
+ interface_class = type.type_class();
+ interface_class.set_is_implemented();
+ }
+ klass->set_interfaces(interfaces);
+ if (kernel_klass->is_abstract()) klass->set_is_abstract();
+ klass->set_is_cycle_free();
+
+ // When bootstrapping we should not finalize types yet because they will be
+ // finalized when the object store's pending_classes list is drained by
+ // ClassFinalizer::ProcessPendingClasses. Even when not bootstrapping we are
+ // careful not to eagerly finalize types that may introduce a circularity
+ // (such as type arguments, interface types, field types, etc.).
+ if (finalize_) ClassFinalizer::FinalizeTypesInClass(*klass);
+}
+
+void KernelReader::ReadClass(const dart::Library& library,
+ Class* kernel_klass) {
+ // This will trigger a call to [ReadPreliminaryClass] if not already done.
+ dart::Class& klass = LookupClass(kernel_klass);
+
+ ActiveClassScope active_class_scope(&active_class_, kernel_klass, &klass);
+
+ TokenPosition pos(0);
+
+ for (intptr_t i = 0; i < kernel_klass->fields().length(); i++) {
+ Field* kernel_field = kernel_klass->fields()[i];
+ ActiveMemberScope active_member_scope(&active_class_, kernel_field);
+
+ const dart::String& name = H.DartFieldName(kernel_field->name());
+ const AbstractType& type =
+ T.TranslateTypeWithoutFinalization(kernel_field->type());
+ dart::Field& field = dart::Field::Handle(
+ Z, dart::Field::New(name, kernel_field->IsStatic(),
+ // In the VM all const fields are implicitly final
+ // whereas in Kernel they are not final because they
+ // are not explicitly declared that way.
+ kernel_field->IsFinal() || kernel_field->IsConst(),
+ kernel_field->IsConst(),
+ false, // is_reflectable
+ klass, type, pos));
+ field.set_kernel_field(kernel_field);
+ field.set_has_initializer(kernel_field->initializer() != NULL);
+ GenerateFieldAccessors(klass, field, kernel_field);
+ klass.AddField(field);
+ }
+
+ for (intptr_t i = 0; i < kernel_klass->constructors().length(); i++) {
+ Constructor* kernel_constructor = kernel_klass->constructors()[i];
+ ActiveMemberScope active_member_scope(&active_class_, kernel_constructor);
+ ActiveFunctionScope active_function_scope(&active_class_,
+ kernel_constructor->function());
+
+ const dart::String& name = H.DartConstructorName(kernel_constructor);
+ Function& function = dart::Function::ZoneHandle(
+ Z, dart::Function::New(name, RawFunction::kConstructor,
+ false, // is_static
+ kernel_constructor->IsConst(),
+ false, // is_abstract
+ kernel_constructor->IsExternal(),
+ false, // is_native
+ klass, pos));
+ klass.AddFunction(function);
+ function.set_kernel_function(kernel_constructor);
+ function.set_result_type(T.ReceiverType(klass));
+ SetupFunctionParameters(H, T, klass, function,
+ kernel_constructor->function(),
+ true, // is_method
+ false); // is_closure
+ }
+
+ for (intptr_t i = 0; i < kernel_klass->procedures().length(); i++) {
+ Procedure* kernel_procedure = kernel_klass->procedures()[i];
+ ActiveMemberScope active_member_scope(&active_class_, kernel_procedure);
+ ReadProcedure(library, klass, kernel_procedure, kernel_klass);
+ }
+
+ if (bootstrapping_ && !klass.is_marked_for_parsing()) {
+ klass.set_is_marked_for_parsing();
+ GrowableObjectArray::Handle(Z, I->object_store()->pending_classes())
+ .Add(klass, Heap::kOld);
+ }
+}
+
+void KernelReader::ReadProcedure(const dart::Library& library,
+ const dart::Class& owner,
+ Procedure* kernel_procedure,
+ Class* kernel_klass) {
+ ActiveClassScope active_class_scope(&active_class_, kernel_klass, &owner);
+ ActiveMemberScope active_member_scope(&active_class_, kernel_procedure);
+ ActiveFunctionScope active_function_scope(&active_class_,
+ kernel_procedure->function());
+
+ const dart::String& name = H.DartProcedureName(kernel_procedure);
+ TokenPosition pos(0);
+ bool is_method = kernel_klass != NULL && !kernel_procedure->IsStatic();
+ bool is_abstract = kernel_procedure->IsAbstract();
+ bool is_external = kernel_procedure->IsExternal();
+ dart::String* native_name = NULL;
+ if (is_external) {
+ // Maybe it has a native implementation, which is not external as far as
+ // the VM is concerned because it does have an implementation. Check for
+ // an ExternalName annotation and extract the string from it.
+ for (int i = 0; i < kernel_procedure->annotations().length(); ++i) {
+ Expression* annotation = kernel_procedure->annotations()[i];
+ if (!annotation->IsConstructorInvocation()) continue;
+ ConstructorInvocation* invocation =
+ ConstructorInvocation::Cast(annotation);
+ Class* annotation_class = Class::Cast(invocation->target()->parent());
+ String* class_name = annotation_class->name();
+ // Just compare by name, do not generate the annotation class.
+ int length = sizeof("ExternalName") - 1;
+ if (class_name->size() != length) continue;
+ if (memcmp(class_name->buffer(), "ExternalName", length) != 0) continue;
+ String* library_name = annotation_class->parent()->name();
+ length = sizeof("dart._internal") - 1;
+ if (library_name->size() != length) continue;
+ if (memcmp(library_name->buffer(), "dart._internal", length) != 0) {
+ continue;
+ }
+
+ is_external = false;
+ ASSERT(invocation->arguments()->positional().length() == 1 &&
+ invocation->arguments()->named().length() == 0);
+ StringLiteral* literal =
+ StringLiteral::Cast(invocation->arguments()->positional()[0]);
+ native_name = &H.DartSymbol(literal->value());
+ break;
+ }
+ }
+ dart::Function& function = dart::Function::ZoneHandle(
+ Z, Function::New(name, GetFunctionType(kernel_procedure),
+ !is_method, // is_static
+ false, // is_const
+ is_abstract, is_external,
+ native_name != NULL, // is_native
+ owner, pos));
+ owner.AddFunction(function);
+ function.set_kernel_function(kernel_procedure);
+ function.set_is_debuggable(false);
+ if (native_name != NULL) {
+ function.set_native_name(*native_name);
+ }
+
+ SetupFunctionParameters(H, T, owner, function, kernel_procedure->function(),
+ is_method,
+ false); // is_closure
+
+ if (kernel_klass == NULL) {
+ library.AddObject(function, name);
+ ASSERT(!Object::Handle(Z, library.LookupObjectAllowPrivate(
+ H.DartProcedureName(kernel_procedure)))
+ .IsNull());
+ }
+}
+
+void KernelReader::GenerateFieldAccessors(const dart::Class& klass,
+ const dart::Field& field,
+ Field* kernel_field) {
+ TokenPosition pos(0);
+
+ if (kernel_field->IsStatic() && kernel_field->initializer() != NULL) {
+ // Static fields with initializers either have the static value set to the
+ // initializer value if it is simple enough or else set to an uninitialized
+ // sentinel.
+ SimpleExpressionConverter converter(H.thread(), Z);
+ if (converter.IsSimple(kernel_field->initializer())) {
+ // We do not need a getter.
+ field.SetStaticValue(converter.SimpleValue(), true);
+ return;
+ }
+ // We do need a getter that evaluates the initializer if necessary.
+ field.SetStaticValue(Object::sentinel(), true);
+ }
+
+ const dart::String& getter_name = H.DartGetterName(kernel_field->name());
+ Function& getter = Function::ZoneHandle(
+ Z,
+ Function::New(
+ getter_name,
+ kernel_field->IsStatic() ? RawFunction::kImplicitStaticFinalGetter
+ : RawFunction::kImplicitGetter,
+ kernel_field->IsStatic(),
+ // The functions created by the parser have is_const for static fields
+ // that are const (not just final) and they have is_const for
+ // non-static
+ // fields that are final.
+ kernel_field->IsStatic() ? kernel_field->IsConst()
+ : kernel_field->IsFinal(),
+ false, // is_abstract
+ false, // is_external
+ false, // is_native
+ klass, pos));
+ klass.AddFunction(getter);
+ if (klass.IsTopLevel()) {
+ dart::Library& library = dart::Library::Handle(Z, klass.library());
+ library.AddObject(getter, getter_name);
+ }
+ getter.set_kernel_function(kernel_field);
+ getter.set_result_type(AbstractType::Handle(Z, field.type()));
+ getter.set_is_debuggable(false);
+ SetupFieldAccessorFunction(klass, getter);
+
+ if (!kernel_field->IsStatic() && !kernel_field->IsFinal()) {
+ // Only static fields can be const.
+ ASSERT(!kernel_field->IsConst());
+ const dart::String& setter_name = H.DartSetterName(kernel_field->name());
+ Function& setter = Function::ZoneHandle(
+ Z, Function::New(setter_name, RawFunction::kImplicitSetter,
+ false, // is_static
+ false, // is_const
+ false, // is_abstract
+ false, // is_external
+ false, // is_native
+ klass, pos));
+ klass.AddFunction(setter);
+ setter.set_kernel_function(kernel_field);
+ setter.set_result_type(Object::void_type());
+ setter.set_is_debuggable(false);
+ SetupFieldAccessorFunction(klass, setter);
+ }
+}
+
+void KernelReader::SetupFunctionParameters(TranslationHelper translation_helper,
+ DartTypeTranslator type_translator,
+ const dart::Class& klass,
+ const dart::Function& function,
+ FunctionNode* node, bool is_method,
+ bool is_closure) {
+ dart::Zone* zone = translation_helper.zone();
+
+ ASSERT(!(is_method && is_closure));
+ bool is_factory = function.IsFactory();
+ intptr_t extra_parameters = (is_method || is_closure || is_factory) ? 1 : 0;
+
+ function.set_num_fixed_parameters(extra_parameters +
+ node->required_parameter_count());
+ if (node->named_parameters().length() > 0) {
+ function.SetNumOptionalParameters(node->named_parameters().length(), false);
+ } else {
+ function.SetNumOptionalParameters(node->positional_parameters().length() -
+ node->required_parameter_count(),
+ true);
+ }
+ intptr_t num_parameters = extra_parameters +
+ node->positional_parameters().length() +
+ node->named_parameters().length();
+ function.set_parameter_types(
+ Array::Handle(zone, Array::New(num_parameters, Heap::kOld)));
+ function.set_parameter_names(
+ Array::Handle(zone, Array::New(num_parameters, Heap::kOld)));
+ intptr_t pos = 0;
+ if (is_method) {
+ ASSERT(!klass.IsNull());
+ function.SetParameterTypeAt(pos,
+ translation_helper.GetCanonicalType(klass));
+ function.SetParameterNameAt(pos, Symbols::This());
+ pos++;
+ } else if (is_closure) {
+ function.SetParameterTypeAt(pos, AbstractType::dynamic_type());
+ function.SetParameterNameAt(pos, Symbols::ClosureParameter());
+ pos++;
+ } else if (is_factory) {
+ function.SetParameterTypeAt(pos, AbstractType::dynamic_type());
+ function.SetParameterNameAt(pos, Symbols::TypeArgumentsParameter());
+ pos++;
+ }
+ for (intptr_t i = 0; i < node->positional_parameters().length(); i++, pos++) {
+ VariableDeclaration* kernel_variable = node->positional_parameters()[i];
+ const AbstractType& type =
+ type_translator.TranslateType(kernel_variable->type());
+ function.SetParameterTypeAt(
+ pos, type.IsMalformed() ? Type::dynamic_type() : type);
+ function.SetParameterNameAt(
+ pos, translation_helper.DartSymbol(kernel_variable->name()));
+ }
+ for (intptr_t i = 0; i < node->named_parameters().length(); i++, pos++) {
+ VariableDeclaration* named_expression = node->named_parameters()[i];
+ const AbstractType& type =
+ type_translator.TranslateType(named_expression->type());
+ function.SetParameterTypeAt(
+ pos, type.IsMalformed() ? Type::dynamic_type() : type);
+ function.SetParameterNameAt(
+ pos, translation_helper.DartSymbol(named_expression->name()));
+ }
+
+ const AbstractType& return_type =
+ type_translator.TranslateType(node->return_type());
+ function.set_result_type(return_type.IsMalformed() ? Type::dynamic_type()
+ : return_type);
+}
+
+void KernelReader::SetupFieldAccessorFunction(const dart::Class& klass,
+ const dart::Function& function) {
+ bool is_setter = function.IsImplicitSetterFunction();
+ bool is_method = !function.IsStaticFunction();
+ intptr_t num_parameters = (is_method ? 1 : 0) + (is_setter ? 1 : 0);
+
+ function.SetNumOptionalParameters(0, false);
+ function.set_num_fixed_parameters(num_parameters);
+ function.set_parameter_types(
+ Array::Handle(Z, Array::New(num_parameters, Heap::kOld)));
+ function.set_parameter_names(
+ Array::Handle(Z, Array::New(num_parameters, Heap::kOld)));
+
+ intptr_t pos = 0;
+ if (is_method) {
+ function.SetParameterTypeAt(pos, T.ReceiverType(klass));
+ function.SetParameterNameAt(pos, Symbols::This());
+ pos++;
+ }
+ if (is_setter) {
+ function.SetParameterTypeAt(pos, AbstractType::dynamic_type());
+ function.SetParameterNameAt(pos, Symbols::Value());
+ pos++;
+ }
+}
+
+dart::Library& KernelReader::LookupLibrary(Library* library) {
+ dart::Library* handle = NULL;
+ if (!libraries_.Lookup(library, &handle)) {
+ const dart::String& url = H.DartSymbol(library->import_uri());
+ handle =
+ &dart::Library::Handle(Z, dart::Library::LookupLibrary(thread_, url));
+ if (handle->IsNull()) {
+ *handle = dart::Library::New(url);
+ handle->Register(thread_);
+ }
+ ASSERT(!handle->IsNull());
+ libraries_.Insert(library, handle);
+ }
+ return *handle;
+}
+
+dart::Class& KernelReader::LookupClass(Class* klass) {
+ dart::Class* handle = NULL;
+ if (!classes_.Lookup(klass, &handle)) {
+ dart::Library& library = LookupLibrary(klass->parent());
+ const dart::String& name = H.DartClassName(klass);
+ handle = &dart::Class::Handle(Z, library.LookupClass(name));
+ if (handle->IsNull()) {
+ // The class needs to have a script because all the functions in the class
+ // will inherit it. The predicate Function::IsOptimizable uses the
+ // absence of a script to detect test functions that should not be
+ // optimized. Use a dummy script.
+ //
+ // TODO(27590): We shouldn't need a dummy script per class. At the
+ // least we could have a singleton. At best, we'd change IsOptimizable to
+ // detect test functions some other way (like simply not setting the
+ // optimizable bit on those functions in the first place).
+ TokenPosition pos(0);
+ Script& script =
+ Script::Handle(Z, Script::New(H.DartString(""), H.DartString(""),
+ RawScript::kScriptTag));
+ handle =
+ &dart::Class::Handle(Z, dart::Class::New(library, name, script, pos));
+ library.AddClass(*handle);
+ } else if (handle->script() == Script::null()) {
+ // When bootstrapping we can encounter classes that do not yet have a
+ // dummy script.
+ TokenPosition pos(0);
+ Script& script =
+ Script::Handle(Z, Script::New(H.DartString(""), H.DartString(""),
+ RawScript::kScriptTag));
+ handle->set_script(script);
+ }
+ // Insert the class in the cache before calling ReadPreliminaryClass so
+ // we do not risk allocating the class again by calling LookupClass
+ // recursively from ReadPreliminaryClass for the same class.
+ classes_.Insert(klass, handle);
+ if (!handle->is_type_finalized()) {
+ ReadPreliminaryClass(handle, klass);
+ }
+ }
+ return *handle;
+}
+
+RawFunction::Kind KernelReader::GetFunctionType(Procedure* kernel_procedure) {
+ intptr_t lookuptable[] = {
+ RawFunction::kRegularFunction, // Procedure::kMethod
+ RawFunction::kGetterFunction, // Procedure::kGetter
+ RawFunction::kSetterFunction, // Procedure::kSetter
+ RawFunction::kRegularFunction, // Procedure::kOperator
+ RawFunction::kConstructor, // Procedure::kFactory
+ };
+ intptr_t kind = static_cast<int>(kernel_procedure->kind());
+ if (kind == Procedure::kIncompleteProcedure) {
+ return RawFunction::kSignatureFunction;
+ } else {
+ ASSERT(0 <= kind && kind <= Procedure::kFactory);
+ return static_cast<RawFunction::Kind>(lookuptable[kind]);
+ }
+}
+
+} // namespace kernel
+} // namespace dart
diff --git a/runtime/vm/kernel_reader.h b/runtime/vm/kernel_reader.h
new file mode 100644
index 0000000..a53d572
--- /dev/null
+++ b/runtime/vm/kernel_reader.h
@@ -0,0 +1,120 @@
+// 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.
+
+#ifndef VM_KERNEL_READER_H_
+#define VM_KERNEL_READER_H_
+
+#include <map>
+
+#include "vm/kernel.h"
+#include "vm/kernel_to_il.h"
+#include "vm/object.h"
+
+namespace dart {
+namespace kernel {
+
+class KernelReader;
+
+class BuildingTranslationHelper : public TranslationHelper {
+ public:
+ BuildingTranslationHelper(KernelReader* reader, dart::Thread* thread,
+ dart::Zone* zone, Isolate* isolate)
+ : TranslationHelper(thread, zone, isolate), reader_(reader) {}
+ virtual ~BuildingTranslationHelper() {}
+
+ virtual void SetFinalize(bool finalize);
+
+ virtual RawLibrary* LookupLibraryByKernelLibrary(Library* library);
+ virtual RawClass* LookupClassByKernelClass(Class* klass);
+
+ private:
+ KernelReader* reader_;
+};
+
+template <typename KernelType, typename VmType>
+class Mapping {
+ public:
+ bool Lookup(KernelType* node, VmType** handle) {
+ typename MapType::iterator value = map_.find(node);
+ if (value != map_.end()) {
+ *handle = value->second;
+ return true;
+ }
+ return false;
+ }
+
+ void Insert(KernelType* node, VmType* object) { map_[node] = object; }
+
+ private:
+ typedef typename std::map<KernelType*, VmType*> MapType;
+ MapType map_;
+};
+
+class KernelReader {
+ public:
+ KernelReader(const uint8_t* buffer, intptr_t len, bool bootstrapping = false)
+ : thread_(dart::Thread::Current()),
+ zone_(thread_->zone()),
+ isolate_(thread_->isolate()),
+ translation_helper_(this, thread_, zone_, isolate_),
+ type_translator_(&translation_helper_, &active_class_, !bootstrapping),
+ bootstrapping_(bootstrapping),
+ finalize_(!bootstrapping),
+ buffer_(buffer),
+ buffer_length_(len) {}
+
+ // Returns either a library or a failure object.
+ dart::Object& ReadProgram();
+
+ static void SetupFunctionParameters(TranslationHelper translation_helper_,
+ DartTypeTranslator type_translator_,
+ const dart::Class& owner,
+ const dart::Function& function,
+ FunctionNode* kernel_function,
+ bool is_method, bool is_closure);
+
+ void ReadLibrary(Library* kernel_library);
+
+ private:
+ friend class BuildingTranslationHelper;
+
+ void ReadPreliminaryClass(dart::Class* klass, Class* kernel_klass);
+ void ReadClass(const dart::Library& library, Class* kernel_klass);
+ void ReadProcedure(const dart::Library& library, const dart::Class& owner,
+ Procedure* procedure, Class* kernel_klass = NULL);
+
+ void GenerateFieldAccessors(const dart::Class& klass,
+ const dart::Field& field, Field* kernel_field);
+
+ void SetupFieldAccessorFunction(const dart::Class& klass,
+ const dart::Function& function);
+
+ dart::Library& LookupLibrary(Library* library);
+ dart::Class& LookupClass(Class* klass);
+
+ dart::RawFunction::Kind GetFunctionType(Procedure* kernel_procedure);
+
+ dart::Thread* thread_;
+ dart::Zone* zone_;
+ dart::Isolate* isolate_;
+ ActiveClass active_class_;
+ BuildingTranslationHelper translation_helper_;
+ DartTypeTranslator type_translator_;
+
+ bool bootstrapping_;
+
+ // Should created classes be finalized when they are created?
+ bool finalize_;
+
+ const uint8_t* buffer_;
+ intptr_t buffer_length_;
+
+ Mapping<Library, dart::Library> libraries_;
+ Mapping<Class, dart::Class> classes_;
+};
+
+} // namespace kernel
+} // namespace dart
+
+#endif // VM_KERNEL_READER_H_
diff --git a/runtime/vm/kernel_to_il.cc b/runtime/vm/kernel_to_il.cc
new file mode 100644
index 0000000..e3320ef
--- /dev/null
+++ b/runtime/vm/kernel_to_il.cc
@@ -0,0 +1,5567 @@
+// 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.
+
+#include <map>
+#include <set>
+#include <string>
+
+#include "vm/kernel_to_il.h"
+
+#include "vm/compiler.h"
+#include "vm/intermediate_language.h"
+#include "vm/kernel_reader.h"
+#include "vm/longjump.h"
+#include "vm/method_recognizer.h"
+#include "vm/object_store.h"
+#include "vm/report.h"
+#include "vm/resolver.h"
+#include "vm/stack_frame.h"
+
+namespace dart {
+
+DECLARE_FLAG(bool, support_externalizable_strings);
+
+namespace kernel {
+
+#define Z (zone_)
+#define H (translation_helper_)
+#define T (type_translator_)
+#define I Isolate::Current()
+
+
+void ScopeBuilder::EnterScope(TreeNode* node) {
+ scope_ = new (Z) LocalScope(scope_, depth_.function_, depth_.loop_);
+ result_->scopes.Insert(node, scope_);
+}
+
+
+void ScopeBuilder::ExitScope() { scope_ = scope_->parent(); }
+
+
+LocalVariable* ScopeBuilder::MakeVariable(const dart::String& name) {
+ return new (Z)
+ LocalVariable(TokenPosition::kNoSource, name, Object::dynamic_type());
+}
+
+
+LocalVariable* ScopeBuilder::MakeVariable(const dart::String& name,
+ const Type& type) {
+ return new (Z) LocalVariable(TokenPosition::kNoSource, name, type);
+}
+
+
+void ScopeBuilder::AddParameters(FunctionNode* function, intptr_t pos) {
+ List<VariableDeclaration>& positional = function->positional_parameters();
+ for (intptr_t i = 0; i < positional.length(); ++i) {
+ AddParameter(positional[i], pos++);
+ }
+ List<VariableDeclaration>& named = function->named_parameters();
+ for (intptr_t i = 0; i < named.length(); ++i) {
+ AddParameter(named[i], pos++);
+ }
+}
+
+
+void ScopeBuilder::AddParameter(VariableDeclaration* declaration,
+ intptr_t pos) {
+ // TODO(27590): Handle final.
+ LocalVariable* variable = MakeVariable(H.DartSymbol(declaration->name()));
+ scope_->InsertParameterAt(pos, variable);
+ result_->locals.Insert(declaration, variable);
+
+ // The default value may contain 'let' bindings for which the constant
+ // evaluator needs scope bindings.
+ Expression* defaultValue = declaration->initializer();
+ if (defaultValue != NULL) {
+ defaultValue->AcceptExpressionVisitor(this);
+ }
+}
+
+
+void ScopeBuilder::AddExceptionVariable(
+ GrowableArray<LocalVariable*>* variables, const char* prefix,
+ intptr_t nesting_depth) {
+ LocalVariable* v = NULL;
+
+ // If we are inside a function with yield points then Kernel transformer
+ // could have lifted some of the auxiliary exception variables into the
+ // context to preserve them across yield points because they might
+ // be needed for rethrow.
+ // Check if it did and capture such variables instead of introducing
+ // new local ones.
+ // Note: function that wrap kSyncYielding function does not contain
+ // its own try/catches.
+ if (current_function_node_->async_marker() == FunctionNode::kSyncYielding) {
+ ASSERT(current_function_scope_->parent() != NULL);
+ v = current_function_scope_->parent()->LocalLookupVariable(
+ GenerateName(prefix, nesting_depth - 1));
+ if (v != NULL) {
+ scope_->CaptureVariable(v);
+ }
+ }
+
+ // No need to create variables for try/catch-statements inside
+ // nested functions.
+ if (depth_.function_ > 0) return;
+ if (variables->length() >= nesting_depth) return;
+
+ // If variable was not lifted by the transformer introduce a new
+ // one into the current function scope.
+ if (v == NULL) {
+ v = MakeVariable(GenerateName(prefix, nesting_depth - 1));
+
+ // If transformer did not lift the variable then there is no need
+ // to lift it into the context when we encouter a YieldStatement.
+ v->set_is_forced_stack();
+ current_function_scope_->AddVariable(v);
+ }
+
+ variables->Add(v);
+}
+
+
+void ScopeBuilder::AddTryVariables() {
+ AddExceptionVariable(&result_->catch_context_variables,
+ ":saved_try_context_var", depth_.try_);
+}
+
+
+void ScopeBuilder::AddCatchVariables() {
+ AddExceptionVariable(&result_->exception_variables, ":exception",
+ depth_.catch_);
+ AddExceptionVariable(&result_->stack_trace_variables, ":stack_trace",
+ depth_.catch_);
+}
+
+
+void ScopeBuilder::AddIteratorVariable() {
+ if (depth_.function_ > 0) return;
+ if (result_->iterator_variables.length() >= depth_.for_in_) return;
+
+ ASSERT(result_->iterator_variables.length() == depth_.for_in_ - 1);
+ LocalVariable* iterator =
+ MakeVariable(GenerateName(":iterator", depth_.for_in_ - 1));
+ current_function_scope_->AddVariable(iterator);
+ result_->iterator_variables.Add(iterator);
+}
+
+
+void ScopeBuilder::LookupVariable(VariableDeclaration* declaration) {
+ LocalVariable* variable = result_->locals.Lookup(declaration);
+ if (variable == NULL) {
+ // We have not seen a declaration of the variable, so it must be the
+ // case that we are compiling a nested function and the variable is
+ // declared in an outer scope. In that case, look it up in the scope by
+ // name and add it to the variable map to simplify later lookup.
+ ASSERT(current_function_scope_->parent() != NULL);
+ const dart::String& name = H.DartSymbol(declaration->name());
+ variable = current_function_scope_->parent()->LookupVariable(name, true);
+ ASSERT(variable != NULL);
+ result_->locals.Insert(declaration, variable);
+ }
+ if (variable->owner()->function_level() < scope_->function_level()) {
+ // We call `LocalScope->CaptureVariable(variable)` in two scenarios for two
+ // different reasons:
+ // Scenario 1:
+ // We need to know which variables defined in this function
+ // are closed over by nested closures in order to ensure we will
+ // create a [Context] object of appropriate size and store captured
+ // variables there instead of the stack.
+ // Scenario 2:
+ // We need to find out which variables defined in enclosing functions
+ // are closed over by this function/closure or nested closures. This
+ // is necessary in order to build a fat flattened [ContextScope]
+ // object.
+ scope_->CaptureVariable(variable);
+ } else {
+ ASSERT(variable->owner()->function_level() == scope_->function_level());
+ }
+}
+
+
+void ScopeBuilder::LookupCapturedVariableByName(LocalVariable** variable,
+ const dart::String& name) {
+ if (*variable == NULL) {
+ *variable = scope_->LookupVariable(name, true);
+ ASSERT(*variable != NULL);
+ scope_->CaptureVariable(*variable);
+ }
+}
+
+
+const dart::String& ScopeBuilder::GenerateName(const char* prefix,
+ intptr_t suffix) {
+ char name[64];
+ OS::SNPrint(name, 64, "%s%" Pd "", prefix, suffix);
+ return H.DartSymbol(name);
+}
+
+
+void ScopeBuilder::AddVariable(VariableDeclaration* declaration) {
+ // TODO(27590): Handle final and const, including function declarations.
+ const dart::String& name = declaration->name()->is_empty()
+ ? GenerateName(":var", name_index_++)
+ : H.DartSymbol(declaration->name());
+ LocalVariable* variable = MakeVariable(name);
+ scope_->AddVariable(variable);
+ result_->locals.Insert(declaration, variable);
+}
+
+
+static bool IsStaticInitializer(const Function& function, Zone* zone) {
+ return (function.kind() == RawFunction::kImplicitStaticFinalGetter) &&
+ dart::String::Handle(zone, function.name())
+ .StartsWith(Symbols::InitPrefix());
+}
+
+
+ScopeBuildingResult* ScopeBuilder::BuildScopes() {
+ if (result_ != NULL) return result_;
+
+ ASSERT(scope_ == NULL && depth_.loop_ == 0 && depth_.function_ == 0);
+ result_ = new (Z) ScopeBuildingResult();
+
+ ParsedFunction* parsed_function = parsed_function_;
+ const dart::Function& function = parsed_function->function();
+
+ LocalScope* enclosing_scope = NULL;
+ if (function.IsLocalFunction()) {
+ enclosing_scope = LocalScope::RestoreOuterScope(
+ ContextScope::Handle(Z, function.context_scope()));
+ }
+ current_function_scope_ = scope_ = new (Z) LocalScope(enclosing_scope, 0, 0);
+ scope_->AddVariable(parsed_function->EnsureExpressionTemp());
+ scope_->AddVariable(parsed_function->current_context_var());
+ parsed_function->SetNodeSequence(
+ new SequenceNode(TokenPosition::kNoSource, scope_));
+
+ switch (function.kind()) {
+ case RawFunction::kClosureFunction:
+ case RawFunction::kRegularFunction:
+ case RawFunction::kGetterFunction:
+ case RawFunction::kSetterFunction:
+ case RawFunction::kConstructor: {
+ FunctionNode* node;
+ if (node_->IsProcedure()) {
+ node = Procedure::Cast(node_)->function();
+ } else if (node_->IsConstructor()) {
+ node = Constructor::Cast(node_)->function();
+ } else {
+ node = FunctionNode::Cast(node_);
+ }
+ current_function_node_ = node;
+
+ intptr_t pos = 0;
+ if (function.IsClosureFunction()) {
+ LocalVariable* variable = MakeVariable(Symbols::ClosureParameter());
+ scope_->InsertParameterAt(pos++, variable);
+ } else if (!function.is_static()) {
+ // We use [is_static] instead of [IsStaticFunction] because the latter
+ // returns `false` for constructors.
+ dart::Class& klass = dart::Class::Handle(Z, function.Owner());
+ Type& klass_type = H.GetCanonicalType(klass);
+ LocalVariable* variable = MakeVariable(Symbols::This(), klass_type);
+ scope_->InsertParameterAt(pos++, variable);
+ result_->this_variable = variable;
+
+ // We visit instance field initializers because they might contain
+ // [Let] expressions and we need to have a mapping.
+ if (node_->IsConstructor()) {
+ Class* klass = Class::Cast(Constructor::Cast(node_)->parent());
+
+ for (intptr_t i = 0; i < klass->fields().length(); i++) {
+ Field* field = klass->fields()[i];
+ if (!field->IsStatic() && (field->initializer() != NULL)) {
+ EnterScope(field);
+ field->initializer()->AcceptExpressionVisitor(this);
+ ExitScope();
+ }
+ }
+ }
+ } else if (function.IsFactory()) {
+ LocalVariable* variable = MakeVariable(
+ Symbols::TypeArgumentsParameter(), AbstractType::dynamic_type());
+ scope_->InsertParameterAt(pos++, variable);
+ result_->type_arguments_variable = variable;
+ }
+ AddParameters(node, pos);
+
+ // We generate a syntethic body for implicit closure functions - which
+ // will forward the call to the real function.
+ // -> see BuildGraphOfImplicitClosureFunction
+ if (!function.IsImplicitClosureFunction()) {
+ node_->AcceptVisitor(this);
+ }
+ break;
+ }
+ case RawFunction::kImplicitGetter:
+ case RawFunction::kImplicitStaticFinalGetter:
+ case RawFunction::kImplicitSetter: {
+ ASSERT(node_->IsField());
+ if (IsStaticInitializer(function, Z)) {
+ node_->AcceptVisitor(this);
+ break;
+ }
+ bool is_setter = function.IsImplicitSetterFunction();
+ bool is_method = !function.IsStaticFunction();
+ intptr_t pos = 0;
+ if (is_method) {
+ dart::Class& klass = dart::Class::Handle(Z, function.Owner());
+ Type& klass_type = H.GetCanonicalType(klass);
+ LocalVariable* variable = MakeVariable(Symbols::This(), klass_type);
+ scope_->InsertParameterAt(pos++, variable);
+ result_->this_variable = variable;
+ }
+ if (is_setter) {
+ result_->setter_value = MakeVariable(Symbols::Value());
+ scope_->InsertParameterAt(pos++, result_->setter_value);
+ }
+ break;
+ }
+ case RawFunction::kMethodExtractor: {
+ // Add a receiver parameter. Though it is captured, we emit code to
+ // explicitly copy it to a fixed offset in a freshly-allocated context
+ // instead of using the generic code for regular functions.
+ // Therefore, it isn't necessary to mark it as captured here.
+ dart::Class& klass = dart::Class::Handle(Z, function.Owner());
+ Type& klass_type = H.GetCanonicalType(klass);
+ LocalVariable* variable = MakeVariable(Symbols::This(), klass_type);
+ scope_->InsertParameterAt(0, variable);
+ result_->this_variable = variable;
+ break;
+ }
+ case RawFunction::kNoSuchMethodDispatcher:
+ case RawFunction::kInvokeFieldDispatcher:
+ for (intptr_t i = 0; i < function.NumParameters(); ++i) {
+ LocalVariable* variable = MakeVariable(
+ dart::String::ZoneHandle(Z, function.ParameterNameAt(i)));
+ scope_->InsertParameterAt(i, variable);
+ }
+ break;
+ case RawFunction::kSignatureFunction:
+ case RawFunction::kIrregexpFunction:
+ UNREACHABLE();
+ }
+
+ parsed_function->AllocateVariables();
+
+ return result_;
+}
+
+
+void ScopeBuilder::VisitThisExpression(ThisExpression* node) {
+ HandleSpecialLoad(&result_->this_variable, Symbols::This());
+}
+
+
+void ScopeBuilder::VisitTypeParameterType(TypeParameterType* node) {
+ Function& function = Function::Handle(Z, parsed_function_->function().raw());
+ while (function.IsClosureFunction()) {
+ function = function.parent_function();
+ }
+
+ if (function.IsFactory()) {
+ // The type argument vector is passed as the very first argument to the
+ // factory constructor function.
+ HandleSpecialLoad(&result_->type_arguments_variable,
+ Symbols::TypeArgumentsParameter());
+ } else {
+ // The type argument vector is stored on the instance object. We therefore
+ // need to capture `this`.
+ HandleSpecialLoad(&result_->this_variable, Symbols::This());
+ }
+}
+
+
+void ScopeBuilder::VisitVariableGet(VariableGet* node) {
+ LookupVariable(node->variable());
+}
+
+
+void ScopeBuilder::VisitVariableSet(VariableSet* node) {
+ LookupVariable(node->variable());
+ node->VisitChildren(this);
+}
+
+
+void ScopeBuilder::HandleLocalFunction(TreeNode* parent,
+ FunctionNode* function) {
+ LocalScope* saved_function_scope = current_function_scope_;
+ FunctionNode* saved_function_node = current_function_node_;
+ ScopeBuilder::DepthState saved_depth_state = depth_;
+ depth_ = DepthState(depth_.function_ + 1);
+ EnterScope(parent);
+ current_function_scope_ = scope_;
+ current_function_node_ = function;
+ if (depth_.function_ == 1) {
+ FunctionScope function_scope = {function, scope_};
+ result_->function_scopes.Add(function_scope);
+ }
+ AddParameters(function);
+ VisitFunctionNode(function);
+ ExitScope();
+ depth_ = saved_depth_state;
+ current_function_scope_ = saved_function_scope;
+ current_function_node_ = saved_function_node;
+}
+
+
+void ScopeBuilder::HandleSpecialLoad(LocalVariable** variable,
+ const dart::String& symbol) {
+ if (current_function_scope_->parent() != NULL) {
+ // We are building the scope tree of a closure function and saw [node]. We
+ // lazily populate the variable using the parent function scope.
+ if (*variable == NULL) {
+ *variable =
+ current_function_scope_->parent()->LookupVariable(symbol, true);
+ ASSERT(*variable != NULL);
+ }
+ }
+
+ if ((current_function_scope_->parent() != NULL) ||
+ (scope_->function_level() > 0)) {
+ // Every scope we use the [variable] from needs to be notified of the usage
+ // in order to ensure that preserving the context scope on that particular
+ // use-site also includes the [variable].
+ scope_->CaptureVariable(*variable);
+ }
+}
+
+
+void ScopeBuilder::VisitFunctionExpression(FunctionExpression* node) {
+ HandleLocalFunction(node, node->function());
+}
+
+
+void ScopeBuilder::VisitLet(Let* node) {
+ EnterScope(node);
+ node->VisitChildren(this);
+ ExitScope();
+}
+
+
+void ScopeBuilder::VisitBlock(Block* node) {
+ EnterScope(node);
+ node->VisitChildren(this);
+ ExitScope();
+}
+
+
+void ScopeBuilder::VisitVariableDeclaration(VariableDeclaration* node) {
+ AddVariable(node);
+ node->VisitChildren(this);
+}
+
+
+void ScopeBuilder::VisitFunctionDeclaration(FunctionDeclaration* node) {
+ VisitVariableDeclaration(node->variable());
+ HandleLocalFunction(node, node->function());
+}
+
+
+void ScopeBuilder::VisitWhileStatement(WhileStatement* node) {
+ ++depth_.loop_;
+ node->VisitChildren(this);
+ --depth_.loop_;
+}
+
+
+void ScopeBuilder::VisitDoStatement(DoStatement* node) {
+ ++depth_.loop_;
+ node->VisitChildren(this);
+ --depth_.loop_;
+}
+
+
+void ScopeBuilder::VisitForStatement(ForStatement* node) {
+ EnterScope(node);
+ List<VariableDeclaration>& variables = node->variables();
+ for (intptr_t i = 0; i < variables.length(); ++i) {
+ VisitVariableDeclaration(variables[i]);
+ }
+ ++depth_.loop_;
+ if (node->condition() != NULL) {
+ node->condition()->AcceptExpressionVisitor(this);
+ }
+ node->body()->AcceptStatementVisitor(this);
+ List<Expression>& updates = node->updates();
+ for (intptr_t i = 0; i < updates.length(); ++i) {
+ updates[i]->AcceptExpressionVisitor(this);
+ }
+ --depth_.loop_;
+ ExitScope();
+}
+
+
+void ScopeBuilder::VisitForInStatement(ForInStatement* node) {
+ node->iterable()->AcceptExpressionVisitor(this);
+ ++depth_.for_in_;
+ AddIteratorVariable();
+ ++depth_.loop_;
+ EnterScope(node);
+ VisitVariableDeclaration(node->variable());
+ node->body()->AcceptStatementVisitor(this);
+ ExitScope();
+ --depth_.loop_;
+ --depth_.for_in_;
+}
+
+
+void ScopeBuilder::AddSwitchVariable() {
+ if ((depth_.function_ == 0) && (result_->switch_variable == NULL)) {
+ LocalVariable* variable = MakeVariable(Symbols::SwitchExpr());
+ current_function_scope_->AddVariable(variable);
+ result_->switch_variable = variable;
+ }
+}
+
+
+void ScopeBuilder::VisitSwitchStatement(SwitchStatement* node) {
+ AddSwitchVariable();
+ node->VisitChildren(this);
+}
+
+
+void ScopeBuilder::VisitReturnStatement(ReturnStatement* node) {
+ if ((depth_.function_ == 0) && (depth_.finally_ > 0) &&
+ (result_->finally_return_variable == NULL)) {
+ const dart::String& name = H.DartSymbol(":try_finally_return_value");
+ LocalVariable* variable = MakeVariable(name);
+ current_function_scope_->AddVariable(variable);
+ result_->finally_return_variable = variable;
+ }
+ node->VisitChildren(this);
+}
+
+
+void ScopeBuilder::VisitTryCatch(TryCatch* node) {
+ ++depth_.try_;
+ AddTryVariables();
+ node->body()->AcceptStatementVisitor(this);
+ --depth_.try_;
+
+ ++depth_.catch_;
+ AddCatchVariables();
+ List<Catch>& catches = node->catches();
+ for (intptr_t i = 0; i < catches.length(); ++i) {
+ Catch* ketch = catches[i];
+ EnterScope(ketch);
+ if (ketch->exception() != NULL) {
+ VisitVariableDeclaration(ketch->exception());
+ }
+ if (ketch->stack_trace() != NULL) {
+ VisitVariableDeclaration(ketch->stack_trace());
+ }
+ ketch->body()->AcceptStatementVisitor(this);
+ ExitScope();
+ }
+ --depth_.catch_;
+}
+
+
+void ScopeBuilder::VisitTryFinally(TryFinally* node) {
+ ++depth_.try_;
+ ++depth_.finally_;
+ AddTryVariables();
+ node->body()->AcceptStatementVisitor(this);
+ --depth_.finally_;
+ --depth_.try_;
+
+ ++depth_.catch_;
+ AddCatchVariables();
+ node->finalizer()->AcceptStatementVisitor(this);
+ --depth_.catch_;
+}
+
+
+void ScopeBuilder::VisitFunctionNode(FunctionNode* node) {
+ List<TypeParameter>& type_parameters = node->type_parameters();
+ for (intptr_t i = 0; i < type_parameters.length(); ++i) {
+ VisitTypeParameter(type_parameters[i]);
+ }
+ // Do not visit the positional and named parameters, because they've
+ // already been added to the scope.
+ if (node->body() != NULL) {
+ node->body()->AcceptStatementVisitor(this);
+ }
+
+ // Ensure that :await_jump_var and :await_ctx_var are captured.
+ if (node->async_marker() == FunctionNode::kSyncYielding) {
+ {
+ LocalVariable* temp = NULL;
+ LookupCapturedVariableByName(
+ (depth_.function_ == 0) ? &result_->yield_jump_variable : &temp,
+ Symbols::AwaitJumpVar());
+ }
+ {
+ LocalVariable* temp = NULL;
+ LookupCapturedVariableByName(
+ (depth_.function_ == 0) ? &result_->yield_context_variable : &temp,
+ Symbols::AwaitContextVar());
+ }
+ }
+}
+
+
+void ScopeBuilder::VisitYieldStatement(YieldStatement* node) {
+ ASSERT(node->is_native());
+ if (depth_.function_ == 0) {
+ AddSwitchVariable();
+ // Promote all currently visible local variables into the context.
+ // TODO(27590) CaptureLocalVariables promotes to many variables into
+ // the scope. Mark those variables as stack_local.
+ // TODO(27590) we don't need to promote those variables that are
+ // not used across yields.
+ scope_->CaptureLocalVariables(current_function_scope_);
+ }
+}
+
+
+void ScopeBuilder::VisitAssertStatement(AssertStatement* node) {
+ if (I->asserts()) {
+ RecursiveVisitor::VisitAssertStatement(node);
+ }
+}
+
+
+void ScopeBuilder::VisitConstructor(Constructor* node) {
+ // Field initializers that come from non-static field declarations are
+ // compiled as if they appear in the constructor initializer list. This is
+ // important for closure-valued field initializers because the VM expects the
+ // corresponding closure functions to appear as if they were nested inside the
+ // constructor.
+ List<Field>& fields = Class::Cast(node->parent())->fields();
+ for (intptr_t i = 0; i < fields.length(); ++i) {
+ Field* field = fields[i];
+ Expression* initializer = field->initializer();
+ if (!field->IsStatic() && (initializer != NULL)) {
+ initializer->AcceptExpressionVisitor(this);
+ }
+ }
+ node->VisitChildren(this);
+}
+
+
+class BreakableBlock {
+ public:
+ BreakableBlock(FlowGraphBuilder* builder, LabeledStatement* statement)
+ : builder_(builder),
+ labeled_statement_(statement),
+ outer_(builder->breakable_block_),
+ destination_(NULL),
+ outer_finally_(builder->try_finally_block_),
+ context_depth_(builder->context_depth_) {
+ builder_->breakable_block_ = this;
+ }
+ ~BreakableBlock() { builder_->breakable_block_ = outer_; }
+
+ bool HadJumper() { return destination_ != NULL; }
+
+ JoinEntryInstr* destination() { return destination_; }
+
+ JoinEntryInstr* BreakDestination(LabeledStatement* label,
+ TryFinallyBlock** outer_finally,
+ intptr_t* context_depth) {
+ BreakableBlock* block = builder_->breakable_block_;
+ while (block->labeled_statement_ != label) {
+ block = block->outer_;
+ }
+ ASSERT(block != NULL);
+ *outer_finally = block->outer_finally_;
+ *context_depth = block->context_depth_;
+ return block->EnsureDestination();
+ }
+
+ private:
+ JoinEntryInstr* EnsureDestination() {
+ if (destination_ == NULL) {
+ destination_ = builder_->BuildJoinEntry();
+ }
+ return destination_;
+ }
+
+ FlowGraphBuilder* builder_;
+ LabeledStatement* labeled_statement_;
+ BreakableBlock* outer_;
+ JoinEntryInstr* destination_;
+ TryFinallyBlock* outer_finally_;
+ intptr_t context_depth_;
+};
+
+
+class SwitchBlock {
+ public:
+ SwitchBlock(FlowGraphBuilder* builder, SwitchStatement* switch_stmt)
+ : builder_(builder),
+ outer_(builder->switch_block_),
+ outer_finally_(builder->try_finally_block_),
+ switch_statement_(switch_stmt),
+ context_depth_(builder->context_depth_) {
+ builder_->switch_block_ = this;
+ }
+ ~SwitchBlock() { builder_->switch_block_ = outer_; }
+
+ bool HadJumper(SwitchCase* switch_case) {
+ return destinations_.Lookup(switch_case) != NULL;
+ }
+
+ JoinEntryInstr* Destination(SwitchCase* label,
+ TryFinallyBlock** outer_finally = NULL,
+ intptr_t* context_depth = NULL) {
+ // Find corresponding [SwitchStatement].
+ SwitchBlock* block = this;
+ while (true) {
+ block->EnsureSwitchCaseMapping();
+ if (block->Contains(label)) break;
+ block = block->outer_;
+ }
+
+ // Set the outer finally block.
+ if (outer_finally != NULL) {
+ *outer_finally = block->outer_finally_;
+ *context_depth = block->context_depth_;
+ }
+
+ // Ensure there's [JoinEntryInstr] for that [SwitchCase].
+ return block->EnsureDestination(label);
+ }
+
+ private:
+ typedef std::set<SwitchCase*> DestinationSwitches;
+
+ JoinEntryInstr* EnsureDestination(SwitchCase* switch_case) {
+ JoinEntryInstr* cached_inst = destinations_.Lookup(switch_case);
+ if (cached_inst == NULL) {
+ JoinEntryInstr* inst = builder_->BuildJoinEntry();
+ destinations_.Insert(switch_case, inst);
+ return inst;
+ }
+ return cached_inst;
+ }
+
+ void EnsureSwitchCaseMapping() {
+ if (destination_switches_.begin() == destination_switches_.end()) {
+ List<SwitchCase>& cases = switch_statement_->cases();
+ for (intptr_t i = 0; i < cases.length(); i++) {
+ destination_switches_.insert(cases[i]);
+ }
+ }
+ }
+
+ bool Contains(SwitchCase* sc) {
+ return destination_switches_.find(sc) != destination_switches_.end();
+ }
+
+ FlowGraphBuilder* builder_;
+ SwitchBlock* outer_;
+
+ Map<SwitchCase, JoinEntryInstr*> destinations_;
+ DestinationSwitches destination_switches_;
+
+ TryFinallyBlock* outer_finally_;
+ SwitchStatement* switch_statement_;
+ intptr_t context_depth_;
+};
+
+
+class TryFinallyBlock {
+ public:
+ TryFinallyBlock(FlowGraphBuilder* builder, Statement* finalizer)
+ : builder_(builder),
+ outer_(builder->try_finally_block_),
+ finalizer_(finalizer),
+ context_depth_(builder->context_depth_),
+ // Finalizers are executed outside of the try block hence
+ // try depth of finalizers are one less than current try
+ // depth.
+ try_depth_(builder->try_depth_ - 1) {
+ builder_->try_finally_block_ = this;
+ }
+ ~TryFinallyBlock() { builder_->try_finally_block_ = outer_; }
+
+ Statement* finalizer() const { return finalizer_; }
+ intptr_t context_depth() const { return context_depth_; }
+ intptr_t try_depth() const { return try_depth_; }
+ TryFinallyBlock* outer() const { return outer_; }
+
+ private:
+ FlowGraphBuilder* const builder_;
+ TryFinallyBlock* const outer_;
+ Statement* const finalizer_;
+ const intptr_t context_depth_;
+ const intptr_t try_depth_;
+};
+
+
+class TryCatchBlock {
+ public:
+ explicit TryCatchBlock(FlowGraphBuilder* builder,
+ intptr_t try_handler_index = -1)
+ : builder_(builder),
+ outer_(builder->try_catch_block_),
+ try_index_(try_handler_index) {
+ if (try_index_ == -1) try_index_ = builder->AllocateTryIndex();
+ builder->try_catch_block_ = this;
+ }
+ ~TryCatchBlock() { builder_->try_catch_block_ = outer_; }
+
+ intptr_t TryIndex() { return try_index_; }
+
+ private:
+ FlowGraphBuilder* builder_;
+ TryCatchBlock* outer_;
+ intptr_t try_index_;
+};
+
+
+class CatchBlock {
+ public:
+ CatchBlock(FlowGraphBuilder* builder, LocalVariable* exception_var,
+ LocalVariable* stack_trace_var, intptr_t catch_try_index)
+ : builder_(builder),
+ outer_(builder->catch_block_),
+ exception_var_(exception_var),
+ stack_trace_var_(stack_trace_var),
+ catch_try_index_(catch_try_index) {
+ builder_->catch_block_ = this;
+ }
+ ~CatchBlock() { builder_->catch_block_ = outer_; }
+
+ LocalVariable* exception_var() { return exception_var_; }
+ LocalVariable* stack_trace_var() { return stack_trace_var_; }
+ intptr_t catch_try_index() { return catch_try_index_; }
+
+ private:
+ FlowGraphBuilder* builder_;
+ CatchBlock* outer_;
+ LocalVariable* exception_var_;
+ LocalVariable* stack_trace_var_;
+ intptr_t catch_try_index_;
+};
+
+
+Fragment& Fragment::operator+=(const Fragment& other) {
+ if (entry == NULL) {
+ entry = other.entry;
+ current = other.current;
+ } else if (current != NULL && other.entry != NULL) {
+ current->LinkTo(other.entry);
+ current = other.current;
+ }
+ return *this;
+}
+
+
+Fragment& Fragment::operator<<=(Instruction* next) {
+ if (entry == NULL) {
+ entry = current = next;
+ } else if (current != NULL) {
+ current->LinkTo(next);
+ current = next;
+ }
+ return *this;
+}
+
+
+Fragment Fragment::closed() {
+ ASSERT(entry != NULL);
+ return Fragment(entry, NULL);
+}
+
+
+Fragment operator+(const Fragment& first, const Fragment& second) {
+ Fragment result = first;
+ result += second;
+ return result;
+}
+
+
+Fragment operator<<(const Fragment& fragment, Instruction* next) {
+ Fragment result = fragment;
+ result <<= next;
+ return result;
+}
+
+
+RawInstance* TranslationHelper::Canonicalize(const Instance& instance) {
+ if (instance.IsNull()) return instance.raw();
+
+ const char* error_str = NULL;
+ RawInstance* result = instance.CheckAndCanonicalize(thread(), &error_str);
+ if (result == Object::null()) {
+ ReportError("Invalid const object %s", error_str);
+ }
+ return result;
+}
+
+
+const dart::String& TranslationHelper::DartString(const char* content,
+ Heap::Space space) {
+ return dart::String::ZoneHandle(Z, dart::String::New(content, space));
+}
+
+
+dart::String& TranslationHelper::DartString(String* content,
+ Heap::Space space) {
+ return dart::String::ZoneHandle(
+ Z, dart::String::FromUTF8(content->buffer(), content->size(), space));
+}
+
+
+const dart::String& TranslationHelper::DartSymbol(const char* content) const {
+ return dart::String::ZoneHandle(Z, Symbols::New(thread_, content));
+}
+
+
+dart::String& TranslationHelper::DartSymbol(String* content) const {
+ return dart::String::ZoneHandle(
+ Z, dart::Symbols::FromUTF8(thread_, content->buffer(), content->size()));
+}
+
+
+const dart::String& TranslationHelper::DartClassName(
+ kernel::Class* kernel_klass) {
+ if (kernel_klass->name() != NULL) {
+ ASSERT(kernel_klass->IsNormalClass());
+ dart::String& name = DartString(kernel_klass->name());
+ return ManglePrivateName(kernel_klass->parent(), &name);
+ } else {
+ // Mixin class names are not mangled.
+ ASSERT(kernel_klass->IsMixinClass());
+
+ // We construct the string from right to left:
+ // "Base&Mixin1&Mixin2&...&MixinN"
+ dart::String& partial = dart::String::Handle(Z, dart::String::New(""));
+ dart::String& amp = dart::String::Handle(Z, dart::String::New("&"));
+ dart::String& tmp = dart::String::Handle(Z);
+ while (kernel_klass->name() == NULL) {
+ ASSERT(kernel_klass->IsMixinClass());
+
+ MixinClass* kernel_mixin_class = MixinClass::Cast(kernel_klass);
+ InterfaceType* base_type = kernel_mixin_class->first();
+ InterfaceType* mixin_type = kernel_mixin_class->second();
+
+ String* mixin_name = NormalClass::Cast(mixin_type->klass())->name();
+
+ tmp = dart::String::FromUTF8(mixin_name->buffer(), mixin_name->size());
+
+ partial = dart::String::Concat(amp, partial);
+ partial = dart::String::Concat(tmp, partial);
+
+ kernel_klass = base_type->klass();
+ }
+
+ tmp = dart::String::FromUTF8(kernel_klass->name()->buffer(),
+ kernel_klass->name()->size());
+
+ partial = dart::String::Concat(amp, partial);
+ partial = dart::String::Concat(tmp, partial);
+
+ partial = dart::Symbols::New(thread_, partial);
+ return partial;
+ }
+}
+
+
+const dart::String& TranslationHelper::DartConstructorName(Constructor* node) {
+ Class* klass = Class::Cast(node->parent());
+ return DartFactoryName(klass, node->name());
+}
+
+
+const dart::String& TranslationHelper::DartProcedureName(Procedure* procedure) {
+ if (procedure->kind() == Procedure::kSetter) {
+ return DartSetterName(procedure->name());
+ } else if (procedure->kind() == Procedure::kGetter) {
+ return DartGetterName(procedure->name());
+ } else if (procedure->kind() == Procedure::kFactory) {
+ return DartFactoryName(Class::Cast(procedure->parent()), procedure->name());
+ } else {
+ return DartMethodName(procedure->name());
+ }
+}
+
+
+const dart::String& TranslationHelper::DartSetterName(Name* kernel_name) {
+ // The names flowing into [content] are coming from the Kernel file:
+ // * user-defined setters: `fieldname=`
+ // * property-set expressions: `fieldname`
+ //
+ // The VM uses `get:fieldname` and `set:fieldname`.
+ //
+ // => In order to be consistent, we remove the `=` always and adopt the VM
+ // conventions.
+ String* content = kernel_name->string();
+ ASSERT(content->size() > 0);
+ intptr_t skip = 0;
+ if (content->buffer()[content->size() - 1] == '=') {
+ skip = 1;
+ }
+ dart::String& name = dart::String::ZoneHandle(
+ Z, dart::String::FromUTF8(content->buffer(), content->size() - skip));
+ ManglePrivateName(kernel_name->library(), &name, false);
+ name = dart::Field::SetterSymbol(name);
+ return name;
+}
+
+
+const dart::String& TranslationHelper::DartGetterName(Name* kernel_name) {
+ dart::String& name = DartString(kernel_name->string());
+ ManglePrivateName(kernel_name->library(), &name, false);
+ name = dart::Field::GetterSymbol(name);
+ return name;
+}
+
+
+const dart::String& TranslationHelper::DartFieldName(Name* kernel_name) {
+ dart::String& name = DartString(kernel_name->string());
+ return ManglePrivateName(kernel_name->library(), &name);
+}
+
+
+const dart::String& TranslationHelper::DartInitializerName(Name* kernel_name) {
+ // The [DartFieldName] will take care of mangling the name.
+ dart::String& name =
+ dart::String::Handle(Z, DartFieldName(kernel_name).raw());
+ name = Symbols::FromConcat(thread_, Symbols::InitPrefix(), name);
+ return name;
+}
+
+
+const dart::String& TranslationHelper::DartMethodName(Name* kernel_name) {
+ dart::String& name = DartString(kernel_name->string());
+ return ManglePrivateName(kernel_name->library(), &name);
+}
+
+
+const dart::String& TranslationHelper::DartFactoryName(Class* klass,
+ Name* method_name) {
+ // [DartMethodName] will mangle the name.
+ dart::String& name =
+ dart::String::Handle(Z, DartMethodName(method_name).raw());
+
+ // We build a String which looks like <classname>.<constructor-name>.
+ // [DartClassName] will mangle the name.
+ dart::String& temp = dart::String::Handle(Z, DartClassName(klass).raw());
+ temp = dart::String::Concat(temp, Symbols::Dot());
+ temp = dart::String::Concat(temp, name);
+ return dart::String::ZoneHandle(Z, dart::Symbols::New(thread_, temp));
+}
+
+
+dart::RawLibrary* TranslationHelper::LookupLibraryByKernelLibrary(
+ Library* kernel_library) {
+ const dart::String& library_name = DartSymbol(kernel_library->import_uri());
+ ASSERT(!library_name.IsNull());
+ dart::RawLibrary* library =
+ dart::Library::LookupLibrary(thread_, library_name);
+ ASSERT(library != Object::null());
+ return library;
+}
+
+
+dart::RawClass* TranslationHelper::LookupClassByKernelClass(
+ Class* kernel_klass) {
+ dart::RawClass* klass = NULL;
+
+ const dart::String& class_name = DartClassName(kernel_klass);
+ Library* kernel_library = Library::Cast(kernel_klass->parent());
+ dart::Library& library =
+ dart::Library::Handle(Z, LookupLibraryByKernelLibrary(kernel_library));
+ klass = library.LookupClassAllowPrivate(class_name);
+
+ ASSERT(klass != Object::null());
+ return klass;
+}
+
+
+dart::RawField* TranslationHelper::LookupFieldByKernelField(
+ Field* kernel_field) {
+ TreeNode* node = kernel_field->parent();
+
+ dart::Class& klass = dart::Class::Handle(Z);
+ if (node->IsClass()) {
+ klass = LookupClassByKernelClass(Class::Cast(node));
+ } else {
+ ASSERT(node->IsLibrary());
+ dart::Library& library = dart::Library::Handle(
+ Z, LookupLibraryByKernelLibrary(Library::Cast(node)));
+ klass = library.toplevel_class();
+ }
+ dart::RawField* field =
+ klass.LookupFieldAllowPrivate(DartSymbol(kernel_field->name()->string()));
+ ASSERT(field != Object::null());
+ return field;
+}
+
+
+dart::RawFunction* TranslationHelper::LookupStaticMethodByKernelProcedure(
+ Procedure* procedure) {
+ ASSERT(procedure->IsStatic());
+ const dart::String& procedure_name = DartProcedureName(procedure);
+
+ // The parent is either a library or a class (in which case the procedure is a
+ // static method).
+ TreeNode* parent = procedure->parent();
+ if (parent->IsClass()) {
+ dart::Class& klass =
+ dart::Class::Handle(Z, LookupClassByKernelClass(Class::Cast(parent)));
+ dart::RawFunction* raw_function =
+ klass.LookupFunctionAllowPrivate(procedure_name);
+ ASSERT(raw_function != Object::null());
+
+ // TODO(27590): We can probably get rid of this after no longer using
+ // core libraries from the source.
+ dart::Function& function = dart::Function::ZoneHandle(Z, raw_function);
+ if (function.IsRedirectingFactory()) {
+ ClassFinalizer::ResolveRedirectingFactory(klass, function);
+ function = function.RedirectionTarget();
+ }
+ return function.raw();
+ } else {
+ ASSERT(parent->IsLibrary());
+ dart::Library& library = dart::Library::Handle(
+ Z, LookupLibraryByKernelLibrary(Library::Cast(parent)));
+ dart::RawFunction* function =
+ library.LookupFunctionAllowPrivate(procedure_name);
+ ASSERT(function != Object::null());
+ return function;
+ }
+}
+
+
+dart::RawFunction* TranslationHelper::LookupConstructorByKernelConstructor(
+ Constructor* constructor) {
+ Class* kernel_klass = Class::Cast(constructor->parent());
+ dart::Class& klass =
+ dart::Class::Handle(Z, LookupClassByKernelClass(kernel_klass));
+ return LookupConstructorByKernelConstructor(klass, constructor);
+}
+
+
+dart::RawFunction* TranslationHelper::LookupConstructorByKernelConstructor(
+ const dart::Class& owner, Constructor* constructor) {
+ dart::RawFunction* function =
+ owner.LookupConstructorAllowPrivate(DartConstructorName(constructor));
+ ASSERT(function != Object::null());
+ return function;
+}
+
+
+dart::Type& TranslationHelper::GetCanonicalType(const dart::Class& klass) {
+ ASSERT(!klass.IsNull());
+ // Note that if cls is _Closure, the returned type will be _Closure,
+ // and not the signature type.
+ Type& type = Type::ZoneHandle(Z, klass.CanonicalType());
+ if (!type.IsNull()) {
+ return type;
+ }
+ type = Type::New(klass, TypeArguments::Handle(Z, klass.type_parameters()),
+ klass.token_pos());
+ if (klass.is_type_finalized()) {
+ type ^= ClassFinalizer::FinalizeType(
+ klass, type, ClassFinalizer::kCanonicalizeWellFormed);
+ // Note that the receiver type may now be a malbounded type.
+ klass.SetCanonicalType(type);
+ }
+ return type;
+}
+
+
+void TranslationHelper::ReportError(const char* format, ...) {
+ const Script& null_script = Script::Handle(Z);
+
+ va_list args;
+ va_start(args, format);
+ Report::MessageV(Report::kError, null_script, TokenPosition::kNoSource,
+ Report::AtLocation, format, args);
+ va_end(args);
+ UNREACHABLE();
+}
+
+
+void TranslationHelper::ReportError(const Error& prev_error, const char* format,
+ ...) {
+ const Script& null_script = Script::Handle(Z);
+
+ va_list args;
+ va_start(args, format);
+ Report::LongJumpV(prev_error, null_script, TokenPosition::kNoSource, format,
+ args);
+ va_end(args);
+ UNREACHABLE();
+}
+
+
+dart::String& TranslationHelper::ManglePrivateName(Library* kernel_library,
+ dart::String* name_to_modify,
+ bool symbolize) {
+ if (name_to_modify->Length() >= 1 && name_to_modify->CharAt(0) == '_') {
+ const dart::Library& library =
+ dart::Library::Handle(Z, LookupLibraryByKernelLibrary(kernel_library));
+ *name_to_modify = library.PrivateName(*name_to_modify);
+ } else if (symbolize) {
+ *name_to_modify = Symbols::New(thread_, *name_to_modify);
+ }
+ return *name_to_modify;
+}
+
+
+const Array& TranslationHelper::ArgumentNames(List<NamedExpression>* named) {
+ if (named->length() == 0) return Array::ZoneHandle(Z);
+
+ const Array& names = Array::ZoneHandle(Z, Array::New(named->length()));
+ for (intptr_t i = 0; i < named->length(); ++i) {
+ names.SetAt(i, DartSymbol((*named)[i]->name()));
+ }
+ return names;
+}
+
+
+Instance& ConstantEvaluator::EvaluateExpression(Expression* expression) {
+ expression->AcceptExpressionVisitor(this);
+ // We return a new `ZoneHandle` here on purpose: The intermediate language
+ // instructions do not make a copy of the handle, so we do it.
+ return dart::Instance::ZoneHandle(Z, result_.raw());
+}
+
+
+Object& ConstantEvaluator::EvaluateExpressionSafe(Expression* expression) {
+ LongJumpScope jump;
+ if (setjmp(*jump.Set()) == 0) {
+ return EvaluateExpression(expression);
+ } else {
+ Thread* thread = Thread::Current();
+ Error& error = Error::Handle(Z);
+ error = thread->sticky_error();
+ thread->clear_sticky_error();
+ return error;
+ }
+}
+
+
+Instance& ConstantEvaluator::EvaluateConstructorInvocation(
+ ConstructorInvocation* node) {
+ VisitConstructorInvocation(node);
+ // We return a new `ZoneHandle` here on purpose: The intermediate language
+ // instructions do not make a copy of the handle, so we do it.
+ return dart::Instance::ZoneHandle(Z, result_.raw());
+}
+
+
+Instance& ConstantEvaluator::EvaluateListLiteral(ListLiteral* node) {
+ VisitListLiteral(node);
+ // We return a new `ZoneHandle` here on purpose: The intermediate language
+ // instructions do not make a copy of the handle, so we do it.
+ return dart::Instance::ZoneHandle(Z, result_.raw());
+}
+
+
+Instance& ConstantEvaluator::EvaluateMapLiteral(MapLiteral* node) {
+ VisitMapLiteral(node);
+ // We return a new `ZoneHandle` here on purpose: The intermediate language
+ // instructions do not make a copy of the handle, so we do it.
+ return dart::Instance::ZoneHandle(Z, result_.raw());
+}
+
+
+void ConstantEvaluator::VisitBigintLiteral(BigintLiteral* node) {
+ const dart::String& value = H.DartString(node->value());
+ result_ = Integer::New(value, Heap::kOld);
+ result_ = H.Canonicalize(result_);
+}
+
+
+void ConstantEvaluator::VisitBoolLiteral(BoolLiteral* node) {
+ result_ = dart::Bool::Get(node->value()).raw();
+}
+
+
+void ConstantEvaluator::VisitDoubleLiteral(DoubleLiteral* node) {
+ result_ = dart::Double::New(H.DartString(node->value()), Heap::kOld);
+ result_ = H.Canonicalize(result_);
+}
+
+
+void ConstantEvaluator::VisitIntLiteral(IntLiteral* node) {
+ result_ = dart::Integer::New(node->value(), Heap::kOld);
+ result_ = H.Canonicalize(result_);
+}
+
+
+void ConstantEvaluator::VisitNullLiteral(NullLiteral* node) {
+ result_ = dart::Instance::null();
+}
+
+
+void ConstantEvaluator::VisitStringLiteral(StringLiteral* node) {
+ result_ = H.DartSymbol(node->value()).raw();
+}
+
+
+void ConstantEvaluator::VisitTypeLiteral(TypeLiteral* node) {
+ const AbstractType& type = T.TranslateType(node->type());
+ if (type.IsMalformed()) {
+ H.ReportError("Malformed type literal in constant expression.");
+ }
+ result_ = type.raw();
+}
+
+
+RawObject* ConstantEvaluator::EvaluateConstConstructorCall(
+ const dart::Class& type_class, const TypeArguments& type_arguments,
+ const Function& constructor, const Object& argument) {
+ // Factories have one extra argument: the type arguments.
+ // Constructors have 1 extra arguments: receiver.
+ const int kNumArgs = 1;
+ const int kNumExtraArgs = 1;
+ const int num_arguments = kNumArgs + kNumExtraArgs;
+ const Array& arg_values =
+ Array::Handle(Z, Array::New(num_arguments, Heap::kOld));
+ Instance& instance = Instance::Handle(Z);
+ if (!constructor.IsFactory()) {
+ instance = Instance::New(type_class, Heap::kOld);
+ if (!type_arguments.IsNull()) {
+ ASSERT(type_arguments.IsInstantiated());
+ instance.SetTypeArguments(
+ TypeArguments::Handle(Z, type_arguments.Canonicalize()));
+ }
+ arg_values.SetAt(0, instance);
+ } else {
+ // Prepend type_arguments to list of arguments to factory.
+ ASSERT(type_arguments.IsZoneHandle());
+ arg_values.SetAt(0, type_arguments);
+ }
+ arg_values.SetAt((0 + kNumExtraArgs), argument);
+ const Array& args_descriptor = Array::Handle(
+ Z, ArgumentsDescriptor::New(num_arguments, Object::empty_array()));
+ const Object& result = Object::Handle(
+ Z, DartEntry::InvokeFunction(constructor, arg_values, args_descriptor));
+ ASSERT(!result.IsError());
+ if (constructor.IsFactory()) {
+ // The factory method returns the allocated object.
+ instance ^= result.raw();
+ }
+ return H.Canonicalize(instance);
+}
+
+
+void ConstantEvaluator::VisitSymbolLiteral(SymbolLiteral* node) {
+ const dart::String& symbol_value = H.DartSymbol(node->value());
+
+ const dart::Class& symbol_class =
+ dart::Class::ZoneHandle(Z, I->object_store()->symbol_class());
+ ASSERT(!symbol_class.IsNull());
+ const dart::Function& symbol_constructor = Function::ZoneHandle(
+ Z, symbol_class.LookupConstructor(Symbols::SymbolCtor()));
+ ASSERT(!symbol_constructor.IsNull());
+ result_ ^= EvaluateConstConstructorCall(
+ symbol_class, TypeArguments::Handle(Z), symbol_constructor, symbol_value);
+}
+
+
+void ConstantEvaluator::VisitListLiteral(ListLiteral* node) {
+ DartType* types[] = {node->type()};
+ const TypeArguments& type_arguments = T.TranslateTypeArguments(types, 1);
+
+ intptr_t length = node->expressions().length();
+ const Array& const_list =
+ Array::ZoneHandle(Z, Array::New(length, Heap::kOld));
+ const_list.SetTypeArguments(type_arguments);
+ for (intptr_t i = 0; i < length; i++) {
+ const Instance& expression = EvaluateExpression(node->expressions()[i]);
+ const_list.SetAt(i, expression);
+ }
+ const_list.MakeImmutable();
+ result_ = H.Canonicalize(const_list);
+}
+
+
+void ConstantEvaluator::VisitMapLiteral(MapLiteral* node) {
+ DartType* types[] = {node->key_type(), node->value_type()};
+ const TypeArguments& type_arguments = T.TranslateTypeArguments(types, 2);
+
+ intptr_t length = node->entries().length();
+
+ Array& const_kv_array =
+ Array::ZoneHandle(Z, Array::New(2 * length, Heap::kOld));
+ for (intptr_t i = 0; i < length; i++) {
+ const_kv_array.SetAt(2 * i + 0,
+ EvaluateExpression(node->entries()[i]->key()));
+ const_kv_array.SetAt(2 * i + 1,
+ EvaluateExpression(node->entries()[i]->value()));
+ }
+
+ const_kv_array.MakeImmutable();
+ const_kv_array ^= H.Canonicalize(const_kv_array);
+
+ const dart::Class& map_class = dart::Class::Handle(
+ Z, dart::Library::LookupCoreClass(Symbols::ImmutableMap()));
+ ASSERT(!map_class.IsNull());
+ ASSERT(map_class.NumTypeArguments() == 2);
+
+ const dart::Field& field = dart::Field::Handle(
+ Z, map_class.LookupInstanceFieldAllowPrivate(H.DartSymbol("_kvPairs")));
+ ASSERT(!field.IsNull());
+
+ // NOTE: This needs to be kept in sync with `runtime/lib/immutable_map.dart`!
+ result_ = Instance::New(map_class, Heap::kOld);
+ ASSERT(!result_.IsNull());
+ result_.SetTypeArguments(type_arguments);
+ result_.SetField(field, const_kv_array);
+ result_ = H.Canonicalize(result_);
+}
+
+
+void ConstantEvaluator::VisitConstructorInvocation(
+ ConstructorInvocation* node) {
+ Arguments* kernel_arguments = node->arguments();
+
+ const Function& constructor = Function::Handle(
+ Z, H.LookupConstructorByKernelConstructor(node->target()));
+ dart::Class& klass = dart::Class::Handle(Z, constructor.Owner());
+
+ // Build the type arguments vector (if necessary).
+ const TypeArguments* type_arguments =
+ TranslateTypeArguments(constructor, &klass, kernel_arguments);
+
+ // Prepare either the instance or the type argument vector for the constructor
+ // call.
+ Instance* receiver = NULL;
+ const TypeArguments* type_arguments_argument = NULL;
+ if (!constructor.IsFactory()) {
+ receiver = &Instance::ZoneHandle(Z, Instance::New(klass, Heap::kOld));
+ if (type_arguments != NULL) {
+ receiver->SetTypeArguments(*type_arguments);
+ }
+ } else {
+ type_arguments_argument = type_arguments;
+ }
+
+ const Object& result = RunFunction(constructor, kernel_arguments, receiver,
+ type_arguments_argument);
+ if (constructor.IsFactory()) {
+ // Factories return the new object.
+ result_ ^= result.raw();
+ result_ = H.Canonicalize(result_);
+ } else {
+ ASSERT(!receiver->IsNull());
+ result_ = H.Canonicalize(*receiver);
+ }
+}
+
+
+void ConstantEvaluator::VisitMethodInvocation(MethodInvocation* node) {
+ Arguments* kernel_arguments = node->arguments();
+
+ // Dart does not support generic methods yet.
+ ASSERT(kernel_arguments->types().length() == 0);
+
+ const dart::Instance& receiver = EvaluateExpression(node->receiver());
+ dart::Class& klass = dart::Class::Handle(
+ Z, isolate_->class_table()->At(receiver.GetClassId()));
+ ASSERT(!klass.IsNull());
+
+ // Search the superclass chain for the selector.
+ // TODO(27590): Can we assume this will never be a no-such-method error?
+ dart::Function& function = dart::Function::Handle(Z);
+ const dart::String& method_name = H.DartMethodName(node->name());
+ while (!klass.IsNull()) {
+ function = klass.LookupDynamicFunctionAllowPrivate(method_name);
+ if (!function.IsNull()) break;
+ klass = klass.SuperClass();
+ }
+ ASSERT(!function.IsNull());
+
+ // Run the method and canonicalize the result.
+ const Object& result = RunFunction(function, kernel_arguments, &receiver);
+ result_ ^= result.raw();
+ result_ = H.Canonicalize(result_);
+}
+
+
+void ConstantEvaluator::VisitStaticGet(StaticGet* node) {
+ Member* member = node->target();
+ if (member->IsField()) {
+ Field* kernel_field = Field::Cast(member);
+ const dart::Field& field =
+ dart::Field::Handle(Z, H.LookupFieldByKernelField(kernel_field));
+ if (field.StaticValue() == Object::sentinel().raw() ||
+ field.StaticValue() == Object::transition_sentinel().raw()) {
+ field.EvaluateInitializer();
+ result_ = field.StaticValue();
+ result_ = H.Canonicalize(result_);
+ field.SetStaticValue(result_, true);
+ } else {
+ result_ = field.StaticValue();
+ }
+ } else if (member->IsProcedure()) {
+ Procedure* procedure = Procedure::Cast(member);
+ const Function& target = Function::ZoneHandle(
+ Z, H.LookupStaticMethodByKernelProcedure(procedure));
+
+ if (procedure->kind() == Procedure::kMethod) {
+ ASSERT(procedure->IsStatic());
+ Function& closure_function =
+ Function::ZoneHandle(Z, target.ImplicitClosureFunction());
+ closure_function.set_kernel_function(target.kernel_function());
+ result_ = closure_function.ImplicitStaticClosure();
+ result_ = H.Canonicalize(result_);
+ } else if (procedure->kind() == Procedure::kGetter) {
+ UNIMPLEMENTED();
+ } else {
+ UNIMPLEMENTED();
+ }
+ }
+}
+
+
+void ConstantEvaluator::VisitVariableGet(VariableGet* node) {
+ // When we see a [VariableGet] the corresponding [VariableDeclaration] must've
+ // been executed already. It therefore must have a constant object associated
+ // with it.
+ LocalVariable* variable = builder_->LookupVariable(node->variable());
+ ASSERT(variable->IsConst());
+ result_ = variable->ConstValue()->raw();
+}
+
+
+void ConstantEvaluator::VisitLet(Let* node) {
+ VariableDeclaration* variable = node->variable();
+ LocalVariable* local = builder_->LookupVariable(variable);
+ local->SetConstValue(EvaluateExpression(variable->initializer()));
+ node->body()->AcceptExpressionVisitor(this);
+}
+
+
+void ConstantEvaluator::VisitStaticInvocation(StaticInvocation* node) {
+ const Function& function = Function::ZoneHandle(
+ Z, H.LookupStaticMethodByKernelProcedure(node->procedure()));
+ dart::Class& klass = dart::Class::Handle(Z, function.Owner());
+
+ // Build the type arguments vector (if necessary).
+ const TypeArguments* type_arguments =
+ TranslateTypeArguments(function, &klass, node->arguments());
+
+ const Object& result =
+ RunFunction(function, node->arguments(), NULL, type_arguments);
+ result_ ^= result.raw();
+ result_ = H.Canonicalize(result_);
+}
+
+
+void ConstantEvaluator::VisitStringConcatenation(StringConcatenation* node) {
+ intptr_t length = node->expressions().length();
+
+ bool all_string = true;
+ const Array& strings = Array::Handle(Z, Array::New(length));
+ for (intptr_t i = 0; i < length; i++) {
+ EvaluateExpression(node->expressions()[i]);
+ strings.SetAt(i, result_);
+ all_string = all_string && result_.IsString();
+ }
+ if (all_string) {
+ result_ = dart::String::ConcatAll(strings, Heap::kOld);
+ result_ = H.Canonicalize(result_);
+ } else {
+ // Get string interpolation function.
+ const dart::Class& cls = dart::Class::Handle(
+ Z, dart::Library::LookupCoreClass(Symbols::StringBase()));
+ ASSERT(!cls.IsNull());
+ const Function& func = Function::Handle(
+ Z, cls.LookupStaticFunction(
+ dart::Library::PrivateCoreLibName(Symbols::Interpolate())));
+ ASSERT(!func.IsNull());
+
+ // Build argument array to pass to the interpolation function.
+ const Array& interpolate_arg = Array::Handle(Z, Array::New(1, Heap::kOld));
+ interpolate_arg.SetAt(0, strings);
+
+ // Run and canonicalize.
+ const Object& result =
+ RunFunction(func, interpolate_arg, Array::null_array());
+ result_ = H.Canonicalize(dart::String::Cast(result));
+ }
+}
+
+
+void ConstantEvaluator::VisitConditionalExpression(
+ ConditionalExpression* node) {
+ EvaluateExpression(node->condition());
+ if (Bool::Cast(result_).value()) {
+ EvaluateExpression(node->then());
+ } else {
+ EvaluateExpression(node->otherwise());
+ }
+}
+
+
+void ConstantEvaluator::VisitLogicalExpression(LogicalExpression* node) {
+ if (node->op() == LogicalExpression::kAnd) {
+ EvaluateExpression(node->left());
+ if (Bool::Cast(result_).value()) {
+ EvaluateExpression(node->right());
+ }
+ } else {
+ ASSERT(node->op() == LogicalExpression::kOr);
+ EvaluateExpression(node->left());
+ if (!Bool::Cast(result_).value()) {
+ EvaluateExpression(node->right());
+ }
+ }
+}
+
+
+void ConstantEvaluator::VisitNot(Not* node) {
+ EvaluateExpression(node->expression());
+ ASSERT(result_.IsBool());
+ result_ =
+ Bool::Cast(result_).value() ? Bool::False().raw() : Bool::True().raw();
+}
+
+
+const TypeArguments* ConstantEvaluator::TranslateTypeArguments(
+ const Function& target, dart::Class* target_klass,
+ Arguments* kernel_arguments) {
+ List<DartType>& kernel_type_arguments = kernel_arguments->types();
+
+ const TypeArguments* type_arguments = NULL;
+ if (kernel_type_arguments.length() > 0) {
+ type_arguments = &T.TranslateInstantiatedTypeArguments(
+ *target_klass, kernel_type_arguments.raw_array(),
+ kernel_type_arguments.length());
+
+ if (!(type_arguments->IsNull() || type_arguments->IsInstantiated())) {
+ H.ReportError("Type must be constant in const constructor.");
+ }
+ } else if (target.IsFactory() && type_arguments == NULL) {
+ // All factories take a type arguments vector as first argument (independent
+ // of whether the class is generic or not).
+ type_arguments = &TypeArguments::ZoneHandle(Z, TypeArguments::null());
+ }
+ return type_arguments;
+}
+
+
+const Object& ConstantEvaluator::RunFunction(const Function& function,
+ Arguments* kernel_arguments,
+ const Instance* receiver,
+ const TypeArguments* type_args) {
+ // We do not support generic methods yet.
+ ASSERT((receiver == NULL) || (type_args == NULL));
+ intptr_t extra_arguments =
+ (receiver != NULL ? 1 : 0) + (type_args != NULL ? 1 : 0);
+
+ // Build up arguments.
+ const Array& arguments = Array::ZoneHandle(
+ Z, Array::New(extra_arguments + kernel_arguments->count()));
+ const Array& names =
+ Array::ZoneHandle(Z, Array::New(kernel_arguments->named().length()));
+ intptr_t pos = 0;
+ if (receiver != NULL) {
+ arguments.SetAt(pos++, *receiver);
+ }
+ if (type_args != NULL) {
+ arguments.SetAt(pos++, *type_args);
+ }
+ for (intptr_t i = 0; i < kernel_arguments->positional().length(); i++) {
+ EvaluateExpression(kernel_arguments->positional()[i]);
+ arguments.SetAt(pos++, result_);
+ }
+ for (intptr_t i = 0; i < kernel_arguments->named().length(); i++) {
+ NamedExpression* named_expression = kernel_arguments->named()[i];
+ EvaluateExpression(named_expression->expression());
+ arguments.SetAt(pos++, result_);
+ names.SetAt(i, H.DartSymbol(named_expression->name()));
+ }
+ return RunFunction(function, arguments, names);
+}
+
+
+const Object& ConstantEvaluator::RunFunction(const Function& function,
+ const Array& arguments,
+ const Array& names) {
+ const Array& args_descriptor =
+ Array::Handle(Z, ArgumentsDescriptor::New(arguments.Length(), names));
+ const Object& result = Object::Handle(
+ Z, DartEntry::InvokeFunction(function, arguments, args_descriptor));
+ if (result.IsError()) {
+ H.ReportError(Error::Cast(result), "error evaluating constant constructor");
+ }
+ return result;
+}
+
+
+FlowGraphBuilder::FlowGraphBuilder(
+ TreeNode* node, ParsedFunction* parsed_function,
+ const ZoneGrowableArray<const ICData*>& ic_data_array,
+ InlineExitCollector* exit_collector, intptr_t osr_id,
+ intptr_t first_block_id)
+ : zone_(Thread::Current()->zone()),
+ translation_helper_(Thread::Current(), zone_,
+ Thread::Current()->isolate()),
+ node_(node),
+ parsed_function_(parsed_function),
+ osr_id_(osr_id),
+ ic_data_array_(ic_data_array),
+ exit_collector_(exit_collector),
+ next_block_id_(first_block_id),
+ next_function_id_(0),
+ context_depth_(0),
+ loop_depth_(0),
+ try_depth_(0),
+ catch_depth_(0),
+ for_in_depth_(0),
+ stack_(NULL),
+ pending_argument_count_(0),
+ graph_entry_(NULL),
+ scopes_(NULL),
+ breakable_block_(NULL),
+ switch_block_(NULL),
+ try_finally_block_(NULL),
+ try_catch_block_(NULL),
+ next_used_try_index_(0),
+ catch_block_(NULL),
+ type_translator_(&translation_helper_, &active_class_),
+ constant_evaluator_(this, zone_, &translation_helper_,
+ &type_translator_) {}
+
+
+FlowGraphBuilder::~FlowGraphBuilder() {}
+
+
+Fragment FlowGraphBuilder::TranslateFinallyFinalizers(
+ TryFinallyBlock* outer_finally, intptr_t target_context_depth) {
+ TryFinallyBlock* const saved_block = try_finally_block_;
+ const intptr_t saved_depth = context_depth_;
+ const intptr_t saved_try_depth = try_depth_;
+
+ Fragment instructions;
+
+ // While translating the body of a finalizer we need to set the try-finally
+ // block which is active when translating the body.
+ while (try_finally_block_ != outer_finally) {
+ // Set correct try depth (in case there are nested try statements).
+ try_depth_ = try_finally_block_->try_depth();
+
+ // Potentially restore the context to what is expected for the finally
+ // block.
+ instructions += AdjustContextTo(try_finally_block_->context_depth());
+
+ Statement* finalizer = try_finally_block_->finalizer();
+ try_finally_block_ = try_finally_block_->outer();
+
+ // This will potentially have exceptional cases as described in
+ // [VisitTryFinally] and will handle them.
+ instructions += TranslateStatement(finalizer);
+
+ // We only need to make sure that if the finalizer ended normally, we
+ // continue towards the next outer try-finally.
+ if (!instructions.is_open()) break;
+ }
+
+ if (instructions.is_open() && target_context_depth != -1) {
+ // A target context depth of -1 indicates that we the code after this
+ // will not care about the context chain so we can leave it any way we
+ // want after the last finalizer. That is used when returning.
+ instructions += AdjustContextTo(target_context_depth);
+ }
+
+ try_finally_block_ = saved_block;
+ context_depth_ = saved_depth;
+ try_depth_ = saved_try_depth;
+
+ return instructions;
+}
+
+
+Fragment FlowGraphBuilder::EnterScope(TreeNode* node, bool* new_context) {
+ Fragment instructions;
+ const intptr_t context_size =
+ scopes_->scopes.Lookup(node)->num_context_variables();
+ if (context_size > 0) {
+ instructions += PushContext(context_size);
+ instructions += Drop();
+ if (new_context != NULL) {
+ *new_context = true;
+ }
+ }
+ return instructions;
+}
+
+
+Fragment FlowGraphBuilder::ExitScope(TreeNode* node) {
+ Fragment instructions;
+ const intptr_t context_size =
+ scopes_->scopes.Lookup(node)->num_context_variables();
+ if (context_size > 0) {
+ instructions += PopContext();
+ }
+ return instructions;
+}
+
+
+Fragment FlowGraphBuilder::LoadContextAt(int depth) {
+ intptr_t delta = context_depth_ - depth;
+ ASSERT(delta >= 0);
+ Fragment instructions = LoadLocal(parsed_function_->current_context_var());
+ while (delta-- > 0) {
+ instructions += LoadField(Context::parent_offset());
+ }
+ return instructions;
+}
+
+
+Fragment FlowGraphBuilder::AdjustContextTo(int depth) {
+ ASSERT(depth <= context_depth_ && depth >= 0);
+ Fragment instructions;
+ if (depth < context_depth_) {
+ instructions += LoadContextAt(depth);
+ instructions += StoreLocal(parsed_function_->current_context_var());
+ instructions += Drop();
+ context_depth_ = depth;
+ }
+ return instructions;
+}
+
+
+Fragment FlowGraphBuilder::PushContext(int size) {
+ ASSERT(size > 0);
+ Fragment instructions = AllocateContext(size);
+ LocalVariable* context = MakeTemporary();
+ instructions += LoadLocal(context);
+ instructions += LoadLocal(parsed_function_->current_context_var());
+ instructions += StoreInstanceField(Context::parent_offset());
+ instructions += StoreLocal(parsed_function_->current_context_var());
+ ++context_depth_;
+ return instructions;
+}
+
+
+Fragment FlowGraphBuilder::PopContext() {
+ return AdjustContextTo(context_depth_ - 1);
+}
+
+
+Fragment FlowGraphBuilder::LoadInstantiatorTypeArguments() {
+ // TODO(27590): We could use `active_class_->IsGeneric()`.
+ Fragment instructions;
+ if (scopes_->type_arguments_variable != NULL) {
+#ifdef DEBUG
+ Function& function =
+ Function::Handle(Z, parsed_function_->function().raw());
+ while (function.IsClosureFunction()) {
+ function = function.parent_function();
+ }
+ ASSERT(function.IsFactory());
+#endif
+ instructions += LoadLocal(scopes_->type_arguments_variable);
+ } else if (scopes_->this_variable != NULL &&
+ active_class_.kernel_class != NULL &&
+ active_class_.kernel_class->type_parameters().length() > 0) {
+ ASSERT(!parsed_function_->function().IsFactory());
+ intptr_t type_arguments_field_offset =
+ active_class_.klass->type_arguments_field_offset();
+ ASSERT(type_arguments_field_offset != dart::Class::kNoTypeArguments);
+
+ instructions += LoadLocal(scopes_->this_variable);
+ instructions += LoadField(type_arguments_field_offset);
+ } else {
+ instructions += NullConstant();
+ }
+ return instructions;
+}
+
+
+Fragment FlowGraphBuilder::InstantiateTypeArguments(
+ const TypeArguments& type_arguments) {
+ InstantiateTypeArgumentsInstr* instr = new (Z) InstantiateTypeArgumentsInstr(
+ TokenPosition::kNoSource, type_arguments, *active_class_.klass, Pop());
+ Push(instr);
+ return Fragment(instr);
+}
+
+
+Fragment FlowGraphBuilder::TranslateInstantiatedTypeArguments(
+ const TypeArguments& type_arguments) {
+ Fragment instructions;
+
+ if (type_arguments.IsNull() || type_arguments.IsInstantiated()) {
+ // There are no type references to type parameters so we can just take it.
+ instructions += Constant(type_arguments);
+ } else {
+ // The [type_arguments] vector contains a type reference to a type
+ // parameter we need to resolve it.
+ const bool use_instantiator =
+ type_arguments.IsUninstantiatedIdentity() ||
+ type_arguments.CanShareInstantiatorTypeArguments(*active_class_.klass);
+ if (use_instantiator) {
+ // If the instantiator type arguments are just passed on, we don't need to
+ // resolve the type parameters.
+ //
+ // This is for example the case here:
+ // class Foo<T> {
+ // newList() => new List<T>();
+ // }
+ // We just use the type argument vector from the [Foo] object and pass it
+ // directly to the `new List<T>()` factory constructor.
+ instructions += LoadInstantiatorTypeArguments();
+ } else {
+ // Otherwise we need to resolve [TypeParameterType]s in the type
+ // expression based on the current instantiator type argument vector.
+ instructions += LoadInstantiatorTypeArguments();
+ instructions += InstantiateTypeArguments(type_arguments);
+ }
+ }
+ return instructions;
+}
+
+
+Fragment FlowGraphBuilder::AllocateContext(int size) {
+ AllocateContextInstr* allocate =
+ new (Z) AllocateContextInstr(TokenPosition::kNoSource, size);
+ Push(allocate);
+ return Fragment(allocate);
+}
+
+
+Fragment FlowGraphBuilder::AllocateObject(const dart::Class& klass,
+ intptr_t argument_count) {
+ ArgumentArray arguments = GetArguments(argument_count);
+ AllocateObjectInstr* allocate =
+ new (Z) AllocateObjectInstr(TokenPosition::kNoSource, klass, arguments);
+ Push(allocate);
+ return Fragment(allocate);
+}
+
+
+Fragment FlowGraphBuilder::AllocateObject(const dart::Class& klass,
+ const Function& closure_function) {
+ ArgumentArray arguments = new (Z) ZoneGrowableArray<PushArgumentInstr*>(Z, 0);
+ AllocateObjectInstr* allocate =
+ new (Z) AllocateObjectInstr(TokenPosition::kNoSource, klass, arguments);
+ allocate->set_closure_function(closure_function);
+ Push(allocate);
+ return Fragment(allocate);
+}
+
+
+Fragment FlowGraphBuilder::BooleanNegate() {
+ BooleanNegateInstr* negate = new (Z) BooleanNegateInstr(Pop());
+ Push(negate);
+ return Fragment(negate);
+}
+
+
+Fragment FlowGraphBuilder::StrictCompare(Token::Kind kind,
+ bool number_check /* = false */) {
+ Value* right = Pop();
+ Value* left = Pop();
+ StrictCompareInstr* compare = new (Z) StrictCompareInstr(
+ TokenPosition::kNoSource, kind, left, right, number_check);
+ Push(compare);
+ return Fragment(compare);
+}
+
+
+Fragment FlowGraphBuilder::BranchIfTrue(TargetEntryInstr** then_entry,
+ TargetEntryInstr** otherwise_entry,
+ bool negate) {
+ Fragment instructions = Constant(Bool::True());
+ return instructions + BranchIfEqual(then_entry, otherwise_entry, negate);
+}
+
+
+Fragment FlowGraphBuilder::BranchIfNull(TargetEntryInstr** then_entry,
+ TargetEntryInstr** otherwise_entry,
+ bool negate) {
+ Fragment instructions = NullConstant();
+ return instructions + BranchIfEqual(then_entry, otherwise_entry, negate);
+}
+
+Fragment FlowGraphBuilder::BranchIfEqual(TargetEntryInstr** then_entry,
+ TargetEntryInstr** otherwise_entry,
+ bool negate) {
+ Value* right_value = Pop();
+ Value* left_value = Pop();
+ StrictCompareInstr* compare = new (Z) StrictCompareInstr(
+ TokenPosition::kNoSource, negate ? Token::kNE_STRICT : Token::kEQ_STRICT,
+ left_value, right_value, false);
+ BranchInstr* branch = new (Z) BranchInstr(compare);
+ *then_entry = *branch->true_successor_address() = BuildTargetEntry();
+ *otherwise_entry = *branch->false_successor_address() = BuildTargetEntry();
+ return Fragment(branch).closed();
+}
+
+
+Fragment FlowGraphBuilder::BranchIfStrictEqual(
+ TargetEntryInstr** then_entry, TargetEntryInstr** otherwise_entry) {
+ Value* rhs = Pop();
+ Value* lhs = Pop();
+ StrictCompareInstr* compare = new (Z) StrictCompareInstr(
+ TokenPosition::kNoSource, Token::kEQ_STRICT, lhs, rhs, false);
+ BranchInstr* branch = new (Z) BranchInstr(compare);
+ *then_entry = *branch->true_successor_address() = BuildTargetEntry();
+ *otherwise_entry = *branch->false_successor_address() = BuildTargetEntry();
+ return Fragment(branch).closed();
+}
+
+
+Fragment FlowGraphBuilder::CatchBlockEntry(const Array& handler_types,
+ intptr_t handler_index) {
+ ASSERT(CurrentException()->is_captured() ==
+ CurrentStackTrace()->is_captured());
+ const bool should_restore_closure_context =
+ CurrentException()->is_captured() ||
+ CurrentCatchContext()->is_captured();
+ CatchBlockEntryInstr* entry = new (Z) CatchBlockEntryInstr(
+ AllocateBlockId(), CurrentTryIndex(), graph_entry_, handler_types,
+ handler_index, *CurrentException(), *CurrentStackTrace(),
+ /* needs_stacktrace = */ true, Thread::Current()->GetNextDeoptId(),
+ should_restore_closure_context);
+ graph_entry_->AddCatchEntry(entry);
+ Fragment instructions(entry);
+
+ // :saved_try_context_var can be captured in the context of
+ // of the closure, in this case CatchBlockEntryInstr restores
+ // :current_context_var to point to closure context in the
+ // same way as normal function prologue does.
+ // Update current context depth to reflect that.
+ const intptr_t saved_context_depth = context_depth_;
+ ASSERT(!CurrentCatchContext()->is_captured() ||
+ CurrentCatchContext()->owner()->context_level() == 0);
+ context_depth_ = 0;
+ instructions += LoadLocal(CurrentCatchContext());
+ instructions += StoreLocal(parsed_function_->current_context_var());
+ instructions += Drop();
+ context_depth_ = saved_context_depth;
+
+ return instructions;
+}
+
+
+Fragment FlowGraphBuilder::TryCatch(int try_handler_index) {
+ // The body of the try needs to have it's own block in order to get a new try
+ // index.
+ //
+ // => We therefore create a block for the body (fresh try index) and another
+ // join block (with current try index).
+ Fragment body;
+ JoinEntryInstr* entry =
+ new (Z) JoinEntryInstr(AllocateBlockId(), try_handler_index);
+ body += LoadLocal(parsed_function_->current_context_var());
+ body += StoreLocal(CurrentCatchContext());
+ body += Drop();
+ body += Goto(entry);
+ return Fragment(body.entry, entry);
+}
+
+
+Fragment FlowGraphBuilder::CheckStackOverflowInPrologue() {
+ if (IsInlining()) {
+ // If we are inlining don't actually attach the stack check. We must still
+ // create the stack check in order to allocate a deopt id.
+ CheckStackOverflow();
+ return Fragment();
+ }
+ return CheckStackOverflow();
+}
+
+
+Fragment FlowGraphBuilder::CheckStackOverflow() {
+ return Fragment(
+ new (Z) CheckStackOverflowInstr(TokenPosition::kNoSource, loop_depth_));
+}
+
+
+Fragment FlowGraphBuilder::CloneContext() {
+ LocalVariable* context_variable = parsed_function_->current_context_var();
+
+ Fragment instructions = LoadLocal(context_variable);
+
+ CloneContextInstr* clone_instruction =
+ new (Z) CloneContextInstr(TokenPosition::kNoSource, Pop());
+ instructions <<= clone_instruction;
+ Push(clone_instruction);
+
+ instructions += StoreLocal(context_variable);
+ instructions += Drop();
+ return instructions;
+}
+
+
+Fragment FlowGraphBuilder::Constant(const Object& value) {
+ ASSERT(value.IsNotTemporaryScopedHandle());
+ ConstantInstr* constant = new (Z) ConstantInstr(value);
+ Push(constant);
+ return Fragment(constant);
+}
+
+
+Fragment FlowGraphBuilder::CreateArray() {
+ Value* element_count = Pop();
+ CreateArrayInstr* array = new (Z) CreateArrayInstr(TokenPosition::kNoSource,
+ Pop(), // Element type.
+ element_count);
+ Push(array);
+ return Fragment(array);
+}
+
+
+Fragment FlowGraphBuilder::Goto(JoinEntryInstr* destination) {
+ return Fragment(new (Z) GotoInstr(destination)).closed();
+}
+
+
+Fragment FlowGraphBuilder::IntConstant(int64_t value) {
+ return Fragment(
+ Constant(Integer::ZoneHandle(Z, Integer::New(value, Heap::kOld))));
+}
+
+
+Fragment FlowGraphBuilder::InstanceCall(const dart::String& name,
+ Token::Kind kind,
+ intptr_t argument_count,
+ intptr_t num_args_checked) {
+ return InstanceCall(name, kind, argument_count, Array::null_array(),
+ num_args_checked);
+}
+
+
+Fragment FlowGraphBuilder::InstanceCall(const dart::String& name,
+ Token::Kind kind,
+ intptr_t argument_count,
+ const Array& argument_names,
+ intptr_t num_args_checked) {
+ ArgumentArray arguments = GetArguments(argument_count);
+ InstanceCallInstr* call = new (Z)
+ InstanceCallInstr(TokenPosition::kNoSource, name, kind, arguments,
+ argument_names, num_args_checked, ic_data_array_);
+ Push(call);
+ return Fragment(call);
+}
+
+
+Fragment FlowGraphBuilder::ClosureCall(int argument_count,
+ const Array& argument_names) {
+ Value* function = Pop();
+ ArgumentArray arguments = GetArguments(argument_count);
+ ClosureCallInstr* call = new (Z) ClosureCallInstr(
+ function, arguments, argument_names, TokenPosition::kNoSource);
+ Push(call);
+ return Fragment(call);
+}
+
+
+Fragment FlowGraphBuilder::ThrowException() {
+ Fragment instructions;
+ instructions += Drop();
+ instructions +=
+ Fragment(new (Z) ThrowInstr(TokenPosition::kNoSource)).closed();
+ // Use it's side effect of leaving a constant on the stack (does not change
+ // the graph).
+ NullConstant();
+
+ pending_argument_count_ -= 1;
+
+ return instructions;
+}
+
+
+Fragment FlowGraphBuilder::RethrowException(int catch_try_index) {
+ Fragment instructions;
+ instructions += Drop();
+ instructions += Drop();
+ instructions +=
+ Fragment(new (Z) ReThrowInstr(TokenPosition::kNoSource, catch_try_index))
+ .closed();
+ // Use it's side effect of leaving a constant on the stack (does not change
+ // the graph).
+ NullConstant();
+
+ pending_argument_count_ -= 2;
+
+ return instructions;
+}
+
+
+Fragment FlowGraphBuilder::LoadClassId() {
+ LoadClassIdInstr* load = new (Z) LoadClassIdInstr(Pop());
+ Push(load);
+ return Fragment(load);
+}
+
+
+Fragment FlowGraphBuilder::LoadField(const dart::Field& field) {
+ LoadFieldInstr* load = new (Z)
+ LoadFieldInstr(Pop(), &field, AbstractType::ZoneHandle(Z, field.type()),
+ TokenPosition::kNoSource);
+ Push(load);
+ return Fragment(load);
+}
+
+
+Fragment FlowGraphBuilder::LoadField(intptr_t offset, intptr_t class_id) {
+ LoadFieldInstr* load = new (Z) LoadFieldInstr(
+ Pop(), offset, AbstractType::ZoneHandle(Z), TokenPosition::kNoSource);
+ load->set_result_cid(class_id);
+ Push(load);
+ return Fragment(load);
+}
+
+
+Fragment FlowGraphBuilder::LoadNativeField(MethodRecognizer::Kind kind,
+ intptr_t offset, const Type& type,
+ intptr_t class_id,
+ bool is_immutable) {
+ LoadFieldInstr* load =
+ new (Z) LoadFieldInstr(Pop(), offset, type, TokenPosition::kNoSource);
+ load->set_recognized_kind(kind);
+ load->set_result_cid(class_id);
+ load->set_is_immutable(is_immutable);
+ Push(load);
+ return Fragment(load);
+}
+
+
+Fragment FlowGraphBuilder::LoadLocal(LocalVariable* variable) {
+ Fragment instructions;
+ if (variable->is_captured()) {
+ instructions += LoadContextAt(variable->owner()->context_level());
+ instructions += LoadField(Context::variable_offset(variable->index()));
+ } else {
+ LoadLocalInstr* load =
+ new (Z) LoadLocalInstr(*variable, TokenPosition::kNoSource);
+ instructions <<= load;
+ Push(load);
+ }
+ return instructions;
+}
+
+
+Fragment FlowGraphBuilder::InitStaticField(const dart::Field& field) {
+ InitStaticFieldInstr* init = new (Z) InitStaticFieldInstr(Pop(), field);
+ return Fragment(init);
+}
+
+
+Fragment FlowGraphBuilder::LoadStaticField() {
+ LoadStaticFieldInstr* load =
+ new (Z) LoadStaticFieldInstr(Pop(), TokenPosition::kNoSource);
+ Push(load);
+ return Fragment(load);
+}
+
+
+Fragment FlowGraphBuilder::NullConstant() {
+ return Constant(Instance::ZoneHandle(Z, Instance::null()));
+}
+
+
+Fragment FlowGraphBuilder::NativeCall(const dart::String* name,
+ const Function* function) {
+ InlineBailout("kernel::FlowGraphBuilder::NativeCall");
+ NativeCallInstr* call = new (Z) NativeCallInstr(
+ name, function, FLAG_link_natives_lazily, TokenPosition::kNoSource);
+ Push(call);
+ return Fragment(call);
+}
+
+
+Fragment FlowGraphBuilder::PushArgument() {
+ PushArgumentInstr* argument = new (Z) PushArgumentInstr(Pop());
+ Push(argument);
+
+ argument->set_temp_index(argument->temp_index() - 1);
+ ++pending_argument_count_;
+
+ return Fragment(argument);
+}
+
+
+Fragment FlowGraphBuilder::Return() {
+ Value* value = Pop();
+ ASSERT(stack_ == NULL);
+ ReturnInstr* return_instr =
+ new (Z) ReturnInstr(TokenPosition::kNoSource, value);
+ if (exit_collector_ != NULL) exit_collector_->AddExit(return_instr);
+ return Fragment(return_instr).closed();
+}
+
+
+Fragment FlowGraphBuilder::StaticCall(const Function& target,
+ intptr_t argument_count) {
+ return StaticCall(target, argument_count, Array::null_array());
+}
+
+
+static intptr_t GetResultCidOfListFactory(Zone* zone,
+ const Function& function,
+ intptr_t argument_count) {
+ if (!function.IsFactory()) {
+ return kDynamicCid;
+ }
+
+ const dart::Class& owner = dart::Class::Handle(zone, function.Owner());
+ if ((owner.library() != dart::Library::CoreLibrary()) &&
+ (owner.library() != dart::Library::TypedDataLibrary())) {
+ return kDynamicCid;
+ }
+
+ if ((owner.Name() == Symbols::List().raw()) &&
+ (function.name() == Symbols::ListFactory().raw())) {
+ ASSERT(argument_count == 1 || argument_count == 2);
+ return (argument_count == 1) ? kGrowableObjectArrayCid : kArrayCid;
+ }
+ return FactoryRecognizer::ResultCid(function);
+}
+
+
+Fragment FlowGraphBuilder::StaticCall(const Function& target,
+ intptr_t argument_count,
+ const Array& argument_names) {
+ ArgumentArray arguments = GetArguments(argument_count);
+ StaticCallInstr* call =
+ new (Z) StaticCallInstr(TokenPosition::kNoSource, target, argument_names,
+ arguments, ic_data_array_);
+ const intptr_t list_cid =
+ GetResultCidOfListFactory(Z, target, argument_count);
+ if (list_cid != kDynamicCid) {
+ call->set_result_cid(list_cid);
+ call->set_is_known_list_constructor(true);
+ } else if (target.recognized_kind() != MethodRecognizer::kUnknown) {
+ call->set_result_cid(MethodRecognizer::ResultCid(target));
+ }
+ Push(call);
+ return Fragment(call);
+}
+
+
+Fragment FlowGraphBuilder::StoreIndexed(intptr_t class_id) {
+ Value* value = Pop();
+ Value* index = Pop();
+ // TODO(27590): Omit store barrier when possible (e.g., storing
+ // some constants).
+ StoreIndexedInstr* store = new (Z) StoreIndexedInstr(
+ Pop(), // Array.
+ index, value, kEmitStoreBarrier, Instance::ElementSizeFor(class_id),
+ class_id, Thread::kNoDeoptId, TokenPosition::kNoSource);
+ Push(store);
+ return Fragment(store);
+}
+
+
+Fragment FlowGraphBuilder::StoreInstanceField(const dart::Field& field) {
+ Value* value = Pop();
+ // TODO(27590): Omit store barrier when possible (e.g., storing
+ // some constants).
+ StoreInstanceFieldInstr* store = new (Z) StoreInstanceFieldInstr(
+ field, Pop(), value, kEmitStoreBarrier, TokenPosition::kNoSource);
+ return Fragment(store);
+}
+
+
+Fragment FlowGraphBuilder::StoreInstanceField(intptr_t offset) {
+ Value* value = Pop();
+ StoreInstanceFieldInstr* store = new (Z) StoreInstanceFieldInstr(
+ offset, Pop(), value, kEmitStoreBarrier, TokenPosition::kNoSource);
+ return Fragment(store);
+}
+
+
+Fragment FlowGraphBuilder::StoreLocal(LocalVariable* variable) {
+ Fragment instructions;
+ if (variable->is_captured()) {
+ LocalVariable* value = MakeTemporary();
+ instructions += LoadContextAt(variable->owner()->context_level());
+ instructions += LoadLocal(value);
+ instructions +=
+ StoreInstanceField(Context::variable_offset(variable->index()));
+ } else {
+ StoreLocalInstr* store =
+ new (Z) StoreLocalInstr(*variable, Pop(), TokenPosition::kNoSource);
+ instructions <<= store;
+ Push(store);
+ }
+ return instructions;
+}
+
+
+Fragment FlowGraphBuilder::StoreStaticField(const dart::Field& field) {
+ return Fragment(
+ new (Z) StoreStaticFieldInstr(field, Pop(), TokenPosition::kNoSource));
+}
+
+
+Fragment FlowGraphBuilder::StringInterpolate() {
+ Value* array = Pop();
+ StringInterpolateInstr* interpolate =
+ new (Z) StringInterpolateInstr(array, TokenPosition::kNoSource);
+ Push(interpolate);
+ return Fragment(interpolate);
+}
+
+
+Fragment FlowGraphBuilder::ThrowTypeError() {
+ const dart::Class& klass = dart::Class::ZoneHandle(
+ Z, dart::Library::LookupCoreClass(Symbols::TypeError()));
+ ASSERT(!klass.IsNull());
+ const dart::Function& constructor = dart::Function::ZoneHandle(
+ Z,
+ klass.LookupConstructorAllowPrivate(H.DartSymbol("_TypeError._create")));
+ ASSERT(!constructor.IsNull());
+
+ const dart::String& url = H.DartString(
+ parsed_function_->function().ToLibNamePrefixedQualifiedCString(),
+ Heap::kOld);
+
+ Fragment instructions;
+
+ // Create instance of _FallThroughError
+ instructions += AllocateObject(klass, 0);
+ LocalVariable* instance = MakeTemporary();
+
+ // Call _AssertionError._create constructor.
+ instructions += LoadLocal(instance);
+ instructions += PushArgument(); // this
+
+ instructions += Constant(url);
+ instructions += PushArgument(); // url
+
+ instructions += NullConstant();
+ instructions += PushArgument(); // line
+
+ instructions += IntConstant(0);
+ instructions += PushArgument(); // column
+
+ instructions += Constant(H.DartSymbol("Malformed type."));
+ instructions += PushArgument(); // message
+
+ instructions += StaticCall(constructor, 5);
+ instructions += Drop();
+
+ // Throw the exception
+ instructions += PushArgument();
+ instructions += ThrowException();
+
+ return instructions;
+}
+
+
+Fragment FlowGraphBuilder::ThrowNoSuchMethodError() {
+ const dart::Class& klass = dart::Class::ZoneHandle(
+ Z, dart::Library::LookupCoreClass(Symbols::NoSuchMethodError()));
+ ASSERT(!klass.IsNull());
+ const dart::Function& throw_function = dart::Function::ZoneHandle(
+ Z, klass.LookupStaticFunctionAllowPrivate(Symbols::ThrowNew()));
+ ASSERT(!throw_function.IsNull());
+
+ Fragment instructions;
+
+ // Call NoSuchMethodError._throwNew static function.
+ instructions += NullConstant();
+ instructions += PushArgument(); // receiver
+
+ instructions += Constant(H.DartString("<unknown>", Heap::kOld));
+ instructions += PushArgument(); // memberName
+
+ instructions += IntConstant(-1);
+ instructions += PushArgument(); // invocation_type
+
+ instructions += NullConstant();
+ instructions += PushArgument(); // arguments
+
+ instructions += NullConstant();
+ instructions += PushArgument(); // argumentNames
+
+ instructions += NullConstant();
+ instructions += PushArgument(); // existingArgumentNames
+
+ instructions += StaticCall(throw_function, 6);
+ // Leave "result" on the stack since callers expect it to be there (even
+ // though the function will result in an exception).
+
+ return instructions;
+}
+
+
+dart::RawFunction* FlowGraphBuilder::LookupMethodByMember(
+ Member* target, const dart::String& method_name) {
+ Class* kernel_klass = Class::Cast(target->parent());
+ dart::Class& klass =
+ dart::Class::Handle(Z, H.LookupClassByKernelClass(kernel_klass));
+
+ dart::RawFunction* function = klass.LookupFunctionAllowPrivate(method_name);
+ ASSERT(function != Object::null());
+ return function;
+}
+
+
+LocalVariable* FlowGraphBuilder::MakeTemporary() {
+ char name[64];
+ intptr_t index = stack_->definition()->temp_index();
+ OS::SNPrint(name, 64, ":temp%" Pd, index);
+ LocalVariable* variable = new (Z) LocalVariable(
+ TokenPosition::kNoSource, H.DartSymbol(name), Object::dynamic_type());
+ // Set the index relative to the base of the expression stack including
+ // outgoing arguments.
+ variable->set_index(parsed_function_->first_stack_local_index() -
+ parsed_function_->num_stack_locals() -
+ pending_argument_count_ - index);
+
+ // The value has uses as if it were a local variable. Mark the definition
+ // as used so that its temp index will not be cleared (causing it to never
+ // be materialized in the expression stack).
+ stack_->definition()->set_ssa_temp_index(0);
+
+ return variable;
+}
+
+
+intptr_t FlowGraphBuilder::CurrentTryIndex() {
+ if (try_catch_block_ == NULL) {
+ return CatchClauseNode::kInvalidTryIndex;
+ } else {
+ return try_catch_block_->TryIndex();
+ }
+}
+
+
+dart::LocalVariable* FlowGraphBuilder::LookupVariable(
+ VariableDeclaration* var) {
+ LocalVariable* local = scopes_->locals.Lookup(var);
+ ASSERT(local != NULL);
+ return local;
+}
+
+
+void FlowGraphBuilder::SetTempIndex(Definition* definition) {
+ definition->set_temp_index(
+ stack_ == NULL ? 0 : stack_->definition()->temp_index() + 1);
+}
+
+
+void FlowGraphBuilder::Push(Definition* definition) {
+ SetTempIndex(definition);
+ Value::AddToList(new (Z) Value(definition), &stack_);
+}
+
+
+Value* FlowGraphBuilder::Pop() {
+ ASSERT(stack_ != NULL);
+ Value* value = stack_;
+ stack_ = value->next_use();
+ if (stack_ != NULL) stack_->set_previous_use(NULL);
+
+ value->set_next_use(NULL);
+ value->set_previous_use(NULL);
+ value->definition()->ClearSSATempIndex();
+ return value;
+}
+
+
+Fragment FlowGraphBuilder::Drop() {
+ ASSERT(stack_ != NULL);
+ Fragment instructions;
+ Definition* definition = stack_->definition();
+ // The SSA renaming implementation doesn't like [LoadLocal]s without a
+ // tempindex.
+ if (definition->HasSSATemp() || definition->IsLoadLocal()) {
+ instructions <<= new (Z) DropTempsInstr(1, NULL);
+ } else {
+ definition->ClearTempIndex();
+ }
+
+ Pop();
+ return instructions;
+}
+
+
+// TODO(27590): This method should be shared with
+// runtime/vm/object.cc:RecognizeArithmeticOp.
+Token::Kind FlowGraphBuilder::MethodKind(const dart::String& name) {
+ ASSERT(name.IsSymbol());
+ if (name.raw() == Symbols::Plus().raw()) {
+ return Token::kADD;
+ } else if (name.raw() == Symbols::Minus().raw()) {
+ return Token::kSUB;
+ } else if (name.raw() == Symbols::Star().raw()) {
+ return Token::kMUL;
+ } else if (name.raw() == Symbols::Slash().raw()) {
+ return Token::kDIV;
+ } else if (name.raw() == Symbols::TruncDivOperator().raw()) {
+ return Token::kTRUNCDIV;
+ } else if (name.raw() == Symbols::Percent().raw()) {
+ return Token::kMOD;
+ } else if (name.raw() == Symbols::BitOr().raw()) {
+ return Token::kBIT_OR;
+ } else if (name.raw() == Symbols::Ampersand().raw()) {
+ return Token::kBIT_AND;
+ } else if (name.raw() == Symbols::Caret().raw()) {
+ return Token::kBIT_XOR;
+ } else if (name.raw() == Symbols::LeftShiftOperator().raw()) {
+ return Token::kSHL;
+ } else if (name.raw() == Symbols::RightShiftOperator().raw()) {
+ return Token::kSHR;
+ } else if (name.raw() == Symbols::Tilde().raw()) {
+ return Token::kBIT_NOT;
+ } else if (name.raw() == Symbols::UnaryMinus().raw()) {
+ return Token::kNEGATE;
+ } else if (name.raw() == Symbols::EqualOperator().raw()) {
+ return Token::kEQ;
+ } else if (name.raw() == Symbols::Token(Token::kNE).raw()) {
+ return Token::kNE;
+ } else if (name.raw() == Symbols::LAngleBracket().raw()) {
+ return Token::kLT;
+ } else if (name.raw() == Symbols::RAngleBracket().raw()) {
+ return Token::kGT;
+ } else if (name.raw() == Symbols::LessEqualOperator().raw()) {
+ return Token::kLTE;
+ } else if (name.raw() == Symbols::GreaterEqualOperator().raw()) {
+ return Token::kGTE;
+ } else if (dart::Field::IsGetterName(name)) {
+ return Token::kGET;
+ } else if (dart::Field::IsSetterName(name)) {
+ return Token::kSET;
+ }
+ return Token::kILLEGAL;
+}
+
+
+void FlowGraphBuilder::InlineBailout(const char* reason) {
+ bool is_inlining = exit_collector_ != NULL;
+ if (is_inlining) {
+ parsed_function_->function().set_is_inlinable(false);
+ parsed_function_->Bailout("kernel::FlowGraphBuilder", reason);
+ }
+}
+
+
+FlowGraph* FlowGraphBuilder::BuildGraph() {
+ const dart::Function& function = parsed_function_->function();
+
+ if (function.IsConstructorClosureFunction()) return NULL;
+
+ dart::Class& klass =
+ dart::Class::Handle(zone_, parsed_function_->function().Owner());
+
+ // Find out if there is an enclosing kernel class (which will be used to
+ // resolve type parameters).
+ Class* kernel_klass = NULL;
+ dart::Function& topmost = dart::Function::Handle(Z, function.raw());
+ while (topmost.parent_function() != Object::null()) {
+ topmost = topmost.parent_function();
+ }
+ TreeNode* topmost_node = static_cast<TreeNode*>(topmost.kernel_function());
+ if (topmost_node != NULL) {
+ // Going up the closure->parent chain needs to result in a Procedure or
+ // Constructor.
+ TreeNode* parent = NULL;
+ if (topmost_node->IsProcedure()) {
+ parent = Procedure::Cast(topmost_node)->parent();
+ } else if (topmost_node->IsConstructor()) {
+ parent = Constructor::Cast(topmost_node)->parent();
+ } else if (topmost_node->IsField()) {
+ parent = Field::Cast(topmost_node)->parent();
+ }
+ if (parent != NULL && parent->IsClass()) kernel_klass = Class::Cast(parent);
+ }
+
+ // Mark that we are using [klass]/[kernell_klass] as active class. Resolving
+ // of type parameters will get resolved via [kernell_klass] unless we are
+ // nested inside a static factory in which case we will use [member].
+ ActiveClassScope active_class_scope(&active_class_, kernel_klass, &klass);
+ Member* member = topmost_node != NULL && topmost_node->IsMember()
+ ? Member::Cast(topmost_node)
+ : NULL;
+ ActiveMemberScope active_member(&active_class_, member);
+
+ // The IR builder will create its own local variables and scopes, and it
+ // will not need an AST. The code generator will assume that there is a
+ // local variable stack slot allocated for the current context and (I
+ // think) that the runtime will expect it to be at a fixed offset which
+ // requires allocating an unused expression temporary variable.
+ scopes_ = parsed_function_->EnsureKernelScopes();
+
+ switch (function.kind()) {
+ case RawFunction::kClosureFunction:
+ case RawFunction::kRegularFunction:
+ case RawFunction::kGetterFunction:
+ case RawFunction::kSetterFunction: {
+ FunctionNode* kernel_function = node_->IsProcedure()
+ ? Procedure::Cast(node_)->function()
+ : FunctionNode::Cast(node_);
+ ActiveFunctionScope active_function_scope(&active_class_,
+ kernel_function);
+ return function.IsImplicitClosureFunction()
+ ? BuildGraphOfImplicitClosureFunction(kernel_function,
+ function)
+ : BuildGraphOfFunction(kernel_function);
+ }
+ case RawFunction::kConstructor: {
+ bool is_factory = function.IsFactory();
+ if (is_factory) {
+ Procedure* procedure = Procedure::Cast(node_);
+ FunctionNode* function = procedure->function();
+ ActiveFunctionScope active_function_scope(&active_class_, function);
+ return BuildGraphOfFunction(function, NULL);
+ } else {
+ Constructor* constructor = Constructor::Cast(node_);
+ FunctionNode* function = constructor->function();
+ ActiveFunctionScope active_function_scope(&active_class_, function);
+ return BuildGraphOfFunction(function, constructor);
+ }
+ }
+ case RawFunction::kImplicitGetter:
+ case RawFunction::kImplicitStaticFinalGetter:
+ case RawFunction::kImplicitSetter: {
+ Field* field = Field::Cast(node_);
+ return IsStaticInitializer(function, Z)
+ ? BuildGraphOfStaticFieldInitializer(field)
+ : BuildGraphOfFieldAccessor(field, scopes_->setter_value);
+ }
+ case RawFunction::kMethodExtractor:
+ return BuildGraphOfMethodExtractor(function);
+ case RawFunction::kNoSuchMethodDispatcher:
+ return BuildGraphOfNoSuchMethodDispatcher(function);
+ case RawFunction::kInvokeFieldDispatcher:
+ return BuildGraphOfInvokeFieldDispatcher(function);
+ case RawFunction::kSignatureFunction:
+ case RawFunction::kIrregexpFunction:
+ break;
+ }
+ UNREACHABLE();
+ return NULL;
+}
+
+
+FlowGraph* FlowGraphBuilder::BuildGraphOfFunction(FunctionNode* function,
+ Constructor* constructor) {
+ const Function& dart_function = parsed_function_->function();
+ TargetEntryInstr* normal_entry = BuildTargetEntry();
+ graph_entry_ = new (Z)
+ GraphEntryInstr(*parsed_function_, normal_entry, Compiler::kNoOSRDeoptId);
+
+ SetupDefaultParameterValues(function);
+
+ Fragment body;
+ if (!dart_function.is_native()) body += CheckStackOverflowInPrologue();
+ intptr_t context_size =
+ parsed_function_->node_sequence()->scope()->num_context_variables();
+ if (context_size > 0) {
+ body += PushContext(context_size);
+ LocalVariable* context = MakeTemporary();
+
+ // Copy captured parameters from the stack into the context.
+ LocalScope* scope = parsed_function_->node_sequence()->scope();
+ intptr_t parameter_count = dart_function.NumParameters();
+ intptr_t parameter_index = parsed_function_->first_parameter_index();
+ for (intptr_t i = 0; i < parameter_count; ++i, --parameter_index) {
+ LocalVariable* variable = scope->VariableAt(i);
+ if (variable->is_captured()) {
+ // There is no LocalVariable describing the on-stack parameter so
+ // create one directly.
+ LocalVariable* parameter =
+ new (Z) LocalVariable(TokenPosition::kNoSource,
+ Symbols::TempParam(), Object::dynamic_type());
+ parameter->set_index(parameter_index);
+ // Mark the stack variable so it will be ignored by the code for
+ // try/catch.
+ parameter->set_is_captured_parameter(true);
+
+ // Copy the parameter from the stack to the context. Overwrite it
+ // with a null constant on the stack so the original value is
+ // eligible for garbage collection.
+ body += LoadLocal(context);
+ body += LoadLocal(parameter);
+ body += StoreInstanceField(Context::variable_offset(variable->index()));
+ body += NullConstant();
+ body += StoreLocal(parameter);
+ body += Drop();
+ }
+ }
+ body += Drop(); // The context.
+ }
+ if (constructor != NULL) {
+ // TODO(27590): Currently the [VariableDeclaration]s from the
+ // initializers will be visible inside the entire body of the constructor.
+ // We should make a separate scope for them.
+ Class* kernel_klass = Class::Cast(constructor->parent());
+ body += TranslateInitializers(kernel_klass, &constructor->initializers());
+ }
+
+ // The specification defines the result of `a == b` to be:
+ //
+ // a) if either side is `null` then the result is `identical(a, b)`.
+ // b) else the result is `a.operator==(b)`
+ //
+ // For user-defined implementations of `operator==` we need therefore
+ // implement the handling of a).
+ //
+ // The default `operator==` implementation in `Object` is implemented in terms
+ // of identical (which we assume here!) which means that case a) is actually
+ // included in b). So we just use the normal implementation in the body.
+ if ((dart_function.NumParameters() == 2) &&
+ (dart_function.name() == Symbols::EqualOperator().raw()) &&
+ (dart_function.Owner() != I->object_store()->object_class())) {
+ LocalVariable* parameter =
+ LookupVariable(function->positional_parameters()[0]);
+
+ TargetEntryInstr* null_entry;
+ TargetEntryInstr* non_null_entry;
+
+ body += LoadLocal(parameter);
+ body += BranchIfNull(&null_entry, &non_null_entry);
+
+ // The argument was `null` and the receiver is not the null class (we only
+ // go into this branch for user-defined == operators) so we can return
+ // false.
+ Fragment null_fragment(null_entry);
+ null_fragment += Constant(Bool::False());
+ null_fragment += Return();
+
+ body = Fragment(body.entry, non_null_entry);
+ }
+
+ if (dart_function.is_native()) {
+ body += NativeFunctionBody(function, dart_function);
+ } else if (function->body() != NULL) {
+ body += TranslateStatement(function->body());
+ }
+ if (body.is_open()) {
+ body += NullConstant();
+ body += Return();
+ }
+
+ // If functions body contains any yield points build switch statement that
+ // selects a continuation point based on the value of :await_jump_var.
+ if (!yield_continuations_.is_empty()) {
+ // The code we are building will be executed right after we enter
+ // the function and before any nested contexts are allocated.
+ // Reset current context_depth_ to match this.
+ intptr_t current_context_depth = context_depth_;
+ context_depth_ = scopes_->yield_jump_variable->owner()->context_level();
+
+ // Prepend an entry corresponding to normal entry to the function.
+ yield_continuations_.InsertAt(
+ 0, YieldContinuation(new (Z) DropTempsInstr(0, NULL),
+ CatchClauseNode::kInvalidTryIndex));
+ yield_continuations_[0].entry->LinkTo(body.entry);
+
+ // Build a switch statement.
+ Fragment dispatch;
+
+ // Load :await_jump_var into a temporary.
+ dispatch += LoadLocal(scopes_->yield_jump_variable);
+ dispatch += StoreLocal(scopes_->switch_variable);
+ dispatch += Drop();
+
+ BlockEntryInstr* block = NULL;
+ for (intptr_t i = 0; i < yield_continuations_.length(); i++) {
+ if (i == 1) {
+ // This is not a normal entry but a resumption. Restore
+ // :current_context_var from :await_ctx_var.
+ // Note: after this point context_depth_ does not match current context
+ // depth so we should not access any local variables anymore.
+ dispatch += LoadLocal(scopes_->yield_context_variable);
+ dispatch += StoreLocal(parsed_function_->current_context_var());
+ dispatch += Drop();
+ }
+ if (i == (yield_continuations_.length() - 1)) {
+ // We reached the last possility, no need to build more ifs.
+ // Coninue to the last continuation.
+ // Note: continuations start with nop DropTemps instruction
+ // which acts like an anchor, so we need to skip it.
+ block->set_try_index(yield_continuations_[i].try_index);
+ dispatch <<= yield_continuations_[i].entry->next();
+ break;
+ }
+
+ // Build comparison:
+ //
+ // if (:await_ctx_var == i) {
+ // -> yield_continuations_[i]
+ // } else ...
+ //
+ TargetEntryInstr* then;
+ TargetEntryInstr* otherwise;
+ dispatch += LoadLocal(scopes_->switch_variable);
+ dispatch += IntConstant(i);
+ dispatch += BranchIfStrictEqual(&then, &otherwise);
+
+ // True branch is linked to appropriate continuation point.
+ // Note: continuations start with nop DropTemps instruction
+ // which acts like an anchor, so we need to skip it.
+ then->LinkTo(yield_continuations_[i].entry->next());
+ then->set_try_index(yield_continuations_[i].try_index);
+
+ // False branch will contain the next comparison.
+ dispatch = Fragment(dispatch.entry, otherwise);
+ block = otherwise;
+ }
+ body = dispatch;
+
+ context_depth_ = current_context_depth;
+ }
+ normal_entry->LinkTo(body.entry);
+
+ return new (Z) FlowGraph(*parsed_function_, graph_entry_, next_block_id_ - 1);
+}
+
+
+Fragment FlowGraphBuilder::NativeFunctionBody(FunctionNode* kernel_function,
+ const Function& function) {
+ ASSERT(function.is_native());
+ // We explicitly build the graph for native functions in the same way that the
+ // from-source backend does. We should find a way to have a single component
+ // to build these graphs so that this code is not duplicated.
+
+ Fragment body;
+ MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function);
+ switch (kind) {
+ case MethodRecognizer::kObjectEquals:
+ body += LoadLocal(scopes_->this_variable);
+ body += LoadLocal(
+ LookupVariable(kernel_function->positional_parameters()[0]));
+ body += StrictCompare(Token::kEQ_STRICT);
+ break;
+ case MethodRecognizer::kStringBaseLength:
+ case MethodRecognizer::kStringBaseIsEmpty:
+ // Depending on FLAG_support_externalizable_strings, treat string length
+ // loads as mutable so that the class check that precedes them will not be
+ // hoisted. This is unsafe because string externalization can change the
+ // class.
+ body += LoadLocal(scopes_->this_variable);
+ body += LoadNativeField(MethodRecognizer::kStringBaseLength,
+ dart::String::length_offset(),
+ Type::ZoneHandle(Z, Type::SmiType()), kSmiCid,
+ !FLAG_support_externalizable_strings);
+ if (kind == MethodRecognizer::kStringBaseIsEmpty) {
+ body += IntConstant(0);
+ body += StrictCompare(Token::kEQ_STRICT);
+ }
+ break;
+ case MethodRecognizer::kGrowableArrayLength:
+ body += LoadLocal(scopes_->this_variable);
+ body += LoadNativeField(kind, GrowableObjectArray::length_offset(),
+ Type::ZoneHandle(Z, Type::SmiType()), kSmiCid);
+ break;
+ case MethodRecognizer::kObjectArrayLength:
+ case MethodRecognizer::kImmutableArrayLength:
+ body += LoadLocal(scopes_->this_variable);
+ body +=
+ LoadNativeField(kind, Array::length_offset(),
+ Type::ZoneHandle(Z, Type::SmiType()), kSmiCid, true);
+ break;
+ case MethodRecognizer::kTypedDataLength:
+ body += LoadLocal(scopes_->this_variable);
+ body +=
+ LoadNativeField(kind, TypedData::length_offset(),
+ Type::ZoneHandle(Z, Type::SmiType()), kSmiCid, true);
+ break;
+ case MethodRecognizer::kClassIDgetID:
+ body += LoadLocal(
+ LookupVariable(kernel_function->positional_parameters()[0]));
+ body += LoadClassId();
+ break;
+ case MethodRecognizer::kGrowableArrayCapacity:
+ body += LoadLocal(scopes_->this_variable);
+ body += LoadField(Array::data_offset(), kArrayCid);
+ body += LoadNativeField(MethodRecognizer::kObjectArrayLength,
+ Array::length_offset(),
+ Type::ZoneHandle(Z, Type::SmiType()), kSmiCid);
+ break;
+ case MethodRecognizer::kObjectArrayAllocate:
+ body += LoadLocal(scopes_->type_arguments_variable);
+ body += LoadLocal(
+ LookupVariable(kernel_function->positional_parameters()[0]));
+ body += CreateArray();
+ break;
+ case MethodRecognizer::kBigint_getDigits:
+ body += LoadLocal(scopes_->this_variable);
+ body += LoadNativeField(kind, Bigint::digits_offset(),
+ Object::dynamic_type(), kTypedDataUint32ArrayCid);
+ break;
+ case MethodRecognizer::kBigint_getUsed:
+ body += LoadLocal(scopes_->this_variable);
+ body += LoadNativeField(kind, Bigint::used_offset(),
+ Type::ZoneHandle(Z, Type::SmiType()), kSmiCid);
+ break;
+ case MethodRecognizer::kLinkedHashMap_getIndex:
+ body += LoadLocal(scopes_->this_variable);
+ body += LoadNativeField(kind, LinkedHashMap::index_offset(),
+ Object::dynamic_type(), kDynamicCid);
+ break;
+ case MethodRecognizer::kLinkedHashMap_setIndex:
+ body += LoadLocal(scopes_->this_variable);
+ body += LoadLocal(
+ LookupVariable(kernel_function->positional_parameters()[0]));
+ body += StoreInstanceField(LinkedHashMap::index_offset());
+ body += NullConstant();
+ break;
+ case MethodRecognizer::kLinkedHashMap_getData:
+ body += LoadLocal(scopes_->this_variable);
+ body += LoadNativeField(kind, LinkedHashMap::data_offset(),
+ Object::dynamic_type(), kArrayCid);
+ break;
+ case MethodRecognizer::kLinkedHashMap_setData:
+ body += LoadLocal(scopes_->this_variable);
+ body += LoadLocal(
+ LookupVariable(kernel_function->positional_parameters()[0]));
+ body += StoreInstanceField(LinkedHashMap::data_offset());
+ body += NullConstant();
+ break;
+ case MethodRecognizer::kLinkedHashMap_getHashMask:
+ body += LoadLocal(scopes_->this_variable);
+ body += LoadNativeField(kind, LinkedHashMap::hash_mask_offset(),
+ Type::ZoneHandle(Z, Type::SmiType()), kSmiCid);
+ break;
+ case MethodRecognizer::kLinkedHashMap_setHashMask:
+ body += LoadLocal(scopes_->this_variable);
+ body += LoadLocal(
+ LookupVariable(kernel_function->positional_parameters()[0]));
+ // TODO(27590): This store does not need a store barrier.
+ body += StoreInstanceField(LinkedHashMap::hash_mask_offset());
+ body += NullConstant();
+ break;
+ case MethodRecognizer::kLinkedHashMap_getUsedData:
+ body += LoadLocal(scopes_->this_variable);
+ body += LoadNativeField(kind, LinkedHashMap::used_data_offset(),
+ Type::ZoneHandle(Z, Type::SmiType()), kSmiCid);
+ break;
+ case MethodRecognizer::kLinkedHashMap_setUsedData:
+ body += LoadLocal(scopes_->this_variable);
+ body += LoadLocal(
+ LookupVariable(kernel_function->positional_parameters()[0]));
+ // TODO(27590): This store does not need a store barrier.
+ body += StoreInstanceField(LinkedHashMap::used_data_offset());
+ body += NullConstant();
+ break;
+ case MethodRecognizer::kLinkedHashMap_getDeletedKeys:
+ body += LoadLocal(scopes_->this_variable);
+ body += LoadNativeField(kind, LinkedHashMap::deleted_keys_offset(),
+ Type::ZoneHandle(Z, Type::SmiType()), kSmiCid);
+ break;
+ case MethodRecognizer::kLinkedHashMap_setDeletedKeys:
+ body += LoadLocal(scopes_->this_variable);
+ body += LoadLocal(
+ LookupVariable(kernel_function->positional_parameters()[0]));
+ // TODO(27590): This store does not need a store barrier.
+ body += StoreInstanceField(LinkedHashMap::deleted_keys_offset());
+ body += NullConstant();
+ break;
+ case MethodRecognizer::kBigint_getNeg:
+ body += LoadLocal(scopes_->this_variable);
+ body += LoadNativeField(kind, Bigint::neg_offset(),
+ Type::ZoneHandle(Z, Type::BoolType()), kBoolCid);
+ break;
+ default: {
+ dart::String& name = dart::String::ZoneHandle(Z, function.native_name());
+ body += NativeCall(&name, &function);
+ break;
+ }
+ }
+ return body + Return();
+}
+
+
+FlowGraph* FlowGraphBuilder::BuildGraphOfFieldAccessor(
+ Field* kernel_field, LocalVariable* setter_value) {
+ const dart::Function& function = parsed_function_->function();
+
+ bool is_setter = function.IsImplicitSetterFunction();
+ bool is_method = !function.IsStaticFunction();
+ dart::Field& field =
+ dart::Field::ZoneHandle(Z, H.LookupFieldByKernelField(kernel_field));
+
+ TargetEntryInstr* normal_entry = BuildTargetEntry();
+ graph_entry_ = new (Z)
+ GraphEntryInstr(*parsed_function_, normal_entry, Compiler::kNoOSRDeoptId);
+
+ // TODO(27590): Add support for FLAG_use_field_guards.
+ Fragment body(normal_entry);
+ if (is_setter) {
+ if (is_method) {
+ body += LoadLocal(scopes_->this_variable);
+ body += LoadLocal(setter_value);
+ body += StoreInstanceField(field);
+ } else {
+ body += LoadLocal(setter_value);
+ body += StoreStaticField(field);
+ }
+ body += NullConstant();
+ } else if (is_method) {
+ body += LoadLocal(scopes_->this_variable);
+ body += LoadField(field);
+ } else if (field.is_const()) {
+ // If the parser needs to know the value of an uninitialized constant field
+ // it will set the value to the transition sentinel (used to detect circular
+ // initialization) and then call the implicit getter. Thus, the getter
+ // cannot contain the InitStaticField instruction that normal static getters
+ // contain because it would detect spurious circular initialization when it
+ // checks for the transition sentinel.
+ Expression* initializer = kernel_field->initializer();
+ ASSERT(initializer != NULL);
+ body += Constant(constant_evaluator_.EvaluateExpression(initializer));
+ } else {
+ // The field always has an initializer because static fields without
+ // initializers are initialized eagerly and do not have implicit getters.
+ ASSERT(field.has_initializer());
+ body += Constant(field);
+ body += InitStaticField(field);
+ body += Constant(field);
+ body += LoadStaticField();
+ }
+ body += Return();
+
+ return new (Z) FlowGraph(*parsed_function_, graph_entry_, next_block_id_ - 1);
+}
+
+
+FlowGraph* FlowGraphBuilder::BuildGraphOfStaticFieldInitializer(
+ Field* kernel_field) {
+ ASSERT(kernel_field->IsStatic());
+
+ Expression* initializer = kernel_field->initializer();
+
+ TargetEntryInstr* normal_entry = BuildTargetEntry();
+ graph_entry_ = new (Z)
+ GraphEntryInstr(*parsed_function_, normal_entry, Compiler::kNoOSRDeoptId);
+
+ Fragment body(normal_entry);
+ body += CheckStackOverflowInPrologue();
+ if (kernel_field->IsConst()) {
+ body += Constant(constant_evaluator_.EvaluateExpression(initializer));
+ } else {
+ body += TranslateExpression(initializer);
+ }
+ body += Return();
+
+ return new (Z) FlowGraph(*parsed_function_, graph_entry_, next_block_id_ - 1);
+}
+
+
+Fragment FlowGraphBuilder::BuildImplicitClosureCreation(
+ const Function& target) {
+ Fragment fragment;
+ const dart::Class& closure_class =
+ dart::Class::ZoneHandle(Z, I->object_store()->closure_class());
+ fragment += AllocateObject(closure_class, target);
+ LocalVariable* closure = MakeTemporary();
+
+ // Allocate a context that closes over `this`.
+ fragment += AllocateContext(1);
+ LocalVariable* context = MakeTemporary();
+
+ // Store the function and the context in the closure.
+ fragment += LoadLocal(closure);
+ fragment += Constant(target);
+ fragment += StoreInstanceField(Closure::function_offset());
+
+ fragment += LoadLocal(closure);
+ fragment += LoadLocal(context);
+ fragment += StoreInstanceField(Closure::context_offset());
+
+ // The context is on top of the operand stack. Store `this`. The context
+ // doesn't need a parent pointer because it doesn't close over anything
+ // else.
+ fragment += LoadLocal(scopes_->this_variable);
+ fragment += StoreInstanceField(Context::variable_offset(0));
+
+ return fragment;
+}
+
+
+FlowGraph* FlowGraphBuilder::BuildGraphOfMethodExtractor(
+ const Function& method) {
+ // A method extractor is the implicit getter for a method.
+ const Function& function =
+ Function::ZoneHandle(Z, method.extracted_method_closure());
+
+ TargetEntryInstr* normal_entry = BuildTargetEntry();
+ graph_entry_ = new (Z)
+ GraphEntryInstr(*parsed_function_, normal_entry, Compiler::kNoOSRDeoptId);
+ Fragment body(normal_entry);
+ body += CheckStackOverflowInPrologue();
+ body += BuildImplicitClosureCreation(function);
+ body += Return();
+
+ return new (Z) FlowGraph(*parsed_function_, graph_entry_, next_block_id_ - 1);
+}
+
+
+FlowGraph* FlowGraphBuilder::BuildGraphOfImplicitClosureFunction(
+ FunctionNode* kernel_function, const Function& function) {
+ const Function& target = Function::ZoneHandle(Z, function.parent_function());
+
+ TargetEntryInstr* normal_entry = BuildTargetEntry();
+ graph_entry_ = new (Z)
+ GraphEntryInstr(*parsed_function_, normal_entry, Compiler::kNoOSRDeoptId);
+ SetupDefaultParameterValues(kernel_function);
+
+ Fragment body(normal_entry);
+ body += CheckStackOverflowInPrologue();
+
+ // Load all the arguments.
+ if (!target.is_static()) {
+ // The context has a fixed shape: a single variable which is the
+ // closed-over receiver.
+ body += LoadLocal(parsed_function_->current_context_var());
+ body += LoadField(Context::variable_offset(0));
+ body += PushArgument();
+ }
+ intptr_t positional_argument_count =
+ kernel_function->positional_parameters().length();
+ for (intptr_t i = 0; i < positional_argument_count; i++) {
+ body +=
+ LoadLocal(LookupVariable(kernel_function->positional_parameters()[i]));
+ body += PushArgument();
+ }
+ intptr_t named_argument_count = kernel_function->named_parameters().length();
+ Array& argument_names = Array::ZoneHandle(Z);
+ if (named_argument_count > 0) {
+ argument_names = Array::New(named_argument_count);
+ for (intptr_t i = 0; i < named_argument_count; i++) {
+ VariableDeclaration* variable = kernel_function->named_parameters()[i];
+ body += LoadLocal(LookupVariable(variable));
+ body += PushArgument();
+ argument_names.SetAt(i, H.DartSymbol(variable->name()));
+ }
+ }
+ // Forward them to the target.
+ intptr_t argument_count = positional_argument_count + named_argument_count;
+ if (!target.is_static()) ++argument_count;
+ body += StaticCall(target, argument_count, argument_names);
+
+ // Return the result.
+ body += Return();
+
+ return new (Z) FlowGraph(*parsed_function_, graph_entry_, next_block_id_ - 1);
+}
+
+
+FlowGraph* FlowGraphBuilder::BuildGraphOfNoSuchMethodDispatcher(
+ const Function& function) {
+ // This function is specialized for a receiver class, a method name, and
+ // the arguments descriptor at a call site.
+
+ TargetEntryInstr* normal_entry = BuildTargetEntry();
+ graph_entry_ = new (Z)
+ GraphEntryInstr(*parsed_function_, normal_entry, Compiler::kNoOSRDeoptId);
+
+ // The backend will expect an array of default values for all the named
+ // parameters, even if they are all known to be passed at the call site
+ // because the call site matches the arguments descriptor. Use null for
+ // the default values.
+ const Array& descriptor_array =
+ Array::ZoneHandle(Z, function.saved_args_desc());
+ ArgumentsDescriptor descriptor(descriptor_array);
+ ZoneGrowableArray<const Instance*>* default_values =
+ new ZoneGrowableArray<const Instance*>(Z, descriptor.NamedCount());
+ for (intptr_t i = 0; i < descriptor.NamedCount(); ++i) {
+ default_values->Add(&Object::null_instance());
+ }
+ parsed_function_->set_default_parameter_values(default_values);
+
+ Fragment body(normal_entry);
+ body += CheckStackOverflowInPrologue();
+
+ // The receiver is the first argument to noSuchMethod, and it is the first
+ // argument passed to the dispatcher function.
+ LocalScope* scope = parsed_function_->node_sequence()->scope();
+ body += LoadLocal(scope->VariableAt(0));
+ body += PushArgument();
+
+ // The second argument to noSuchMethod is an invocation mirror. Push the
+ // arguments for allocating the invocation mirror. First, the name.
+ body += Constant(dart::String::ZoneHandle(Z, function.name()));
+ body += PushArgument();
+
+ // Second, the arguments descriptor.
+ body += Constant(descriptor_array);
+ body += PushArgument();
+
+ // Third, an array containing the original arguments. Create it and fill
+ // it in.
+ body += Constant(TypeArguments::ZoneHandle(Z, TypeArguments::null()));
+ body += IntConstant(descriptor.Count());
+ body += CreateArray();
+ LocalVariable* array = MakeTemporary();
+ for (intptr_t i = 0; i < descriptor.PositionalCount(); ++i) {
+ body += LoadLocal(array);
+ body += IntConstant(i);
+ body += LoadLocal(scope->VariableAt(i));
+ body += StoreIndexed(kArrayCid);
+ body += Drop();
+ }
+ dart::String& name = dart::String::Handle(Z);
+ for (intptr_t i = 0; i < descriptor.NamedCount(); ++i) {
+ intptr_t parameter_index = descriptor.PositionalCount() + i;
+ name = descriptor.NameAt(i);
+ name = dart::Symbols::New(H.thread(), name);
+ body += LoadLocal(array);
+ body += IntConstant(descriptor.PositionAt(i));
+ body += LoadLocal(scope->VariableAt(parameter_index));
+ body += StoreIndexed(kArrayCid);
+ body += Drop();
+ }
+ body += PushArgument();
+
+ // Fourth, false indicating this is not a super NoSuchMethod.
+ body += Constant(Bool::False());
+ body += PushArgument();
+
+ const dart::Class& mirror_class = dart::Class::Handle(
+ Z, dart::Library::LookupCoreClass(Symbols::InvocationMirror()));
+ ASSERT(!mirror_class.IsNull());
+ const Function& allocation_function = Function::ZoneHandle(
+ Z, mirror_class.LookupStaticFunction(dart::Library::PrivateCoreLibName(
+ Symbols::AllocateInvocationMirror())));
+ ASSERT(!allocation_function.IsNull());
+ body += StaticCall(allocation_function, 4);
+ body += PushArgument(); // For the call to noSuchMethod.
+
+ ArgumentsDescriptor two_arguments(
+ Array::Handle(Z, ArgumentsDescriptor::New(2)));
+ Function& no_such_method =
+ Function::ZoneHandle(Z, Resolver::ResolveDynamicForReceiverClass(
+ dart::Class::Handle(Z, function.Owner()),
+ Symbols::NoSuchMethod(), two_arguments));
+ if (no_such_method.IsNull()) {
+ // If noSuchMethod is not found on the receiver class, call
+ // Object.noSuchMethod.
+ no_such_method = Resolver::ResolveDynamicForReceiverClass(
+ dart::Class::Handle(Z, I->object_store()->object_class()),
+ Symbols::NoSuchMethod(), two_arguments);
+ }
+ body += StaticCall(no_such_method, 2);
+ body += Return();
+
+ return new (Z) FlowGraph(*parsed_function_, graph_entry_, next_block_id_ - 1);
+}
+
+
+FlowGraph* FlowGraphBuilder::BuildGraphOfInvokeFieldDispatcher(
+ const Function& function) {
+ // Find the name of the field we should dispatch to.
+ const dart::Class& owner = dart::Class::Handle(Z, function.Owner());
+ ASSERT(!owner.IsNull());
+ const dart::String& field_name = dart::String::Handle(Z, function.name());
+ const dart::String& getter_name = dart::String::ZoneHandle(
+ Z,
+ Symbols::New(H.thread(), dart::String::Handle(
+ Z, dart::Field::GetterSymbol(field_name))));
+
+ // Determine if this is `class Closure { get call => this; }`
+ const dart::Class& closure_class =
+ dart::Class::Handle(Z, I->object_store()->closure_class());
+ const bool is_closure_call = (owner.raw() == closure_class.raw()) &&
+ field_name.Equals(Symbols::Call());
+
+ // Set default parameters & construct argument names array.
+ //
+ // The backend will expect an array of default values for all the named
+ // parameters, even if they are all known to be passed at the call site
+ // because the call site matches the arguments descriptor. Use null for
+ // the default values.
+ const Array& descriptor_array =
+ Array::ZoneHandle(Z, function.saved_args_desc());
+ ArgumentsDescriptor descriptor(descriptor_array);
+ const Array& argument_names =
+ Array::ZoneHandle(Z, Array::New(descriptor.NamedCount(), Heap::kOld));
+ ZoneGrowableArray<const Instance*>* default_values =
+ new ZoneGrowableArray<const Instance*>(Z, descriptor.NamedCount());
+ dart::String& string_handle = dart::String::Handle(Z);
+ for (intptr_t i = 0; i < descriptor.NamedCount(); ++i) {
+ default_values->Add(&Object::null_instance());
+ string_handle = descriptor.NameAt(i);
+ argument_names.SetAt(i, string_handle);
+ }
+ parsed_function_->set_default_parameter_values(default_values);
+
+ TargetEntryInstr* normal_entry = BuildTargetEntry();
+ graph_entry_ = new (Z)
+ GraphEntryInstr(*parsed_function_, normal_entry, Compiler::kNoOSRDeoptId);
+
+ Fragment body(normal_entry);
+ body += CheckStackOverflowInPrologue();
+
+ LocalScope* scope = parsed_function_->node_sequence()->scope();
+
+ LocalVariable* closure = NULL;
+ if (is_closure_call) {
+ closure = scope->VariableAt(0);
+
+ // The closure itself is the first argument.
+ body += LoadLocal(closure);
+ } else {
+ // Invoke the getter to get the field value.
+ body += LoadLocal(scope->VariableAt(0));
+ body += PushArgument();
+ body += InstanceCall(getter_name, Token::kGET, 1);
+ }
+
+ body += PushArgument();
+
+ // Push all arguments onto the stack.
+ intptr_t pos = 1;
+ for (; pos < descriptor.Count(); pos++) {
+ body += LoadLocal(scope->VariableAt(pos));
+ body += PushArgument();
+ }
+
+ if (is_closure_call) {
+ // Lookup the function in the closure.
+ body += LoadLocal(closure);
+ body += LoadField(Closure::function_offset());
+
+ body += ClosureCall(descriptor.Count(), argument_names);
+ } else {
+ body += InstanceCall(Symbols::Call(), Token::kILLEGAL, descriptor.Count(),
+ argument_names);
+ }
+
+ body += Return();
+
+ return new (Z) FlowGraph(*parsed_function_, graph_entry_, next_block_id_ - 1);
+}
+
+
+void FlowGraphBuilder::SetupDefaultParameterValues(FunctionNode* function) {
+ intptr_t num_optional_parameters =
+ parsed_function_->function().NumOptionalParameters();
+ if (num_optional_parameters > 0) {
+ ZoneGrowableArray<const Instance*>* default_values =
+ new ZoneGrowableArray<const Instance*>(Z, num_optional_parameters);
+
+ if (parsed_function_->function().HasOptionalNamedParameters()) {
+ ASSERT(!parsed_function_->function().HasOptionalPositionalParameters());
+ for (intptr_t i = 0; i < num_optional_parameters; i++) {
+ VariableDeclaration* variable = function->named_parameters()[i];
+ Instance* default_value;
+ if (variable->initializer() != NULL) {
+ default_value =
+ &constant_evaluator_.EvaluateExpression(variable->initializer());
+ } else {
+ default_value = &Instance::ZoneHandle(Z, Instance::null());
+ }
+ default_values->Add(default_value);
+ }
+ } else {
+ ASSERT(parsed_function_->function().HasOptionalPositionalParameters());
+ intptr_t required = function->required_parameter_count();
+ for (intptr_t i = 0; i < num_optional_parameters; i++) {
+ VariableDeclaration* variable =
+ function->positional_parameters()[required + i];
+ Instance* default_value;
+ if (variable->initializer() != NULL) {
+ default_value =
+ &constant_evaluator_.EvaluateExpression(variable->initializer());
+ } else {
+ default_value = &Instance::ZoneHandle(Z, Instance::null());
+ }
+ default_values->Add(default_value);
+ }
+ }
+ parsed_function_->set_default_parameter_values(default_values);
+ }
+}
+
+
+TargetEntryInstr* FlowGraphBuilder::BuildTargetEntry() {
+ return new (Z) TargetEntryInstr(AllocateBlockId(), CurrentTryIndex());
+}
+
+
+JoinEntryInstr* FlowGraphBuilder::BuildJoinEntry() {
+ return new (Z) JoinEntryInstr(AllocateBlockId(), CurrentTryIndex());
+}
+
+
+Fragment FlowGraphBuilder::TranslateInitializers(
+ Class* kernel_klass, List<Initializer>* initializers) {
+ Fragment instructions;
+
+ // These come from:
+ // class A {
+ // var x = (expr);
+ // }
+ for (intptr_t i = 0; i < kernel_klass->fields().length(); i++) {
+ Field* kernel_field = kernel_klass->fields()[i];
+ Expression* init = kernel_field->initializer();
+ if (!kernel_field->IsStatic() && init != NULL) {
+ dart::Field& field =
+ dart::Field::ZoneHandle(Z, H.LookupFieldByKernelField(kernel_field));
+
+ EnterScope(kernel_field);
+ // TODO(27590): Support FLAG_use_field_guards.
+ instructions += LoadLocal(scopes_->this_variable);
+ instructions += TranslateExpression(init);
+ instructions += StoreInstanceField(field);
+ ExitScope(kernel_field);
+ }
+ }
+
+ // These to come from:
+ // class A {
+ // var x;
+ // var y;
+ // A(this.x) : super(expr), y = (expr);
+ // }
+ for (intptr_t i = 0; i < initializers->length(); i++) {
+ Initializer* initializer = (*initializers)[i];
+ if (initializer->IsFieldInitializer()) {
+ FieldInitializer* init = FieldInitializer::Cast(initializer);
+ dart::Field& field =
+ dart::Field::ZoneHandle(Z, H.LookupFieldByKernelField(init->field()));
+
+ // TODO(27590): Support FLAG_use_field_guards.
+ instructions += LoadLocal(scopes_->this_variable);
+ instructions += TranslateExpression(init->value());
+ instructions += StoreInstanceField(field);
+ } else if (initializer->IsSuperInitializer()) {
+ SuperInitializer* init = SuperInitializer::Cast(initializer);
+
+ instructions += LoadLocal(scopes_->this_variable);
+ instructions += PushArgument();
+
+ ASSERT(init->arguments()->types().length() == 0);
+ Array& argument_names = Array::ZoneHandle(Z);
+ instructions += TranslateArguments(init->arguments(), &argument_names);
+
+ const Function& target = Function::ZoneHandle(
+ Z, H.LookupConstructorByKernelConstructor(init->target()));
+ intptr_t argument_count = init->arguments()->count() + 1;
+ instructions += StaticCall(target, argument_count, argument_names);
+ instructions += Drop();
+ } else if (initializer->IsRedirectingInitializer()) {
+ RedirectingInitializer* init = RedirectingInitializer::Cast(initializer);
+
+ instructions += LoadLocal(scopes_->this_variable);
+ instructions += PushArgument();
+
+ ASSERT(init->arguments()->types().length() == 0);
+ Array& argument_names = Array::ZoneHandle(Z);
+ instructions += TranslateArguments(init->arguments(), &argument_names);
+
+ const Function& target = Function::ZoneHandle(
+ Z, H.LookupConstructorByKernelConstructor(init->target()));
+ intptr_t argument_count = init->arguments()->count() + 1;
+ instructions += StaticCall(target, argument_count, argument_names);
+ instructions += Drop();
+ } else if (initializer->IsLocalInitializer()) {
+ // The other initializers following this one might read the variable. This
+ // is used e.g. for evaluating the arguments to a super call first, run
+ // normal field initializers next and then make the actual super call:
+ //
+ // The frontend converts
+ //
+ // class A {
+ // var x;
+ // A(a, b) : super(a + b), x = 2*b {}
+ // }
+ //
+ // to
+ //
+ // class A {
+ // var x;
+ // A(a, b) : tmp = a + b, x = 2*b, super(tmp) {}
+ // }
+ //
+ // (This is strictly speaking not what one should do in terms of the
+ // specification but that is how it is currently implemented.)
+ LocalInitializer* init = LocalInitializer::Cast(initializer);
+
+ VariableDeclaration* declaration = init->variable();
+ LocalVariable* variable = LookupVariable(declaration);
+ Expression* initializer = init->variable()->initializer();
+ ASSERT(initializer != NULL);
+ ASSERT(!declaration->IsConst());
+
+ instructions += TranslateExpression(initializer);
+ instructions += StoreLocal(variable);
+ instructions += Drop();
+
+ fragment_ = instructions;
+ } else {
+ UNIMPLEMENTED();
+ }
+ }
+ return instructions;
+}
+
+
+Fragment FlowGraphBuilder::TranslateStatement(Statement* statement) {
+#ifdef DEBUG
+ intptr_t original_context_depth = context_depth_;
+#endif
+ statement->AcceptStatementVisitor(this);
+ DEBUG_ASSERT(context_depth_ == original_context_depth);
+ return fragment_;
+}
+
+
+Fragment FlowGraphBuilder::TranslateCondition(Expression* expression,
+ bool* negate) {
+ *negate = expression->IsNot();
+ if (*negate) {
+ return TranslateExpression(Not::Cast(expression)->expression());
+ }
+ return TranslateExpression(expression);
+}
+
+
+Fragment FlowGraphBuilder::TranslateExpression(Expression* expression) {
+ expression->AcceptExpressionVisitor(this);
+ return fragment_;
+}
+
+
+ArgumentArray FlowGraphBuilder::GetArguments(int count) {
+ ArgumentArray arguments =
+ new (Z) ZoneGrowableArray<PushArgumentInstr*>(Z, count);
+ arguments->SetLength(count);
+ for (intptr_t i = count - 1; i >= 0; --i) {
+ ASSERT(stack_->definition()->IsPushArgument());
+ ASSERT(!stack_->definition()->HasSSATemp());
+ arguments->data()[i] = stack_->definition()->AsPushArgument();
+ Drop();
+ }
+ pending_argument_count_ -= count;
+ ASSERT(pending_argument_count_ >= 0);
+ return arguments;
+}
+
+
+void FlowGraphBuilder::VisitInvalidExpression(InvalidExpression* node) {
+ // TODO(27590): Once we have better error information we might need to
+ // make some invalid expressions not NSM errors but type/compile-time/...
+ // errors.
+ fragment_ = ThrowNoSuchMethodError();
+}
+
+
+void FlowGraphBuilder::VisitNullLiteral(NullLiteral* node) {
+ fragment_ = Constant(Instance::ZoneHandle(Z, Instance::null()));
+}
+
+
+void FlowGraphBuilder::VisitBoolLiteral(BoolLiteral* node) {
+ fragment_ = Constant(Bool::Get(node->value()));
+}
+
+
+void FlowGraphBuilder::VisitIntLiteral(IntLiteral* node) {
+ fragment_ = IntConstant(node->value());
+}
+
+
+void FlowGraphBuilder::VisitBigintLiteral(BigintLiteral* node) {
+ const dart::String& value = H.DartString(node->value());
+ fragment_ = Constant(Integer::ZoneHandle(Z, Integer::New(value, Heap::kOld)));
+}
+
+
+void FlowGraphBuilder::VisitDoubleLiteral(DoubleLiteral* node) {
+ fragment_ = Constant(constant_evaluator_.EvaluateExpression(node));
+}
+
+
+void FlowGraphBuilder::VisitStringLiteral(StringLiteral* node) {
+ fragment_ = Constant(H.DartSymbol(node->value()));
+}
+
+
+void FlowGraphBuilder::VisitSymbolLiteral(SymbolLiteral* node) {
+ fragment_ = Constant(constant_evaluator_.EvaluateExpression(node));
+}
+
+
+AbstractType& DartTypeTranslator::TranslateType(DartType* node) {
+ node->AcceptDartTypeVisitor(this);
+
+ // We return a new `ZoneHandle` here on purpose: The intermediate language
+ // instructions do not make a copy of the handle, so we do it.
+ return dart::AbstractType::ZoneHandle(Z, result_.raw());
+}
+
+
+AbstractType& DartTypeTranslator::TranslateTypeWithoutFinalization(
+ DartType* node) {
+ bool saved_finalize = finalize_;
+ finalize_ = false;
+ H.SetFinalize(false);
+ AbstractType& result = TranslateType(node);
+ finalize_ = saved_finalize;
+ H.SetFinalize(saved_finalize);
+ return result;
+}
+
+
+void DartTypeTranslator::VisitInvalidType(InvalidType* node) {
+ result_ = ClassFinalizer::NewFinalizedMalformedType(
+ Error::Handle(Z), // No previous error.
+ dart::Script::Handle(Z, dart::Script::null()), TokenPosition::kNoSource,
+ "[InvalidType] in Kernel IR.");
+}
+
+
+void DartTypeTranslator::VisitFunctionType(FunctionType* node) {
+ // TODO(27590): Fix function types which are composed of malformed types.
+ // We might need to convert them to dynamic types instead of making the
+ // function type malformed.
+ const Function& signature_function = Function::ZoneHandle(
+ Z, Function::NewSignatureFunction(*active_class_->klass,
+ TokenPosition::kNoSource));
+
+ node->return_type()->AcceptDartTypeVisitor(this);
+ if (result_.IsMalformed()) return;
+ signature_function.set_result_type(result_);
+
+ const intptr_t positional_count = node->positional_parameters().length();
+ const intptr_t named_count = node->named_parameters().length();
+ const intptr_t all_count = positional_count + named_count;
+ const intptr_t required_count = node->required_parameter_count();
+
+ // The additional first parameter is the receiver type (set to dynamic).
+ signature_function.set_num_fixed_parameters(1 + required_count);
+ signature_function.SetNumOptionalParameters(
+ all_count - required_count, positional_count > required_count);
+
+ const Array& parameter_types =
+ Array::Handle(Z, Array::New(1 + all_count, Heap::kOld));
+ signature_function.set_parameter_types(parameter_types);
+ const Array& parameter_names =
+ Array::Handle(Z, Array::New(1 + all_count, Heap::kOld));
+ signature_function.set_parameter_names(parameter_names);
+
+ intptr_t pos = 0;
+ parameter_types.SetAt(pos, AbstractType::dynamic_type());
+ parameter_names.SetAt(pos, H.DartSymbol("_receiver_"));
+ pos++;
+ for (intptr_t i = 0; i < positional_count; i++, pos++) {
+ node->positional_parameters()[i]->AcceptDartTypeVisitor(this);
+ if (result_.IsMalformed()) return;
+ parameter_types.SetAt(pos, result_);
+ parameter_names.SetAt(pos, H.DartSymbol("noname"));
+ }
+ for (intptr_t i = 0; i < named_count; i++, pos++) {
+ Tuple<String, DartType>* tuple = node->named_parameters()[i];
+ tuple->second()->AcceptDartTypeVisitor(this);
+ if (result_.IsMalformed()) return;
+ parameter_types.SetAt(pos, result_);
+ parameter_names.SetAt(pos, H.DartSymbol(tuple->first()));
+ }
+
+ Type& signature_type =
+ Type::ZoneHandle(Z, signature_function.SignatureType());
+
+ if (finalize_) {
+ signature_type ^= ClassFinalizer::FinalizeType(
+ *active_class_->klass, signature_type, ClassFinalizer::kCanonicalize);
+ }
+ signature_function.SetSignatureType(signature_type);
+
+ result_ = signature_type.raw();
+}
+
+
+void DartTypeTranslator::VisitTypeParameterType(TypeParameterType* node) {
+ ASSERT(active_class_->kernel_class != NULL);
+
+ List<TypeParameter>* parameters =
+ &active_class_->kernel_class->type_parameters();
+ if ((active_class_->member != NULL) && active_class_->member->IsProcedure()) {
+ Procedure* procedure = Procedure::Cast(active_class_->member);
+ if ((procedure->function() != NULL) &&
+ (procedure->function()->type_parameters().length() > 0)) {
+ //
+ // WARNING: This is a little hackish:
+ //
+ // We have a static factory constructor. The kernel IR gives the factory
+ // constructor function it's own type parameters (which are equal in name
+ // and number to the ones of the enclosing class).
+ // I.e.,
+ //
+ // class A<T> {
+ // factory A.x() { return new B<T>(); }
+ // }
+ //
+ // is basically translated to this:
+ //
+ // class A<T> {
+ // static A.x<T'>() { return new B<T'>(); }
+ // }
+ //
+ parameters = &procedure->function()->type_parameters();
+ }
+ }
+
+ for (intptr_t i = 0; i < parameters->length(); i++) {
+ TypeParameter* type_parameter = (*parameters)[i];
+ if (node->parameter() == type_parameter) {
+ // The index of the type parameter in [parameters] is
+ // the same index into the `klass->type_parameters()` array.
+ result_ ^= dart::TypeArguments::Handle(
+ Z, active_class_->klass->type_parameters())
+ .TypeAt(i);
+ return;
+ }
+ }
+
+ UNREACHABLE();
+}
+
+
+void DartTypeTranslator::VisitInterfaceType(InterfaceType* node) {
+ // NOTE: That an interface type like `T<A, B>` is considered to be
+ // malformed iff `T` is malformed.
+ // => We therefore ignore errors in `A` or `B`.
+ const TypeArguments& type_arguments = TranslateTypeArguments(
+ node->type_arguments().raw_array(), node->type_arguments().length());
+
+ const dart::Class& klass =
+ dart::Class::Handle(Z, H.LookupClassByKernelClass(node->klass()));
+
+ result_ = Type::New(klass, type_arguments, TokenPosition::kNoSource);
+ result_.SetIsResolved();
+ if (finalize_) {
+ result_ = ClassFinalizer::FinalizeType(klass, result_,
+ ClassFinalizer::kCanonicalize);
+ }
+}
+
+
+void DartTypeTranslator::VisitDynamicType(DynamicType* node) {
+ result_ = Object::dynamic_type().raw();
+}
+
+
+void DartTypeTranslator::VisitVoidType(VoidType* node) {
+ result_ = Object::void_type().raw();
+}
+
+
+const TypeArguments& DartTypeTranslator::TranslateTypeArguments(
+ DartType** dart_types, intptr_t length) {
+ bool only_dynamic = true;
+ for (intptr_t i = 0; i < length; i++) {
+ if (!dart_types[i]->IsDynamicType()) {
+ only_dynamic = false;
+ break;
+ }
+ }
+ TypeArguments& type_arguments = TypeArguments::ZoneHandle(Z);
+ if (!only_dynamic) {
+ type_arguments = TypeArguments::New(length);
+ for (intptr_t i = 0; i < length; i++) {
+ dart_types[i]->AcceptDartTypeVisitor(this);
+ if (result_.IsMalformed()) {
+ type_arguments = TypeArguments::null();
+ return type_arguments;
+ }
+ type_arguments.SetTypeAt(i, result_);
+ }
+ if (finalize_) {
+ type_arguments = type_arguments.Canonicalize();
+ }
+ }
+ return type_arguments;
+}
+
+
+const TypeArguments& DartTypeTranslator::TranslateInstantiatedTypeArguments(
+ const dart::Class& receiver_class, DartType** receiver_type_arguments,
+ intptr_t length) {
+ const TypeArguments& type_arguments =
+ TranslateTypeArguments(receiver_type_arguments, length);
+ if (type_arguments.IsNull()) return type_arguments;
+
+ // We make a temporary [Type] object and use `ClassFinalizer::FinalizeType` to
+ // finalize the argument types.
+ // (This can for example make the [type_arguments] vector larger)
+ Type& type = Type::Handle(
+ Z, Type::New(receiver_class, type_arguments, TokenPosition::kNoSource));
+ if (finalize_) {
+ type ^= ClassFinalizer::FinalizeType(
+ *active_class_->klass, type, ClassFinalizer::kCanonicalizeWellFormed);
+ }
+
+ const TypeArguments& instantiated_type_arguments =
+ TypeArguments::ZoneHandle(Z, type.arguments());
+ return instantiated_type_arguments;
+}
+
+
+const Type& DartTypeTranslator::ReceiverType(const dart::Class& klass) {
+ ASSERT(!klass.IsNull());
+ ASSERT(!klass.IsTypedefClass());
+ // Note that if klass is _Closure, the returned type will be _Closure,
+ // and not the signature type.
+ Type& type = Type::ZoneHandle(Z, klass.CanonicalType());
+ if (!type.IsNull()) {
+ return type;
+ }
+ type = Type::New(klass, TypeArguments::Handle(Z, klass.type_parameters()),
+ klass.token_pos());
+ return type;
+}
+
+
+void FlowGraphBuilder::VisitTypeLiteral(TypeLiteral* node) {
+ const AbstractType& type = T.TranslateType(node->type());
+ if (type.IsMalformed()) H.ReportError("Malformed type literal");
+
+ fragment_ = Constant(type);
+}
+
+
+void FlowGraphBuilder::VisitVariableGet(VariableGet* node) {
+ fragment_ = LoadLocal(LookupVariable(node->variable()));
+}
+
+
+void FlowGraphBuilder::VisitVariableSet(VariableSet* node) {
+ Fragment instructions = TranslateExpression(node->expression());
+ // The IR should not include assignments to final or const variables.
+ // This is https://github.com/dart-lang/rasta/issues/83.
+ //
+ // TODO(27590): simply ASSERT that the variable is not const or final
+ // when that issue is fixed.
+ fragment_ = instructions +
+ ((node->variable()->IsFinal() || node->variable()->IsConst())
+ ? Drop() + ThrowNoSuchMethodError()
+ : StoreLocal(LookupVariable(node->variable())));
+}
+
+
+void FlowGraphBuilder::VisitStaticGet(StaticGet* node) {
+ Member* target = node->target();
+ if (target->IsField()) {
+ Field* kernel_field = Field::Cast(target);
+ const dart::Field& field =
+ dart::Field::ZoneHandle(Z, H.LookupFieldByKernelField(kernel_field));
+ if (kernel_field->IsConst()) {
+ fragment_ = Constant(constant_evaluator_.EvaluateExpression(node));
+ } else {
+ const dart::Class& owner = dart::Class::Handle(Z, field.Owner());
+ const dart::String& getter_name = H.DartGetterName(kernel_field->name());
+ const Function& getter =
+ Function::ZoneHandle(Z, owner.LookupStaticFunction(getter_name));
+ if (getter.IsNull() || !field.has_initializer()) {
+ Fragment instructions = Constant(field);
+ fragment_ = instructions + LoadStaticField();
+ } else {
+ // TODO(27590): figure out how to trigger this case and add tests.
+ fragment_ = StaticCall(getter, 0);
+ }
+ }
+ } else {
+ Procedure* procedure = Procedure::Cast(target);
+ const Function& target = Function::ZoneHandle(
+ Z, H.LookupStaticMethodByKernelProcedure(procedure));
+
+ if (procedure->kind() == Procedure::kGetter) {
+ fragment_ = StaticCall(target, 0);
+ } else if (procedure->kind() == Procedure::kMethod) {
+ ASSERT(procedure->IsStatic());
+ Function& closure_function =
+ Function::ZoneHandle(Z, target.ImplicitClosureFunction());
+ closure_function.set_kernel_function(target.kernel_function());
+ const Instance& closure =
+ Instance::ZoneHandle(Z, closure_function.ImplicitStaticClosure());
+ fragment_ = Constant(closure);
+ } else {
+ UNIMPLEMENTED();
+ }
+ }
+}
+
+
+void FlowGraphBuilder::VisitStaticSet(StaticSet* node) {
+ Member* target = node->target();
+ if (target->IsField()) {
+ Field* kernel_field = Field::Cast(target);
+ const dart::Field& field =
+ dart::Field::ZoneHandle(Z, H.LookupFieldByKernelField(kernel_field));
+ Fragment instructions = TranslateExpression(node->expression());
+ LocalVariable* variable = MakeTemporary();
+ instructions += LoadLocal(variable);
+ fragment_ = instructions + StoreStaticField(field);
+ } else {
+ ASSERT(target->IsProcedure());
+
+ // Evaluate the expression on the right hand side.
+ Fragment instructions = TranslateExpression(node->expression());
+ LocalVariable* variable = MakeTemporary();
+
+ // Prepare argument.
+ instructions += LoadLocal(variable);
+ instructions += PushArgument();
+
+ // Invoke the setter function.
+ Procedure* procedure = Procedure::Cast(target);
+ const Function& target = Function::ZoneHandle(
+ Z, H.LookupStaticMethodByKernelProcedure(procedure));
+ instructions += StaticCall(target, 1);
+
+ // Drop the unused result & leave the stored value on the stack.
+ fragment_ = instructions + Drop();
+ }
+}
+
+
+void FlowGraphBuilder::VisitPropertyGet(PropertyGet* node) {
+ Fragment instructions = TranslateExpression(node->receiver());
+ instructions += PushArgument();
+ const dart::String& getter_name = H.DartGetterName(node->name());
+ fragment_ = instructions + InstanceCall(getter_name, Token::kGET, 1);
+}
+
+
+void FlowGraphBuilder::VisitPropertySet(PropertySet* node) {
+ Fragment instructions(NullConstant());
+ LocalVariable* variable = MakeTemporary();
+ instructions += TranslateExpression(node->receiver());
+ instructions += PushArgument();
+ instructions += TranslateExpression(node->value());
+ instructions += StoreLocal(variable);
+ instructions += PushArgument();
+
+ const dart::String& setter_name = H.DartSetterName(node->name());
+ instructions += InstanceCall(setter_name, Token::kSET, 2);
+ fragment_ = instructions + Drop();
+}
+
+
+void FlowGraphBuilder::VisitDirectPropertyGet(DirectPropertyGet* node) {
+ Function& target = Function::ZoneHandle(Z);
+ if (node->target()->IsProcedure()) {
+ Procedure* kernel_procedure = Procedure::Cast(node->target());
+ Name* kernel_name = kernel_procedure->name();
+ if (kernel_procedure->kind() == Procedure::kGetter) {
+ target =
+ LookupMethodByMember(kernel_procedure, H.DartGetterName(kernel_name));
+ } else {
+ target =
+ LookupMethodByMember(kernel_procedure, H.DartMethodName(kernel_name));
+ target = target.ImplicitClosureFunction();
+ ASSERT(!target.IsNull());
+ fragment_ = BuildImplicitClosureCreation(target);
+ return;
+ }
+ } else {
+ ASSERT(node->target()->IsField());
+ const dart::String& getter_name = H.DartGetterName(node->target()->name());
+ target = LookupMethodByMember(node->target(), getter_name);
+ ASSERT(target.IsGetterFunction() || target.IsImplicitGetterFunction());
+ }
+
+ Fragment instructions = TranslateExpression(node->receiver());
+ instructions += PushArgument();
+ fragment_ = instructions + StaticCall(target, 1);
+}
+
+
+void FlowGraphBuilder::VisitDirectPropertySet(DirectPropertySet* node) {
+ const dart::String& method_name = H.DartSetterName(node->target()->name());
+ const Function& target = Function::ZoneHandle(
+ Z, LookupMethodByMember(node->target(), method_name));
+ ASSERT(target.IsSetterFunction() || target.IsImplicitSetterFunction());
+
+ Fragment instructions(NullConstant());
+ LocalVariable* value = MakeTemporary();
+ instructions += TranslateExpression(node->receiver());
+ instructions += PushArgument();
+ instructions += TranslateExpression(node->value());
+ instructions += StoreLocal(value);
+ instructions += PushArgument();
+ instructions += StaticCall(target, 2);
+
+ fragment_ = instructions + Drop();
+}
+
+
+void FlowGraphBuilder::VisitStaticInvocation(StaticInvocation* node) {
+ const Function& target = Function::ZoneHandle(
+ Z, H.LookupStaticMethodByKernelProcedure(node->procedure()));
+ const dart::Class& klass = dart::Class::ZoneHandle(Z, target.Owner());
+ intptr_t argument_count = node->arguments()->count();
+ if (target.IsGenerativeConstructor() || target.IsFactory()) {
+ // The VM requires a TypeArguments object as first parameter for
+ // every factory constructor.
+ ++argument_count;
+ }
+ List<NamedExpression>& named = node->arguments()->named();
+ const Array& argument_names = H.ArgumentNames(&named);
+
+ Fragment instructions;
+ if (!target.AreValidArguments(argument_count, argument_names, NULL)) {
+ // An argument mismatch for a static invocation really should not occur
+ // in the IR. This is issue https://github.com/dart-lang/rasta/issues/76.
+ //
+ // TODO(27590): Change this to an ASSERT when that issue is fixed.
+ List<Expression>& positional = node->arguments()->positional();
+ for (intptr_t i = 0; i < positional.length(); ++i) {
+ instructions += TranslateExpression(positional[i]);
+ instructions += Drop();
+ }
+
+ for (intptr_t i = 0; i < named.length(); ++i) {
+ instructions += TranslateExpression(named[i]->expression());
+ instructions += Drop();
+ }
+
+ fragment_ = instructions + ThrowNoSuchMethodError();
+ return;
+ }
+
+ LocalVariable* instance_variable = NULL;
+
+ // If we cross the Kernel -> VM core library boundary, a [StaticInvocation]
+ // can appear, but the thing we're calling is not a static method, but a
+ // factory constructor.
+ // The `H.LookupStaticmethodByKernelProcedure` will potentially resolve to the
+ // forwarded constructor.
+ // In that case we'll make an instance and pass it as first argument.
+ //
+ // TODO(27590): Get rid of this after we're using core libraries compiled
+ // into Kernel.
+ if (target.IsGenerativeConstructor()) {
+ if (klass.NumTypeArguments() > 0) {
+ List<DartType>& kernel_type_arguments = node->arguments()->types();
+ const TypeArguments& type_arguments =
+ T.TranslateInstantiatedTypeArguments(
+ klass, kernel_type_arguments.raw_array(),
+ kernel_type_arguments.length());
+ instructions += TranslateInstantiatedTypeArguments(type_arguments);
+ instructions += PushArgument();
+ instructions += AllocateObject(klass, 1);
+ } else {
+ instructions += AllocateObject(klass, 0);
+ }
+
+ instance_variable = MakeTemporary();
+
+ instructions += LoadLocal(instance_variable);
+ instructions += PushArgument();
+ } else if (target.IsFactory()) {
+ // The VM requires currently a TypeArguments object as first parameter for
+ // every factory constructor :-/ !
+ //
+ // TODO(27590): Get rid of this after we're using core libraries compiled
+ // into Kernel.
+ List<DartType>& kernel_type_arguments = node->arguments()->types();
+
+ const TypeArguments& type_arguments = T.TranslateInstantiatedTypeArguments(
+ klass, kernel_type_arguments.raw_array(),
+ kernel_type_arguments.length());
+
+ instructions += TranslateInstantiatedTypeArguments(type_arguments);
+ instructions += PushArgument();
+ } else {
+ ASSERT(node->arguments()->types().length() == 0);
+ }
+
+ // Special case identical(x, y) call.
+ // TODO(27590) consider moving this into the inliner and force inline it
+ // there.
+ if (klass.IsTopLevel() && (klass.library() == dart::Library::CoreLibrary()) &&
+ (target.name() == Symbols::Identical().raw())) {
+ ASSERT(argument_count == 2);
+
+ List<Expression>& positional = node->arguments()->positional();
+ for (intptr_t i = 0; i < positional.length(); ++i) {
+ instructions += TranslateExpression(positional[i]);
+ }
+ instructions += StrictCompare(Token::kEQ_STRICT, /*number_check=*/true);
+ } else {
+ instructions += TranslateArguments(node->arguments(), NULL);
+ instructions += StaticCall(target, argument_count, argument_names);
+
+ if (target.IsGenerativeConstructor()) {
+ // Drop the result of the constructor call and leave [instance_variable]
+ // on top-of-stack.
+ instructions += Drop();
+ }
+ }
+
+ fragment_ = instructions;
+}
+
+
+static bool IsNumberLiteral(Node* node) {
+ return node->IsIntLiteral() || node->IsDoubleLiteral();
+}
+
+
+void FlowGraphBuilder::VisitMethodInvocation(MethodInvocation* node) {
+ const dart::String& name = H.DartMethodName(node->name());
+ const intptr_t argument_count = node->arguments()->count() + 1;
+ const Token::Kind token_kind = MethodKind(name);
+ if (IsNumberLiteral(node->receiver())) {
+ if ((argument_count == 1) && (token_kind == Token::kNEGATE)) {
+ const Object& result = constant_evaluator_.EvaluateExpressionSafe(node);
+ if (!result.IsError()) {
+ fragment_ = Constant(result);
+ return;
+ }
+ } else if ((argument_count == 2) &&
+ Token::IsBinaryArithmeticOperator(token_kind) &&
+ IsNumberLiteral(node->arguments()->positional()[0])) {
+ const Object& result = constant_evaluator_.EvaluateExpressionSafe(node);
+ if (!result.IsError()) {
+ fragment_ = Constant(result);
+ return;
+ }
+ }
+ }
+
+ Fragment instructions = TranslateExpression(node->receiver());
+ instructions += PushArgument();
+
+ // Dart does not support generic methods yet.
+ ASSERT(node->arguments()->types().length() == 0);
+
+ Array& argument_names = Array::ZoneHandle(Z);
+ instructions += TranslateArguments(node->arguments(), &argument_names);
+
+ intptr_t num_args_checked = 1;
+ // If we have a special operation (e.g. +/-/==) we mark both arguments as
+ // to be checked.
+ if (token_kind != Token::kILLEGAL) {
+ ASSERT(argument_count <= 2);
+ num_args_checked = argument_count;
+ }
+
+ fragment_ = instructions + InstanceCall(name, token_kind, argument_count,
+ argument_names, num_args_checked);
+}
+
+
+void FlowGraphBuilder::VisitDirectMethodInvocation(
+ DirectMethodInvocation* node) {
+ const dart::String& method_name = H.DartMethodName(node->target()->name());
+ const Function& target = Function::ZoneHandle(
+ Z, LookupMethodByMember(node->target(), method_name));
+
+ intptr_t argument_count = node->arguments()->count() + 1;
+ Array& argument_names = Array::ZoneHandle(Z);
+
+ ASSERT(node->arguments()->types().length() == 0);
+ Fragment instructions = TranslateExpression(node->receiver());
+ instructions += PushArgument();
+ instructions += TranslateArguments(node->arguments(), &argument_names);
+ fragment_ = instructions + StaticCall(target, argument_count, argument_names);
+}
+
+
+void FlowGraphBuilder::VisitConstructorInvocation(ConstructorInvocation* node) {
+ if (node->is_const()) {
+ fragment_ =
+ Constant(constant_evaluator_.EvaluateConstructorInvocation(node));
+ return;
+ }
+
+ Class* kernel_class = Class::Cast(node->target()->parent());
+
+ dart::Class& klass =
+ dart::Class::ZoneHandle(Z, H.LookupClassByKernelClass(kernel_class));
+
+ Fragment instructions;
+ if (klass.NumTypeArguments() > 0) {
+ List<DartType>& kernel_type_arguments = node->arguments()->types();
+ const TypeArguments& type_arguments = T.TranslateInstantiatedTypeArguments(
+ klass, kernel_type_arguments.raw_array(),
+ kernel_type_arguments.length());
+
+ if (type_arguments.IsNull() || type_arguments.IsInstantiated()) {
+ instructions += TranslateInstantiatedTypeArguments(type_arguments);
+ } else {
+ if (!klass.IsGeneric()) {
+ Type& type = Type::ZoneHandle(Z, T.ReceiverType(klass).raw());
+
+ // TODO(27590): Can we move this code into [ReceiverType]?
+ type ^= ClassFinalizer::FinalizeType(*active_class_.klass, type,
+ ClassFinalizer::kFinalize);
+ ASSERT(!type.IsMalformedOrMalbounded());
+
+ TypeArguments& canonicalized_type_arguments =
+ TypeArguments::ZoneHandle(Z, type.arguments());
+ canonicalized_type_arguments =
+ canonicalized_type_arguments.Canonicalize();
+ instructions += Constant(canonicalized_type_arguments);
+ } else {
+ instructions += TranslateInstantiatedTypeArguments(type_arguments);
+ }
+ }
+
+ instructions += PushArgument();
+ instructions += AllocateObject(klass, 1);
+ } else {
+ instructions += AllocateObject(klass, 0);
+ }
+ LocalVariable* variable = MakeTemporary();
+
+ instructions += LoadLocal(variable);
+ instructions += PushArgument();
+
+ Array& argument_names = Array::ZoneHandle(Z);
+ instructions += TranslateArguments(node->arguments(), &argument_names);
+
+ const Function& target = Function::ZoneHandle(
+ Z, H.LookupConstructorByKernelConstructor(klass, node->target()));
+ intptr_t argument_count = node->arguments()->count() + 1;
+ instructions += StaticCall(target, argument_count, argument_names);
+ fragment_ = instructions + Drop();
+}
+
+
+void FlowGraphBuilder::VisitIsExpression(IsExpression* node) {
+ Fragment instructions = TranslateExpression(node->operand());
+
+ // The VM does not like an instanceOf call with a dynamic type. We need to
+ // special case this situation.
+ const Type& object_type = Type::Handle(Z, Type::ObjectType());
+ const AbstractType& type = T.TranslateType(node->type());
+ if (type.IsMalformed()) {
+ instructions += Drop();
+ instructions += ThrowTypeError();
+ fragment_ = instructions;
+ return;
+ }
+
+ if (type.IsInstantiated() &&
+ object_type.IsSubtypeOf(type, NULL, NULL, Heap::kOld)) {
+ // Evaluate the expression on the left but ignore it's result.
+ instructions += Drop();
+
+ // Let condition be always true.
+ instructions += Constant(Bool::True());
+ } else {
+ instructions += PushArgument();
+
+ if (!type.IsInstantiated()) {
+ instructions += LoadInstantiatorTypeArguments();
+ } else {
+ instructions += NullConstant();
+ }
+ instructions += PushArgument(); // Type arguments.
+
+ instructions += Constant(type);
+ instructions += PushArgument(); // Type.
+
+ instructions += Constant(Bool::False());
+ instructions += PushArgument(); // Negate?.
+
+ instructions +=
+ InstanceCall(dart::Library::PrivateCoreLibName(Symbols::_instanceOf()),
+ Token::kIS, 4);
+ }
+
+ fragment_ = instructions;
+}
+
+
+void FlowGraphBuilder::VisitAsExpression(AsExpression* node) {
+ Fragment instructions = TranslateExpression(node->operand());
+
+ // The VM does not like an Object_as call with a dynamic type. We need to
+ // special case this situation.
+ const Type& object_type = Type::Handle(Z, Type::ObjectType());
+ const AbstractType& type = T.TranslateType(node->type());
+ if (type.IsMalformed()) {
+ instructions += Drop();
+ instructions += ThrowTypeError();
+ fragment_ = instructions;
+ return;
+ }
+
+ if (type.IsInstantiated() &&
+ object_type.IsSubtypeOf(type, NULL, NULL, Heap::kOld)) {
+ // We already evaluated the operand on the left and just leave it there as
+ // the result of the `obj as dynamic` expression.
+ } else {
+ instructions += PushArgument();
+
+ if (!type.IsInstantiated()) {
+ instructions += LoadInstantiatorTypeArguments();
+ } else {
+ instructions += NullConstant();
+ }
+ instructions += PushArgument(); // Type arguments.
+
+ instructions += Constant(type);
+ instructions += PushArgument(); // Type.
+
+ instructions += InstanceCall(
+ dart::Library::PrivateCoreLibName(Symbols::_as()), Token::kAS, 3);
+ }
+
+ fragment_ = instructions;
+}
+
+
+void FlowGraphBuilder::VisitConditionalExpression(ConditionalExpression* node) {
+ bool negate;
+ Fragment instructions = TranslateCondition(node->condition(), &negate);
+
+ TargetEntryInstr* then_entry;
+ TargetEntryInstr* otherwise_entry;
+ instructions += BranchIfTrue(&then_entry, &otherwise_entry, negate);
+
+ Value* top = stack_;
+ Fragment then_fragment(then_entry);
+ then_fragment += TranslateExpression(node->then());
+ then_fragment += StoreLocal(parsed_function_->expression_temp_var());
+ then_fragment += Drop();
+
+ ASSERT(stack_ == top);
+ Fragment otherwise_fragment(otherwise_entry);
+ otherwise_fragment += TranslateExpression(node->otherwise());
+ otherwise_fragment += StoreLocal(parsed_function_->expression_temp_var());
+ otherwise_fragment += Drop();
+
+ JoinEntryInstr* join = BuildJoinEntry();
+ then_fragment += Goto(join);
+ otherwise_fragment += Goto(join);
+
+ fragment_ = Fragment(instructions.entry, join) +
+ LoadLocal(parsed_function_->expression_temp_var());
+}
+
+
+void FlowGraphBuilder::VisitLogicalExpression(LogicalExpression* node) {
+ bool negate;
+ Fragment instructions = TranslateCondition(node->left(), &negate);
+ TargetEntryInstr* right_entry;
+ TargetEntryInstr* constant_entry;
+
+ if (node->op() == LogicalExpression::kAnd) {
+ instructions += BranchIfTrue(&right_entry, &constant_entry, negate);
+ } else {
+ instructions += BranchIfTrue(&constant_entry, &right_entry, negate);
+ }
+
+ Value* top = stack_;
+ Fragment right_fragment(right_entry);
+ right_fragment += TranslateCondition(node->right(), &negate);
+ right_fragment += Constant(Bool::True());
+ right_fragment +=
+ StrictCompare(negate ? Token::kNE_STRICT : Token::kEQ_STRICT);
+ right_fragment += StoreLocal(parsed_function_->expression_temp_var());
+ right_fragment += Drop();
+
+ ASSERT(top == stack_);
+ Fragment constant_fragment(constant_entry);
+ constant_fragment +=
+ Constant(Bool::Get(node->op() == LogicalExpression::kOr));
+ constant_fragment += StoreLocal(parsed_function_->expression_temp_var());
+ constant_fragment += Drop();
+
+ JoinEntryInstr* join = BuildJoinEntry();
+ right_fragment += Goto(join);
+ constant_fragment += Goto(join);
+
+ fragment_ = Fragment(instructions.entry, join) +
+ LoadLocal(parsed_function_->expression_temp_var());
+}
+
+
+void FlowGraphBuilder::VisitNot(Not* node) {
+ Fragment instructions = TranslateExpression(node->expression());
+ fragment_ = instructions + BooleanNegate();
+}
+
+
+void FlowGraphBuilder::VisitThisExpression(ThisExpression* node) {
+ fragment_ = LoadLocal(scopes_->this_variable);
+}
+
+
+void FlowGraphBuilder::VisitStringConcatenation(StringConcatenation* node) {
+ List<Expression>& expressions = node->expressions();
+
+ Fragment instructions;
+
+ // The type arguments for CreateArray.
+ instructions += Constant(TypeArguments::ZoneHandle(Z));
+ instructions += IntConstant(expressions.length());
+ instructions += CreateArray();
+ LocalVariable* array = MakeTemporary();
+
+ for (intptr_t i = 0; i < node->expressions().length(); i++) {
+ instructions += LoadLocal(array);
+ instructions += IntConstant(i);
+ instructions += TranslateExpression(node->expressions()[i]);
+ instructions += StoreIndexed(kArrayCid);
+ instructions += Drop();
+ }
+
+ instructions += StringInterpolate();
+
+ fragment_ = instructions;
+}
+
+
+void FlowGraphBuilder::VisitListLiteral(ListLiteral* node) {
+ if (node->is_const()) {
+ fragment_ = Constant(constant_evaluator_.EvaluateListLiteral(node));
+ return;
+ }
+
+ DartType* types[] = {node->type()};
+ const TypeArguments& type_arguments = T.TranslateTypeArguments(types, 1);
+
+ // The type argument for the factory call.
+ Fragment instructions = TranslateInstantiatedTypeArguments(type_arguments);
+ instructions += PushArgument();
+ List<Expression>& expressions = node->expressions();
+ if (expressions.length() == 0) {
+ instructions += Constant(Object::empty_array());
+ } else {
+ // The type arguments for CreateArray.
+ instructions += Constant(TypeArguments::ZoneHandle(Z));
+ instructions += IntConstant(expressions.length());
+ instructions += CreateArray();
+
+ LocalVariable* array = MakeTemporary();
+ for (intptr_t i = 0; i < expressions.length(); ++i) {
+ instructions += LoadLocal(array);
+ instructions += IntConstant(i);
+ instructions += TranslateExpression(expressions[i]);
+ instructions += StoreIndexed(kArrayCid);
+ instructions += Drop();
+ }
+ }
+ instructions += PushArgument(); // The array.
+
+ const dart::Class& factory_class =
+ dart::Class::Handle(Z, dart::Library::LookupCoreClass(Symbols::List()));
+ const Function& factory_method = Function::ZoneHandle(
+ Z, factory_class.LookupFactory(
+ dart::Library::PrivateCoreLibName(Symbols::ListLiteralFactory())));
+ fragment_ = instructions + StaticCall(factory_method, 2);
+}
+
+
+void FlowGraphBuilder::VisitMapLiteral(MapLiteral* node) {
+ if (node->is_const()) {
+ fragment_ = Constant(constant_evaluator_.EvaluateMapLiteral(node));
+ return;
+ }
+
+ const dart::Class& map_class =
+ dart::Class::Handle(Z, dart::Library::LookupCoreClass(Symbols::Map()));
+ const Function& factory_method = Function::ZoneHandle(
+ Z, map_class.LookupFactory(
+ dart::Library::PrivateCoreLibName(Symbols::MapLiteralFactory())));
+
+ DartType* types[] = {node->key_type(), node->value_type()};
+ const TypeArguments& type_arguments = T.TranslateTypeArguments(types, 2);
+
+ // The type argument for the factory call `new Map<K, V>._fromLiteral(List)`.
+ Fragment instructions = TranslateInstantiatedTypeArguments(type_arguments);
+ instructions += PushArgument();
+
+ List<MapEntry>& entries = node->entries();
+ if (entries.length() == 0) {
+ instructions += Constant(Object::empty_array());
+ } else {
+ // The type arguments for `new List<X>(int len)`.
+ instructions += Constant(TypeArguments::ZoneHandle(Z));
+
+ // We generate a list of tuples, i.e. [key1, value1, ..., keyN, valueN].
+ instructions += IntConstant(2 * entries.length());
+ instructions += CreateArray();
+
+ LocalVariable* array = MakeTemporary();
+ for (intptr_t i = 0; i < entries.length(); ++i) {
+ instructions += LoadLocal(array);
+ instructions += IntConstant(2 * i);
+ instructions += TranslateExpression(entries[i]->key());
+ instructions += StoreIndexed(kArrayCid);
+ instructions += Drop();
+
+ instructions += LoadLocal(array);
+ instructions += IntConstant(2 * i + 1);
+ instructions += TranslateExpression(entries[i]->value());
+ instructions += StoreIndexed(kArrayCid);
+ instructions += Drop();
+ }
+ }
+ instructions += PushArgument(); // The array.
+
+ fragment_ = instructions + StaticCall(factory_method, 2);
+}
+
+
+void FlowGraphBuilder::VisitFunctionExpression(FunctionExpression* node) {
+ fragment_ = TranslateFunctionNode(node->function(), node);
+}
+
+
+void FlowGraphBuilder::VisitLet(Let* node) {
+ Fragment instructions = TranslateStatement(node->variable());
+ instructions += TranslateExpression(node->body());
+ fragment_ = instructions;
+}
+
+
+void FlowGraphBuilder::VisitThrow(Throw* node) {
+ Fragment instructions;
+
+ instructions += TranslateExpression(node->expression());
+ instructions += PushArgument();
+ instructions += ThrowException();
+ ASSERT(instructions.is_closed());
+
+ fragment_ = instructions;
+}
+
+
+void FlowGraphBuilder::VisitRethrow(Rethrow* node) {
+ Fragment instructions;
+
+ instructions += LoadLocal(catch_block_->exception_var());
+ instructions += PushArgument();
+ instructions += LoadLocal(catch_block_->stack_trace_var());
+ instructions += PushArgument();
+ instructions += RethrowException(catch_block_->catch_try_index());
+
+ fragment_ = instructions;
+}
+
+
+void FlowGraphBuilder::VisitBlockExpression(BlockExpression* node) {
+ Fragment instructions = TranslateStatement(node->body());
+ instructions += TranslateExpression(node->value());
+ fragment_ = instructions;
+}
+
+
+Fragment FlowGraphBuilder::TranslateArguments(Arguments* node,
+ Array* argument_names) {
+ Fragment instructions;
+
+ List<Expression>& positional = node->positional();
+ for (intptr_t i = 0; i < positional.length(); ++i) {
+ instructions += TranslateExpression(positional[i]);
+ instructions += PushArgument();
+ }
+
+ List<NamedExpression>& named = node->named();
+ if (argument_names != NULL) {
+ *argument_names = H.ArgumentNames(&named).raw();
+ }
+ for (intptr_t i = 0; i < named.length(); ++i) {
+ NamedExpression* named_expression = named[i];
+ instructions += TranslateExpression(named_expression->expression());
+ instructions += PushArgument();
+ }
+ return instructions;
+}
+
+
+void FlowGraphBuilder::VisitInvalidStatement(InvalidStatement* node) {
+ H.ReportError("Invalid statements not implemented yet!");
+}
+
+
+void FlowGraphBuilder::VisitEmptyStatement(EmptyStatement* node) {
+ fragment_ = Fragment();
+}
+
+
+void FlowGraphBuilder::VisitBlock(Block* node) {
+ Fragment instructions;
+
+ instructions += EnterScope(node);
+ List<Statement>& statements = node->statements();
+ for (intptr_t i = 0; i < statements.length(); ++i) {
+ instructions += TranslateStatement(statements[i]);
+ }
+ instructions += ExitScope(node);
+
+ fragment_ = instructions;
+}
+
+
+void FlowGraphBuilder::VisitReturnStatement(ReturnStatement* node) {
+ bool inside_try_finally = try_finally_block_ != NULL;
+
+ Fragment instructions = node->expression() == NULL
+ ? NullConstant()
+ : TranslateExpression(node->expression());
+ if (inside_try_finally) {
+ ASSERT(scopes_->finally_return_variable != NULL);
+ instructions += StoreLocal(scopes_->finally_return_variable);
+ instructions += Drop();
+ instructions += TranslateFinallyFinalizers(NULL, -1);
+ if (instructions.is_open()) {
+ instructions += LoadLocal(scopes_->finally_return_variable);
+ instructions += Return();
+ }
+ } else {
+ instructions += Return();
+ }
+ fragment_ = instructions;
+}
+
+
+void FlowGraphBuilder::VisitExpressionStatement(ExpressionStatement* node) {
+ Fragment instructions = TranslateExpression(node->expression());
+ instructions += Drop();
+ fragment_ = instructions;
+}
+
+
+void FlowGraphBuilder::VisitVariableDeclaration(VariableDeclaration* node) {
+ LocalVariable* variable = LookupVariable(node);
+ Expression* initializer = node->initializer();
+
+ Fragment instructions;
+ if (initializer == NULL) {
+ instructions += NullConstant();
+ } else {
+ if (node->IsConst()) {
+ const Instance& constant_value =
+ constant_evaluator_.EvaluateExpression(initializer);
+ variable->SetConstValue(constant_value);
+ instructions += Constant(constant_value);
+ } else {
+ instructions += TranslateExpression(initializer);
+ }
+ }
+ instructions += StoreLocal(variable);
+ instructions += Drop();
+ fragment_ = instructions;
+}
+
+
+void FlowGraphBuilder::VisitFunctionDeclaration(FunctionDeclaration* node) {
+ Fragment instructions = TranslateFunctionNode(node->function(), node);
+ instructions += StoreLocal(LookupVariable(node->variable()));
+ instructions += Drop();
+ fragment_ = instructions;
+}
+
+
+void FlowGraphBuilder::VisitIfStatement(IfStatement* node) {
+ bool negate;
+ Fragment instructions = TranslateCondition(node->condition(), &negate);
+ TargetEntryInstr* then_entry;
+ TargetEntryInstr* otherwise_entry;
+ instructions += BranchIfTrue(&then_entry, &otherwise_entry, negate);
+
+ Fragment then_fragment(then_entry);
+ then_fragment += TranslateStatement(node->then());
+
+ Fragment otherwise_fragment(otherwise_entry);
+ otherwise_fragment += TranslateStatement(node->otherwise());
+
+ if (then_fragment.is_open()) {
+ if (otherwise_fragment.is_open()) {
+ JoinEntryInstr* join = BuildJoinEntry();
+ then_fragment += Goto(join);
+ otherwise_fragment += Goto(join);
+ fragment_ = Fragment(instructions.entry, join);
+ } else {
+ fragment_ = Fragment(instructions.entry, then_fragment.current);
+ }
+ } else if (otherwise_fragment.is_open()) {
+ fragment_ = Fragment(instructions.entry, otherwise_fragment.current);
+ } else {
+ fragment_ = instructions.closed();
+ }
+}
+
+
+void FlowGraphBuilder::VisitWhileStatement(WhileStatement* node) {
+ ++loop_depth_;
+ bool negate;
+ Fragment condition = TranslateCondition(node->condition(), &negate);
+ TargetEntryInstr* body_entry;
+ TargetEntryInstr* loop_exit;
+ condition += BranchIfTrue(&body_entry, &loop_exit, negate);
+
+ Fragment body(body_entry);
+ body += TranslateStatement(node->body());
+
+ Instruction* entry;
+ if (body.is_open()) {
+ JoinEntryInstr* join = BuildJoinEntry();
+ body += Goto(join);
+
+ Fragment loop(join);
+ loop += CheckStackOverflow();
+ loop += condition;
+ entry = new (Z) GotoInstr(join);
+ } else {
+ entry = condition.entry;
+ }
+
+
+ fragment_ = Fragment(entry, loop_exit);
+ --loop_depth_;
+}
+
+
+void FlowGraphBuilder::VisitDoStatement(DoStatement* node) {
+ ++loop_depth_;
+ Fragment body = TranslateStatement(node->body());
+
+ if (body.is_closed()) {
+ fragment_ = body;
+ --loop_depth_;
+ return;
+ }
+
+ bool negate;
+ JoinEntryInstr* join = BuildJoinEntry();
+ Fragment loop(join);
+ loop += CheckStackOverflow();
+ loop += body;
+ loop += TranslateCondition(node->condition(), &negate);
+ TargetEntryInstr* loop_repeat;
+ TargetEntryInstr* loop_exit;
+ loop += BranchIfTrue(&loop_repeat, &loop_exit, negate);
+
+ Fragment repeat(loop_repeat);
+ repeat += Goto(join);
+
+ fragment_ = Fragment(new (Z) GotoInstr(join), loop_exit);
+ --loop_depth_;
+}
+
+
+void FlowGraphBuilder::VisitForStatement(ForStatement* node) {
+ Fragment declarations;
+
+ bool new_context = false;
+ declarations += EnterScope(node, &new_context);
+
+ List<VariableDeclaration>& variables = node->variables();
+ for (intptr_t i = 0; i < variables.length(); ++i) {
+ declarations += TranslateStatement(variables[i]);
+ }
+
+ ++loop_depth_;
+ bool negate = false;
+ Fragment condition = node->condition() == NULL
+ ? Constant(Bool::True())
+ : TranslateCondition(node->condition(), &negate);
+ TargetEntryInstr* body_entry;
+ TargetEntryInstr* loop_exit;
+ condition += BranchIfTrue(&body_entry, &loop_exit, negate);
+
+ Fragment body(body_entry);
+ body += TranslateStatement(node->body());
+
+ if (body.is_open()) {
+ // We allocated a fresh context before the loop which contains captured
+ // [ForStatement] variables. Before jumping back to the loop entry we clone
+ // the context object (at same depth) which ensures the next iteration of
+ // the body gets a fresh set of [ForStatement] variables (with the old
+ // (possibly updated) values).
+ if (new_context) body += CloneContext();
+
+ List<Expression>& updates = node->updates();
+ for (intptr_t i = 0; i < updates.length(); ++i) {
+ body += TranslateExpression(updates[i]);
+ body += Drop();
+ }
+ JoinEntryInstr* join = BuildJoinEntry();
+ declarations += Goto(join);
+ body += Goto(join);
+
+ Fragment loop(join);
+ loop += CheckStackOverflow();
+ loop += condition;
+ } else {
+ declarations += condition;
+ }
+
+ Fragment loop(declarations.entry, loop_exit);
+ --loop_depth_;
+
+ loop += ExitScope(node);
+
+ fragment_ = loop;
+}
+
+
+void FlowGraphBuilder::VisitForInStatement(ForInStatement* node) {
+ Fragment instructions = TranslateExpression(node->iterable());
+ instructions += PushArgument();
+
+ const dart::String& iterator_getter = dart::String::ZoneHandle(
+ Z, dart::Field::GetterSymbol(Symbols::Iterator()));
+ instructions += InstanceCall(iterator_getter, Token::kGET, 1);
+ LocalVariable* iterator = scopes_->iterator_variables[for_in_depth_];
+ instructions += StoreLocal(iterator);
+ instructions += Drop();
+
+ ++for_in_depth_;
+ ++loop_depth_;
+ Fragment condition = LoadLocal(iterator);
+ condition += PushArgument();
+ condition += InstanceCall(Symbols::MoveNext(), Token::kILLEGAL, 1);
+ TargetEntryInstr* body_entry;
+ TargetEntryInstr* loop_exit;
+ condition += BranchIfTrue(&body_entry, &loop_exit);
+
+ Fragment body(body_entry);
+ body += EnterScope(node);
+ body += LoadLocal(iterator);
+ body += PushArgument();
+ const dart::String& current_getter = dart::String::ZoneHandle(
+ Z, dart::Field::GetterSymbol(Symbols::Current()));
+ body += InstanceCall(current_getter, Token::kGET, 1);
+ body += StoreLocal(LookupVariable(node->variable()));
+ body += Drop();
+ body += TranslateStatement(node->body());
+ body += ExitScope(node);
+
+ if (body.is_open()) {
+ JoinEntryInstr* join = BuildJoinEntry();
+ instructions += Goto(join);
+ body += Goto(join);
+
+ Fragment loop(join);
+ loop += CheckStackOverflow();
+ loop += condition;
+ } else {
+ instructions += condition;
+ }
+
+ fragment_ = Fragment(instructions.entry, loop_exit);
+ --loop_depth_;
+ --for_in_depth_;
+}
+
+
+void FlowGraphBuilder::VisitLabeledStatement(LabeledStatement* node) {
+ // There can be serveral cases:
+ //
+ // * the body contains a break
+ // * the body doesn't contain a break
+ //
+ // * translating the body results in a closed fragment
+ // * translating the body results in a open fragment
+ //
+ // => We will only know which case we are in after the body has been
+ // traversed.
+
+ BreakableBlock block(this, node);
+ Fragment instructions = TranslateStatement(node->body());
+ if (block.HadJumper()) {
+ if (instructions.is_open()) {
+ instructions += Goto(block.destination());
+ }
+ fragment_ = Fragment(instructions.entry, block.destination());
+ } else {
+ fragment_ = instructions;
+ }
+}
+
+
+void FlowGraphBuilder::VisitBreakStatement(BreakStatement* node) {
+ TryFinallyBlock* outer_finally = NULL;
+ intptr_t target_context_depth = -1;
+ JoinEntryInstr* destination = breakable_block_->BreakDestination(
+ node->target(), &outer_finally, &target_context_depth);
+
+ Fragment instructions;
+ instructions +=
+ TranslateFinallyFinalizers(outer_finally, target_context_depth);
+ if (instructions.is_open()) {
+ instructions += Goto(destination);
+ }
+ fragment_ = instructions;
+}
+
+
+void FlowGraphBuilder::VisitSwitchStatement(SwitchStatement* node) {
+ SwitchBlock block(this, node);
+
+ // Instead of using a variable we should reuse the expression on the stack,
+ // since it won't be assigned again, we don't need phi nodes.
+ Fragment head_instructions = TranslateExpression(node->condition());
+ head_instructions += StoreLocal(scopes_->switch_variable);
+ head_instructions += Drop();
+
+ // Phase 1: Generate bodies and try to find out whether a body will be target
+ // of a jump due to:
+ // * `continue case_label`
+ // * `case e1: case e2: body`
+ Fragment* body_fragments = new Fragment[node->cases().length()];
+
+ intptr_t num_cases = node->cases().length();
+ for (intptr_t i = 0; i < num_cases; i++) {
+ SwitchCase* switch_case = node->cases()[i];
+ Fragment& body_fragment = body_fragments[i] =
+ TranslateStatement(switch_case->body());
+
+ if (body_fragment.entry == NULL) {
+ // Make a NOP in order to ensure linking works properly.
+ body_fragment = NullConstant();
+ body_fragment += Drop();
+ }
+
+ // The Dart language specification mandates fall-throughs in [SwitchCase]es
+ // to be runtime errors.
+ if (!switch_case->is_default() && body_fragment.is_open() &&
+ (i < (node->cases().length() - 1))) {
+ const dart::Class& klass = dart::Class::ZoneHandle(
+ Z, dart::Library::LookupCoreClass(Symbols::FallThroughError()));
+ ASSERT(!klass.IsNull());
+ const dart::Function& constructor = dart::Function::ZoneHandle(
+ Z, klass.LookupConstructorAllowPrivate(
+ H.DartSymbol("FallThroughError._create")));
+ ASSERT(!constructor.IsNull());
+ const dart::String& url = H.DartString(
+ parsed_function_->function().ToLibNamePrefixedQualifiedCString(),
+ Heap::kOld);
+
+ // Create instance of _FallThroughError
+ body_fragment += AllocateObject(klass, 0);
+ LocalVariable* instance = MakeTemporary();
+
+ // Call _AssertionError._create constructor.
+ body_fragment += LoadLocal(instance);
+ body_fragment += PushArgument(); // this
+
+ body_fragment += Constant(url);
+ body_fragment += PushArgument(); // url
+
+ body_fragment += NullConstant();
+ body_fragment += PushArgument(); // line
+
+ body_fragment += StaticCall(constructor, 3);
+ body_fragment += Drop();
+
+ // Throw the exception
+ body_fragment += PushArgument();
+ body_fragment += ThrowException();
+ body_fragment += Drop();
+ }
+
+ // If there is an implicit fall-through we have one [SwitchCase] and
+ // multiple expressions, e.g.
+ //
+ // switch(expr) {
+ // case a:
+ // case b:
+ // <stmt-body>
+ // }
+ //
+ // This means that the <stmt-body> will have more than 1 incoming edge (one
+ // from `a == expr` and one from `a != expr && b == expr`). The
+ // `block.Destination()` records the additional jump.
+ if (switch_case->expressions().length() > 1) {
+ block.Destination(switch_case);
+ }
+ }
+
+ // Phase 2: Generate everything except the real bodies:
+ // * jump directly to a body (if there is no jumper)
+ // * jump to a wrapper block which jumps to the body (if there is a jumper)
+ Fragment current_instructions = head_instructions;
+ for (intptr_t i = 0; i < num_cases; i++) {
+ SwitchCase* switch_case = node->cases()[i];
+
+ if (switch_case->is_default()) {
+ ASSERT(i == (node->cases().length() - 1));
+
+ // Evaluate the conditions for the default [SwitchCase] just for the
+ // purpose of potentially triggering a compile-time error.
+ for (intptr_t k = 0; k < switch_case->expressions().length(); k++) {
+ constant_evaluator_.EvaluateExpression(switch_case->expressions()[k]);
+ }
+
+ if (block.HadJumper(switch_case)) {
+ // There are several branches to the body, so we will make a goto to
+ // the join block (and prepend a join instruction to the real body).
+ JoinEntryInstr* join = block.Destination(switch_case);
+ current_instructions += Goto(join);
+
+ current_instructions = Fragment(current_instructions.entry, join);
+ current_instructions += body_fragments[i];
+ } else {
+ current_instructions += body_fragments[i];
+ }
+ } else {
+ JoinEntryInstr* body_join = NULL;
+ if (block.HadJumper(switch_case)) {
+ body_join = block.Destination(switch_case);
+ body_fragments[i] = Fragment(body_join) + body_fragments[i];
+ }
+
+ for (intptr_t j = 0; j < switch_case->expressions().length(); j++) {
+ TargetEntryInstr* then;
+ TargetEntryInstr* otherwise;
+
+ current_instructions += Constant(constant_evaluator_.EvaluateExpression(
+ switch_case->expressions()[j]));
+ current_instructions += PushArgument();
+ current_instructions += LoadLocal(scopes_->switch_variable);
+ current_instructions += PushArgument();
+ current_instructions +=
+ InstanceCall(Symbols::EqualOperator(), Token::kEQ,
+ /*argument_count=*/2,
+ /*num_args_checked=*/2);
+ current_instructions += BranchIfTrue(&then, &otherwise);
+
+ Fragment then_fragment(then);
+
+ if (body_join != NULL) {
+ // There are several branches to the body, so we will make a goto to
+ // the join block (the real body has already been prepended with a
+ // join instruction).
+ then_fragment += Goto(body_join);
+ } else {
+ // There is only a signle branch to the body, so we will just append
+ // the body fragment.
+ then_fragment += body_fragments[i];
+ }
+
+ current_instructions = Fragment(otherwise);
+ }
+ }
+ }
+
+ bool has_no_default =
+ num_cases > 0 && !node->cases()[num_cases - 1]->is_default();
+ if (has_no_default) {
+ // There is no default, which means we have an open [current_instructions]
+ // (which is a [TargetEntryInstruction] for the last "otherwise" branch).
+ //
+ // Furthermore the last [SwitchCase] can be open as well. If so, we need
+ // to join these two.
+ Fragment& last_body = body_fragments[node->cases().length() - 1];
+ if (last_body.is_open()) {
+ ASSERT(current_instructions.is_open());
+ ASSERT(current_instructions.current->IsTargetEntry());
+
+ // Join the last "otherwise" branch and the last [SwitchCase] fragment.
+ JoinEntryInstr* join = BuildJoinEntry();
+ current_instructions += Goto(join);
+ last_body += Goto(join);
+
+ current_instructions = Fragment(join);
+ }
+ } else {
+ // All non-default cases will be closed (i.e. break/continue/throw/return)
+ // So it is fine to just let more statements after the switch append to the
+ // default case.
+ }
+
+ delete[] body_fragments;
+
+ fragment_ = Fragment(head_instructions.entry, current_instructions.current);
+}
+
+
+void FlowGraphBuilder::VisitContinueSwitchStatement(
+ ContinueSwitchStatement* node) {
+ TryFinallyBlock* outer_finally = NULL;
+ intptr_t target_context_depth = -1;
+ JoinEntryInstr* entry = switch_block_->Destination(
+ node->target(), &outer_finally, &target_context_depth);
+
+ Fragment instructions;
+ instructions +=
+ TranslateFinallyFinalizers(outer_finally, target_context_depth);
+ if (instructions.is_open()) {
+ instructions += Goto(entry);
+ }
+ fragment_ = instructions;
+}
+
+
+void FlowGraphBuilder::VisitAssertStatement(AssertStatement* node) {
+ if (!I->asserts()) {
+ fragment_ = Fragment();
+ return;
+ }
+
+ TargetEntryInstr* then;
+ TargetEntryInstr* otherwise;
+
+ bool negate;
+ Fragment instructions;
+ instructions += TranslateCondition(node->condition(), &negate);
+ instructions += BranchIfTrue(&then, &otherwise, negate);
+
+ const dart::Class& klass = dart::Class::ZoneHandle(
+ Z, dart::Library::LookupCoreClass(Symbols::AssertionError()));
+ ASSERT(!klass.IsNull());
+ const dart::Function& constructor = dart::Function::ZoneHandle(
+ Z, klass.LookupConstructorAllowPrivate(
+ H.DartSymbol("_AssertionError._create")));
+ ASSERT(!constructor.IsNull());
+
+ const dart::String& url = H.DartString(
+ parsed_function_->function().ToLibNamePrefixedQualifiedCString(),
+ Heap::kOld);
+
+ // Create instance of _AssertionError
+ Fragment otherwise_fragment(otherwise);
+ otherwise_fragment += AllocateObject(klass, 0);
+ LocalVariable* instance = MakeTemporary();
+
+ // Call _AssertionError._create constructor.
+ otherwise_fragment += LoadLocal(instance);
+ otherwise_fragment += PushArgument(); // this
+
+ otherwise_fragment +=
+ node->message() != NULL
+ ? TranslateExpression(node->message())
+ : Constant(H.DartString("<no message>", Heap::kOld));
+ otherwise_fragment += PushArgument(); // message
+
+ otherwise_fragment += Constant(url);
+ otherwise_fragment += PushArgument(); // url
+
+ otherwise_fragment += IntConstant(0);
+ otherwise_fragment += PushArgument(); // line
+
+ otherwise_fragment += IntConstant(0);
+ otherwise_fragment += PushArgument(); // column
+
+ otherwise_fragment += StaticCall(constructor, 5);
+ otherwise_fragment += Drop();
+
+ // Throw _AssertionError exception.
+ otherwise_fragment += PushArgument();
+ otherwise_fragment += ThrowException();
+ otherwise_fragment += Drop();
+
+ fragment_ = Fragment(instructions.entry, then);
+}
+
+
+void FlowGraphBuilder::VisitTryFinally(TryFinally* node) {
+ InlineBailout("kernel::FlowgraphBuilder::VisitTryFinally");
+
+ // There are 5 different cases where we need to execute the finally block:
+ //
+ // a) 1/2/3th case: Special control flow going out of `node->body()`:
+ //
+ // * [BreakStatement] transfers control to a [LabledStatement]
+ // * [ContinueSwitchStatement] transfers control to a [SwitchCase]
+ // * [ReturnStatement] returns a value
+ //
+ // => All three cases will automatically append all finally blocks
+ // between the branching point and the destination (so we don't need to
+ // do anything here).
+ //
+ // b) 4th case: Translating the body resulted in an open fragment (i.e. body
+ // executes without any control flow out of it)
+ //
+ // => We are responsible for jumping out of the body to a new block (with
+ // different try index) and execute the finalizer.
+ //
+ // c) 5th case: An exception occured inside the body.
+ //
+ // => We are responsible for catching it, executing the finally block and
+ // rethrowing the exception.
+ intptr_t try_handler_index = AllocateTryIndex();
+ Fragment try_body = TryCatch(try_handler_index);
+ JoinEntryInstr* after_try = BuildJoinEntry();
+
+ // Fill in the body of the try.
+ ++try_depth_;
+ {
+ TryCatchBlock tcb(this, try_handler_index);
+ TryFinallyBlock tfb(this, node->finalizer());
+ try_body += TranslateStatement(node->body());
+ }
+ --try_depth_;
+
+ if (try_body.is_open()) {
+ // Please note: The try index will be on level out of this block,
+ // thereby ensuring if there's an exception in the finally block we
+ // won't run it twice.
+ JoinEntryInstr* finally_entry = BuildJoinEntry();
+
+ try_body += Goto(finally_entry);
+
+ Fragment finally_body(finally_entry);
+ finally_body += TranslateStatement(node->finalizer());
+ finally_body += Goto(after_try);
+ }
+
+ // Fill in the body of the catch.
+ ++catch_depth_;
+ const Array& handler_types = Array::ZoneHandle(Z, Array::New(1, Heap::kOld));
+ handler_types.SetAt(0, Object::dynamic_type());
+ Fragment finally_body = CatchBlockEntry(handler_types, try_handler_index);
+ finally_body += TranslateStatement(node->finalizer());
+ if (finally_body.is_open()) {
+ finally_body += LoadLocal(CurrentException());
+ finally_body += PushArgument();
+ finally_body += LoadLocal(CurrentStackTrace());
+ finally_body += PushArgument();
+ finally_body += RethrowException(try_handler_index);
+ Drop();
+ }
+ --catch_depth_;
+
+ fragment_ = Fragment(try_body.entry, after_try);
+}
+
+
+void FlowGraphBuilder::VisitTryCatch(class TryCatch* node) {
+ InlineBailout("kernel::FlowgraphBuilder::VisitTryCatch");
+
+ intptr_t try_handler_index = AllocateTryIndex();
+ Fragment try_body = TryCatch(try_handler_index);
+ JoinEntryInstr* after_try = BuildJoinEntry();
+
+ // Fill in the body of the try.
+ ++try_depth_;
+ {
+ TryCatchBlock block(this, try_handler_index);
+ try_body += TranslateStatement(node->body());
+ try_body += Goto(after_try);
+ }
+ --try_depth_;
+
+ ++catch_depth_;
+ const Array& handler_types =
+ Array::ZoneHandle(Z, Array::New(node->catches().length(), Heap::kOld));
+ Fragment catch_body = CatchBlockEntry(handler_types, try_handler_index);
+ // Fill in the body of the catch.
+ for (intptr_t i = 0; i < node->catches().length(); i++) {
+ Catch* catch_clause = node->catches()[i];
+
+ Fragment catch_handler_body;
+
+ catch_handler_body += EnterScope(catch_clause);
+
+ if (catch_clause->exception() != NULL) {
+ catch_handler_body += LoadLocal(CurrentException());
+ catch_handler_body +=
+ StoreLocal(LookupVariable(catch_clause->exception()));
+ catch_handler_body += Drop();
+ }
+ if (catch_clause->stack_trace() != NULL) {
+ catch_handler_body += LoadLocal(CurrentStackTrace());
+ catch_handler_body +=
+ StoreLocal(LookupVariable(catch_clause->stack_trace()));
+ catch_handler_body += Drop();
+ }
+ AbstractType* type_guard = NULL;
+ if (catch_clause->guard() != NULL &&
+ !catch_clause->guard()->IsDynamicType()) {
+ type_guard = &T.TranslateType(catch_clause->guard());
+ handler_types.SetAt(i, *type_guard);
+ } else {
+ handler_types.SetAt(i, Object::dynamic_type());
+ }
+
+ {
+ CatchBlock block(this, CurrentException(), CurrentStackTrace(),
+ try_handler_index);
+
+ catch_handler_body += TranslateStatement(catch_clause->body());
+
+ // Note: ExitScope adjusts context_depth_ so even if catch_handler_body
+ // is closed we still need to execute ExitScope for its side effect.
+ catch_handler_body += ExitScope(catch_clause);
+ if (catch_handler_body.is_open()) {
+ catch_handler_body += Goto(after_try);
+ }
+ }
+
+ if (type_guard != NULL) {
+ if (type_guard->IsMalformed()) {
+ catch_body += ThrowTypeError();
+ catch_body += Drop();
+ } else {
+ catch_body += LoadLocal(CurrentException());
+ catch_body += PushArgument(); // exception
+ catch_body += NullConstant();
+ catch_body += PushArgument(); // type arguments
+ catch_body += Constant(*type_guard);
+ catch_body += PushArgument(); // guard type
+ catch_body += Constant(Object::bool_false());
+ catch_body += PushArgument(); // negate
+ catch_body += InstanceCall(
+ dart::Library::PrivateCoreLibName(Symbols::_instanceOf()),
+ Token::kIS, 4);
+
+ TargetEntryInstr* catch_entry;
+ TargetEntryInstr* next_catch_entry;
+ catch_body += BranchIfTrue(&catch_entry, &next_catch_entry);
+
+ Fragment(catch_entry) + catch_handler_body;
+ catch_body = Fragment(next_catch_entry);
+ }
+ } else {
+ catch_body += catch_handler_body;
+ }
+ }
+
+ // In case the last catch body was not handling the exception and branching to
+ // after the try block, we will rethrow the exception (i.e. no default catch
+ // handler).
+ if (catch_body.is_open()) {
+ catch_body += LoadLocal(CurrentException());
+ catch_body += PushArgument();
+ catch_body += LoadLocal(CurrentStackTrace());
+ catch_body += PushArgument();
+ catch_body += RethrowException(try_handler_index);
+ Drop();
+ }
+ --catch_depth_;
+
+ fragment_ = Fragment(try_body.entry, after_try);
+}
+
+
+void FlowGraphBuilder::VisitYieldStatement(YieldStatement* node) {
+ ASSERT(node->is_native()); // Must have been desugared.
+ // Setup yield/continue point:
+ //
+ // ...
+ // :await_jump_var = index;
+ // :await_ctx_var = :current_context_var
+ // return <expr>
+ //
+ // Continuation<index>:
+ // Drop(1)
+ // ...
+ //
+ // BuildGraphOfFunction will create a dispatch that jumps to
+ // Continuation<:await_jump_var> upon entry to the function.
+ //
+ Fragment instructions = IntConstant(yield_continuations_.length() + 1);
+ instructions += StoreLocal(scopes_->yield_jump_variable);
+ instructions += Drop();
+ instructions += LoadLocal(parsed_function_->current_context_var());
+ instructions += StoreLocal(scopes_->yield_context_variable);
+ instructions += Drop();
+ instructions += TranslateExpression(node->expression());
+ instructions += Return();
+
+ // Note: DropTempsInstr serves as an anchor instruction. It will not
+ // be linked into the resulting graph.
+ DropTempsInstr* anchor = new (Z) DropTempsInstr(0, NULL);
+ yield_continuations_.Add(YieldContinuation(anchor, CurrentTryIndex()));
+
+ Fragment continuation(instructions.entry, anchor);
+
+ // TODO(27590): we need a better way to detect if we need to check for an
+ // exception after yield or not.
+ if (parsed_function_->function().NumOptionalPositionalParameters() == 3) {
+ // If function takes three parameters then the second and the third
+ // are exception and stack_trace. Check if exception is non-null
+ // and rethrow it.
+ //
+ // :async_op([:result, :exception, :stack_trace]) {
+ // ...
+ // Continuation<index>:
+ // if (:exception != null) rethrow(:exception, :stack_trace);
+ // ...
+ // }
+ //
+ LocalScope* scope = parsed_function_->node_sequence()->scope();
+ LocalVariable* exception_var = scope->VariableAt(2);
+ LocalVariable* stack_trace_var = scope->VariableAt(3);
+ ASSERT(exception_var->name().raw() == Symbols::ExceptionParameter().raw());
+ ASSERT(stack_trace_var->name().raw() ==
+ Symbols::StackTraceParameter().raw());
+
+ TargetEntryInstr* no_error;
+ TargetEntryInstr* error;
+
+ continuation += LoadLocal(exception_var);
+ continuation += BranchIfNull(&no_error, &error);
+
+ Fragment rethrow(error);
+ rethrow += LoadLocal(exception_var);
+ rethrow += PushArgument();
+ rethrow += LoadLocal(stack_trace_var);
+ rethrow += PushArgument();
+ rethrow += RethrowException(CatchClauseNode::kInvalidTryIndex);
+ Drop();
+
+
+ continuation = Fragment(continuation.entry, no_error);
+ }
+
+ fragment_ = continuation;
+}
+
+
+Fragment FlowGraphBuilder::TranslateFunctionNode(FunctionNode* node,
+ TreeNode* parent) {
+ // The VM has a per-isolate table of functions indexed by the enclosing
+ // function and token position. We don't have token positions, so we've
+ // simply numbered the immediately-nested functions with respect to the
+ // parent.
+ Function& function = Function::ZoneHandle(Z);
+ for (intptr_t i = 0; i < scopes_->function_scopes.length(); ++i) {
+ if (scopes_->function_scopes[i].function != node) continue;
+
+ function = I->LookupClosureFunction(parsed_function_->function(),
+ TokenPosition(i));
+ if (function.IsNull()) {
+ const dart::String* name;
+ if (parent->IsFunctionExpression()) {
+ name = &Symbols::AnonymousClosure();
+ } else {
+ ASSERT(parent->IsFunctionDeclaration());
+ name = &H.DartSymbol(
+ FunctionDeclaration::Cast(parent)->variable()->name());
+ }
+ function = Function::NewClosureFunction(
+ *name, parsed_function_->function(), TokenPosition(i));
+ function.set_is_debuggable(false);
+ LocalScope* scope = scopes_->function_scopes[i].scope;
+ const ContextScope& context_scope =
+ ContextScope::Handle(Z, scope->PreserveOuterScope(context_depth_));
+ function.set_context_scope(context_scope);
+ function.set_kernel_function(node);
+ KernelReader::SetupFunctionParameters(H, T, dart::Class::Handle(Z),
+ function, node,
+ false, // is_method
+ true); // is_closure
+ // Finalize function type.
+ Type& signature_type = Type::Handle(Z, function.SignatureType());
+ signature_type ^= ClassFinalizer::FinalizeType(
+ *active_class_.klass, signature_type, ClassFinalizer::kCanonicalize);
+ function.SetSignatureType(signature_type);
+
+ I->AddClosureFunction(function);
+ }
+ break;
+ }
+
+ const dart::Class& closure_class =
+ dart::Class::ZoneHandle(Z, I->object_store()->closure_class());
+ ASSERT(!closure_class.IsNull());
+ Fragment instructions = AllocateObject(closure_class, function);
+ LocalVariable* closure = MakeTemporary();
+
+ // TODO(27590): Generic closures need type arguments.
+
+ // Store the function and the context in the closure.
+ instructions += LoadLocal(closure);
+ instructions += Constant(function);
+ instructions += StoreInstanceField(Closure::function_offset());
+
+ instructions += LoadLocal(closure);
+ instructions += LoadLocal(parsed_function_->current_context_var());
+ instructions += StoreInstanceField(Closure::context_offset());
+
+ return instructions;
+}
+
+
+} // namespace kernel
+} // namespace dart
diff --git a/runtime/vm/kernel_to_il.h b/runtime/vm/kernel_to_il.h
new file mode 100644
index 0000000..6f50949
--- /dev/null
+++ b/runtime/vm/kernel_to_il.h
@@ -0,0 +1,839 @@
+// 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.
+
+#ifndef VM_KERNEL_TO_IL_H_
+#define VM_KERNEL_TO_IL_H_
+
+#include "vm/growable_array.h"
+#include "vm/hash_map.h"
+
+#include "vm/flow_graph.h"
+#include "vm/flow_graph_builder.h"
+#include "vm/intermediate_language.h"
+#include "vm/kernel.h"
+
+namespace dart {
+namespace kernel {
+
+template <typename K, typename V>
+class Map : public DirectChainedHashMap<RawPointerKeyValueTrait<K, V> > {
+ public:
+ typedef typename RawPointerKeyValueTrait<K, V>::Key Key;
+ typedef typename RawPointerKeyValueTrait<K, V>::Value Value;
+ typedef typename RawPointerKeyValueTrait<K, V>::Pair Pair;
+
+ inline void Insert(const Key& key, const Value& value) {
+ Pair pair(key, value);
+ DirectChainedHashMap<RawPointerKeyValueTrait<K, V> >::Insert(pair);
+ }
+
+ inline V Lookup(const Key& key) {
+ Pair* pair =
+ DirectChainedHashMap<RawPointerKeyValueTrait<K, V> >::Lookup(key);
+ if (pair == NULL) {
+ return V();
+ } else {
+ return pair->value;
+ }
+ }
+};
+
+class BreakableBlock;
+class CatchBlock;
+class FlowGraphBuilder;
+class SwitchBlock;
+class TryCatchBlock;
+class TryFinallyBlock;
+
+class Fragment {
+ public:
+ Instruction* entry;
+ Instruction* current;
+
+ Fragment() : entry(NULL), current(NULL) {}
+
+ explicit Fragment(Instruction* instruction)
+ : entry(instruction), current(instruction) {}
+
+ Fragment(Instruction* entry, Instruction* current)
+ : entry(entry), current(current) {}
+
+ bool is_open() { return entry == NULL || current != NULL; }
+ bool is_closed() { return !is_open(); }
+
+ Fragment& operator+=(const Fragment& other);
+ Fragment& operator<<=(Instruction* next);
+
+ Fragment closed();
+};
+
+Fragment operator+(const Fragment& first, const Fragment& second);
+Fragment operator<<(const Fragment& fragment, Instruction* next);
+
+typedef ZoneGrowableArray<PushArgumentInstr*>* ArgumentArray;
+
+
+class ActiveClass {
+ public:
+ ActiveClass()
+ : kernel_class(NULL), klass(NULL), member(NULL), kernel_function(NULL) {}
+
+ // The current enclosing kernel class (if available, otherwise NULL).
+ Class* kernel_class;
+
+ // The current enclosing class (or the library top-level class). When this is
+ // a library's top-level class, the kernel_class will be NULL.
+ const dart::Class* klass;
+
+ // The enclosing member (e.g., Constructor, Procedure, or Field) if there
+ // is one.
+ Member* member;
+
+ // The current function.
+ FunctionNode* kernel_function;
+};
+
+
+class ActiveClassScope {
+ public:
+ ActiveClassScope(ActiveClass* active_class, Class* kernel_class,
+ const dart::Class* klass)
+ : active_class_(active_class), saved_(*active_class) {
+ active_class_->kernel_class = kernel_class;
+ active_class_->klass = klass;
+ active_class_->member = NULL;
+ active_class_->kernel_function = NULL;
+ }
+
+ ~ActiveClassScope() { *active_class_ = saved_; }
+
+ private:
+ ActiveClass* active_class_;
+ ActiveClass saved_;
+};
+
+
+class ActiveMemberScope {
+ public:
+ ActiveMemberScope(ActiveClass* active_class, Member* member)
+ : active_class_(active_class), saved_(*active_class) {
+ // The class and kernel_class is inherited.
+ active_class_->member = member;
+ active_class_->kernel_function = NULL;
+ }
+
+ ~ActiveMemberScope() { *active_class_ = saved_; }
+
+ private:
+ ActiveClass* active_class_;
+ ActiveClass saved_;
+};
+
+
+class ActiveFunctionScope {
+ public:
+ ActiveFunctionScope(ActiveClass* active_class, FunctionNode* kernel_function)
+ : active_class_(active_class), saved_(*active_class) {
+ // The class, kernel_class, and member are inherited.
+ active_class_->kernel_function = kernel_function;
+ }
+
+ ~ActiveFunctionScope() { *active_class_ = saved_; }
+
+ private:
+ ActiveClass* active_class_;
+ ActiveClass saved_;
+};
+
+
+class TranslationHelper {
+ public:
+ TranslationHelper(dart::Thread* thread, dart::Zone* zone, Isolate* isolate)
+ : thread_(thread), zone_(zone), isolate_(isolate) {}
+ virtual ~TranslationHelper() {}
+
+ Thread* thread() { return thread_; }
+
+ Zone* zone() { return zone_; }
+
+ Isolate* isolate() { return isolate_; }
+
+ // Set whether unfinalized classes should be finalized. The base class
+ // implementation used at flow graph construction time looks up classes in the
+ // VM's heap, all of which should already be finalized.
+ virtual void SetFinalize(bool finalize) {}
+
+ RawInstance* Canonicalize(const Instance& instance);
+
+ const dart::String& DartString(const char* content,
+ Heap::Space space = Heap::kNew);
+ dart::String& DartString(String* content, Heap::Space space = Heap::kNew);
+ const dart::String& DartSymbol(const char* content) const;
+ dart::String& DartSymbol(String* content) const;
+
+ const dart::String& DartClassName(Class* kernel_klass);
+ const dart::String& DartConstructorName(Constructor* node);
+ const dart::String& DartProcedureName(Procedure* procedure);
+
+ const dart::String& DartSetterName(Name* kernel_name);
+ const dart::String& DartGetterName(Name* kernel_name);
+ const dart::String& DartFieldName(Name* kernel_name);
+ const dart::String& DartInitializerName(Name* kernel_name);
+ const dart::String& DartMethodName(Name* kernel_name);
+ const dart::String& DartFactoryName(Class* klass, Name* kernel_name);
+
+ const Array& ArgumentNames(List<NamedExpression>* named);
+
+ // A subclass overrides these when reading in the Kernel program in order to
+ // support recursive type expressions (e.g. for "implements X" ...
+ // annotations).
+ virtual RawLibrary* LookupLibraryByKernelLibrary(Library* library);
+ virtual RawClass* LookupClassByKernelClass(Class* klass);
+
+ RawField* LookupFieldByKernelField(Field* field);
+ RawFunction* LookupStaticMethodByKernelProcedure(Procedure* procedure);
+ RawFunction* LookupConstructorByKernelConstructor(Constructor* constructor);
+ dart::RawFunction* LookupConstructorByKernelConstructor(
+ const dart::Class& owner, Constructor* constructor);
+
+ dart::Type& GetCanonicalType(const dart::Class& klass);
+
+ void ReportError(const char* format, ...);
+ void ReportError(const Error& prev_error, const char* format, ...);
+
+ private:
+ // This will mangle [kernel_name] (if necessary) and make the result a symbol.
+ // The result will be avilable in [name_to_modify] and it is also returned.
+ dart::String& ManglePrivateName(Library* kernel_library,
+ dart::String* name_to_modify,
+ bool symbolize = true);
+
+ dart::Thread* thread_;
+ dart::Zone* zone_;
+ dart::Isolate* isolate_;
+};
+
+// Regarding malformed types:
+// The spec says in section "19.1 Static Types" roughly:
+//
+// A type T is malformed iff:
+// * T does not denote a type in scope
+// * T refers to a type parameter in a static member
+// * T is a parametrized Type G<T1, ...> and G is malformed
+// * T denotes declarations from multiple imports
+//
+// Any use of a malformed type gives rise to a static warning. A malformed
+// type is then interpreted as dynamic by the static type checker and the
+// runtime unless explicitly specified otherwise.
+class DartTypeTranslator : public DartTypeVisitor {
+ public:
+ DartTypeTranslator(TranslationHelper* helper, ActiveClass* active_class,
+ bool finalize = true)
+ : translation_helper_(*helper),
+ active_class_(active_class),
+ zone_(helper->zone()),
+ result_(AbstractType::Handle(helper->zone())),
+ finalize_(finalize) {}
+
+ // Can return a malformed type.
+ AbstractType& TranslateType(DartType* node);
+
+ // Can return a malformed type.
+ AbstractType& TranslateTypeWithoutFinalization(DartType* node);
+
+
+ virtual void VisitDefaultDartType(DartType* node) { UNREACHABLE(); }
+
+ virtual void VisitInvalidType(InvalidType* node);
+
+ virtual void VisitFunctionType(FunctionType* node);
+
+ virtual void VisitTypeParameterType(TypeParameterType* node);
+
+ virtual void VisitInterfaceType(InterfaceType* node);
+
+ virtual void VisitDynamicType(DynamicType* node);
+
+ virtual void VisitVoidType(VoidType* node);
+
+ // Will return `TypeArguments::null()` in case any of the arguments are
+ // malformed.
+ const TypeArguments& TranslateInstantiatedTypeArguments(
+ const dart::Class& receiver_class, DartType** receiver_type_arguments,
+ intptr_t length);
+
+ // Will return `TypeArguments::null()` in case any of the arguments are
+ // malformed.
+ const TypeArguments& TranslateTypeArguments(DartType** dart_types,
+ intptr_t length);
+
+ const Type& ReceiverType(const dart::Class& klass);
+
+ private:
+ TranslationHelper& translation_helper_;
+ ActiveClass* active_class_;
+ Zone* zone_;
+ AbstractType& result_;
+
+ bool finalize_;
+};
+
+
+// There are several cases when we are compiling constant expressions:
+//
+// * constant field initializers:
+// const FieldName = <expr>;
+//
+// * constant expressions:
+// const [<expr>, ...]
+// const {<expr> : <expr>, ...}
+// const Constructor(<expr>, ...)
+//
+// * constant default parameters:
+// f(a, [b = <expr>])
+// f(a, {b: <expr>})
+//
+// * constant values to compare in a [SwitchCase]
+// case <expr>:
+//
+// In all cases `<expr>` must be recursively evaluated and canonicalized at
+// compile-time.
+class ConstantEvaluator : public ExpressionVisitor {
+ public:
+ ConstantEvaluator(FlowGraphBuilder* builder, Zone* zone, TranslationHelper* h,
+ DartTypeTranslator* type_translator)
+ : builder_(builder),
+ isolate_(Isolate::Current()),
+ zone_(zone),
+ translation_helper_(*h),
+ type_translator_(*type_translator),
+ result_(dart::Instance::Handle(zone)) {}
+ virtual ~ConstantEvaluator() {}
+
+ Instance& EvaluateExpression(Expression* node);
+ Object& EvaluateExpressionSafe(Expression* node);
+ Instance& EvaluateConstructorInvocation(ConstructorInvocation* node);
+ Instance& EvaluateListLiteral(ListLiteral* node);
+ Instance& EvaluateMapLiteral(MapLiteral* node);
+
+ virtual void VisitDefaultExpression(Expression* node) { UNREACHABLE(); }
+
+ virtual void VisitBigintLiteral(BigintLiteral* node);
+ virtual void VisitBoolLiteral(BoolLiteral* node);
+ virtual void VisitDoubleLiteral(DoubleLiteral* node);
+ virtual void VisitIntLiteral(IntLiteral* node);
+ virtual void VisitNullLiteral(NullLiteral* node);
+ virtual void VisitStringLiteral(StringLiteral* node);
+ virtual void VisitSymbolLiteral(SymbolLiteral* node);
+ virtual void VisitTypeLiteral(TypeLiteral* node);
+
+ virtual void VisitListLiteral(ListLiteral* node);
+ virtual void VisitMapLiteral(MapLiteral* node);
+
+ virtual void VisitConstructorInvocation(ConstructorInvocation* node);
+ virtual void VisitMethodInvocation(MethodInvocation* node);
+ virtual void VisitStaticGet(StaticGet* node);
+ virtual void VisitVariableGet(VariableGet* node);
+ virtual void VisitLet(Let* node);
+ virtual void VisitStaticInvocation(StaticInvocation* node);
+ virtual void VisitStringConcatenation(StringConcatenation* node);
+ virtual void VisitConditionalExpression(ConditionalExpression* node);
+ virtual void VisitLogicalExpression(LogicalExpression* node);
+ virtual void VisitNot(Not* node);
+
+ private:
+ // This will translate type arguments form [kernel_arguments]. If no type
+ // arguments are passed and the [target] is a factory then the null type
+ // argument array will be returned.
+ //
+ // If none of these cases apply, NULL will be returned.
+ const TypeArguments* TranslateTypeArguments(const Function& target,
+ dart::Class* target_klass,
+ Arguments* kernel_arguments);
+
+ const Object& RunFunction(const Function& function, Arguments* arguments,
+ const Instance* receiver = NULL,
+ const TypeArguments* type_args = NULL);
+
+ const Object& RunFunction(const Function& function, const Array& arguments,
+ const Array& names);
+
+ RawObject* EvaluateConstConstructorCall(const dart::Class& type_class,
+ const TypeArguments& type_arguments,
+ const Function& constructor,
+ const Object& argument);
+
+ FlowGraphBuilder* builder_;
+ Isolate* isolate_;
+ Zone* zone_;
+ TranslationHelper& translation_helper_;
+ DartTypeTranslator& type_translator_;
+
+ Instance& result_;
+};
+
+
+struct FunctionScope {
+ FunctionNode* function;
+ LocalScope* scope;
+};
+
+
+class ScopeBuildingResult : public ZoneAllocated {
+ public:
+ ScopeBuildingResult()
+ : this_variable(NULL),
+ type_arguments_variable(NULL),
+ switch_variable(NULL),
+ finally_return_variable(NULL),
+ setter_value(NULL),
+ yield_jump_variable(NULL),
+ yield_context_variable(NULL) {}
+
+ Map<VariableDeclaration, LocalVariable*> locals;
+ Map<TreeNode, LocalScope*> scopes;
+ GrowableArray<FunctionScope> function_scopes;
+
+ // Only non-NULL for instance functions.
+ LocalVariable* this_variable;
+
+ // Only non-NULL for factory constructor functions.
+ LocalVariable* type_arguments_variable;
+
+ // Non-NULL when the function contains a switch statement.
+ LocalVariable* switch_variable;
+
+ // Non-NULL when the function contains a return inside a finally block.
+ LocalVariable* finally_return_variable;
+
+ // Non-NULL when the function is a setter.
+ LocalVariable* setter_value;
+
+ // Non-NULL if the function contains yield statement.
+ // TODO(27590) actual variable is called :await_jump_var, we should rename
+ // it to reflect the fact that it is used for both await and yield.
+ LocalVariable* yield_jump_variable;
+
+ // Non-NULL if the function contains yield statement.
+ // TODO(27590) actual variable is called :await_ctx_var, we should rename
+ // it to reflect the fact that it is used for both await and yield.
+ LocalVariable* yield_context_variable;
+
+ // Variables used in exception handlers, one per exception handler nesting
+ // level.
+ GrowableArray<LocalVariable*> exception_variables;
+ GrowableArray<LocalVariable*> stack_trace_variables;
+ GrowableArray<LocalVariable*> catch_context_variables;
+
+ // For-in iterators, one per for-in nesting level.
+ GrowableArray<LocalVariable*> iterator_variables;
+};
+
+
+class ScopeBuilder : public RecursiveVisitor {
+ public:
+ ScopeBuilder(ParsedFunction* parsed_function, TreeNode* node)
+ : result_(NULL),
+ parsed_function_(parsed_function),
+ node_(node),
+ zone_(Thread::Current()->zone()),
+ translation_helper_(Thread::Current(), zone_, Isolate::Current()),
+ current_function_scope_(NULL),
+ scope_(NULL),
+ depth_(0),
+ name_index_(0) {}
+
+ virtual ~ScopeBuilder() {}
+
+ ScopeBuildingResult* BuildScopes();
+
+ virtual void VisitName(Name* node) { /* NOP */
+ }
+
+ virtual void VisitThisExpression(ThisExpression* node);
+ virtual void VisitTypeParameterType(TypeParameterType* node);
+ virtual void VisitVariableGet(VariableGet* node);
+ virtual void VisitVariableSet(VariableSet* node);
+ virtual void VisitFunctionExpression(FunctionExpression* node);
+ virtual void VisitLet(Let* node);
+ virtual void VisitBlock(Block* node);
+ virtual void VisitVariableDeclaration(VariableDeclaration* node);
+ virtual void VisitFunctionDeclaration(FunctionDeclaration* node);
+ virtual void VisitWhileStatement(WhileStatement* node);
+ virtual void VisitDoStatement(DoStatement* node);
+ virtual void VisitForStatement(ForStatement* node);
+ virtual void VisitForInStatement(ForInStatement* node);
+ virtual void VisitSwitchStatement(SwitchStatement* node);
+ virtual void VisitReturnStatement(ReturnStatement* node);
+ virtual void VisitTryCatch(TryCatch* node);
+ virtual void VisitTryFinally(TryFinally* node);
+ virtual void VisitYieldStatement(YieldStatement* node);
+ virtual void VisitAssertStatement(AssertStatement* node);
+
+ virtual void VisitFunctionNode(FunctionNode* node);
+
+ virtual void VisitConstructor(Constructor* node);
+
+ private:
+ void EnterScope(TreeNode* node);
+ void ExitScope();
+
+ LocalVariable* MakeVariable(const dart::String& name);
+ LocalVariable* MakeVariable(const dart::String& name, const Type& type);
+
+ void AddParameters(FunctionNode* function, intptr_t pos = 0);
+ void AddParameter(VariableDeclaration* declaration, intptr_t pos);
+ void AddVariable(VariableDeclaration* declaration);
+ void AddExceptionVariable(GrowableArray<LocalVariable*>* variables,
+ const char* prefix, intptr_t nesting_depth);
+ void AddTryVariables();
+ void AddCatchVariables();
+ void AddIteratorVariable();
+ void AddSwitchVariable();
+
+ // Record an assignment or reference to a variable. If the occurrence is
+ // in a nested function, ensure that the variable is handled properly as a
+ // captured variable.
+ void LookupVariable(VariableDeclaration* declaration);
+
+ const dart::String& GenerateName(const char* prefix, intptr_t suffix);
+
+ void HandleLocalFunction(TreeNode* parent, FunctionNode* function);
+ void HandleSpecialLoad(LocalVariable** variable, const dart::String& symbol);
+ void LookupCapturedVariableByName(LocalVariable** variable,
+ const dart::String& name);
+
+
+ struct DepthState {
+ explicit DepthState(intptr_t function)
+ : loop_(0),
+ function_(function),
+ try_(0),
+ catch_(0),
+ finally_(0),
+ for_in_(0) {}
+
+ intptr_t loop_;
+ intptr_t function_;
+ intptr_t try_;
+ intptr_t catch_;
+ intptr_t finally_;
+ intptr_t for_in_;
+ };
+
+ ScopeBuildingResult* result_;
+ ParsedFunction* parsed_function_;
+ TreeNode* node_;
+
+ Zone* zone_;
+ TranslationHelper translation_helper_;
+
+
+ FunctionNode* current_function_node_;
+ LocalScope* current_function_scope_;
+ LocalScope* scope_;
+ DepthState depth_;
+
+ intptr_t name_index_;
+};
+
+
+class FlowGraphBuilder : public TreeVisitor {
+ public:
+ FlowGraphBuilder(TreeNode* node, ParsedFunction* parsed_function,
+ const ZoneGrowableArray<const ICData*>& ic_data_array,
+ InlineExitCollector* exit_collector, intptr_t osr_id,
+ intptr_t first_block_id = 1);
+ virtual ~FlowGraphBuilder();
+
+ FlowGraph* BuildGraph();
+
+ virtual void VisitDefaultTreeNode(TreeNode* node) { UNREACHABLE(); }
+
+ virtual void VisitInvalidExpression(InvalidExpression* node);
+ virtual void VisitNullLiteral(NullLiteral* node);
+ virtual void VisitBoolLiteral(BoolLiteral* node);
+ virtual void VisitIntLiteral(IntLiteral* node);
+ virtual void VisitBigintLiteral(BigintLiteral* node);
+ virtual void VisitDoubleLiteral(DoubleLiteral* node);
+ virtual void VisitStringLiteral(StringLiteral* node);
+ virtual void VisitSymbolLiteral(SymbolLiteral* node);
+ virtual void VisitTypeLiteral(TypeLiteral* node);
+ virtual void VisitVariableGet(VariableGet* node);
+ virtual void VisitVariableSet(VariableSet* node);
+ virtual void VisitStaticGet(StaticGet* node);
+ virtual void VisitStaticSet(StaticSet* node);
+ virtual void VisitPropertyGet(PropertyGet* node);
+ virtual void VisitPropertySet(PropertySet* node);
+ virtual void VisitDirectPropertyGet(DirectPropertyGet* node);
+ virtual void VisitDirectPropertySet(DirectPropertySet* node);
+ virtual void VisitStaticInvocation(StaticInvocation* node);
+ virtual void VisitMethodInvocation(MethodInvocation* node);
+ virtual void VisitDirectMethodInvocation(DirectMethodInvocation* node);
+ virtual void VisitConstructorInvocation(ConstructorInvocation* node);
+ virtual void VisitIsExpression(IsExpression* node);
+ virtual void VisitAsExpression(AsExpression* node);
+ virtual void VisitConditionalExpression(ConditionalExpression* node);
+ virtual void VisitLogicalExpression(LogicalExpression* node);
+ virtual void VisitNot(Not* node);
+ virtual void VisitThisExpression(ThisExpression* node);
+ virtual void VisitStringConcatenation(StringConcatenation* node);
+ virtual void VisitListLiteral(ListLiteral* node);
+ virtual void VisitMapLiteral(MapLiteral* node);
+ virtual void VisitFunctionExpression(FunctionExpression* node);
+ virtual void VisitLet(Let* node);
+ virtual void VisitThrow(Throw* node);
+ virtual void VisitRethrow(Rethrow* node);
+ virtual void VisitBlockExpression(BlockExpression* node);
+
+ virtual void VisitInvalidStatement(InvalidStatement* node);
+ virtual void VisitEmptyStatement(EmptyStatement* node);
+ virtual void VisitBlock(Block* node);
+ virtual void VisitReturnStatement(ReturnStatement* node);
+ virtual void VisitExpressionStatement(ExpressionStatement* node);
+ virtual void VisitVariableDeclaration(VariableDeclaration* node);
+ virtual void VisitFunctionDeclaration(FunctionDeclaration* node);
+ virtual void VisitIfStatement(IfStatement* node);
+ virtual void VisitWhileStatement(WhileStatement* node);
+ virtual void VisitDoStatement(DoStatement* node);
+ virtual void VisitForStatement(ForStatement* node);
+ virtual void VisitForInStatement(ForInStatement* node);
+ virtual void VisitLabeledStatement(LabeledStatement* node);
+ virtual void VisitBreakStatement(BreakStatement* node);
+ virtual void VisitSwitchStatement(SwitchStatement* node);
+ virtual void VisitContinueSwitchStatement(ContinueSwitchStatement* node);
+ virtual void VisitAssertStatement(AssertStatement* node);
+ virtual void VisitTryFinally(TryFinally* node);
+ virtual void VisitTryCatch(TryCatch* node);
+ virtual void VisitYieldStatement(YieldStatement* node);
+
+ private:
+ FlowGraph* BuildGraphOfFunction(FunctionNode* node,
+ Constructor* constructor = NULL);
+ FlowGraph* BuildGraphOfFieldAccessor(Field* node,
+ LocalVariable* setter_value);
+ FlowGraph* BuildGraphOfStaticFieldInitializer(Field* node);
+ FlowGraph* BuildGraphOfMethodExtractor(const Function& method);
+ FlowGraph* BuildGraphOfImplicitClosureFunction(FunctionNode* kernel_function,
+ const Function& function);
+ FlowGraph* BuildGraphOfNoSuchMethodDispatcher(const Function& function);
+ FlowGraph* BuildGraphOfInvokeFieldDispatcher(const Function& function);
+
+ Fragment NativeFunctionBody(FunctionNode* kernel_function,
+ const Function& function);
+
+ void SetupDefaultParameterValues(FunctionNode* function);
+
+ TargetEntryInstr* BuildTargetEntry();
+ JoinEntryInstr* BuildJoinEntry();
+
+ Fragment TranslateArguments(Arguments* node, Array* argument_names);
+ ArgumentArray GetArguments(int count);
+
+ Fragment TranslateInitializers(Class* kernel_klass,
+ List<Initializer>* initialiers);
+
+ Fragment TranslateStatement(Statement* statement);
+ Fragment TranslateCondition(Expression* expression, bool* negate);
+ Fragment TranslateExpression(Expression* expression);
+
+ Fragment TranslateFinallyFinalizers(TryFinallyBlock* outer_finally,
+ intptr_t target_context_depth);
+
+ Fragment TranslateFunctionNode(FunctionNode* node, TreeNode* parent);
+
+ Fragment EnterScope(TreeNode* node, bool* new_context = NULL);
+ Fragment ExitScope(TreeNode* node);
+
+ Fragment LoadContextAt(int depth);
+ Fragment AdjustContextTo(int depth);
+
+ Fragment PushContext(int size);
+ Fragment PopContext();
+
+ Fragment LoadInstantiatorTypeArguments();
+ Fragment InstantiateTypeArguments(const TypeArguments& type_arguments);
+ Fragment TranslateInstantiatedTypeArguments(
+ const TypeArguments& type_arguments);
+
+ Fragment AllocateContext(int size);
+ Fragment AllocateObject(const dart::Class& klass, intptr_t argument_count);
+ Fragment AllocateObject(const dart::Class& klass,
+ const Function& closure_function);
+ Fragment BooleanNegate();
+ Fragment StrictCompare(Token::Kind kind, bool number_check = false);
+ Fragment BranchIfTrue(TargetEntryInstr** then_entry,
+ TargetEntryInstr** otherwise_entry,
+ bool negate = false);
+ Fragment BranchIfNull(TargetEntryInstr** then_entry,
+ TargetEntryInstr** otherwise_entry,
+ bool negate = false);
+ Fragment BranchIfEqual(TargetEntryInstr** then_entry,
+ TargetEntryInstr** otherwise_entry,
+ bool negate = false);
+ Fragment BranchIfStrictEqual(TargetEntryInstr** then_entry,
+ TargetEntryInstr** otherwise_entry);
+ Fragment CatchBlockEntry(const Array& handler_types, intptr_t handler_index);
+ Fragment TryCatch(int try_handler_index);
+ Fragment CheckStackOverflowInPrologue();
+ Fragment CheckStackOverflow();
+ Fragment CloneContext();
+ Fragment Constant(const Object& value);
+ Fragment CreateArray();
+ Fragment Goto(JoinEntryInstr* destination);
+ Fragment IntConstant(int64_t value);
+ Fragment InstanceCall(const dart::String& name, Token::Kind kind,
+ intptr_t argument_count, intptr_t num_args_checked = 1);
+ Fragment InstanceCall(const dart::String& name, Token::Kind kind,
+ intptr_t argument_count, const Array& argument_names,
+ intptr_t num_args_checked = 1);
+ Fragment ClosureCall(int argument_count, const Array& argument_names);
+ Fragment ThrowException();
+ Fragment RethrowException(int catch_try_index);
+ Fragment LoadClassId();
+ Fragment LoadField(const dart::Field& field);
+ Fragment LoadField(intptr_t offset, intptr_t class_id = kDynamicCid);
+ Fragment LoadNativeField(MethodRecognizer::Kind kind, intptr_t offset,
+ const Type& type, intptr_t class_id,
+ bool is_immutable = false);
+ Fragment LoadLocal(LocalVariable* variable);
+ Fragment InitStaticField(const dart::Field& field);
+ Fragment LoadStaticField();
+ Fragment NullConstant();
+ Fragment NativeCall(const dart::String* name, const Function* function);
+ Fragment PushArgument();
+ Fragment Return();
+ Fragment StaticCall(const Function& target, intptr_t argument_count);
+ Fragment StaticCall(const Function& target, intptr_t argument_count,
+ const Array& argument_names);
+ Fragment StoreIndexed(intptr_t class_id);
+ Fragment StoreInstanceField(const dart::Field& field);
+ Fragment StoreInstanceField(intptr_t offset);
+ Fragment StoreLocal(LocalVariable* variable);
+ Fragment StoreStaticField(const dart::Field& field);
+ Fragment StringInterpolate();
+ Fragment ThrowTypeError();
+ Fragment ThrowNoSuchMethodError();
+ Fragment BuildImplicitClosureCreation(const Function& target);
+
+ dart::RawFunction* LookupMethodByMember(Member* target,
+ const dart::String& method_name);
+
+ LocalVariable* MakeTemporary();
+ LocalVariable* MakeNonTemporary(const dart::String& symbol);
+
+ intptr_t CurrentTryIndex();
+ intptr_t AllocateTryIndex() { return next_used_try_index_++; }
+
+ void AddVariable(VariableDeclaration* declaration, LocalVariable* variable);
+ void AddParameter(VariableDeclaration* declaration, LocalVariable* variable,
+ intptr_t pos);
+ dart::LocalVariable* LookupVariable(VariableDeclaration* var);
+
+ void SetTempIndex(Definition* definition);
+
+ void Push(Definition* definition);
+ Value* Pop();
+ Fragment Drop();
+
+ bool IsInlining() { return exit_collector_ != NULL; }
+
+ Token::Kind MethodKind(const dart::String& name);
+
+ void InlineBailout(const char* reason);
+
+ Zone* zone_;
+ TranslationHelper translation_helper_;
+
+ // The node we are currently compiling (e.g. FunctionNode, Constructor,
+ // Field)
+ TreeNode* node_;
+
+ ParsedFunction* parsed_function_;
+ intptr_t osr_id_;
+ const ZoneGrowableArray<const ICData*>& ic_data_array_;
+ InlineExitCollector* exit_collector_;
+
+ intptr_t next_block_id_;
+ intptr_t AllocateBlockId() { return next_block_id_++; }
+
+ intptr_t next_function_id_;
+ intptr_t AllocateFunctionId() { return next_function_id_++; }
+
+ intptr_t context_depth_;
+ intptr_t loop_depth_;
+ intptr_t try_depth_;
+ intptr_t catch_depth_;
+ intptr_t for_in_depth_;
+ Fragment fragment_;
+ Value* stack_;
+ intptr_t pending_argument_count_;
+
+ GraphEntryInstr* graph_entry_;
+
+ ScopeBuildingResult* scopes_;
+
+ struct YieldContinuation {
+ Instruction* entry;
+ intptr_t try_index;
+
+ YieldContinuation(Instruction* entry, intptr_t try_index)
+ : entry(entry), try_index(try_index) {}
+
+ YieldContinuation()
+ : entry(NULL), try_index(CatchClauseNode::kInvalidTryIndex) {}
+ };
+
+ GrowableArray<YieldContinuation> yield_continuations_;
+
+ LocalVariable* CurrentException() {
+ return scopes_->exception_variables[catch_depth_ - 1];
+ }
+ LocalVariable* CurrentStackTrace() {
+ return scopes_->stack_trace_variables[catch_depth_ - 1];
+ }
+ LocalVariable* CurrentCatchContext() {
+ return scopes_->catch_context_variables[try_depth_];
+ }
+
+ // A chained list of breakable blocks. Chaining and lookup is done by the
+ // [BreakableBlock] class.
+ BreakableBlock* breakable_block_;
+
+ // A chained list of switch blocks. Chaining and lookup is done by the
+ // [SwitchBlock] class.
+ SwitchBlock* switch_block_;
+
+ // A chained list of try-finally blocks. Chaining and lookup is done by the
+ // [TryFinallyBlock] class.
+ TryFinallyBlock* try_finally_block_;
+
+ // A chained list of try-catch blocks. Chaining and lookup is done by the
+ // [TryCatchBlock] class.
+ TryCatchBlock* try_catch_block_;
+ intptr_t next_used_try_index_;
+
+ // A chained list of catch blocks. Chaining and lookup is done by the
+ // [CatchBlock] class.
+ CatchBlock* catch_block_;
+
+ ActiveClass active_class_;
+ DartTypeTranslator type_translator_;
+ ConstantEvaluator constant_evaluator_;
+
+ friend class BreakableBlock;
+ friend class CatchBlock;
+ friend class ConstantEvaluator;
+ friend class DartTypeTranslator;
+ friend class ScopeBuilder;
+ friend class SwitchBlock;
+ friend class TryCatchBlock;
+ friend class TryFinallyBlock;
+};
+
+} // namespace kernel
+} // namespace dart
+
+
+#endif // VM_KERNEL_TO_IL_H_
diff --git a/runtime/vm/lockers.cc b/runtime/vm/lockers.cc
index b8ac4b6..39733da 100644
--- a/runtime/vm/lockers.cc
+++ b/runtime/vm/lockers.cc
@@ -29,6 +29,7 @@
Monitor::WaitResult MonitorLocker::WaitWithSafepointCheck(Thread* thread,
int64_t millis) {
ASSERT(thread == Thread::Current());
+ ASSERT(thread->execution_state() == Thread::kThreadInVM);
thread->set_execution_state(Thread::kThreadInBlockedState);
thread->EnterSafepoint();
Monitor::WaitResult result = monitor_->Wait(millis);
diff --git a/runtime/vm/native_arguments.h b/runtime/vm/native_arguments.h
index 77c67ed..2f94d8f 100644
--- a/runtime/vm/native_arguments.h
+++ b/runtime/vm/native_arguments.h
@@ -44,10 +44,11 @@
}
#endif
+void VerifyOnTransition();
+
#define VERIFY_ON_TRANSITION \
if (FLAG_verify_on_transition) { \
- VerifyPointersVisitor::VerifyPointers(); \
- Isolate::Current()->heap()->Verify(); \
+ VerifyOnTransition(); \
}
#define DEOPTIMIZE_ALOT \
if (FLAG_deoptimize_alot) { \
@@ -142,6 +143,8 @@
}
RawObject* ReturnValue() const {
+ // Tell MemorySanitizer the retval_ was initialized (by generated code).
+ MSAN_UNPOISON(retval_, kWordSize);
return *retval_;
}
diff --git a/runtime/vm/native_entry.cc b/runtime/vm/native_entry.cc
index e1e7e45..e56bfa8 100644
--- a/runtime/vm/native_entry.cc
+++ b/runtime/vm/native_entry.cc
@@ -10,6 +10,7 @@
#include "vm/code_patcher.h"
#include "vm/dart_api_impl.h"
#include "vm/dart_api_state.h"
+#include "vm/native_symbol.h"
#include "vm/object_store.h"
#include "vm/reusable_handles.h"
#include "vm/safepoint.h"
@@ -132,6 +133,7 @@
/* Tell MemorySanitizer 'arguments' is initialized by generated code. */
MSAN_UNPOISON(arguments, sizeof(*arguments));
Thread* thread = arguments->thread();
+ ASSERT(thread->execution_state() == Thread::kThreadInGenerated);
if (!arguments->IsNativeAutoSetupScope()) {
TransitionGeneratedToNative transition(thread);
func(args);
@@ -173,8 +175,9 @@
delete scope;
}
DEOPTIMIZE_ALOT;
- VERIFY_ON_TRANSITION;
}
+ ASSERT(thread->execution_state() == Thread::kThreadInGenerated);
+ VERIFY_ON_TRANSITION;
}
diff --git a/runtime/vm/native_symbol_linux.cc b/runtime/vm/native_symbol_linux.cc
index a903938..120ef9a 100644
--- a/runtime/vm/native_symbol_linux.cc
+++ b/runtime/vm/native_symbol_linux.cc
@@ -5,6 +5,7 @@
#include "vm/globals.h"
#if defined(TARGET_OS_LINUX)
+#include "platform/memory_sanitizer.h"
#include "vm/native_symbol.h"
#include <cxxabi.h> // NOLINT
@@ -32,8 +33,10 @@
if (start != NULL) {
*start = reinterpret_cast<uintptr_t>(info.dli_saddr);
}
- int status;
- char* demangled = abi::__cxa_demangle(info.dli_sname, NULL, NULL, &status);
+ int status = 0;
+ size_t len = 0;
+ char* demangled = abi::__cxa_demangle(info.dli_sname, NULL, &len, &status);
+ MSAN_UNPOISON(demangled, len);
if (status == 0) {
return demangled;
}
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 6f0f164..d958643 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -2691,6 +2691,7 @@
extractor.set_parameter_types(Object::extractor_parameter_types());
extractor.set_parameter_names(Object::extractor_parameter_names());
extractor.set_result_type(Object::dynamic_type());
+ extractor.set_kernel_function(kernel_function());
extractor.set_extracted_method_closure(closure_function);
extractor.set_is_debuggable(false);
@@ -6612,6 +6613,7 @@
NOT_IN_PRECOMPILED(result.set_deoptimization_counter(0));
NOT_IN_PRECOMPILED(result.set_optimized_instruction_count(0));
NOT_IN_PRECOMPILED(result.set_optimized_call_site_count(0));
+ result.set_kernel_function(NULL);
result.set_is_optimizable(is_native ? false : true);
result.set_is_inlinable(true);
result.set_allows_hoisting_check_class(true);
@@ -6640,6 +6642,7 @@
clone.set_deoptimization_counter(0);
clone.set_optimized_instruction_count(0);
clone.set_optimized_call_site_count(0);
+ clone.set_kernel_function(kernel_function());
if (new_owner.NumTypeParameters() > 0) {
// Adjust uninstantiated types to refer to type parameters of the new owner.
AbstractType& type = AbstractType::Handle(clone.result_type());
@@ -6780,6 +6783,8 @@
param_name = ParameterNameAt(has_receiver - kClosure + i);
closure_function.SetParameterNameAt(i, param_name);
}
+ closure_function.set_kernel_function(kernel_function());
+
const Type& signature_type = Type::Handle(closure_function.SignatureType());
if (!signature_type.IsFinalized()) {
ClassFinalizer::FinalizeType(
@@ -7546,6 +7551,7 @@
result.set_token_pos(token_pos);
result.set_has_initializer(false);
result.set_is_unboxing_candidate(true);
+ result.set_kernel_field(NULL);
Isolate* isolate = Isolate::Current();
// Use field guards if they are enabled and the isolate has never reloaded.
@@ -7636,6 +7642,7 @@
Field& clone = Field::Handle();
clone ^= Object::Clone(*this, Heap::kOld);
clone.SetOriginal(original);
+ clone.set_kernel_field(original.kernel_field());
return clone.raw();
}
@@ -7876,7 +7883,6 @@
: Instance::Cast(value));
return;
} else if (StaticValue() == Object::transition_sentinel().raw()) {
- SetStaticValue(Object::null_instance());
const Array& ctor_args = Array::Handle(Array::New(1));
const String& field_name = String::Handle(name());
ctor_args.SetAt(0, field_name);
@@ -12165,7 +12171,7 @@
const char* Stackmap::ToCString() const {
-#define FORMAT "%#x: "
+#define FORMAT "%#05x: "
if (IsNull()) {
return "{null}";
} else {
@@ -13818,6 +13824,9 @@
if (v.IsNull()) {
ASSERT(!is_optimized());
const Function& f = Function::Handle(function());
+ if (f.kernel_function() != NULL) {
+ return v.raw();
+ }
ASSERT(!f.IsIrregexpFunction()); // Not yet implemented.
Compiler::ComputeLocalVarDescriptors(*this);
}
@@ -14229,8 +14238,6 @@
result.set_is_alive(false);
result.set_comments(Comments::New(0));
result.set_compile_timestamp(0);
- result.set_lazy_deopt_return_pc_offset(kInvalidPc);
- result.set_lazy_deopt_throw_pc_offset(kInvalidPc);
result.set_pc_descriptors(Object::empty_descriptors());
}
return result.raw();
@@ -14296,8 +14303,8 @@
}
// Hook up Code and Instructions objects.
- code.SetActiveInstructions(instrs.raw());
- code.set_instructions(instrs.raw());
+ code.SetActiveInstructions(instrs);
+ code.set_instructions(instrs);
code.set_is_alive(true);
// Set object pool in Instructions object.
@@ -14509,7 +14516,7 @@
ASSERT(instructions() == active_instructions());
const Code& new_code =
Code::Handle(StubCode::FixCallersTarget_entry()->code());
- SetActiveInstructions(new_code.instructions());
+ SetActiveInstructions(Instructions::Handle(new_code.instructions()));
}
@@ -14520,7 +14527,7 @@
ASSERT(instructions() == active_instructions());
const Code& new_code =
Code::Handle(StubCode::FixAllocationStubTarget_entry()->code());
- SetActiveInstructions(new_code.instructions());
+ SetActiveInstructions(Instructions::Handle(new_code.instructions()));
#else
// DBC does not use allocation stubs.
UNIMPLEMENTED();
@@ -14528,34 +14535,22 @@
}
-void Code::SetActiveInstructions(RawInstructions* instructions) const {
+void Code::SetActiveInstructions(const Instructions& instructions) const {
#if defined(DART_PRECOMPILED_RUNTIME)
UNREACHABLE();
#else
DEBUG_ASSERT(IsMutatorOrAtSafepoint() || !is_alive());
// RawInstructions are never allocated in New space and hence a
// store buffer update is not needed here.
- StorePointer(&raw_ptr()->active_instructions_, instructions);
+ StorePointer(&raw_ptr()->active_instructions_, instructions.raw());
StoreNonPointer(&raw_ptr()->entry_point_,
- Instructions::UncheckedEntryPoint(instructions));
+ Instructions::UncheckedEntryPoint(instructions.raw()));
StoreNonPointer(&raw_ptr()->checked_entry_point_,
- Instructions::CheckedEntryPoint(instructions));
+ Instructions::CheckedEntryPoint(instructions.raw()));
#endif
}
-uword Code::GetLazyDeoptReturnPc() const {
- return (lazy_deopt_return_pc_offset() != kInvalidPc)
- ? PayloadStart() + lazy_deopt_return_pc_offset() : 0;
-}
-
-
-uword Code::GetLazyDeoptThrowPc() const {
- return (lazy_deopt_throw_pc_offset() != kInvalidPc)
- ? PayloadStart() + lazy_deopt_throw_pc_offset() : 0;
-}
-
-
RawStackmap* Code::GetStackmap(
uint32_t pc_offset, Array* maps, Stackmap* map) const {
// This code is used during iterating frames during a GC and hence it
@@ -14577,7 +14572,7 @@
return map->raw(); // We found a stack map for this frame.
}
}
- ASSERT(!is_optimized());
+ ASSERT(!is_optimized() || (pc_offset == Instructions::kUncheckedEntryOffset));
return Stackmap::null();
}
@@ -20111,19 +20106,21 @@
bool String::Equals(const int32_t* utf32_array, intptr_t len) const {
- CodePointIterator it(*this);
- intptr_t i = 0;
- bool has_more = it.Next();
- while (has_more && (i < len)) {
- if ((it.Current() != static_cast<int32_t>(utf32_array[i]))) {
- return false;
+ if (len < 0) return false;
+ intptr_t j = 0;
+ for (intptr_t i = 0; i < len; ++i) {
+ if (Utf::IsSupplementary(utf32_array[i])) {
+ uint16_t encoded[2];
+ Utf16::Encode(utf32_array[i], &encoded[0]);
+ if (j + 1 >= Length()) return false;
+ if (CharAt(j++) != encoded[0]) return false;
+ if (CharAt(j++) != encoded[1]) return false;
+ } else {
+ if (j >= Length()) return false;
+ if (CharAt(j++) != utf32_array[i]) return false;
}
- // Advance both streams forward.
- ++i;
- has_more = it.Next();
}
- // Strings are only true iff we reached the end in both streams.
- return (i == len) && !has_more;
+ return j == Length();
}
@@ -22608,10 +22605,11 @@
const Script& script = Script::Handle(zone, function.script());
const String& function_name =
String::Handle(zone, function.QualifiedUserVisibleName());
- const String& url = String::Handle(zone, script.url());
+ const String& url = String::Handle(zone,
+ script.IsNull() ? String::New("Kernel") : script.url());
intptr_t line = -1;
intptr_t column = -1;
- if (token_pos.IsReal()) {
+ if (!script.IsNull() && token_pos.IsReal()) {
if (script.HasSource()) {
script.GetTokenLocation(token_pos, &line, &column);
} else {
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 3ce365b..8358380 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -2632,6 +2632,20 @@
#endif
}
+ void* kernel_function() const {
+#if defined(DART_PRECOMPILED_RUNTIME)
+ return NULL;
+#else
+ return raw_ptr()->kernel_function_;
+#endif
+ }
+
+ void set_kernel_function(void* kernel_function) const {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ StoreNonPointer(&raw_ptr()->kernel_function_, kernel_function);
+#endif
+ }
+
bool IsOptimizable() const;
bool IsNativeAutoSetupScope() const;
void SetIsOptimizable(bool value) const;
@@ -3152,6 +3166,21 @@
set_kind_bits(DoubleInitializedBit::update(value, raw_ptr()->kind_bits_));
}
+ void* kernel_field() const {
+#if defined(DART_PRECOMPILED_RUNTIME)
+ return NULL;
+#else
+ return raw_ptr()->kernel_field_;
+#endif
+ }
+
+ void set_kernel_field(void* kernel_field) const {
+#if !defined(DART_PRECOMPILED_RUNTIME)
+ StoreNonPointer(&raw_ptr()->kernel_field_, kernel_field);
+#endif
+ }
+
+
inline intptr_t Offset() const;
// Called during class finalization.
inline void SetOffset(intptr_t offset_in_bytes) const;
@@ -4129,17 +4158,17 @@
static const intptr_t kCheckedEntryOffset = 0;
static const intptr_t kUncheckedEntryOffset = 0;
#elif defined(TARGET_ARCH_X64)
- static const intptr_t kCheckedEntryOffset = 23;
- static const intptr_t kUncheckedEntryOffset = 44;
-#elif defined(TARGET_ARCH_ARM)
- static const intptr_t kCheckedEntryOffset = 12;
- static const intptr_t kUncheckedEntryOffset = 36;
-#elif defined(TARGET_ARCH_ARM64)
- static const intptr_t kCheckedEntryOffset = 24;
- static const intptr_t kUncheckedEntryOffset = 48;
-#elif defined(TARGET_ARCH_MIPS)
static const intptr_t kCheckedEntryOffset = 16;
- static const intptr_t kUncheckedEntryOffset = 56;
+ static const intptr_t kUncheckedEntryOffset = 38;
+#elif defined(TARGET_ARCH_ARM)
+ static const intptr_t kCheckedEntryOffset = 8;
+ static const intptr_t kUncheckedEntryOffset = 32;
+#elif defined(TARGET_ARCH_ARM64)
+ static const intptr_t kCheckedEntryOffset = 16;
+ static const intptr_t kUncheckedEntryOffset = 40;
+#elif defined(TARGET_ARCH_MIPS)
+ static const intptr_t kCheckedEntryOffset = 12;
+ static const intptr_t kUncheckedEntryOffset = 52;
#elif defined(TARGET_ARCH_DBC)
static const intptr_t kCheckedEntryOffset = 0;
static const intptr_t kUncheckedEntryOffset = 0;
@@ -4918,13 +4947,6 @@
}
TokenPosition GetTokenIndexOfPC(uword pc) const;
- enum {
- kInvalidPc = -1
- };
-
- uword GetLazyDeoptReturnPc() const;
- uword GetLazyDeoptThrowPc() const;
-
// Find pc, return 0 if not found.
uword GetPcForDeoptId(intptr_t deopt_id, RawPcDescriptors::Kind kind) const;
intptr_t GetDeoptIdForOsr(uword pc) const;
@@ -4940,35 +4962,6 @@
#endif
}
- intptr_t lazy_deopt_return_pc_offset() const {
-#if defined(DART_PRECOMPILED_RUNTIME)
- return 0;
-#else
- return raw_ptr()->lazy_deopt_return_pc_offset_;
-#endif
- }
- void set_lazy_deopt_return_pc_offset(intptr_t pc) const {
-#if defined(DART_PRECOMPILED_RUNTIME)
- UNREACHABLE();
-#else
- StoreNonPointer(&raw_ptr()->lazy_deopt_return_pc_offset_, pc);
-#endif
- }
- intptr_t lazy_deopt_throw_pc_offset() const {
-#if defined(DART_PRECOMPILED_RUNTIME)
- return 0;
-#else
- return raw_ptr()->lazy_deopt_throw_pc_offset_;
-#endif
- }
- void set_lazy_deopt_throw_pc_offset(intptr_t pc) const {
-#if defined(DART_PRECOMPILED_RUNTIME)
- UNREACHABLE();
-#else
- StoreNonPointer(&raw_ptr()->lazy_deopt_throw_pc_offset_, pc);
-#endif
- }
-
bool IsAllocationStubCode() const;
bool IsStubCode() const;
bool IsFunctionCode() const;
@@ -4981,7 +4974,7 @@
if (!IsDisabled()) return;
ASSERT(Thread::Current()->IsMutatorThread());
ASSERT(instructions() != active_instructions());
- SetActiveInstructions(instructions());
+ SetActiveInstructions(Instructions::Handle(instructions()));
}
bool IsDisabled() const {
@@ -5037,11 +5030,11 @@
#endif
}
- void SetActiveInstructions(RawInstructions* instructions) const;
+ void SetActiveInstructions(const Instructions& instructions) const;
- void set_instructions(RawInstructions* instructions) const {
+ void set_instructions(const Instructions& instructions) const {
ASSERT(Thread::Current()->IsMutatorThread() || !is_alive());
- StorePointer(&raw_ptr()->instructions_, instructions);
+ StorePointer(&raw_ptr()->instructions_, instructions.raw());
}
void set_pointer_offsets_length(intptr_t value) {
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index 73e2d70..d4594d6 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -4726,4 +4726,19 @@
}
}
+
+VM_TEST_CASE(String_EqualsUTF32) {
+ // Regression test for Issue 27433. Checks that comparisons between Strings
+ // and utf32 arrays happens after conversion to utf16 instead of utf32, as
+ // required for proper canonicalization of string literals with a lossy
+ // utf32->utf16 conversion.
+ int32_t char_codes[] = {
+ 0, 0x0a, 0x0d, 0x7f, 0xff, 0xffff, 0xd800, 0xdc00, 0xdbff, 0xdfff
+ };
+
+ const String& str =
+ String::Handle(String::FromUTF32(char_codes, ARRAY_SIZE(char_codes)));
+ EXPECT(str.Equals(char_codes, ARRAY_SIZE(char_codes)));
+}
+
} // namespace dart
diff --git a/runtime/vm/os_linux.cc b/runtime/vm/os_linux.cc
index 12dd646..7f5eff7 100644
--- a/runtime/vm/os_linux.cc
+++ b/runtime/vm/os_linux.cc
@@ -19,6 +19,7 @@
#include <fcntl.h> // NOLINT
#include <unistd.h> // NOLINT
+#include "platform/memory_sanitizer.h"
#include "platform/utils.h"
#include "vm/code_observers.h"
#include "vm/dart.h"
@@ -321,6 +322,7 @@
int OS::VSNPrint(char* str, size_t size, const char* format, va_list args) {
+ MSAN_UNPOISON(str, size);
int retval = vsnprintf(str, size, format, args);
if (retval < 0) {
FATAL1("Fatal error in OS::VSNPrint with format '%s'", format);
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index def0cfd..b41e0ef 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -16,6 +16,7 @@
#include "vm/compiler_stats.h"
#include "vm/dart_api_impl.h"
#include "vm/dart_entry.h"
+#include "vm/kernel_to_il.h"
#include "vm/growable_array.h"
#include "vm/handles.h"
#include "vm/hash_table.h"
@@ -61,6 +62,7 @@
DECLARE_FLAG(bool, profile_vm);
DECLARE_FLAG(bool, trace_service);
+DECLARE_FLAG(bool, ignore_patch_signature_mismatch);
// Quick access to the current thread, isolate and zone.
#define T (thread())
@@ -225,6 +227,19 @@
}
+kernel::ScopeBuildingResult* ParsedFunction::EnsureKernelScopes() {
+ if (kernel_scopes_ == NULL) {
+ kernel::TreeNode* node = NULL;
+ if (function().kernel_function() != NULL) {
+ node = static_cast<kernel::TreeNode*>(function().kernel_function());
+ }
+ kernel::ScopeBuilder builder(this, node);
+ kernel_scopes_ = builder.BuildScopes();
+ }
+ return kernel_scopes_;
+}
+
+
LocalVariable* ParsedFunction::EnsureExpressionTemp() {
if (!has_expression_temp_var()) {
LocalVariable* temp =
@@ -1592,10 +1607,13 @@
&Object::dynamic_type());
ASSERT(func.num_fixed_parameters() == 2); // closure, value.
} else if (!parent.IsGetterFunction() && !parent.IsImplicitGetterFunction()) {
- const bool allow_explicit_default_values = true;
- SkipFunctionPreamble();
- ParseFormalParameterList(allow_explicit_default_values, false, ¶ms);
- SetupDefaultsForOptionalParams(params);
+ // NOTE: For the `kernel -> flowgraph` we don't use the parser.
+ if (parent.kernel_function() == NULL) {
+ const bool allow_explicit_default_values = true;
+ SkipFunctionPreamble();
+ ParseFormalParameterList(allow_explicit_default_values, false, ¶ms);
+ SetupDefaultsForOptionalParams(params);
+ }
}
// Populate function scope with the formal parameters.
@@ -2184,7 +2202,7 @@
if (params->has_optional_positional_parameters) {
ExpectToken(Token::kASSIGN);
} else {
- ExpectToken(Token::kCOLON);
+ ConsumeToken();
}
params->num_optional_parameters++;
params->has_explicit_default_values = true; // Also if explicitly NULL.
@@ -4731,35 +4749,37 @@
"class '%s' must be patched with identical type parameters",
class_name.ToCString());
}
- TypeParameter& new_type_param = TypeParameter::Handle(Z);
- TypeParameter& orig_type_param = TypeParameter::Handle(Z);
- String& new_name = String::Handle(Z);
- String& orig_name = String::Handle(Z);
- AbstractType& new_bound = AbstractType::Handle(Z);
- AbstractType& orig_bound = AbstractType::Handle(Z);
- for (int i = 0; i < new_type_params_count; i++) {
- new_type_param ^= new_type_parameters.TypeAt(i);
- orig_type_param ^= orig_type_parameters.TypeAt(i);
- new_name = new_type_param.name();
- orig_name = orig_type_param.name();
- if (!new_name.Equals(orig_name)) {
- ReportError(new_type_param.token_pos(),
- "type parameter '%s' of patch class '%s' does not match "
- "original type parameter '%s'",
- new_name.ToCString(),
- class_name.ToCString(),
- orig_name.ToCString());
- }
- new_bound = new_type_param.bound();
- orig_bound = orig_type_param.bound();
- if (!new_bound.Equals(orig_bound)) {
- ReportError(new_type_param.token_pos(),
- "bound '%s' of type parameter '%s' of patch class '%s' "
- "does not match original type parameter bound '%s'",
- String::Handle(new_bound.UserVisibleName()).ToCString(),
- new_name.ToCString(),
- class_name.ToCString(),
- String::Handle(orig_bound.UserVisibleName()).ToCString());
+ if (!FLAG_ignore_patch_signature_mismatch) {
+ TypeParameter& new_type_param = TypeParameter::Handle(Z);
+ TypeParameter& orig_type_param = TypeParameter::Handle(Z);
+ String& new_name = String::Handle(Z);
+ String& orig_name = String::Handle(Z);
+ AbstractType& new_bound = AbstractType::Handle(Z);
+ AbstractType& orig_bound = AbstractType::Handle(Z);
+ for (int i = 0; i < new_type_params_count; i++) {
+ new_type_param ^= new_type_parameters.TypeAt(i);
+ orig_type_param ^= orig_type_parameters.TypeAt(i);
+ new_name = new_type_param.name();
+ orig_name = orig_type_param.name();
+ if (!new_name.Equals(orig_name)) {
+ ReportError(new_type_param.token_pos(),
+ "type parameter '%s' of patch class '%s' does not match "
+ "original type parameter '%s'",
+ new_name.ToCString(),
+ class_name.ToCString(),
+ orig_name.ToCString());
+ }
+ new_bound = new_type_param.bound();
+ orig_bound = orig_type_param.bound();
+ if (!new_bound.Equals(orig_bound)) {
+ ReportError(new_type_param.token_pos(),
+ "bound '%s' of type parameter '%s' of patch class '%s' "
+ "does not match original type parameter bound '%s'",
+ String::Handle(new_bound.UserVisibleName()).ToCString(),
+ new_name.ToCString(),
+ class_name.ToCString(),
+ String::Handle(orig_bound.UserVisibleName()).ToCString());
+ }
}
}
cls.set_type_parameters(orig_type_parameters);
@@ -10999,9 +11019,7 @@
right_operand = new(Z) TypeNode(type_pos, type);
// In production mode, the type may be malformed.
// In checked mode, the type may be malformed or malbounded.
- if (((op_kind == Token::kIS) || (op_kind == Token::kISNOT) ||
- (op_kind == Token::kAS)) &&
- type.IsMalformedOrMalbounded()) {
+ if (type.IsMalformedOrMalbounded()) {
// Note that a type error is thrown in a type test or in
// a type cast even if the tested value is null.
// We need to evaluate the left operand for potential
@@ -11278,18 +11296,18 @@
if (name.IsNull()) {
ReportError(left_pos, "expression is not assignable");
}
- LetNode* let_node = new(Z) LetNode(left_pos);
- let_node->AddInitializer(rhs);
- let_node->AddNode(ThrowNoSuchMethodError(
+ ArgumentListNode* error_arguments =
+ new(Z) ArgumentListNode(rhs->token_pos());
+ error_arguments->Add(rhs);
+ result = ThrowNoSuchMethodError(
original->token_pos(),
*target_cls,
String::Handle(Z, Field::SetterName(name)),
- NULL, // No arguments.
+ error_arguments,
InvocationMirror::kStatic,
original->IsLoadLocalNode() ?
InvocationMirror::kLocalVar : InvocationMirror::kSetter,
- NULL)); // No existing function.
- result = let_node;
+ NULL); // No existing function.
}
// The compound assignment operator a ??= b is different from other
// a op= b assignments. If a is non-null, the assignment to a must be
@@ -11914,15 +11932,9 @@
// TODO(regis): Verify that CaptureFunctionInstantiator() was already
// called if necessary.
// TODO(regis): Finalize type parameter and return as type node.
- // For now, throw a type error.
- Type& malformed_type = Type::ZoneHandle(Z);
- malformed_type = ClassFinalizer::NewFinalizedMalformedType(
- Error::Handle(Z), // No previous error.
- script_,
- primary_pos,
- "function type parameter '%s' not yet supported",
- String::Handle(Z, type_parameter.name()).ToCString());
- return ThrowTypeError(primary_pos, malformed_type);
+ // For now, map to dynamic type.
+ Type& type = Type::ZoneHandle(Z, Type::DynamicType());
+ return new(Z) TypeNode(primary_pos, type);
}
}
@@ -12215,7 +12227,8 @@
obj = prefix.LookupObject(extractor_name);
}
}
- if (!prefix.is_loaded() && (parsed_function() != NULL)) {
+ if (!prefix.is_loaded() && (parsed_function() != NULL) &&
+ !FLAG_load_deferred_eagerly) {
// Remember that this function depends on an import prefix of an
// unloaded deferred library.
parsed_function()->AddDeferredPrefix(prefix);
@@ -12383,15 +12396,8 @@
NULL));
if (!type_parameter.IsNull()) {
// TODO(regis): Check for absence of type arguments.
- // For now, return as malformed type.
- Type& malformed_type = Type::ZoneHandle(Z);
- malformed_type = ClassFinalizer::NewFinalizedMalformedType(
- Error::Handle(Z), // No previous error.
- script_,
- type->token_pos(),
- "function type parameter '%s' not yet supported",
- String::Handle(Z, type_parameter.name()).ToCString());
- *type = malformed_type.raw();
+ // For now, resolve the function type parameter to dynamic.
+ *type = Type::DynamicType();
return;
}
}
@@ -13001,15 +13007,9 @@
CaptureFunctionInstantiator();
}
// TODO(regis): Finalize type parameter and return as type node.
- // For now, return as malformed type.
- Type& malformed_type = Type::ZoneHandle(Z);
- malformed_type = ClassFinalizer::NewFinalizedMalformedType(
- Error::Handle(Z), // No previous error.
- script_,
- ident_pos,
- "function type parameter '%s' not yet supported",
- ident.ToCString());
- return new(Z) TypeNode(ident_pos, malformed_type);
+ // For now, map to dynamic type.
+ Type& type = Type::ZoneHandle(Z, Type::DynamicType());
+ return new(Z) TypeNode(ident_pos, type);
}
}
}
@@ -13966,6 +13966,15 @@
const Error& error = Error::Handle(Z, type.error());
ReportError(error);
}
+ if (arguments->length() > 0) {
+ // Evaluate arguments for side-effects and throw.
+ LetNode* error_result = new(Z) LetNode(type_pos);
+ for (intptr_t i = 0; i < arguments->length(); ++i) {
+ error_result->AddNode(arguments->NodeAt(i));
+ }
+ error_result->AddNode(ThrowTypeError(type_pos, type));
+ return error_result;
+ }
return ThrowTypeError(type_pos, type);
}
@@ -14041,7 +14050,8 @@
UnresolvedClass::Handle(Z, redirect_type.unresolved_class());
const LibraryPrefix& prefix =
LibraryPrefix::Handle(Z, cls.library_prefix());
- if (!prefix.IsNull() && !prefix.is_loaded()) {
+ if (!prefix.IsNull() && !prefix.is_loaded() &&
+ !FLAG_load_deferred_eagerly) {
// If the redirection type is unresolved because it refers to
// an unloaded deferred prefix, mark this function as depending
// on the library prefix. It will then get invalidated when the
@@ -14458,32 +14468,13 @@
ConsumeToken(); // Prefix name.
primary = new(Z) LiteralNode(qual_ident_pos, prefix);
} else {
- // TODO(hausner): Ideally we should generate the NoSuchMethodError
- // later, when we know more about how the unresolved name is used.
- // For example, we don't know yet whether the unresolved name
- // refers to a getter or a setter. However, it is more awkward
- // to distinuish four NoSuchMethodError cases all over the place
- // in the parser. The four cases are: prefixed vs non-prefixed
- // name, static vs dynamic context in which the unresolved name
- // is used. We cheat a little here by looking at the next token
- // to determine whether we have an unresolved method call or
- // field access.
GrowableHandlePtrArray<const String> pieces(Z, 3);
pieces.Add(String::Handle(Z, prefix.name()));
pieces.Add(Symbols::Dot());
pieces.Add(ident);
const String& qualified_name = String::ZoneHandle(Z,
Symbols::FromConcatAll(T, pieces));
- InvocationMirror::Type call_type =
- CurrentToken() == Token::kLPAREN ?
- InvocationMirror::kMethod : InvocationMirror::kGetter;
- primary = ThrowNoSuchMethodError(qual_ident_pos,
- current_class(),
- qualified_name,
- NULL, // No arguments.
- InvocationMirror::kTopLevel,
- call_type,
- NULL); // No existing function.
+ primary = new(Z) PrimaryNode(qual_ident_pos, qualified_name);
}
} else if (FLAG_load_deferred_eagerly && prefix.is_deferred_load()) {
// primary != NULL.
@@ -15034,6 +15025,12 @@
}
+kernel::ScopeBuildingResult* ParsedFunction::EnsureKernelScopes() {
+ UNREACHABLE();
+ return NULL;
+}
+
+
LocalVariable* ParsedFunction::EnsureExpressionTemp() {
UNREACHABLE();
return NULL;
diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h
index 9134bb1..0756cba 100644
--- a/runtime/vm/parser.h
+++ b/runtime/vm/parser.h
@@ -14,6 +14,7 @@
#include "vm/ast.h"
#include "vm/class_finalizer.h"
#include "vm/compiler_stats.h"
+#include "vm/kernel.h"
#include "vm/hash_table.h"
#include "vm/object.h"
#include "vm/raw_object.h"
@@ -22,6 +23,13 @@
namespace dart {
// Forward declarations.
+
+namespace kernel {
+
+class ScopeBuildingResult;
+
+} // kernel
+
class ArgumentsDescriptor;
class Isolate;
class LocalScope;
@@ -101,7 +109,8 @@
first_stack_local_index_(0),
num_copied_params_(0),
num_stack_locals_(0),
- have_seen_await_expr_(false) {
+ have_seen_await_expr_(false),
+ kernel_scopes_(NULL) {
ASSERT(function.IsZoneHandle());
// Every function has a local variable for the current context.
LocalVariable* temp = new(zone()) LocalVariable(
@@ -215,6 +224,8 @@
void Bailout(const char* origin, const char* reason) const;
+ kernel::ScopeBuildingResult* EnsureKernelScopes();
+
private:
Thread* thread_;
const Function& function_;
@@ -235,6 +246,8 @@
int num_stack_locals_;
bool have_seen_await_expr_;
+ kernel::ScopeBuildingResult* kernel_scopes_;
+
friend class Parser;
DISALLOW_COPY_AND_ASSIGN(ParsedFunction);
};
diff --git a/runtime/vm/precompiler.cc b/runtime/vm/precompiler.cc
index d55a6f1..22348eb 100644
--- a/runtime/vm/precompiler.cc
+++ b/runtime/vm/precompiler.cc
@@ -1495,8 +1495,7 @@
}
}
- // Locate all entries with one function only, and whose owner is neither
- // subclassed nor implemented.
+ // Locate all entries with one function only
Table::Iterator iter(&table);
String& key = String::Handle(Z);
UniqueFunctionsSet functions_set(HashTables::New<UniqueFunctionsSet>(20));
@@ -1508,9 +1507,7 @@
if (farray.Length() == 1) {
function ^= farray.At(0);
cls = function.Owner();
- if (!CHA::IsImplemented(cls) && !CHA::HasSubclasses(cls)) {
- functions_set.Insert(function);
- }
+ functions_set.Insert(function);
}
}
@@ -2345,8 +2342,8 @@
code_ = function.CurrentCode();
instructions_ = code_.instructions();
instructions_ = DedupOneInstructions(instructions_);
- code_.SetActiveInstructions(instructions_.raw());
- code_.set_instructions(instructions_.raw());
+ code_.SetActiveInstructions(instructions_);
+ code_.set_instructions(instructions_);
function.SetInstructions(code_); // Update cached entry point.
}
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index cef387b..4f0a768f 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -869,6 +869,7 @@
uint32_t kind_tag_; // See Function::KindTagBits.
int16_t num_fixed_parameters_;
int16_t num_optional_parameters_; // > 0: positional; < 0: named.
+ NOT_IN_PRECOMPILED(void* kernel_function_);
NOT_IN_PRECOMPILED(uint16_t optimized_instruction_count_);
NOT_IN_PRECOMPILED(uint16_t optimized_call_site_count_);
NOT_IN_PRECOMPILED(int8_t deoptimization_counter_);
@@ -941,8 +942,9 @@
switch (kind) {
case Snapshot::kCore:
case Snapshot::kScript:
- case Snapshot::kAppWithJIT:
return reinterpret_cast<RawObject**>(&ptr()->guarded_list_length_);
+ case Snapshot::kAppWithJIT:
+ return reinterpret_cast<RawObject**>(&ptr()->dependent_code_);
case Snapshot::kAppNoJIT:
return reinterpret_cast<RawObject**>(&ptr()->initializer_);
case Snapshot::kMessage:
@@ -964,6 +966,7 @@
int8_t guarded_list_length_in_object_offset_;
uint8_t kind_bits_; // static, final, const, has initializer....
+ NOT_IN_PRECOMPILED(void* kernel_field_);
friend class CidRewriteVisitor;
};
@@ -1141,18 +1144,18 @@
NOT_IN_PRECOMPILED(RawArray* deopt_info_array_);
// (code-offset, function, code) triples.
NOT_IN_PRECOMPILED(RawArray* static_calls_target_table_);
- NOT_IN_PRECOMPILED(RawLocalVarDescriptors* var_descriptors_);
NOT_IN_PRECOMPILED(RawArray* inlined_metadata_);
- NOT_IN_PRECOMPILED(RawCodeSourceMap* code_source_map_);
- NOT_IN_PRECOMPILED(RawArray* comments_);
// If return_address_metadata_ is a Smi, it is the offset to the prologue.
// Else, return_address_metadata_ is null.
NOT_IN_PRECOMPILED(RawObject* return_address_metadata_);
+ NOT_IN_PRECOMPILED(RawLocalVarDescriptors* var_descriptors_);
+ NOT_IN_PRECOMPILED(RawCodeSourceMap* code_source_map_);
+ NOT_IN_PRECOMPILED(RawArray* comments_);
RawObject** to() {
#if defined(DART_PRECOMPILED_RUNTIME)
return reinterpret_cast<RawObject**>(&ptr()->stackmaps_);
#else
- return reinterpret_cast<RawObject**>(&ptr()->return_address_metadata_);
+ return reinterpret_cast<RawObject**>(&ptr()->comments_);
#endif
}
@@ -1165,10 +1168,6 @@
// Alive: If true, the embedded object pointers will be visited during GC.
int32_t state_bits_;
- // PC offsets for code patching.
- NOT_IN_PRECOMPILED(int32_t lazy_deopt_return_pc_offset_);
- NOT_IN_PRECOMPILED(int32_t lazy_deopt_throw_pc_offset_);
-
// Variable length data follows here.
int32_t* data() { OPEN_ARRAY_START(int32_t, int32_t); }
const int32_t* data() const { OPEN_ARRAY_START(int32_t, int32_t); }
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index f345a19..c8ea0f2 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -714,6 +714,7 @@
func.set_deoptimization_counter(reader->Read<int8_t>());
func.set_optimized_instruction_count(reader->Read<uint16_t>());
func.set_optimized_call_site_count(reader->Read<uint16_t>());
+ func.set_kernel_function(NULL);
func.set_was_compiled(false);
// Set all the object fields.
@@ -820,6 +821,7 @@
field.set_guarded_cid(reader->Read<int32_t>());
field.set_is_nullable(reader->Read<int32_t>());
field.set_kind_bits(reader->Read<uint8_t>());
+ field.set_kernel_field(NULL);
// Set all the object fields.
READ_OBJECT_FIELDS(field,
@@ -1189,7 +1191,8 @@
reader->Read<int16_t>());
prefix.StoreNonPointer(&prefix.raw_ptr()->is_deferred_load_,
reader->Read<bool>());
- prefix.StoreNonPointer(&prefix.raw_ptr()->is_loaded_, reader->Read<bool>());
+ prefix.StoreNonPointer(&prefix.raw_ptr()->is_loaded_,
+ !prefix.raw_ptr()->is_deferred_load_);
// Set all the object fields.
READ_OBJECT_FIELDS(prefix,
@@ -1220,7 +1223,6 @@
// Write out all non object fields.
writer->Write<int16_t>(ptr()->num_imports_);
writer->Write<bool>(ptr()->is_deferred_load_);
- writer->Write<bool>(ptr()->is_loaded_);
// Write out all the object pointer fields.
SnapshotWriterVisitor visitor(writer, kAsReference);
diff --git a/runtime/vm/redundancy_elimination.cc b/runtime/vm/redundancy_elimination.cc
index f7bc9b7..c13ec9d 100644
--- a/runtime/vm/redundancy_elimination.cc
+++ b/runtime/vm/redundancy_elimination.cc
@@ -3353,10 +3353,15 @@
GrowableArray<Definition*> cdefs(idefs->length());
cdefs.AddArray(*idefs);
- // exception_var and stacktrace_var are never constant.
- intptr_t ex_idx = base - catch_entry->exception_var().index();
- intptr_t st_idx = base - catch_entry->stacktrace_var().index();
- cdefs[ex_idx] = cdefs[st_idx] = NULL;
+ // exception_var and stacktrace_var are never constant. In asynchronous or
+ // generator functions they may be context-allocated in which case they are
+ // not tracked in the environment anyway.
+ if (!catch_entry->exception_var().is_captured()) {
+ cdefs[base - catch_entry->exception_var().index()] = NULL;
+ }
+ if (!catch_entry->stacktrace_var().is_captured()) {
+ cdefs[base - catch_entry->stacktrace_var().index()] = NULL;
+ }
for (BlockIterator block_it = flow_graph->reverse_postorder_iterator();
!block_it.Done();
@@ -3372,10 +3377,14 @@
ASSERT(env != NULL);
for (intptr_t env_idx = 0; env_idx < cdefs.length(); ++env_idx) {
if (cdefs[env_idx] != NULL &&
+ !cdefs[env_idx]->IsConstant() &&
env->ValueAt(env_idx)->BindsToConstant()) {
+ // If the recorded definition is not a constant, record this
+ // definition as the current constant definition.
cdefs[env_idx] = env->ValueAt(env_idx)->definition();
}
if (cdefs[env_idx] != env->ValueAt(env_idx)->definition()) {
+ // Non-constant definitions are reset to NULL.
cdefs[env_idx] = NULL;
}
}
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index a082636..68b2fd7 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -10,6 +10,17 @@
namespace dart {
+#if defined(TESTING) || defined(DEBUG)
+void VerifyOnTransition() {
+ Thread* thread = Thread::Current();
+ TransitionGeneratedToVM transition(thread);
+ thread->isolate()->heap()->WaitForSweeperTasks();
+ SafepointOperationScope safepoint_scope(thread);
+ VerifyPointersVisitor::VerifyPointers();
+ thread->isolate()->heap()->Verify();
+}
+#endif
+
// Add function to a class and that class to the class dictionary so that
// frame walking can be used.
diff --git a/runtime/vm/scavenger.cc b/runtime/vm/scavenger.cc
index fe366b0..5031909 100644
--- a/runtime/vm/scavenger.cc
+++ b/runtime/vm/scavenger.cc
@@ -358,9 +358,6 @@
UpdateMaxHeapCapacity();
UpdateMaxHeapUsage();
- if (heap_ != NULL) {
- heap_->UpdateGlobalMaxUsed();
- }
}
diff --git a/runtime/vm/scopes.cc b/runtime/vm/scopes.cc
index be2cdda..9acac1f 100644
--- a/runtime/vm/scopes.cc
+++ b/runtime/vm/scopes.cc
@@ -616,7 +616,8 @@
while (scope != top_scope->parent()) {
for (intptr_t i = 0; i < scope->num_variables(); i++) {
LocalVariable* variable = scope->VariableAt(i);
- if ((variable->name().raw() == Symbols::StackTraceVar().raw()) ||
+ if (variable->is_forced_stack() ||
+ (variable->name().raw() == Symbols::StackTraceVar().raw()) ||
(variable->name().raw() == Symbols::ExceptionVar().raw()) ||
(variable->name().raw() == Symbols::SavedTryContextVar().raw())) {
// Don't capture those variables because the VM expects them to be on
diff --git a/runtime/vm/scopes.h b/runtime/vm/scopes.h
index c2fbfe0..9b1877e 100644
--- a/runtime/vm/scopes.h
+++ b/runtime/vm/scopes.h
@@ -33,6 +33,7 @@
is_captured_(false),
is_invisible_(false),
is_captured_parameter_(false),
+ is_forced_stack_(false),
index_(LocalVariable::kUninitializedIndex) {
ASSERT(type.IsZoneHandle() || type.IsReadOnlyHandle());
ASSERT(type.IsFinalized());
@@ -55,6 +56,13 @@
bool is_captured() const { return is_captured_; }
void set_is_captured() { is_captured_ = true; }
+ // Variables marked as forced to stack are skipped and not captured by
+ // CaptureLocalVariables - which iterates scope chain between two scopes
+ // and indiscriminately marks all variables as captured.
+ // TODO(27590) remove the hardcoded blacklist from CaptureLocalVariables
+ bool is_forced_stack() const { return is_forced_stack_; }
+ void set_is_forced_stack() { is_forced_stack_ = true; }
+
bool HasIndex() const {
return index_ != kUninitializedIndex;
}
@@ -122,6 +130,7 @@
// in the stack frame.
bool is_invisible_;
bool is_captured_parameter_;
+ bool is_forced_stack_;
int index_; // Allocation index in words relative to frame pointer (if not
// captured), or relative to the context pointer (if captured).
@@ -331,7 +340,7 @@
RawContextScope* PreserveOuterScope(int current_context_level) const;
// Mark all local variables that are accessible from this scope up to
- // top_scope (included) as captured.
+ // top_scope (included) as captured unless they are marked as forced to stack.
void CaptureLocalVariables(LocalScope* top_scope);
// Creates a LocalScope representing the outer scope of a local function to be
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index efc5c24..abd4271 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -971,6 +971,7 @@
void Service::HandleIsolateMessage(Isolate* isolate, const Array& msg) {
ASSERT(isolate != NULL);
InvokeMethod(isolate, msg);
+ MaybePause(isolate);
}
@@ -1085,6 +1086,11 @@
"vm-service: isolate '%s' has no debugger attached and is paused.",
name);
break;
+ case ServiceEvent::kPausePostRequest:
+ OS::PrintErr(
+ "vm-service: isolate '%s' has no debugger attached and is paused "
+ "post reload.", name);
+ break;
default:
UNREACHABLE();
break;
@@ -2510,6 +2516,7 @@
static const MethodParameter* reload_sources_params[] = {
RUNNABLE_ISOLATE_PARAMETER,
new BoolParameter("force", false),
+ new BoolParameter("pause", false),
NULL,
};
@@ -2554,10 +2561,30 @@
isolate->ReloadSources(js, force_reload);
+ Service::CheckForPause(isolate, js);
+
return true;
}
+void Service::CheckForPause(Isolate* isolate, JSONStream* stream) {
+ // Should we pause?
+ isolate->set_should_pause_post_service_request(
+ BoolParameter::Parse(stream->LookupParam("pause"), false));
+}
+
+
+void Service::MaybePause(Isolate* isolate) {
+ // Don't pause twice.
+ if (!isolate->IsPaused()) {
+ if (isolate->should_pause_post_service_request()) {
+ isolate->set_should_pause_post_service_request(false);
+ isolate->PausePostRequest();
+ }
+ }
+}
+
+
static bool AddBreakpointCommon(Thread* thread,
JSONStream* js,
const String& script_uri) {
@@ -4163,6 +4190,8 @@
remove_breakpoint_params },
{ "_restartVM", RestartVM,
restart_vm_params },
+ { "reloadSources", ReloadSources,
+ reload_sources_params },
{ "_reloadSources", ReloadSources,
reload_sources_params },
{ "resume", Resume,
diff --git a/runtime/vm/service.h b/runtime/vm/service.h
index 6f9d1d6..935f176 100644
--- a/runtime/vm/service.h
+++ b/runtime/vm/service.h
@@ -164,6 +164,8 @@
static void PrintJSONForVM(JSONStream* js, bool ref);
+ static void CheckForPause(Isolate* isolate, JSONStream* stream);
+
private:
static void InvokeMethod(Isolate* isolate,
const Array& message,
@@ -199,6 +201,8 @@
const char* kind,
JSONStream* event);
+ static void MaybePause(Isolate* isolate);
+
static EmbedderServiceHandler* isolate_service_handler_head_;
static EmbedderServiceHandler* root_service_handler_head_;
static Dart_ServiceStreamListenCallback stream_listen_callback_;
diff --git a/runtime/vm/service_event.cc b/runtime/vm/service_event.cc
index 3ff1e1b..5d7cc75 100644
--- a/runtime/vm/service_event.cc
+++ b/runtime/vm/service_event.cc
@@ -83,6 +83,8 @@
return "PauseInterrupted";
case kPauseException:
return "PauseException";
+ case kPausePostRequest:
+ return "PausePostRequest";
case kNone:
return "None";
case kResume:
@@ -135,6 +137,7 @@
case kPauseBreakpoint:
case kPauseInterrupted:
case kPauseException:
+ case kPausePostRequest:
case kNone:
case kResume:
case kBreakpointAdded:
diff --git a/runtime/vm/service_event.h b/runtime/vm/service_event.h
index cd48844..369f522 100644
--- a/runtime/vm/service_event.h
+++ b/runtime/vm/service_event.h
@@ -37,7 +37,8 @@
kPauseBreakpoint,
kPauseInterrupted,
kPauseException,
- kNone, // isolate has not been made runnable yet.
+ kPausePostRequest, // isolate is paused after a service request.
+ kNone, // isolate has not been made runnable yet.
kResume,
kBreakpointAdded,
kBreakpointResolved,
@@ -92,6 +93,7 @@
case kPauseBreakpoint:
case kPauseInterrupted:
case kPauseException:
+ case kPausePostRequest:
return true;
default:
return false;
@@ -131,6 +133,7 @@
ASSERT(kind() == kPauseBreakpoint ||
kind() == kPauseInterrupted ||
kind() == kPauseException ||
+ kind() == kPausePostRequest ||
kind() == kResume);
top_frame_ = frame;
}
diff --git a/runtime/vm/simulator_dbc.cc b/runtime/vm/simulator_dbc.cc
index 67c1728..6c7112e 100644
--- a/runtime/vm/simulator_dbc.cc
+++ b/runtime/vm/simulator_dbc.cc
@@ -1209,11 +1209,12 @@
INVOKE_RUNTIME(DRT_OptimizeInvokedFunction, args);
{
// DRT_OptimizeInvokedFunction returns the code object to execute.
- ASSERT(FP[1]->GetClassId() == kCodeCid);
- RawCode* code = static_cast<RawCode*>(FP[1]);
+ ASSERT(FP[1]->GetClassId() == kFunctionCid);
+ RawFunction* function = static_cast<RawFunction*>(FP[1]);
+ RawCode* code = function->ptr()->code_;
SimulatorHelpers::SetFrameCode(FP, code);
pp = code->ptr()->object_pool_->ptr();
- pc = reinterpret_cast<uint32_t*>(code->ptr()->entry_point_);
+ pc = reinterpret_cast<uint32_t*>(function->ptr()->entry_point_);
pc_ = reinterpret_cast<uword>(pc); // For the profiler.
}
}
@@ -2367,7 +2368,20 @@
const uint16_t value_reg = rC;
RawInstance* instance = reinterpret_cast<RawInstance*>(FP[rA]);
- RawObject* value = reinterpret_cast<RawObject*>(FP[value_reg]);
+ RawObject* value = FP[value_reg];
+
+ instance->StorePointer(
+ reinterpret_cast<RawObject**>(instance->ptr()) + offset_in_words,
+ value);
+ DISPATCH();
+ }
+
+ {
+ BYTECODE(StoreFieldExt, A_D);
+ // The offset is stored in the following nop-instruction which is skipped.
+ const uint16_t offset_in_words = Bytecode::DecodeD(*pc++);
+ RawInstance* instance = reinterpret_cast<RawInstance*>(FP[rA]);
+ RawObject* value = FP[rD];
instance->StorePointer(
reinterpret_cast<RawObject**>(instance->ptr()) + offset_in_words,
@@ -2398,6 +2412,16 @@
}
{
+ BYTECODE(LoadFieldExt, A_D);
+ // The offset is stored in the following nop-instruction which is skipped.
+ const uint16_t offset_in_words = Bytecode::DecodeD(*pc++);
+ const uint16_t instance_reg = rD;
+ RawInstance* instance = reinterpret_cast<RawInstance*>(FP[instance_reg]);
+ FP[rA] = reinterpret_cast<RawObject**>(instance->ptr())[offset_in_words];
+ DISPATCH();
+ }
+
+ {
BYTECODE(LoadUntagged, A_B_C);
const uint16_t instance_reg = rB;
const uint16_t offset_in_words = rC;
@@ -2649,21 +2673,29 @@
}
{
- BYTECODE(AssertAssignable, A_D); // Stack: instance, type args, type, name
+ BYTECODE(BadTypeError, 0); // Stack: instance, type args, type, name
RawObject** args = SP - 3;
if (args[0] != null_value) {
- const AbstractType& dst_type =
- AbstractType::Handle(static_cast<RawAbstractType*>(args[2]));
- if (dst_type.IsMalformedOrMalbounded()) {
- SP[1] = args[0]; // instance.
- SP[2] = args[3]; // name.
- SP[3] = args[2]; // type.
- Exit(thread, FP, SP + 4, pc);
- NativeArguments native_args(thread, 3, SP + 1, SP - 3);
- INVOKE_RUNTIME(DRT_BadTypeError, native_args);
- UNREACHABLE();
- }
+ SP[1] = args[0]; // instance.
+ SP[2] = args[3]; // name.
+ SP[3] = args[2]; // type.
+ Exit(thread, FP, SP + 4, pc);
+ NativeArguments native_args(thread, 3, SP + 1, SP - 3);
+ INVOKE_RUNTIME(DRT_BadTypeError, native_args);
+ UNREACHABLE();
+ }
+ SP -= 3;
+ DISPATCH();
+ }
+ {
+ BYTECODE(AssertAssignable, A_D); // Stack: instance, type args, type, name
+ RawObject** args = SP - 3;
+ const bool may_be_smi = (rA == 1);
+ const bool is_smi =
+ ((reinterpret_cast<intptr_t>(args[0]) & kSmiTagMask) == kSmiTag);
+ const bool smi_ok = is_smi && may_be_smi;
+ if (!smi_ok && (args[0] != null_value)) {
RawSubtypeTestCache* cache =
static_cast<RawSubtypeTestCache*>(LOAD_CONSTANT(rD));
if (cache != null_value) {
@@ -2850,8 +2882,8 @@
pc++;
break;
}
- // The cids are sorted.
- if (cid < desired_cid) {
+ // The cids are sorted in descending order.
+ if (cid > desired_cid) {
break;
}
}
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index 0062dac..08cf77c 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -704,7 +704,10 @@
}
-void AssemblyInstructionsWriter::Write() {
+void AssemblyInstructionsWriter::Write(uint8_t* vmisolate_buffer,
+ intptr_t vmisolate_length,
+ uint8_t* isolate_buffer,
+ intptr_t isolate_length) {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
NOT_IN_PRODUCT(TimelineDurationScope tds(thread,
@@ -849,10 +852,28 @@
WriteWordLiteralData(*cursor);
}
}
+
+
+ assembly_stream_.Print(".globl _kVmIsolateSnapshot\n");
+ assembly_stream_.Print(".balign %" Pd ", 0\n", VirtualMemory::PageSize());
+ assembly_stream_.Print("_kVmIsolateSnapshot:\n");
+ for (intptr_t i = 0; i < vmisolate_length; i++) {
+ assembly_stream_.Print(".byte %" Pd "\n", vmisolate_buffer[i]);
+ }
+
+ assembly_stream_.Print(".globl _kIsolateSnapshot\n");
+ assembly_stream_.Print(".balign %" Pd ", 0\n", VirtualMemory::PageSize());
+ assembly_stream_.Print("_kIsolateSnapshot:\n");
+ for (intptr_t i = 0; i < isolate_length; i++) {
+ assembly_stream_.Print(".byte %" Pd "\n", isolate_buffer[i]);
+ }
}
-void BlobInstructionsWriter::Write() {
+void BlobInstructionsWriter::Write(uint8_t* vmisolate_buffer,
+ intptr_t vmisolate_len,
+ uint8_t* isolate_buffer,
+ intptr_t isolate_length) {
Thread* thread = Thread::Current();
Zone* zone = thread->zone();
NOT_IN_PRODUCT(TimelineDurationScope tds(thread,
diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h
index 3f767b8..020f4485 100644
--- a/runtime/vm/snapshot.h
+++ b/runtime/vm/snapshot.h
@@ -750,7 +750,10 @@
int32_t GetObjectOffsetFor(RawObject* raw_object);
- virtual void Write() = 0;
+ virtual void Write(uint8_t* vmisolate_buffer,
+ intptr_t vmisolate_length,
+ uint8_t* isolate_buffer,
+ intptr_t isolate_length) = 0;
virtual intptr_t text_size() = 0;
virtual intptr_t data_size() = 0;
@@ -803,7 +806,10 @@
data_size_(0) {
}
- virtual void Write();
+ virtual void Write(uint8_t* vmisolate_buffer,
+ intptr_t vmisolate_length,
+ uint8_t* isolate_buffer,
+ intptr_t isolate_length);
virtual intptr_t text_size() { return text_size_; }
virtual intptr_t data_size() { return data_size_; }
@@ -849,7 +855,10 @@
rodata_blob_stream_(rodata_blob_buffer, alloc, initial_size) {
}
- virtual void Write();
+ virtual void Write(uint8_t* vmisolate_buffer,
+ intptr_t vmisolate_length,
+ uint8_t* isolate_buffer,
+ intptr_t isolate_length);
virtual intptr_t text_size() { return InstructionsBlobSize(); }
virtual intptr_t data_size() { return RodataBlobSize(); }
diff --git a/runtime/vm/stack_frame.cc b/runtime/vm/stack_frame.cc
index f93111e..6603127 100644
--- a/runtime/vm/stack_frame.cc
+++ b/runtime/vm/stack_frame.cc
@@ -566,4 +566,15 @@
}
+#if defined(DEBUG)
+void ValidateFrames() {
+ StackFrameIterator frames(StackFrameIterator::kValidateFrames);
+ StackFrame* frame = frames.NextFrame();
+ while (frame != NULL) {
+ frame = frames.NextFrame();
+ }
+}
+#endif
+
+
} // namespace dart
diff --git a/runtime/vm/stack_frame.h b/runtime/vm/stack_frame.h
index 268ca4a..3198872 100644
--- a/runtime/vm/stack_frame.h
+++ b/runtime/vm/stack_frame.h
@@ -51,8 +51,27 @@
return 0;
}
+ uword IsMarkedForLazyDeopt() const {
+ uword raw_pc = *reinterpret_cast<uword*>(
+ sp() + (kSavedPcSlotFromSp * kWordSize));
+ return raw_pc == StubCode::DeoptimizeLazyFromReturn_entry()->EntryPoint();
+ }
+ void MarkForLazyDeopt() {
+ set_pc(StubCode::DeoptimizeLazyFromReturn_entry()->EntryPoint());
+ }
+ void UnmarkForLazyDeopt() {
+ // If this frame was marked for lazy deopt, pc_ was computed to be the
+ // original return address using the pending deopts table in GetCallerPc.
+ // Write this value back into the frame.
+ uword original_pc = pc();
+ ASSERT(original_pc !=
+ StubCode::DeoptimizeLazyFromReturn_entry()->EntryPoint());
+ set_pc(original_pc);
+ }
+
void set_pc(uword value) {
*reinterpret_cast<uword*>(sp() + (kSavedPcSlotFromSp * kWordSize)) = value;
+ pc_ = value;
}
void set_pc_marker(RawCode* code) {
@@ -110,8 +129,13 @@
}
uword GetCallerPc() const {
- return *(reinterpret_cast<uword*>(
+ uword raw_pc = *(reinterpret_cast<uword*>(
fp() + (kSavedCallerPcSlotFromFp * kWordSize)));
+ ASSERT(raw_pc != StubCode::DeoptimizeLazyFromThrow_entry()->EntryPoint());
+ if (raw_pc == StubCode::DeoptimizeLazyFromReturn_entry()->EntryPoint()) {
+ return isolate()->FindPendingDeopt(GetCallerFp());
+ }
+ return raw_pc;
}
uword fp_;
@@ -348,6 +372,11 @@
};
+#if defined(DEBUG)
+void ValidateFrames();
+#endif
+
+
#if !defined(TARGET_ARCH_DBC)
DART_FORCE_INLINE static intptr_t LocalVarIndex(intptr_t fp_offset,
intptr_t var_index) {
diff --git a/runtime/vm/stub_code_arm.cc b/runtime/vm/stub_code_arm.cc
index 3bcf173..b7c2346 100644
--- a/runtime/vm/stub_code_arm.cc
+++ b/runtime/vm/stub_code_arm.cc
@@ -522,7 +522,7 @@
__ CallRuntime(kDeoptimizeMaterializeRuntimeEntry, 0);
// Result tells stub how many bytes to remove from the expression stack
// of the bottom-most frame. They were used as materialization arguments.
- __ Pop(R1);
+ __ Pop(R2);
if (kind == kLazyDeoptFromReturn) {
__ Pop(R0); // Restore result.
} else if (kind == kLazyDeoptFromThrow) {
@@ -531,34 +531,32 @@
}
__ LeaveStubFrame();
// Remove materialization arguments.
- __ add(SP, SP, Operand(R1, ASR, kSmiTagSize));
+ __ add(SP, SP, Operand(R2, ASR, kSmiTagSize));
__ Ret();
}
-// LR: return address + call-instruction-size
// R0: result, must be preserved
void StubCode::GenerateDeoptimizeLazyFromReturnStub(Assembler* assembler) {
- // Correct return address to point just after the call that is being
- // deoptimized.
- __ AddImmediate(LR, -CallPattern::DeoptCallPatternLengthInBytes());
// Push zap value instead of CODE_REG for lazy deopt.
__ LoadImmediate(IP, 0xf1f1f1f1);
__ Push(IP);
+ // Return address for "call" to deopt stub.
+ __ LoadImmediate(LR, 0xe1e1e1e1);
+ __ ldr(CODE_REG, Address(THR, Thread::lazy_deopt_from_return_stub_offset()));
GenerateDeoptimizationSequence(assembler, kLazyDeoptFromReturn);
}
-// LR: return address + call-instruction-size
// R0: exception, must be preserved
// R1: stacktrace, must be preserved
void StubCode::GenerateDeoptimizeLazyFromThrowStub(Assembler* assembler) {
- // Correct return address to point just after the call that is being
- // deoptimized.
- __ AddImmediate(LR, -CallPattern::DeoptCallPatternLengthInBytes());
// Push zap value instead of CODE_REG for lazy deopt.
__ LoadImmediate(IP, 0xf1f1f1f1);
__ Push(IP);
+ // Return address for "call" to deopt stub.
+ __ LoadImmediate(LR, 0xe1e1e1e1);
+ __ ldr(CODE_REG, Address(THR, Thread::lazy_deopt_from_throw_stub_offset()));
GenerateDeoptimizationSequence(assembler, kLazyDeoptFromThrow);
}
@@ -1898,12 +1896,12 @@
__ Push(R8);
__ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1);
__ Pop(R0); // Discard argument.
- __ Pop(R0); // Get Code object
+ __ Pop(R0); // Get Function object
__ Pop(R4); // Restore argument descriptor.
__ LeaveStubFrame();
- __ mov(CODE_REG, Operand(R0));
- __ ldr(R0, FieldAddress(R0, Code::entry_point_offset()));
- __ bx(R0);
+ __ ldr(CODE_REG, FieldAddress(R0, Function::code_offset()));
+ __ ldr(R1, FieldAddress(R0, Function::entry_point_offset()));
+ __ bx(R1);
__ bkpt(0);
}
@@ -2237,6 +2235,7 @@
// Called from the monomorphic checked entry.
// R0: receiver
void StubCode::GenerateMonomorphicMissStub(Assembler* assembler) {
+ __ ldr(CODE_REG, Address(THR, Thread::monomorphic_miss_stub_offset()));
__ EnterStubFrame();
__ Push(R0); // Preserve receiver.
diff --git a/runtime/vm/stub_code_arm64.cc b/runtime/vm/stub_code_arm64.cc
index 7ee3dd3..1e3c78c 100644
--- a/runtime/vm/stub_code_arm64.cc
+++ b/runtime/vm/stub_code_arm64.cc
@@ -542,8 +542,8 @@
__ CallRuntime(kDeoptimizeMaterializeRuntimeEntry, 0);
// Result tells stub how many bytes to remove from the expression stack
// of the bottom-most frame. They were used as materialization arguments.
- __ Pop(R1);
- __ SmiUntag(R1);
+ __ Pop(R2);
+ __ SmiUntag(R2);
if (kind == kLazyDeoptFromReturn) {
__ Pop(R0); // Restore result.
} else if (kind == kLazyDeoptFromThrow) {
@@ -552,34 +552,32 @@
}
__ LeaveStubFrame();
// Remove materialization arguments.
- __ add(SP, SP, Operand(R1));
+ __ add(SP, SP, Operand(R2));
__ ret();
}
-// LR: return address + call-instruction-size
// R0: result, must be preserved
void StubCode::GenerateDeoptimizeLazyFromReturnStub(Assembler* assembler) {
- // Correct return address to point just after the call that is being
- // deoptimized.
- __ AddImmediate(LR, LR, -CallPattern::kDeoptCallLengthInBytes);
// Push zap value instead of CODE_REG for lazy deopt.
__ LoadImmediate(TMP, 0xf1f1f1f1);
__ Push(TMP);
+ // Return address for "call" to deopt stub.
+ __ LoadImmediate(LR, 0xe1e1e1e1);
+ __ ldr(CODE_REG, Address(THR, Thread::lazy_deopt_from_return_stub_offset()));
GenerateDeoptimizationSequence(assembler, kLazyDeoptFromReturn);
}
-// LR: return address + call-instruction-size
// R0: exception, must be preserved
// R1: stacktrace, must be preserved
void StubCode::GenerateDeoptimizeLazyFromThrowStub(Assembler* assembler) {
- // Correct return address to point just after the call that is being
- // deoptimized.
- __ AddImmediate(LR, LR, -CallPattern::kDeoptCallLengthInBytes);
// Push zap value instead of CODE_REG for lazy deopt.
__ LoadImmediate(TMP, 0xf1f1f1f1);
__ Push(TMP);
+ // Return address for "call" to deopt stub.
+ __ LoadImmediate(LR, 0xe1e1e1e1);
+ __ ldr(CODE_REG, Address(THR, Thread::lazy_deopt_from_throw_stub_offset()));
GenerateDeoptimizationSequence(assembler, kLazyDeoptFromThrow);
}
@@ -1951,11 +1949,12 @@
__ Push(R6);
__ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1);
__ Pop(R0); // Discard argument.
- __ Pop(CODE_REG); // Get Code object
+ __ Pop(R0); // Get Function object
__ Pop(R4); // Restore argument descriptor.
- __ LoadFieldFromOffset(R0, CODE_REG, Code::entry_point_offset());
+ __ LoadFieldFromOffset(CODE_REG, R0, Function::code_offset());
+ __ LoadFieldFromOffset(R1, R0, Function::entry_point_offset());
__ LeaveStubFrame();
- __ br(R0);
+ __ br(R1);
__ brk(0);
}
@@ -2296,6 +2295,7 @@
// Called from the monomorphic checked entry.
// R0: receiver
void StubCode::GenerateMonomorphicMissStub(Assembler* assembler) {
+ __ ldr(CODE_REG, Address(THR, Thread::monomorphic_miss_stub_offset()));
__ EnterStubFrame();
__ Push(R0); // Preserve receiver.
diff --git a/runtime/vm/stub_code_ia32.cc b/runtime/vm/stub_code_ia32.cc
index fab258e..83f6ba0 100644
--- a/runtime/vm/stub_code_ia32.cc
+++ b/runtime/vm/stub_code_ia32.cc
@@ -461,27 +461,19 @@
}
-// TOS: return address + call-instruction-size (5 bytes).
// EAX: result, must be preserved
void StubCode::GenerateDeoptimizeLazyFromReturnStub(Assembler* assembler) {
- // Correct return address to point just after the call that is being
- // deoptimized.
- __ popl(EBX);
- __ subl(EBX, Immediate(CallPattern::pattern_length_in_bytes()));
- __ pushl(EBX);
+ // Return address for "call" to deopt stub.
+ __ pushl(Immediate(0xe1e1e1e1));
GenerateDeoptimizationSequence(assembler, kLazyDeoptFromReturn);
}
-// TOS: return address + call-instruction-size (5 bytes).
// EAX: exception, must be preserved
// EDX: stacktrace, must be preserved
void StubCode::GenerateDeoptimizeLazyFromThrowStub(Assembler* assembler) {
- // Correct return address to point just after the call that is being
- // deoptimized.
- __ popl(EBX);
- __ subl(EBX, Immediate(CallPattern::pattern_length_in_bytes()));
- __ pushl(EBX);
+ // Return address for "call" to deopt stub.
+ __ pushl(Immediate(0xe1e1e1e1));
GenerateDeoptimizationSequence(assembler, kLazyDeoptFromThrow);
}
@@ -1848,10 +1840,11 @@
__ pushl(EBX);
__ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1);
__ popl(EAX); // Discard argument.
- __ popl(EAX); // Get Code object
+ __ popl(EAX); // Get Function object
__ popl(EDX); // Restore argument descriptor.
- __ movl(EAX, FieldAddress(EAX, Code::entry_point_offset()));
__ LeaveFrame();
+ __ movl(CODE_REG, FieldAddress(EAX, Function::code_offset()));
+ __ movl(EAX, FieldAddress(EAX, Function::entry_point_offset()));
__ jmp(EAX);
__ int3();
}
diff --git a/runtime/vm/stub_code_mips.cc b/runtime/vm/stub_code_mips.cc
index de6db70..6df0642 100644
--- a/runtime/vm/stub_code_mips.cc
+++ b/runtime/vm/stub_code_mips.cc
@@ -547,29 +547,27 @@
__ Ret();
}
-// RA: return address + call-instruction-size
// V0: result, must be preserved
void StubCode::GenerateDeoptimizeLazyFromReturnStub(Assembler* assembler) {
- // Correct return address to point just after the call that is being
- // deoptimized.
- __ AddImmediate(RA, -CallPattern::kDeoptCallLengthInBytes);
// Push zap value instead of CODE_REG for lazy deopt.
__ LoadImmediate(TMP, 0xf1f1f1f1);
__ Push(TMP);
+ // Return address for "call" to deopt stub.
+ __ LoadImmediate(RA, 0xe1e1e1e1);
+ __ lw(CODE_REG, Address(THR, Thread::lazy_deopt_from_return_stub_offset()));
GenerateDeoptimizationSequence(assembler, kLazyDeoptFromReturn);
}
-// RA: return address + call-instruction-size
// V0: exception, must be preserved
// V1: stacktrace, must be preserved
void StubCode::GenerateDeoptimizeLazyFromThrowStub(Assembler* assembler) {
- // Correct return address to point just after the call that is being
- // deoptimized.
- __ AddImmediate(RA, -CallPattern::kDeoptCallLengthInBytes);
// Push zap value instead of CODE_REG for lazy deopt.
__ LoadImmediate(TMP, 0xf1f1f1f1);
__ Push(TMP);
+ // Return address for "call" to deopt stub.
+ __ LoadImmediate(RA, 0xe1e1e1e1);
+ __ lw(CODE_REG, Address(THR, Thread::lazy_deopt_from_throw_stub_offset()));
GenerateDeoptimizationSequence(assembler, kLazyDeoptFromThrow);
}
@@ -2025,12 +2023,13 @@
__ sw(T0, Address(SP, 0 * kWordSize));
__ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1);
__ Comment("OptimizeFunctionStub return");
- __ lw(CODE_REG, Address(SP, 1 * kWordSize)); // Get Code object
+ __ lw(T0, Address(SP, 1 * kWordSize)); // Get Function object
__ lw(S4, Address(SP, 2 * kWordSize)); // Restore argument descriptor.
__ addiu(SP, SP, Immediate(3 * kWordSize)); // Discard argument.
- __ lw(T0, FieldAddress(CODE_REG, Code::entry_point_offset()));
- __ LeaveStubFrameAndReturn(T0);
+ __ lw(CODE_REG, FieldAddress(T0, Function::code_offset()));
+ __ lw(T1, FieldAddress(T0, Function::entry_point_offset()));
+ __ LeaveStubFrameAndReturn(T1);
__ break_(0);
}
@@ -2373,6 +2372,7 @@
// Called from the monomorphic checked entry.
// T0: receiver
void StubCode::GenerateMonomorphicMissStub(Assembler* assembler) {
+ __ lw(CODE_REG, Address(THR, Thread::monomorphic_miss_stub_offset()));
__ EnterStubFrame();
__ Push(T0); // Preserve receiver.
diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
index 6ec5ba1..7ff72e2 100644
--- a/runtime/vm/stub_code_x64.cc
+++ b/runtime/vm/stub_code_x64.cc
@@ -497,31 +497,25 @@
}
-// TOS: return address + call-instruction-size (5 bytes).
// RAX: result, must be preserved
void StubCode::GenerateDeoptimizeLazyFromReturnStub(Assembler* assembler) {
- // Correct return address to point just after the call that is being
- // deoptimized.
- __ popq(RBX);
- __ subq(RBX, Immediate(ShortCallPattern::pattern_length_in_bytes()));
// Push zap value instead of CODE_REG for lazy deopt.
__ pushq(Immediate(0xf1f1f1f1));
- __ pushq(RBX);
+ // Return address for "call" to deopt stub.
+ __ pushq(Immediate(0xe1e1e1e1));
+ __ movq(CODE_REG, Address(THR, Thread::lazy_deopt_from_return_stub_offset()));
GenerateDeoptimizationSequence(assembler, kLazyDeoptFromReturn);
}
-// TOS: return address + call-instruction-size (5 bytes).
// RAX: exception, must be preserved
// RDX: stacktrace, must be preserved
void StubCode::GenerateDeoptimizeLazyFromThrowStub(Assembler* assembler) {
- // Correct return address to point just after the call that is being
- // deoptimized.
- __ popq(RBX);
- __ subq(RBX, Immediate(ShortCallPattern::pattern_length_in_bytes()));
// Push zap value instead of CODE_REG for lazy deopt.
__ pushq(Immediate(0xf1f1f1f1));
- __ pushq(RBX);
+ // Return address for "call" to deopt stub.
+ __ pushq(Immediate(0xe1e1e1e1));
+ __ movq(CODE_REG, Address(THR, Thread::lazy_deopt_from_throw_stub_offset()));
GenerateDeoptimizationSequence(assembler, kLazyDeoptFromThrow);
}
@@ -1920,11 +1914,12 @@
__ pushq(RDI); // Arg0: function to optimize
__ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1);
__ popq(RAX); // Disard argument.
- __ popq(CODE_REG); // Get Code object.
+ __ popq(RAX); // Get Code object.
__ popq(R10); // Restore argument descriptor.
- __ movq(RAX, FieldAddress(CODE_REG, Code::entry_point_offset()));
__ LeaveStubFrame();
- __ jmp(RAX);
+ __ movq(CODE_REG, FieldAddress(RAX, Function::code_offset()));
+ __ movq(RCX, FieldAddress(RAX, Function::entry_point_offset()));
+ __ jmp(RCX);
__ int3();
}
@@ -2265,6 +2260,7 @@
// Called from the monomorphic checked entry.
// RDI: receiver
void StubCode::GenerateMonomorphicMissStub(Assembler* assembler) {
+ __ movq(CODE_REG, Address(THR, Thread::monomorphic_miss_stub_offset()));
__ EnterStubFrame();
__ pushq(RDI); // Preserve receiver.
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h
index 50b5c47..093e82a 100644
--- a/runtime/vm/thread.h
+++ b/runtime/vm/thread.h
@@ -92,6 +92,10 @@
StubCode::MonomorphicMiss_entry()->code(), NULL) \
V(RawCode*, ic_lookup_through_code_stub_, \
StubCode::ICCallThroughCode_entry()->code(), NULL) \
+ V(RawCode*, lazy_deopt_from_return_stub_, \
+ StubCode::DeoptimizeLazyFromReturn_entry()->code(), NULL) \
+ V(RawCode*, lazy_deopt_from_throw_stub_, \
+ StubCode::DeoptimizeLazyFromThrow_entry()->code(), NULL) \
#endif
@@ -112,6 +116,8 @@
StubCode::CallToRuntime_entry()->EntryPoint(), 0) \
V(uword, megamorphic_call_checked_entry_, \
StubCode::MegamorphicCall_entry()->CheckedEntryPoint(), 0) \
+ V(uword, monomorphic_miss_entry_, \
+ StubCode::MonomorphicMiss_entry()->EntryPoint(), 0) \
#endif
diff --git a/runtime/vm/vm_sources.gypi b/runtime/vm/vm_sources.gypi
index 156b120..83b325f 100644
--- a/runtime/vm/vm_sources.gypi
+++ b/runtime/vm/vm_sources.gypi
@@ -362,6 +362,13 @@
'port_test.cc',
'precompiler.cc',
'precompiler.h',
+ 'kernel.h',
+ 'kernel.cc',
+ 'kernel_binary.cc',
+ 'kernel_to_il.cc',
+ 'kernel_to_il.h',
+ 'kernel_reader.h',
+ 'kernel_reader.cc',
'proccpuinfo.cc',
'proccpuinfo.h',
'profiler_service.cc',
diff --git a/runtime/vm/weak_code.cc b/runtime/vm/weak_code.cc
index 6dedc88..4de2189 100644
--- a/runtime/vm/weak_code.cc
+++ b/runtime/vm/weak_code.cc
@@ -76,7 +76,7 @@
code = frame->LookupDartCode();
if (IsOptimizedCode(code_objects, code)) {
ReportDeoptimization(code);
- DeoptimizeAt(code, frame->pc());
+ DeoptimizeAt(code, frame);
}
frame = iterator.NextFrame();
}
diff --git a/sdk/lib/_internal/js_runtime/lib/isolate_patch.dart b/sdk/lib/_internal/js_runtime/lib/isolate_patch.dart
index 79931ba..ed72e6c 100644
--- a/sdk/lib/_internal/js_runtime/lib/isolate_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/isolate_patch.dart
@@ -10,6 +10,8 @@
ReceivePortImpl,
RawReceivePortImpl;
+typedef _UnaryFunction(arg);
+
@patch
class Isolate {
static final _currentIsolateCache = IsolateNatives.currentIsolate;
@@ -42,6 +44,11 @@
(onExit != null) ||
(onError != null);
try {
+ // Check for the type of `entryPoint` on the spawning isolate to make
+ // error-handling easier.
+ if (entryPoint is! _UnaryFunction) {
+ throw new ArgumentError(entryPoint);
+ }
// TODO: Consider passing the errorsAreFatal/onExit/onError values
// as arguments to the internal spawnUri instead of setting
// them after the isolate has been created.
diff --git a/sdk/lib/_internal/js_runtime/lib/js_number.dart b/sdk/lib/_internal/js_runtime/lib/js_number.dart
index 1f9748c..7513b1e 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_number.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_number.dart
@@ -56,7 +56,7 @@
return JS('num', r'# % #', this, b);
}
- num abs() => JS('returns:num;effects:none;depends:none;throws:never',
+ num abs() => JS('returns:num;effects:none;depends:none;throws:never;gvn:true',
r'Math.abs(#)', this);
num get sign => this > 0 ? 1 : this < 0 ? -1 : this;
diff --git a/sdk/lib/io/http.dart b/sdk/lib/io/http.dart
index d61835c..f8eacb7 100644
--- a/sdk/lib/io/http.dart
+++ b/sdk/lib/io/http.dart
@@ -149,7 +149,7 @@
* about the streaming qualities of an HttpServer.
* Pausing the subscription of the stream, pauses at the OS level.
*
- * * The [http_server](https://pub.dartlang.org/packages/http_server)
+ * * The [shelf](https://pub.dartlang.org/packages/shelf)
* package on pub.dartlang.org contains a set of high-level classes that,
* together with this class, makes it easy to provide content through HTTP
* servers.
diff --git a/sdk/lib/io/io.dart b/sdk/lib/io/io.dart
index c0d63de..d3690f3 100644
--- a/sdk/lib/io/io.dart
+++ b/sdk/lib/io/io.dart
@@ -62,7 +62,7 @@
* The [HttpServer] class provides the basic functionality for
* implementing an HTTP server.
* For some higher-level building-blocks, we recommend that you try
- * the [http_server](https://pub.dartlang.org/packages/http_server)
+ * the [shelf](https://pub.dartlang.org/packages/shelf)
* pub package, which contains
* a set of high-level classes that, together with the [HttpServer] class
* in this library, make it easier to implement HTTP servers.
diff --git a/tests/co19/co19-co19.status b/tests/co19/co19-co19.status
index 8b1627d..0934228 100644
--- a/tests/co19/co19-co19.status
+++ b/tests/co19/co19-co19.status
@@ -18,6 +18,8 @@
LibTest/core/RegExp/firstMatch_A01_t01: Fail # co19 issue 742
+Language/Functions/Formal_Parameters/Optional_Formals/syntax_t14: Fail # co19 issue 80
+
[ $system == linux ]
LibTest/collection/ListBase/ListBase_class_A01_t01: Fail # co19 issue 72
LibTest/collection/ListBase/ListBase_class_A01_t02: Fail # co19 issue 72
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index 1a80ab8..cc8930b 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -541,23 +541,13 @@
Language/Metadata/compilation_t11: Pass # mirrors not supported, fails for the wrong reason
WebPlatformTest/shadow-dom/testcommon: Fail # mirrors not supported
-[ $compiler == dart2js && ($runtime == jsshell || ($fast_startup && ($runtime != chrome && $runtime != ff && $runtime != drt)))]
-LibTest/isolate/Isolate/spawn_A04_t04: Fail # please triage
+[ $compiler == dart2js && ($runtime == jsshell || ($fast_startup && ($runtime == safari || ($minified && $runtime == d8))))]
+LibTest/isolate/Isolate/spawn_A04_t04: Fail # Issue 27558
[ $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/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-004_t01: Fail # please triage
WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-004_t02: Fail # please triage
@@ -580,7 +570,6 @@
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/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
@@ -589,15 +578,15 @@
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/test-009_t01: Fail # please triage
-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 && $runtime == chrome && $fast_startup && $checked ]
+WebPlatformTest/custom-elements/instantiating/createElementNS_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
+
+[ $compiler == dart2js && $runtime == drt && $fast_startup && $checked ]
+WebPlatformTest/custom-elements/instantiating/createElementNS_A05_t01: RuntimeError # Please triage this failure
+WebPlatformTest/custom-elements/instantiating/createElement_A05_t01: RuntimeError # Please triage this failure
[ $compiler == dart2js && $fast_startup && $browser && $runtime != chrome && $runtime != drt]
WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-005_t01: Fail # please triage
@@ -626,7 +615,6 @@
WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t04: 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/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-002_t01: Fail # please triage
WebPlatformTest/shadow-dom/html-elements-in-shadow-trees/inert-html-elements/test-002_t01: Fail # please triage
@@ -676,8 +664,6 @@
[ $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
-LibTest/isolate/Isolate/spawn_A02_t04: RuntimeError # Issue 27185
-LibTest/isolate/Isolate/spawn_A02_t05: RuntimeError # Issue 27185
[ $compiler == dart2js && $minified ]
LibTest/typed_data/Float32List/runtimeType_A01_t01: fail # co19-roll r559: Please triage this failure
@@ -1797,13 +1783,7 @@
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 ]
+[ $compiler == dart2js && $runtime == chrome ]
WebPlatformTest/custom-elements/concepts/type_A03_t01: RuntimeError # Please triage this failure
[ $compiler == dart2js && $runtime == chrome && $checked ]
@@ -2004,8 +1984,15 @@
LayoutTests/fast/text/text-combine-shrink-to-fit_t01: RuntimeError # Please triage this failure
[ $compiler == dart2js && $runtime == chrome && $system == windows ]
-Language/Expressions/Bitwise_Expressions/method_invocation_super_t01: Pass, Slow # Issue 25940
Language/Classes/Constructors/Generative_Constructors/execution_of_an_initializer_t04: Pass, Slow # Issue 25940
+Language/Expressions/Bitwise_Expressions/method_invocation_super_t01: Pass, Slow # Issue 25940
+LayoutTests/fast/css/background-serialize_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dom/HTMLLabelElement/click-label_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dom/HTMLLabelElement/form/test1_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/forms/form-attribute-nonexistence-form-id_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/forms/onchange-change-type_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/html/empty-fragment-id-goto-top_t01: RuntimeError # Please triage this failure
+LibTest/isolate/Isolate/spawn_A04_t04: Skip # Times out. Please triage this failure
[ $compiler == dart2js && $runtime == chrome && $system == linux]
LayoutTests/fast/css/background-serialize_t01: RuntimeError # Please triage this failure
@@ -2674,19 +2661,7 @@
WebPlatformTest/webstorage/event_constructor_t01: RuntimeError # Please triage this failure
WebPlatformTest/webstorage/event_constructor_t02: RuntimeError # Please triage this failure
-[ $compiler == dart2js && $runtime == drt && $fast_startup ]
-WebPlatformTest/custom-elements/concepts/type_A04_t01: RuntimeError # Please triage this failure
-WebPlatformTest/custom-elements/instantiating/createElementNS_A02_t01: RuntimeError # Please triage this failure
-WebPlatformTest/custom-elements/instantiating/createElementNS_A03_t01: RuntimeError # Please triage this failure
-WebPlatformTest/custom-elements/instantiating/createElement_A02_t01: RuntimeError # Please triage this failure
-WebPlatformTest/custom-elements/instantiating/createElement_A03_t01: RuntimeError # Please triage this failure
-WebPlatformTest/custom-elements/instantiating/createElement_A04_t01: RuntimeError # Please triage this failure
-WebPlatformTest/custom-elements/instantiating/isAttribute_A01_t01: RuntimeError # Please triage this failure
-WebPlatformTest/custom-elements/instantiating/isAttribute_A01_t02: 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 == drt && $fast_startup == false ]
+[ $compiler == dart2js && $runtime == drt ]
WebPlatformTest/custom-elements/concepts/type_A03_t01: RuntimeError # Please triage this failure
[ $compiler == dart2js && $runtime == drt && $fast_startup && $checked ]
@@ -2794,7 +2769,6 @@
LayoutTests/fast/backgrounds/background-repeat-computed-style_t01: RuntimeError # Please triage this failure
LayoutTests/fast/backgrounds/background-shorthand-with-backgroundSize-style_t01: RuntimeError # Please triage this failure
LayoutTests/fast/backgrounds/mask-box-image-width_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/backgrounds/multiple-backgrounds-computed-style_t01: RuntimeError # Please triage this failure
LayoutTests/fast/backgrounds/repeat/parsing-background-repeat_t01: RuntimeError # Please triage this failure
LayoutTests/fast/borders/border-color-visited_t01: RuntimeError # Please triage this failure
LayoutTests/fast/borders/border-radius-child_t01: Pass, RuntimeError # Please triage this failure
@@ -2812,6 +2786,7 @@
LayoutTests/fast/canvas/canvas-blending-text_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-composite-canvas_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-composite-image_t01: Pass, RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/canvas-composite-text-alpha_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-currentColor_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-currentTransform_t01: RuntimeError # Feature is not implemented.
LayoutTests/fast/canvas/canvas-drawImage-incomplete_t01: RuntimeError # Please triage this failure
@@ -2845,12 +2820,13 @@
LayoutTests/fast/canvas/canvas-strokeRect-zeroSizeGradient_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-strokeText-invalid-maxWidth_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-strokeText-zeroSizeGradient_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/test-setting-canvas-color_t01: Pass, RuntimeError # co19 issue 64 (depends on the FF version)
LayoutTests/fast/canvas/canvas-toDataURL-crash_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/draw-custom-focus-ring_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/drawImage-with-valid-image_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/fillText-shadow_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/getPutImageDataPairTest_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/rgba-parsing_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/text-globalAlpha_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/WebGLContextEvent_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias-t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/context-destroyed-crash_t01: Pass, RuntimeError # Issue 26898
@@ -2858,10 +2834,10 @@
LayoutTests/fast/canvas/webgl/context-lost_t01: Pass, RuntimeError # Issue 26898
LayoutTests/fast/canvas/webgl/renderer-and-vendor-strings_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-array-buffer-view_t01: Skip # Times out.
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgb565_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgba4444_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgba5551_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/tex-input-validation_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/tex-sub-image-2d-bad-args_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/texture-transparent-pixels-initialized_t01: RuntimeError # Please triage this failure
@@ -2869,10 +2845,11 @@
LayoutTests/fast/canvas/webgl/uninitialized-test_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/webgl-depth-texture_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/webgl-large-texture_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css-generated-content/details-before-after-content_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css-generated-content/malformed-url_t01: Skip # Times out. Please triage this failure
-LayoutTests/fast/css-generated-content/pseudo-animation_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/css-generated-content/pseudo-animation-before-onload_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/css-generated-content/pseudo-animation-display_t01: Skip # Times out. Please triage this failure
+LayoutTests/fast/css-generated-content/pseudo-animation_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/css-generated-content/pseudo-element-events_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/css-generated-content/pseudo-transition-event_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/css-generated-content/pseudo-transition_t01: RuntimeError # Please triage this failure
@@ -2925,7 +2902,6 @@
LayoutTests/fast/css-intrinsic-dimensions/multicol_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css-intrinsic-dimensions/tables_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css-intrinsic-dimensions/width-property-value_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css-intrinsic-dimensions/width-shrinks-avoid-floats_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/aspect-ratio-inheritance_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/aspect-ratio-parsing-tests_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/auto-min-size_t01: RuntimeError # Please triage this failure
@@ -2938,7 +2914,6 @@
LayoutTests/fast/css/border-shorthand-initialize-longhands_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/border-start-end_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/border-width-large_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/box-sizing-backwards-compat-prefix_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/checked-pseudo-selector_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/child-selector-implicit-tbody_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/content/content-none_t01: RuntimeError # Please triage this failure
@@ -2948,14 +2923,11 @@
LayoutTests/fast/css/counters/counter-cssText_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/counters/counter-reset-subtree-insert-crash_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/css-escaped-identifier_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/css-keyframe-style-crash_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/css-keyframe-unexpected-end_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/css-properties-case-insensitive_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/css3-nth-tokens-style_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/csstext-of-content-string_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/cursor-parsing-image-set_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/cursor-parsing_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/deprecated-flex-box-zero-width-intrinsic-max-width_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/deprecated-flexbox-auto-min-size_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/draggable-region-parser_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/dynamic-class-backdrop-pseudo_t01: RuntimeError # Please triage this failure
@@ -2994,6 +2966,7 @@
LayoutTests/fast/css/inherited-properties-rare-text_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/insertRule-font-face_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/insertRule-media_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/invalid-hex-color_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/invalid-import-rule-insertion_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/invalid-predefined-color_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/invalidation/clears-invalidation-whole-tree_t01: RuntimeError # Please triage this failure
@@ -3059,6 +3032,7 @@
LayoutTests/fast/css/style-scoped/style-scoped-scoping-nodes-different-order_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/style-scoped/style-scoped-shadow-crash_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/style-scoped/style-scoped-with-important-rule_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/test-setting-canvas-color_t01: Pass, RuntimeError # co19 issue 64 (depends on the FF version)
LayoutTests/fast/css/text-align-webkit-match-parent-parse_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/text-align-webkit-match-parent_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/unicode-bidi-computed-value_t01: RuntimeError # Please triage this failure
@@ -3109,6 +3083,7 @@
LayoutTests/fast/dom/HTMLDialogElement/dialog-close-event_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/HTMLDialogElement/dialog-enabled_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/HTMLDialogElement/dialog-open_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dom/HTMLDialogElement/dialog-return-value_t01: RuntimeError # Dartium JSInterop failure
LayoutTests/fast/dom/HTMLDialogElement/dialog-scrolled-viewport_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/HTMLDialogElement/dialog-show-modal_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/HTMLDialogElement/inert-does-not-match-disabled-selector_t01: RuntimeError # Please triage this failure
@@ -3158,6 +3133,7 @@
LayoutTests/fast/dom/HTMLInputElement/input-hidden-value_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/HTMLInputElement/input-image-alt-text_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/HTMLLabelElement/click-label_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dom/HTMLLabelElement/form/test1_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/HTMLLinkElement/link-and-subresource-test_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/dom/HTMLLinkElement/link-beforeload-recursive_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/dom/HTMLLinkElement/link-onerror-stylesheet-with-existent-and-non-existent-import_t01: Pass, RuntimeError # Please triage this failure
@@ -3172,6 +3148,7 @@
LayoutTests/fast/dom/HTMLOptionElement/collection-setter-getter_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/HTMLOutputElement/dom-settable-token-list_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/HTMLOutputElement/htmloutputelement-validity_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dom/HTMLOutputElement/htmloutputelement_t01: RuntimeError # Issue 26714
LayoutTests/fast/dom/HTMLProgressElement/set-progress-properties_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/HTMLScriptElement/async-false-inside-async-false-load_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/HTMLScriptElement/async-inline-script_t01: RuntimeError # Please triage this failure
@@ -3281,8 +3258,6 @@
LayoutTests/fast/dom/horizontal-scrollbar-in-rtl-doesnt-fire-onscroll_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/horizontal-scrollbar-in-rtl_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/horizontal-scrollbar-when-dir-change_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/dom/HTMLDialogElement/dialog-return-value_t01: RuntimeError # Dartium JSInterop failure
-LayoutTests/fast/dom/HTMLOutputElement/htmloutputelement_t01: RuntimeError # Issue 26714
LayoutTests/fast/dom/icon-size-property_t01: RuntimeError # Issue 26714
LayoutTests/fast/dom/importNode-unsupported-node-type_t01: RuntimeError # Please triage this failure
LayoutTests/fast/dom/insert-span-into-long-text-bug-28245_t01: RuntimeError # Please triage this failure
@@ -3464,8 +3439,6 @@
LayoutTests/fast/filesystem/snapshot-file-with-gc_t01: RuntimeError # Please triage this failure
LayoutTests/fast/flexbox/box-orient-button_t01: RuntimeError # Please triage this failure
LayoutTests/fast/flexbox/box-size-integer-overflow_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/flexbox/flexing-overflow-scroll-item_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/flexbox/repaint-scrollbar_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/11423_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/4628409_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/8250_t01: RuntimeError # Please triage this failure
@@ -3484,8 +3457,8 @@
LayoutTests/fast/forms/autofocus-opera-005_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/autofocus-opera-007_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/forms/autofocus-readonly-attribute_t01: Skip # Times out. Please triage this failure
-LayoutTests/fast/forms/button/button-disabled-blur_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/forms/button-baseline-and-collapsing_t01: Pass, RuntimeError # Please triage this failure
+LayoutTests/fast/forms/button/button-disabled-blur_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/forms/checkValidity-001_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/forms/checkValidity-002_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/forms/checkValidity-004_t01: Pass, RuntimeError # Please triage this failure
@@ -3506,7 +3479,6 @@
LayoutTests/fast/forms/date/input-valueasdate-date_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/date/input-valueasnumber-date_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-change-layout-by-value_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/forms/datetimelocal/input-valueasnumber-datetimelocal_t01: RuntimeError # Dartium JSInterop failure
LayoutTests/fast/forms/datetimelocal/ValidityState-rangeOverflow-datetimelocal_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/datetimelocal/ValidityState-rangeUnderflow-datetimelocal_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/datetimelocal/ValidityState-stepMismatch-datetimelocal_t01: RuntimeError # Please triage this failure
@@ -3514,12 +3486,14 @@
LayoutTests/fast/forms/datetimelocal/datetimelocal-input-type_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/datetimelocal/datetimelocal-pseudo-classes_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/datetimelocal/input-valueasdate-datetimelocal_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/forms/datetimelocal/input-valueasnumber-datetimelocal_t01: RuntimeError # Dartium JSInterop failure
LayoutTests/fast/forms/delete-text-with-invisible-br_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/fieldset/fieldset-disabled_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/fieldset/fieldset-elements_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/file/file-input-capture_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/focus-style-pending_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/forms/focus_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/forms/form-attribute-nonexistence-form-id_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/form-attribute_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/form-dirname-attribute_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/formmethod-attribute-button-html_t01: Pass, RuntimeError # Please triage this failure
@@ -3565,8 +3539,8 @@
LayoutTests/fast/forms/setCustomValidity-existence_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/setrangetext_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/shadow-tree-exposure_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/forms/submit-form-with-dirname-attribute_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/forms/submit-form-with-dirname-attribute-with-ancestor-dir-attribute_t01: Pass, RuntimeError # Please triage this failure
+LayoutTests/fast/forms/submit-form-with-dirname-attribute_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/forms/text-control-select-blurred_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/textarea-maxlength_t01: RuntimeError # Please triage this failure
LayoutTests/fast/forms/textarea-no-scroll-on-blur_t01: RuntimeError # Please triage this failure
@@ -3585,7 +3559,6 @@
LayoutTests/fast/html/details-add-details-child-1_t01: RuntimeError # Please triage this failure
LayoutTests/fast/html/details-add-details-child-2_t01: RuntimeError # Please triage this failure
LayoutTests/fast/html/details-click-controls_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/html/details-mouse-click_t01: RuntimeError # Please triage this failure
LayoutTests/fast/html/figcaption-element_t01: RuntimeError # Please triage this failure
LayoutTests/fast/html/figure-element_t01: RuntimeError # Please triage this failure
LayoutTests/fast/html/footer-element_t01: RuntimeError # Please triage this failure
@@ -3699,11 +3672,11 @@
LayoutTests/fast/shapes/shape-outside-floats/shape-outside-floats-inset-rounded-different-writing-modes-right_t01: RuntimeError # Please triage this failure
LayoutTests/fast/shapes/shape-outside-floats/shape-outside-rounded-boxes_t01: RuntimeError # Please triage this failure
LayoutTests/fast/shapes/shape-outside-floats/shape-outside-rounded-boxes_t02: RuntimeError # Please triage this failure
-LayoutTests/fast/speechsynthesis/speech-synthesis-boundary-events_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/speechsynthesis/speech-synthesis-cancel_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/speechsynthesis/speech-synthesis-pause-resume_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/speechsynthesis/speech-synthesis-speak_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/speechsynthesis/speech-synthesis-utterance-uses-voice_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/speechsynthesis/speech-synthesis-boundary-events_t01: Skip # Times out. Please triage this failure
+LayoutTests/fast/speechsynthesis/speech-synthesis-cancel_t01: Skip # Times out. Please triage this failure
+LayoutTests/fast/speechsynthesis/speech-synthesis-pause-resume_t01: Skip # Times out. Please triage this failure
+LayoutTests/fast/speechsynthesis/speech-synthesis-speak_t01: Skip # Times out. Please triage this failure
+LayoutTests/fast/speechsynthesis/speech-synthesis-utterance-uses-voice_t01: Skip # Times out. Please triage this failure
LayoutTests/fast/speechsynthesis/speech-synthesis-voices_t01: RuntimeError # Please triage this failure
LayoutTests/fast/storage/disallowed-storage_t01: RuntimeError # Please triage this failure
LayoutTests/fast/storage/storage-disallowed-in-data-url_t01: RuntimeError # Please triage this failure
@@ -3749,8 +3722,6 @@
LayoutTests/fast/text/window-find_t01: RuntimeError # Please triage this failure
LayoutTests/fast/text/zero-width-characters-complex-script_t01: RuntimeError # Please triage this failure
LayoutTests/fast/text/zero-width-characters_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/transforms/topmost-becomes-bottomost-for-scrolling_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/transforms/transform-inside-overflow-scroll_t01: RuntimeError # Please triage this failure
LayoutTests/fast/url/anchor_t01: RuntimeError # Please triage this failure
LayoutTests/fast/url/file-http-base_t01: RuntimeError # Please triage this failure
LayoutTests/fast/url/file_t01: RuntimeError # Please triage this failure
@@ -3800,8 +3771,8 @@
LayoutTests/fast/xpath/node-name-case-sensitivity_t01: RuntimeError # Please triage this failure
LayoutTests/fast/xpath/node-name-case-sensitivity_t02: RuntimeError # Please triage this failure
LayoutTests/fast/xpath/position_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/xpath/py-dom-xpath/axes_t01: RuntimeError # Dartium JSInterop failure
LayoutTests/fast/xpath/py-dom-xpath/abbreviations_t01: RuntimeError # Dartium JSInterop failure
+LayoutTests/fast/xpath/py-dom-xpath/axes_t01: RuntimeError # Dartium JSInterop failure
LayoutTests/fast/xpath/py-dom-xpath/data_t01: RuntimeError # Please triage this failure
LayoutTests/fast/xpath/py-dom-xpath/expressions_t01: RuntimeError # Please triage this failure
LayoutTests/fast/xpath/py-dom-xpath/paths_t01: RuntimeError # Please triage this failure
@@ -3910,14 +3881,8 @@
LibTest/html/Window/resizeBy_A01_t01: RuntimeError # Please triage this failure
LibTest/html/Window/resizeTo_A01_t01: RuntimeError # Please triage this failure
LibTest/math/log_A01_t01: Fail # Please triage this failure.
-LibTest/typed_data/Float32List/Float32List.view_A06_t01: RuntimeError # Please triage this failure
LibTest/typed_data/Float32x4List/Float32x4List.view_A06_t01: RuntimeError # Please triage this failure
-LibTest/typed_data/Float64List/Float64List.view_A06_t01: RuntimeError # Please triage this failure
-LibTest/typed_data/Int16List/Int16List.view_A06_t01: RuntimeError # Please triage this failure
-LibTest/typed_data/Int32List/Int32List.view_A06_t01: RuntimeError # Please triage this failure
LibTest/typed_data/Int32x4/operator_OR_A01_t01: RuntimeError # Please triage this failure
-LibTest/typed_data/Uint16List/Uint16List.view_A06_t01: RuntimeError # Please triage this failure
-LibTest/typed_data/Uint32List/Uint32List.view_A06_t01: RuntimeError # Please triage this failure
WebPlatformTest/DOMEvents/approved/EventObject.after.dispatchEvenr_t01: RuntimeError # Please triage this failure
WebPlatformTest/DOMEvents/approved/ProcessingInstruction.DOMCharacterDataModified_t01: Skip # Times out. Please triage this failure
WebPlatformTest/DOMEvents/approved/addEventListener.optional.useCapture_t01: RuntimeError # Please triage this failure
@@ -3994,8 +3959,10 @@
WebPlatformTest/html/dom/elements/global-attributes/dataset-set_t01: RuntimeError # Please triage this failure
WebPlatformTest/html/semantics/embedded-content/media-elements/error-codes/error_t01: Skip # Times out. Please triage this failure
WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLMediaElement/addTextTrack_t01: RuntimeError # Please triage this failure
+WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/kind_t01: RuntimeError # Please triage this failure
WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/HTMLElement/HTMLTrackElement/src_t01: RuntimeError # Please triage this failure
WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/cues_t01: RuntimeError # Please triage this failure
+WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/kind_t01: RuntimeError # Please triage this failure
WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/mode_t01: RuntimeError # Please triage this failure
WebPlatformTest/html/semantics/forms/attributes-common-to-form-controls/formAction_document_address_t01: RuntimeError # Please triage this failure
WebPlatformTest/html/semantics/forms/attributes-common-to-form-controls/formaction_t01: RuntimeError # Please triage this failure
@@ -4030,7 +3997,6 @@
WebPlatformTest/html/semantics/forms/the-option-element/option-text-spaces_t01: RuntimeError # Please triage this failure
WebPlatformTest/html/semantics/grouping-content/the-blockquote-element/grouping-blockquote_t01: RuntimeError # Please triage this failure
WebPlatformTest/html/semantics/grouping-content/the-ol-element/ol.start-reflection_t02: RuntimeError # Please triage this failure
-WebPlatformTest/html/semantics/interactive-elements/the-details-element/toggleEvent_t01: RuntimeError # Please triage this failure
WebPlatformTest/html/semantics/interactive-elements/the-dialog-element/dialog-close_t01: RuntimeError # Please triage this failure
WebPlatformTest/html/semantics/interactive-elements/the-dialog-element/dialog-showModal_t01: RuntimeError # Please triage this failure
WebPlatformTest/html/semantics/scripting-1/the-script-element/script-text_t02: RuntimeError # Please triage this failure
@@ -4046,13 +4012,13 @@
WebPlatformTest/html/semantics/tabular-data/the-table-element/table-rows_t01: RuntimeError # Please triage this failure
WebPlatformTest/html/syntax/parsing/Document.getElementsByTagName-foreign_t02: RuntimeError # Please triage this failure
WebPlatformTest/html/syntax/serializing-html-fragments/outerHTML_t01: RuntimeError # Please triage this failure
-WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol_t00: RuntimeError # Please triage this failure
WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t01: RuntimeError # Please triage this failure
WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t02: RuntimeError # Please triage this failure
WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t03: RuntimeError # Please triage this failure
WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t04: RuntimeError # Please triage this failure
WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t05: RuntimeError # Please triage this failure
WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol/t06: RuntimeError # Please triage this failure
+WebPlatformTest/html/webappapis/system-state-and-capabilities/the-navigator-object/protocol_t00: RuntimeError # Please triage this failure
WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-001_t01: RuntimeError # Please triage this failure
WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-004_t01: RuntimeError # Please triage this failure
WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-004_t02: RuntimeError # Please triage this failure
@@ -4158,6 +4124,7 @@
WebPlatformTest/webstorage/storage_session_setitem_quotaexceedederr_t01: Skip # Times out. Please triage this failure
[ $compiler == dart2js && $runtime == ff && $system == windows ]
+LayoutTests/fast/canvas/webgl/draw-webgl-to-canvas-2d_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/drawingbuffer-test_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/webgl/gl-get-calls_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/font-face-multiple-ranges-for-unicode-range_t01: RuntimeError # Please triage this failure
@@ -5381,7 +5348,7 @@
LayoutTests/fast/canvas/canvas-blending-shadow_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-blending-text_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-blending-transforms_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-composite-canvas_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/canvas-composite-canvas_t01: Skip # Times out on Windows 8. Please triage this failure
LayoutTests/fast/canvas/canvas-composite-stroke-alpha_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-composite-text-alpha_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-currentTransform_t01: RuntimeError # Feature is not implemented
@@ -5586,7 +5553,6 @@
LayoutTests/fast/css/computed-offset-with-zoom_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/content/content-none_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/content/content-normal_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/content/content-quotes-01_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/content/content-quotes-05_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/css-escaped-identifier_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/css-properties-case-insensitive_t01: RuntimeError # Please triage this failure
@@ -6269,6 +6235,11 @@
LayoutTests/fast/xpath/reverse-axes_t01: RuntimeError # Please triage this failure
LayoutTests/fast/xpath/xpath-template-element_t01: RuntimeError # Please triage this failure
LayoutTests/fast/xsl/default-html_t01: RuntimeError # Please triage this failure
+LibTest/async/Future/doWhile_A05_t01: RuntimeError # Please triage this failure
+LibTest/async/Future/forEach_A04_t02: RuntimeError # Please triage this failure
+LibTest/async/Stream/timeout_A01_t01: Pass, RuntimeError # Please triage this failure
+LibTest/async/Stream/timeout_A03_t01: Pass, RuntimeError # Please triage this failure
+LibTest/async/Stream/timeout_A04_t01: Pass, RuntimeError # Please triage this failure
LibTest/core/List/List_A02_t01: RuntimeError # Please triage this failure
LibTest/core/List/List_A03_t01: RuntimeError # Please triage this failure
LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t01: RuntimeError # Issue 22200
@@ -6652,12 +6623,6 @@
WebPlatformTest/webstorage/event_local_key_t01: RuntimeError # Please triage this failure
WebPlatformTest/webstorage/event_session_key_t01: RuntimeError # Please triage this failure
-# This test is not flaky: IE10 on Windows 7 is different from IE10 on Windows 8.
-# The test fails on Windows 7's version, but it is currently not possible to test
-# for the OS version (see https://code.google.com/p/dart/issues/detail?id=22806).
-[ $compiler == dart2js && $runtime == ie10 ]
-LayoutTests/fast/table/hittest-tablecell-with-borders-bottom-edge_t01: RuntimeError, Pass # Issue 22752. Please triage this failure.
-
[ $compiler == dart2js && $runtime == ie10 ]
Language/Expressions/Top_level_Getter_Invocation/17_Getter_Invocation_A03_t02: Skip # Times out. Please triage this failure
Language/Statements/Yield_and_Yield_Each/Yield/execution_async_t01: RuntimeError # Issue 26615
@@ -6717,6 +6682,7 @@
LayoutTests/fast/canvas/canvas-blending-transforms_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-clip-rule_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-composite-canvas_t01: Pass, RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/canvas-composite-image_t01: Pass, RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-currentColor_t01: RuntimeError # Please triage this failure
LayoutTests/fast/canvas/canvas-currentTransform_t01: RuntimeError # Feature is not implemented
LayoutTests/fast/canvas/canvas-ellipse-360-winding_t01: RuntimeError # Please triage this failure
@@ -6954,7 +6920,6 @@
LayoutTests/fast/css/computed-offset-with-zoom_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/content/content-none_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/content/content-normal_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/content/content-quotes-01_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/content/content-quotes-03_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/content/content-quotes-06_t01: RuntimeError # Please triage this failure
LayoutTests/fast/css/counters/complex-before_t01: RuntimeError # Please triage this failure
@@ -7921,6 +7886,7 @@
LayoutTests/fast/table/css-table-max-width_t01: RuntimeError # Please triage this failure
LayoutTests/fast/table/css-table-width-with-border-padding_t01: RuntimeError # Please triage this failure
LayoutTests/fast/table/hittest-tablecell-right-edge_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/table/hittest-tablecell-with-borders-bottom-edge_t01: RuntimeError, Pass # Fails on Windows 7 but not Windows8.
LayoutTests/fast/table/hittest-tablecell-with-borders-right-edge_t01: RuntimeError # Please triage this failure
LayoutTests/fast/table/large-shrink-wrapped-width_t01: RuntimeError # Please triage this failure
LayoutTests/fast/table/margins-perpendicular-containing-block_t01: RuntimeError # Please triage this failure
@@ -8079,7 +8045,12 @@
LayoutTests/fast/xsl/xslt-fragment-in-empty-doc_t01: RuntimeError # Please triage this failure
LayoutTests/fast/xsl/xslt-string-parameters_t01: RuntimeError # Please triage this failure
LayoutTests/fast/xsl/xslt-transform-to-fragment-crash_t01: RuntimeError # Please triage this failure
+LibTest/async/Future/doWhile_A05_t01: Pass, RuntimeError # Sometimes passes on windows 8. Please triage this failure
+LibTest/async/Future/forEach_A04_t02: RuntimeError # Please triage this failure
LibTest/async/Stream/Stream.periodic_A01_t01: Pass, RuntimeError # Please triage this failure
+LibTest/async/Stream/timeout_A01_t01: Pass, RuntimeError # Sometimes passes on windows 8. Please triage this failure
+LibTest/async/Stream/timeout_A03_t01: Pass, RuntimeError # Sometimes passes on windows 8. Please triage this failure
+LibTest/async/Stream/timeout_A04_t01: Pass, RuntimeError # Sometimes passes on windows 8. Please triage this failure
LibTest/async/StreamController/StreamController.broadcast_A04_t01: Pass, RuntimeError # Please triage this failure
LibTest/async/Timer/Timer.periodic_A01_t01: Pass, RuntimeError # Please triage this failure
LibTest/async/Timer/Timer_A01_t01: Pass, RuntimeError # Please triage this failure
diff --git a/tests/co19/co19-dartium.status b/tests/co19/co19-dartium.status
index 91274b0..f2d3d8a 100644
--- a/tests/co19/co19-dartium.status
+++ b/tests/co19/co19-dartium.status
@@ -11,6 +11,8 @@
LayoutTests/fast/writing-mode/broken-ideographic-font_t01: Skip # Timing out on the bots. Please triage this failure.
LayoutTests/fast/writing-mode/flipped-blocks-hit-test-overflow_t01: Pass, RuntimeError # Issue 21605
LayoutTests/fast/writing-mode/vertical-inline-block-hittest_t01: Pass, RuntimeError # Issue 21605
+LibTest/collection/ListBase/ListBase_class_A01_t02: Skip # Timing out on the bots. Please triage this failure.
+WebPlatformTest/custom-elements/concepts/type_A07_t01: Skip # Timing out on the bots. Please triage this failure.
[ $compiler == none && $runtime == dartium && $system == windows ]
LayoutTests/fast/writing-mode/vertical-inline-block-hittest_t01: Pass, RuntimeError # Issue 21605
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index e0845d9..743ccfa 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -59,11 +59,7 @@
[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_app) && $system == windows ]
Language/Expressions/Function_Invocation/async_invokation_t04: Pass, RuntimeError # co19 issue 54
-[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_app) && $checked == false ]
-LibTest/isolate/Isolate/spawn_A02_t04: RuntimeError # Issue 27185
-LibTest/isolate/Isolate/spawn_A02_t05: RuntimeError, Crash # Issue 27185
-
-[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_app) && ($arch != x64 && $arch != simarm64 && $arch != arm64 && $arch != simdbc && $arch != simdbc64) ]
+[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_app) && ($arch != x64 && $arch != simarm64 && $arch != arm64 && $arch != simdbc64) ]
LibTest/core/int/operator_left_shift_A01_t02: Fail # co19 issue 129
[ ($compiler == none || $compiler == precompiler) && ($runtime == vm || $runtime == dart_precompiled) && ($arch == mips || $arch == arm64) ]
diff --git a/tests/compiler/dart2js/analyze_test_test.dart b/tests/compiler/dart2js/analyze_test_test.dart
index caa69cd..9f917bb 100644
--- a/tests/compiler/dart2js/analyze_test_test.dart
+++ b/tests/compiler/dart2js/analyze_test_test.dart
@@ -27,9 +27,6 @@
"Library 'package:async/async.dart' doesn't export a "
"'ForkableStream' declaration.",
],
- "/utils.dart": const [
- "Duplicated library name 'utils'.",
- ],
};
const List<String> SKIP_LIST = const <String>[
diff --git a/tests/compiler/dart2js/analyze_unused_dart2js_test.dart b/tests/compiler/dart2js/analyze_unused_dart2js_test.dart
index 6440587..ae753a2 100644
--- a/tests/compiler/dart2js/analyze_unused_dart2js_test.dart
+++ b/tests/compiler/dart2js/analyze_unused_dart2js_test.dart
@@ -39,7 +39,7 @@
// Serialization code is only used in test.
"lib/src/serialization/": const ["is never"],
- "lib/src/universe/universe.dart": const [
+ "lib/src/universe/world_builder.dart": const [
"The method 'getterInvocationsByName' is never called.",
"The method 'setterInvocationsByName' is never called."
],
diff --git a/tests/compiler/dart2js/js_spec_optimization_test.dart b/tests/compiler/dart2js/js_spec_optimization_test.dart
index 822175e..4b5df36 100644
--- a/tests/compiler/dart2js/js_spec_optimization_test.dart
+++ b/tests/compiler/dart2js/js_spec_optimization_test.dart
@@ -57,6 +57,33 @@
}
""";
+const String TEST_4 = r"""
+ import 'dart:_foreign_helper';
+ main() {
+ var s = JS('String|Null', '"Hello"');
+ var s1 = JS('returns:String;depends:none;effects:none;throws:null(1)',
+ '#.toLowerCase()', s);
+ var s2 = JS('returns:String;depends:none;effects:none;throws:null(1)',
+ '#.toUpperCase()', s);
+
+ // present: 'erCase' - retained at least one call to guarantee exception.
+ }
+""";
+
+const String TEST_5 = r"""
+ import 'dart:_foreign_helper';
+ main() {
+ var s = JS('String', '"Hello"');
+ var s1 = JS('returns:String;depends:none;effects:none;throws:null(1)',
+ '#.toLowerCase()', s);
+ var s2 = JS('returns:String;depends:none;effects:none;throws:null(1)',
+ '#.toUpperCase()', s);
+
+ // absent: 'erCase' - neither call needs to be retained since there is no
+ // exception.
+ }
+""";
+
main() {
RegExp directivePattern = new RegExp(
// \1 \2 \3
@@ -90,5 +117,7 @@
check(TEST_1),
check(TEST_2),
check(TEST_3),
+ check(TEST_4),
+ check(TEST_5),
]));
}
diff --git a/tests/compiler/dart2js/kernel/assert_test.dart b/tests/compiler/dart2js/kernel/assert_test.dart
new file mode 100644
index 0000000..1495ff4
--- /dev/null
+++ b/tests/compiler/dart2js/kernel/assert_test.dart
@@ -0,0 +1,35 @@
+// 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:compiler/src/commandline_options.dart' show Flags;
+import 'package:test/test.dart';
+
+import 'helper.dart' show check;
+
+main() {
+ test('assert without message', () {
+ String code = '''
+bool foo() => 2 + 2 == 4;
+main() {
+ assert(foo());
+}''';
+ return check(code, extraOptions: const <String>[Flags.enableCheckedMode]);
+ });
+
+ test('assert with message', () {
+ String code = '''
+bool foo() => 2 + 2 == 4;
+main() {
+ assert(foo(), "foo failed");
+}''';
+ return check(code,
+ // disable type inference because kernel doesn't yet support
+ // checked mode type checks
+ disableTypeInference: false,
+ extraOptions: const <String>[
+ Flags.enableCheckedMode,
+ Flags.enableAssertMessage,
+ ]);
+ });
+}
diff --git a/tests/compiler/dart2js/kernel/helper.dart b/tests/compiler/dart2js/kernel/helper.dart
index 1d83a10..d7d4b11 100644
--- a/tests/compiler/dart2js/kernel/helper.dart
+++ b/tests/compiler/dart2js/kernel/helper.dart
@@ -16,12 +16,14 @@
Future<String> compile(String code,
{String entry: 'main',
bool useKernel: true,
- bool disableTypeInference: true}) async {
+ bool disableTypeInference: true,
+ List<String> extraOptions: const <String>[]}) async {
List<String> options = <String>[
Flags.disableInlining,
];
if (disableTypeInference) options.add(Flags.disableTypeInference);
if (useKernel) options.add(Flags.useKernel);
+ options.addAll(extraOptions);
if (entry != 'main' && !code.contains('main')) {
code = "$code\n\nmain() => $entry;";
@@ -36,14 +38,18 @@
}
Future check(String code,
- {String entry: 'main', bool disableTypeInference: true}) async {
+ {String entry: 'main',
+ bool disableTypeInference: true,
+ List<String> extraOptions: const <String>[]}) async {
var original = await compile(code,
entry: entry,
useKernel: false,
- disableTypeInference: disableTypeInference);
+ disableTypeInference: disableTypeInference,
+ extraOptions: extraOptions);
var kernel = await compile(code,
entry: entry,
useKernel: true,
- disableTypeInference: disableTypeInference);
+ disableTypeInference: disableTypeInference,
+ extraOptions: extraOptions);
expect(kernel, original);
}
diff --git a/tests/compiler/dart2js/kernel/impact_test.dart b/tests/compiler/dart2js/kernel/impact_test.dart
index 2716d53..3d5f56f 100644
--- a/tests/compiler/dart2js/kernel/impact_test.dart
+++ b/tests/compiler/dart2js/kernel/impact_test.dart
@@ -11,12 +11,15 @@
import 'package:compiler/src/common/names.dart';
import 'package:compiler/src/common/resolution.dart';
import 'package:compiler/src/compiler.dart';
+import 'package:compiler/src/dart_types.dart';
import 'package:compiler/src/elements/elements.dart';
import 'package:compiler/src/resolution/registry.dart';
import 'package:compiler/src/ssa/kernel_impact.dart';
import 'package:compiler/src/serialization/equivalence.dart';
+import 'package:compiler/src/universe/call_structure.dart';
import 'package:compiler/src/universe/feature.dart';
import 'package:compiler/src/universe/use.dart';
+import 'package:expect/expect.dart';
import '../memory_compiler.dart';
import '../serialization/test_helper.dart';
@@ -53,14 +56,57 @@
testPostDec(null);
testPreInc(null);
testPreDec(null);
+ testIs(null);
+ testIsGeneric(null);
+ testIsGenericRaw(null);
+ testIsGenericDynamic(null);
+ testIsNot(null);
+ testIsNotGeneric(null);
+ testIsNotGenericRaw(null);
+ testIsNotGenericDynamic(null);
+ testIsTypedef(null);
+ testIsTypedefGeneric(null);
+ testIsTypedefGenericRaw(null);
+ testIsTypedefGenericDynamic(null);
+ testAs(null);
+ testAsGeneric(null);
+ testAsGenericRaw(null);
+ testAsGenericDynamic(null);
+ testThrow();
+ testIfNull(null);
+ testSetIfNull(null);
+ testSyncStar();
+ testAsync();
+ testAsyncStar();
testIfThen();
testIfThenElse();
+ testForIn(null);
+ testForInTyped(null);
+ testAsyncForIn(null);
+ testAsyncForInTyped(null);
+ testTryCatch();
+ testTryCatchOn();
+ testTryCatchStackTrace();
+ testTryFinally();
+ testSwitchWithoutFallthrough(null);
+ testSwitchWithFallthrough(null);
testTopLevelInvoke();
testTopLevelInvokeTyped();
testTopLevelFunctionTyped();
testTopLevelFunctionGet();
+ testTopLevelGetterGet();
+ testTopLevelGetterGetTyped();
+ testTopLevelSetterSet();
+ testTopLevelSetterSetTyped();
testTopLevelField();
+ testTopLevelFieldLazy();
+ testTopLevelFieldConst();
+ testTopLevelFieldFinal();
testTopLevelFieldTyped();
+ testTopLevelFieldGeneric1();
+ testTopLevelFieldGeneric2();
+ testTopLevelFieldGeneric3();
+ testTopLevelFieldWrite();
testDynamicInvoke(null);
testDynamicGet(null);
testDynamicSet(null);
@@ -77,6 +123,10 @@
testInvokeIndexSet(null);
testAssert();
testAssertWithMessage();
+ testConstructorInvoke();
+ testConstructorInvokeGeneric();
+ testConstructorInvokeGenericRaw();
+ testConstructorInvokeGenericDynamic();
testFactoryInvoke();
testFactoryInvokeGeneric();
testFactoryInvokeGenericRaw();
@@ -85,6 +135,14 @@
testRedirectingFactoryInvokeGeneric();
testRedirectingFactoryInvokeGenericRaw();
testRedirectingFactoryInvokeGenericDynamic();
+ testConstRedirectingFactoryInvoke();
+ testConstRedirectingFactoryInvokeGeneric();
+ testConstRedirectingFactoryInvokeGenericRaw();
+ testConstRedirectingFactoryInvokeGenericDynamic();
+ testImplicitConstructor();
+ testFactoryConstructor();
+ testDefaultValuesPositional();
+ testDefaultValuesNamed();
}
testEmpty() {}
@@ -117,6 +175,30 @@
testPostDec(o) => o--;
testPreInc(o) => ++o;
testPreDec(o) => --o;
+
+testIs(o) => o is Class;
+testIsGeneric(o) => o is GenericClass<int, String>;
+testIsGenericRaw(o) => o is GenericClass;
+testIsGenericDynamic(o) => o is GenericClass<dynamic, dynamic>;
+testIsNot(o) => o is! Class;
+testIsNotGeneric(o) => o is! GenericClass<int, String>;
+testIsNotGenericRaw(o) => o is! GenericClass;
+testIsNotGenericDynamic(o) => o is! GenericClass<dynamic, dynamic>;
+testIsTypedef(o) => o is Typedef;
+testIsTypedefGeneric(o) => o is GenericTypedef<int, String>;
+testIsTypedefGenericRaw(o) => o is GenericTypedef;
+testIsTypedefGenericDynamic(o) => o is GenericTypedef<dynamic, dynamic>;
+testAs(o) => o as Class;
+testAsGeneric(o) => o as GenericClass<int, String>;
+testAsGenericRaw(o) => o as GenericClass;
+testAsGenericDynamic(o) => o as GenericClass<dynamic, dynamic>;
+testThrow() => throw '';
+testIfNull(o) => o ?? 42;
+testSetIfNull(o) => o ??= 42;
+
+testSyncStar() sync* {}
+testAsync() async {}
+testAsyncStar() async* {}
testIfThen() {
if (false) return 42;
return 1;
@@ -128,6 +210,55 @@
return 1;
}
}
+testForIn(o) {
+ for (var e in o) {}
+}
+testForInTyped(o) {
+ for (int e in o) {}
+}
+testAsyncForIn(o) async {
+ await for (var e in o) {}
+}
+testAsyncForInTyped(o) async {
+ await for (int e in o) {}
+}
+testTryCatch() {
+ try {} catch (e) {}
+}
+testTryCatchOn() {
+ try {} on String catch (e) {}
+}
+testTryCatchStackTrace() {
+ try {} catch (e, s) {}
+}
+testTryFinally() {
+ try {} finally {}
+}
+testSwitchWithoutFallthrough(o) {
+ switch (o) {
+ case 0:
+ case 1:
+ o = 2;
+ break;
+ case 2:
+ o = 3;
+ return;
+ case 3:
+ default:
+ }
+}
+testSwitchWithFallthrough(o) {
+ switch (o) {
+ case 0:
+ case 1:
+ o = 2;
+ case 2:
+ o = 3;
+ return;
+ case 3:
+ default:
+ }
+}
topLevelFunction1(a) {}
topLevelFunction2(a, [b, c]) {}
topLevelFunction3(a, {b, c}) {}
@@ -170,11 +301,32 @@
topLevelFunctionTyped4(null);
}
testTopLevelFunctionGet() => topLevelFunction1;
+get topLevelGetter => 0;
+testTopLevelGetterGet() => topLevelGetter;
+int get topLevelGetterTyped => 0;
+testTopLevelGetterGetTyped() => topLevelGetterTyped;
+set topLevelSetter(_) {}
+testTopLevelSetterSet() => topLevelSetter = 0;
+void set topLevelSetterTyped(int value) {}
+testTopLevelSetterSetTyped() => topLevelSetterTyped = 0;
var topLevelField;
testTopLevelField() => topLevelField;
+var topLevelFieldLazy = topLevelFunction1(null);
+testTopLevelFieldLazy() => topLevelFieldLazy;
+const topLevelFieldConst = 0;
+testTopLevelFieldConst() => topLevelFieldConst;
+final topLevelFieldFinal = topLevelFunction1(null);
+testTopLevelFieldFinal() => topLevelFieldFinal;
int topLevelFieldTyped;
testTopLevelFieldTyped() => topLevelFieldTyped;
+GenericClass topLevelFieldGeneric1;
+testTopLevelFieldGeneric1() => topLevelFieldGeneric1;
+GenericClass<dynamic, dynamic> topLevelFieldGeneric2;
+testTopLevelFieldGeneric2() => topLevelFieldGeneric2;
+GenericClass<int, String> topLevelFieldGeneric3;
+testTopLevelFieldGeneric3() => topLevelFieldGeneric3;
+testTopLevelFieldWrite() => topLevelField = 3;
testDynamicInvoke(o) {
o.f1(0);
o.f2(1);
@@ -225,6 +377,18 @@
testAssertWithMessage() {
assert(true, 'ok');
}
+testConstructorInvoke() {
+ new Class.generative();
+}
+testConstructorInvokeGeneric() {
+ new GenericClass<int, String>.generative();
+}
+testConstructorInvokeGenericRaw() {
+ new GenericClass.generative();
+}
+testConstructorInvokeGenericDynamic() {
+ new GenericClass<dynamic, dynamic>.generative();
+}
testFactoryInvoke() {
new Class.fact();
}
@@ -249,18 +413,40 @@
testRedirectingFactoryInvokeGenericDynamic() {
new GenericClass<dynamic, dynamic>.redirect();
}
+testConstRedirectingFactoryInvoke() {
+ const Class.redirect();
+}
+testConstRedirectingFactoryInvokeGeneric() {
+ const GenericClass<int, String>.redirect();
+}
+testConstRedirectingFactoryInvokeGenericRaw() {
+ const GenericClass.redirect();
+}
+testConstRedirectingFactoryInvokeGenericDynamic() {
+ const GenericClass<dynamic, dynamic>.redirect();
+}
+class ClassImplicitConstructor {}
+testImplicitConstructor() => new ClassImplicitConstructor();
+class ClassFactoryConstructor {
+ factory ClassFactoryConstructor() => null;
+}
+testFactoryConstructor() => new ClassFactoryConstructor();
+testDefaultValuesPositional([bool value = false]) {}
+testDefaultValuesNamed({bool value: false}) {}
''',
'helper.dart': '''
class Class {
- Class.generative();
+ const Class.generative();
factory Class.fact() => null;
- factory Class.redirect() = Class.generative;
+ const factory Class.redirect() = Class.generative;
}
class GenericClass<X, Y> {
- GenericClass.generative();
+ const GenericClass.generative();
factory GenericClass.fact() => null;
- factory GenericClass.redirect() = GenericClass.generative;
+ const factory GenericClass.redirect() = GenericClass<X, Y>.generative;
}
+typedef Typedef();
+typedef X GenericTypedef<X, Y>(Y y);
''',
};
@@ -285,7 +471,12 @@
void checkLibrary(Compiler compiler, LibraryElement library) {
library.forEachLocalMember((AstElement element) {
if (element.isClass) {
- // TODO(johnniwinther): Handle class members.
+ ClassElement cls = element;
+ cls.forEachLocalMember((AstElement member) {
+ checkElement(compiler, member);
+ });
+ } else if (element.isTypedef) {
+ // Skip typedefs.
} else {
checkElement(compiler, element);
}
@@ -294,35 +485,67 @@
void checkElement(Compiler compiler, AstElement element) {
ResolutionImpact astImpact = compiler.resolution.getResolutionImpact(element);
- astImpact = laxImpact(element, astImpact);
+ astImpact = laxImpact(compiler, element, astImpact);
ResolutionImpact kernelImpact = build(compiler, element.resolvedAst);
+ Expect.isNotNull(kernelImpact, 'No impact computed for $element');
testResolutionImpactEquivalence(
astImpact, kernelImpact, const CheckStrategy());
}
/// Lax the precision of [impact] to meet expectancy of the corresponding impact
/// generated from kernel.
-ResolutionImpact laxImpact(AstElement element, ResolutionImpact impact) {
+ResolutionImpact laxImpact(
+ Compiler compiler, AstElement element, ResolutionImpact impact) {
ResolutionWorldImpactBuilder builder =
new ResolutionWorldImpactBuilder('Lax impact of ${element}');
- impact.staticUses.forEach(builder.registerStaticUse);
+ for (StaticUse staticUse in impact.staticUses) {
+ switch (staticUse.kind) {
+ case StaticUseKind.CONST_CONSTRUCTOR_INVOKE:
+ ConstructorElement constructor = staticUse.element;
+ ConstructorElement effectiveTarget = constructor.effectiveTarget;
+ DartType effectiveTargetType =
+ constructor.computeEffectiveTargetType(staticUse.type);
+ builder.registerStaticUse(new StaticUse.constConstructorInvoke(
+ effectiveTarget, null, effectiveTargetType));
+ break;
+ default:
+ builder.registerStaticUse(staticUse);
+ break;
+ }
+ }
impact.dynamicUses.forEach(builder.registerDynamicUse);
- impact.typeUses.forEach(builder.registerTypeUse);
+ for (TypeUse typeUse in impact.typeUses) {
+ if (typeUse.type.isTypedef) {
+ typeUse = new TypeUse.internal(typeUse.type.unaliased, typeUse.kind);
+ }
+ builder.registerTypeUse(typeUse);
+ }
impact.constantLiterals.forEach(builder.registerConstantLiteral);
impact.constSymbolNames.forEach(builder.registerConstSymbolName);
impact.listLiterals.forEach(builder.registerListLiteral);
impact.mapLiterals.forEach(builder.registerMapLiteral);
for (Feature feature in impact.features) {
- builder.registerFeature(feature);
switch (feature) {
case Feature.STRING_INTERPOLATION:
case Feature.STRING_JUXTAPOSITION:
// These are both converted into a string concatenation in kernel so
- // we cannot tell the diferrence.
+ // we cannot tell the difference.
builder.registerFeature(Feature.STRING_INTERPOLATION);
builder.registerFeature(Feature.STRING_JUXTAPOSITION);
break;
+ case Feature.FALL_THROUGH_ERROR:
+ LibraryElement library =
+ compiler.libraryLoader.lookupLibrary(Uris.dart_core);
+ ClassElement cls =
+ library.implementation.localLookup('FallThroughError');
+ ConstructorElement constructor = cls.lookupConstructor('');
+ builder.registerStaticUse(new StaticUse.typedConstructorInvoke(
+ constructor, CallStructure.NO_ARGS, cls.thisType));
+ builder.registerFeature(Feature.THROW_EXPRESSION);
+ break;
default:
+ builder.registerFeature(feature);
+ break;
}
}
impact.nativeData.forEach(builder.registerNativeData);
diff --git a/tests/compiler/dart2js/kernel/visitor_test.dart b/tests/compiler/dart2js/kernel/visitor_test.dart
index 1edd591..68a6f89 100644
--- a/tests/compiler/dart2js/kernel/visitor_test.dart
+++ b/tests/compiler/dart2js/kernel/visitor_test.dart
@@ -7,6 +7,7 @@
import 'dart:io';
import 'package:compiler/src/compiler.dart' show Compiler;
+import 'package:compiler/src/elements/elements.dart';
import 'package:compiler/src/js_backend/backend.dart' show JavaScriptBackend;
import 'package:compiler/src/commandline_options.dart' show Flags;
import 'package:kernel/ast.dart';
@@ -22,6 +23,8 @@
const List<String> SKIP_TESTS = const <String>[];
main(List<String> arguments) {
+ Compiler compiler = compilerFor(
+ options: [Flags.analyzeOnly, Flags.analyzeMain, Flags.useKernel]);
Directory directory = new Directory('${TESTCASE_DIR}/input');
for (FileSystemEntity file in directory.listSync()) {
if (file is File && file.path.endsWith('.dart')) {
@@ -33,16 +36,13 @@
}
test(name, () async {
- var result = await runCompiler(
- entryPoint: file.absolute.uri,
- options: [Flags.analyzeOnly, Flags.useKernel]);
- Compiler compiler = result.compiler;
+ LibraryElement library = await compiler.analyzeUri(file.absolute.uri);
JavaScriptBackend backend = compiler.backend;
StringBuffer buffer = new StringBuffer();
- Program program = backend.kernelTask.program;
+ Program program = backend.kernelTask.buildProgram(library);
new MixinFullResolution().transform(program);
- new Printer(buffer).writeLibraryFile(
- backend.kernelTask.program.mainMethod.enclosingLibrary);
+ new Printer(buffer)
+ .writeLibraryFile(program.mainMethod.enclosingLibrary);
String actual = buffer.toString();
String expected =
new File('${TESTCASE_DIR}/spec-mode/$name.baseline.txt')
diff --git a/tests/compiler/dart2js/mock_libraries.dart b/tests/compiler/dart2js/mock_libraries.dart
index 4ceb375..867bf4d 100644
--- a/tests/compiler/dart2js/mock_libraries.dart
+++ b/tests/compiler/dart2js/mock_libraries.dart
@@ -155,6 +155,9 @@
String contextName, var context,
var typeArguments) {}''',
'checkMalformedType': 'checkMalformedType(value, message) {}',
+ 'checkInt': 'checkInt(value) {}',
+ 'checkNum': 'checkNum(value) {}',
+ 'checkString': 'checkString(value) {}',
'Closure': 'abstract class Closure implements Function { }',
'closureFromTearOff':
r'''closureFromTearOff(receiver, functions, reflectionInfo,
diff --git a/tests/compiler/dart2js/needs_no_such_method_test.dart b/tests/compiler/dart2js/needs_no_such_method_test.dart
new file mode 100644
index 0000000..3dadbb7
--- /dev/null
+++ b/tests/compiler/dart2js/needs_no_such_method_test.dart
@@ -0,0 +1,293 @@
+// 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:async';
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+import 'package:compiler/src/common.dart';
+import 'package:compiler/src/elements/elements.dart'
+ show Element, ClassElement, PublicName;
+import 'package:compiler/src/universe/call_structure.dart';
+import 'package:compiler/src/universe/selector.dart';
+import 'package:compiler/src/world.dart' show ClosedWorld, ClassQuery;
+import 'type_test_helper.dart';
+
+void main() {
+ asyncTest(() async {
+ await testClassSets();
+ });
+}
+
+const String CLASSES = r"""
+class Superclass {
+ foo() {}
+}
+class Subclass extends Superclass {
+ bar() {}
+}
+class Subtype implements Superclass {
+ bar() {}
+}
+""";
+
+testClassSets() async {
+ Selector foo, bar, baz;
+ ClosedWorld closedWorld;
+ ClassElement superclass, subclass, subtype;
+
+ Future run(List<String> instantiated) async {
+ StringBuffer main = new StringBuffer();
+ main.write('main() {');
+ for (String cls in instantiated) {
+ main.write('new $cls();');
+ }
+ main.write('}');
+
+ var env = await TypeEnvironment.create(CLASSES,
+ mainSource: main.toString(), useMockCompiler: false);
+ foo = new Selector.call(const PublicName('foo'), CallStructure.NO_ARGS);
+ bar = new Selector.call(const PublicName('bar'), CallStructure.NO_ARGS);
+ baz = new Selector.call(const PublicName('baz'), CallStructure.NO_ARGS);
+
+ closedWorld = env.compiler.closedWorld;
+ superclass = env.getElement('Superclass');
+ subclass = env.getElement('Subclass');
+ subtype = env.getElement('Subtype');
+ }
+
+ void check(ClassElement cls, ClassQuery query, Selector selector,
+ bool expectedResult) {
+ bool result = closedWorld.needsNoSuchMethod(cls, selector, query);
+ Expect.equals(expectedResult, result,
+ 'Unexpected result for $selector in $cls ($query)');
+ }
+
+ await run([]);
+
+ Expect.isFalse(closedWorld.isDirectlyInstantiated(superclass));
+ Expect.isFalse(closedWorld.isIndirectlyInstantiated(superclass));
+ Expect.isFalse(closedWorld.isImplemented(superclass));
+
+ Expect.isFalse(closedWorld.isDirectlyInstantiated(subclass));
+ Expect.isFalse(closedWorld.isIndirectlyInstantiated(subclass));
+ Expect.isFalse(closedWorld.isImplemented(subclass));
+
+ Expect.isFalse(closedWorld.isDirectlyInstantiated(subtype));
+ Expect.isFalse(closedWorld.isIndirectlyInstantiated(subtype));
+ Expect.isFalse(closedWorld.isImplemented(subtype));
+
+ check(superclass, ClassQuery.EXACT, foo, false);
+ check(superclass, ClassQuery.EXACT, bar, false);
+ check(superclass, ClassQuery.EXACT, baz, false);
+ check(superclass, ClassQuery.SUBCLASS, foo, false);
+ check(superclass, ClassQuery.SUBCLASS, bar, false);
+ check(superclass, ClassQuery.SUBCLASS, baz, false);
+ check(superclass, ClassQuery.SUBTYPE, foo, false);
+ check(superclass, ClassQuery.SUBTYPE, bar, false);
+ check(superclass, ClassQuery.SUBTYPE, baz, false);
+
+ check(subclass, ClassQuery.EXACT, foo, false);
+ check(subclass, ClassQuery.EXACT, bar, false);
+ check(subclass, ClassQuery.EXACT, baz, false);
+ check(subclass, ClassQuery.SUBCLASS, foo, false);
+ check(subclass, ClassQuery.SUBCLASS, bar, false);
+ check(subclass, ClassQuery.SUBCLASS, baz, false);
+ check(subclass, ClassQuery.SUBTYPE, foo, false);
+ check(subclass, ClassQuery.SUBTYPE, bar, false);
+ check(subclass, ClassQuery.SUBTYPE, baz, false);
+
+ check(subtype, ClassQuery.EXACT, foo, false);
+ check(subtype, ClassQuery.EXACT, bar, false);
+ check(subtype, ClassQuery.EXACT, baz, false);
+ check(subtype, ClassQuery.SUBCLASS, foo, false);
+ check(subtype, ClassQuery.SUBCLASS, bar, false);
+ check(subtype, ClassQuery.SUBCLASS, baz, false);
+ check(subtype, ClassQuery.SUBTYPE, foo, false);
+ check(subtype, ClassQuery.SUBTYPE, bar, false);
+ check(subtype, ClassQuery.SUBTYPE, baz, false);
+
+ await run(['Superclass']);
+
+ Expect.isTrue(closedWorld.isDirectlyInstantiated(superclass));
+ Expect.isFalse(closedWorld.isIndirectlyInstantiated(superclass));
+ Expect.isTrue(closedWorld.isImplemented(superclass));
+
+ Expect.isFalse(closedWorld.isDirectlyInstantiated(subclass));
+ Expect.isFalse(closedWorld.isIndirectlyInstantiated(subclass));
+ Expect.isFalse(closedWorld.isImplemented(subclass));
+
+ Expect.isFalse(closedWorld.isDirectlyInstantiated(subtype));
+ Expect.isFalse(closedWorld.isIndirectlyInstantiated(subtype));
+ Expect.isFalse(closedWorld.isImplemented(subtype));
+
+ check(superclass, ClassQuery.EXACT, foo, false);
+ check(superclass, ClassQuery.EXACT, bar, true);
+ check(superclass, ClassQuery.EXACT, baz, true);
+ check(superclass, ClassQuery.SUBCLASS, foo, false);
+ check(superclass, ClassQuery.SUBCLASS, bar, true);
+ check(superclass, ClassQuery.SUBCLASS, baz, true);
+ check(superclass, ClassQuery.SUBTYPE, foo, false);
+ check(superclass, ClassQuery.SUBTYPE, bar, true);
+ check(superclass, ClassQuery.SUBTYPE, baz, true);
+
+ check(subclass, ClassQuery.EXACT, foo, false);
+ check(subclass, ClassQuery.EXACT, bar, false);
+ check(subclass, ClassQuery.EXACT, baz, false);
+ check(subclass, ClassQuery.SUBCLASS, foo, false);
+ check(subclass, ClassQuery.SUBCLASS, bar, false);
+ check(subclass, ClassQuery.SUBCLASS, baz, false);
+ check(subclass, ClassQuery.SUBTYPE, foo, false);
+ check(subclass, ClassQuery.SUBTYPE, bar, false);
+ check(subclass, ClassQuery.SUBTYPE, baz, false);
+
+ check(subtype, ClassQuery.EXACT, foo, false);
+ check(subtype, ClassQuery.EXACT, bar, false);
+ check(subtype, ClassQuery.EXACT, baz, false);
+ check(subtype, ClassQuery.SUBCLASS, foo, false);
+ check(subtype, ClassQuery.SUBCLASS, bar, false);
+ check(subtype, ClassQuery.SUBCLASS, baz, false);
+ check(subtype, ClassQuery.SUBTYPE, foo, false);
+ check(subtype, ClassQuery.SUBTYPE, bar, false);
+ check(subtype, ClassQuery.SUBTYPE, baz, false);
+
+ await run(['Subclass']);
+
+ Expect.isFalse(closedWorld.isDirectlyInstantiated(superclass));
+ Expect.isTrue(closedWorld.isIndirectlyInstantiated(superclass));
+ Expect.isTrue(closedWorld.isImplemented(superclass));
+
+ Expect.isTrue(closedWorld.isDirectlyInstantiated(subclass));
+ Expect.isFalse(closedWorld.isIndirectlyInstantiated(subclass));
+ Expect.isTrue(closedWorld.isImplemented(subclass));
+
+ Expect.isFalse(closedWorld.isDirectlyInstantiated(subtype));
+ Expect.isFalse(closedWorld.isIndirectlyInstantiated(subtype));
+ Expect.isFalse(closedWorld.isImplemented(subtype));
+
+ check(superclass, ClassQuery.EXACT, foo, false);
+ // Should be false since the class is not directly instantiated:
+ check(superclass, ClassQuery.EXACT, bar, true);
+ // Should be false since the class is not directly instantiated:
+ check(superclass, ClassQuery.EXACT, baz, true);
+ check(superclass, ClassQuery.SUBCLASS, foo, false);
+ // Should be false since all live subclasses have a concrete implementation:
+ check(superclass, ClassQuery.SUBCLASS, bar, true);
+ check(superclass, ClassQuery.SUBCLASS, baz, true);
+ check(superclass, ClassQuery.SUBTYPE, foo, false);
+ // Should be false since all live subtypes have a concrete implementation:
+ check(superclass, ClassQuery.SUBTYPE, bar, true);
+ check(superclass, ClassQuery.SUBTYPE, baz, true);
+
+ check(subclass, ClassQuery.EXACT, foo, false);
+ check(subclass, ClassQuery.EXACT, bar, false);
+ check(subclass, ClassQuery.EXACT, baz, true);
+ check(subclass, ClassQuery.SUBCLASS, foo, false);
+ check(subclass, ClassQuery.SUBCLASS, bar, false);
+ check(subclass, ClassQuery.SUBCLASS, baz, true);
+ check(subclass, ClassQuery.SUBTYPE, foo, false);
+ check(subclass, ClassQuery.SUBTYPE, bar, false);
+ check(subclass, ClassQuery.SUBTYPE, baz, true);
+
+ check(subtype, ClassQuery.EXACT, foo, false);
+ check(subtype, ClassQuery.EXACT, bar, false);
+ check(subtype, ClassQuery.EXACT, baz, false);
+ check(subtype, ClassQuery.SUBCLASS, foo, false);
+ check(subtype, ClassQuery.SUBCLASS, bar, false);
+ check(subtype, ClassQuery.SUBCLASS, baz, false);
+ check(subtype, ClassQuery.SUBTYPE, foo, false);
+ check(subtype, ClassQuery.SUBTYPE, bar, false);
+ check(subtype, ClassQuery.SUBTYPE, baz, false);
+
+ await run(['Subtype']);
+
+ Expect.isFalse(closedWorld.isDirectlyInstantiated(superclass));
+ Expect.isFalse(closedWorld.isIndirectlyInstantiated(superclass));
+ Expect.isTrue(closedWorld.isImplemented(superclass));
+
+ Expect.isFalse(closedWorld.isDirectlyInstantiated(subclass));
+ Expect.isFalse(closedWorld.isIndirectlyInstantiated(subclass));
+ Expect.isFalse(closedWorld.isImplemented(subclass));
+
+ Expect.isTrue(closedWorld.isDirectlyInstantiated(subtype));
+ Expect.isFalse(closedWorld.isIndirectlyInstantiated(subtype));
+ Expect.isTrue(closedWorld.isImplemented(subtype));
+
+ check(superclass, ClassQuery.EXACT, foo, false);
+ check(superclass, ClassQuery.EXACT, bar, false);
+ check(superclass, ClassQuery.EXACT, baz, false);
+ check(superclass, ClassQuery.SUBCLASS, foo, false);
+ check(superclass, ClassQuery.SUBCLASS, bar, false);
+ check(superclass, ClassQuery.SUBCLASS, baz, false);
+ check(superclass, ClassQuery.SUBTYPE, foo, true);
+ check(superclass, ClassQuery.SUBTYPE, bar, false);
+ check(superclass, ClassQuery.SUBTYPE, baz, true);
+
+ check(subclass, ClassQuery.EXACT, foo, false);
+ check(subclass, ClassQuery.EXACT, bar, false);
+ check(subclass, ClassQuery.EXACT, baz, false);
+ check(subclass, ClassQuery.SUBCLASS, foo, false);
+ check(subclass, ClassQuery.SUBCLASS, bar, false);
+ check(subclass, ClassQuery.SUBCLASS, baz, false);
+ check(subclass, ClassQuery.SUBTYPE, foo, false);
+ check(subclass, ClassQuery.SUBTYPE, bar, false);
+ check(subclass, ClassQuery.SUBTYPE, baz, false);
+
+ check(subtype, ClassQuery.EXACT, foo, true);
+ check(subtype, ClassQuery.EXACT, bar, false);
+ check(subtype, ClassQuery.EXACT, baz, true);
+ check(subtype, ClassQuery.SUBCLASS, foo, true);
+ check(subtype, ClassQuery.SUBCLASS, bar, false);
+ check(subtype, ClassQuery.SUBCLASS, baz, true);
+ check(subtype, ClassQuery.SUBTYPE, foo, true);
+ check(subtype, ClassQuery.SUBTYPE, bar, false);
+ check(subtype, ClassQuery.SUBTYPE, baz, true);
+
+ await run(['Subclass', 'Subtype']);
+
+ Expect.isFalse(closedWorld.isDirectlyInstantiated(superclass));
+ Expect.isTrue(closedWorld.isIndirectlyInstantiated(superclass));
+ Expect.isTrue(closedWorld.isImplemented(superclass));
+
+ Expect.isTrue(closedWorld.isDirectlyInstantiated(subclass));
+ Expect.isFalse(closedWorld.isIndirectlyInstantiated(subclass));
+ Expect.isTrue(closedWorld.isImplemented(subclass));
+
+ Expect.isTrue(closedWorld.isDirectlyInstantiated(subtype));
+ Expect.isFalse(closedWorld.isIndirectlyInstantiated(subtype));
+ Expect.isTrue(closedWorld.isImplemented(subtype));
+
+ check(superclass, ClassQuery.EXACT, foo, false);
+ // Should be false since the class is not directly instantiated:
+ check(superclass, ClassQuery.EXACT, bar, true);
+ // Should be false since the class is not directly instantiated:
+ check(superclass, ClassQuery.EXACT, baz, true);
+ check(superclass, ClassQuery.SUBCLASS, foo, false);
+ // Should be false since all live subclasses have a concrete implementation:
+ check(superclass, ClassQuery.SUBCLASS, bar, true);
+ check(superclass, ClassQuery.SUBCLASS, baz, true);
+ check(superclass, ClassQuery.SUBTYPE, foo, true);
+ // Should be false since all live subtypes have a concrete implementation:
+ check(superclass, ClassQuery.SUBTYPE, bar, true);
+ check(superclass, ClassQuery.SUBTYPE, baz, true);
+
+ check(subclass, ClassQuery.EXACT, foo, false);
+ check(subclass, ClassQuery.EXACT, bar, false);
+ check(subclass, ClassQuery.EXACT, baz, true);
+ check(subclass, ClassQuery.SUBCLASS, foo, false);
+ check(subclass, ClassQuery.SUBCLASS, bar, false);
+ check(subclass, ClassQuery.SUBCLASS, baz, true);
+ check(subclass, ClassQuery.SUBTYPE, foo, false);
+ check(subclass, ClassQuery.SUBTYPE, bar, false);
+ check(subclass, ClassQuery.SUBTYPE, baz, true);
+
+ check(subtype, ClassQuery.EXACT, foo, true);
+ check(subtype, ClassQuery.EXACT, bar, false);
+ check(subtype, ClassQuery.EXACT, baz, true);
+ check(subtype, ClassQuery.SUBCLASS, foo, true);
+ check(subtype, ClassQuery.SUBCLASS, bar, false);
+ check(subtype, ClassQuery.SUBCLASS, baz, true);
+ check(subtype, ClassQuery.SUBTYPE, foo, true);
+ check(subtype, ClassQuery.SUBTYPE, bar, false);
+ check(subtype, ClassQuery.SUBTYPE, baz, true);
+}
diff --git a/tests/compiler/dart2js/serialization/model_test_helper.dart b/tests/compiler/dart2js/serialization/model_test_helper.dart
index 90cde97..9a4484a 100644
--- a/tests/compiler/dart2js/serialization/model_test_helper.dart
+++ b/tests/compiler/dart2js/serialization/model_test_helper.dart
@@ -72,11 +72,7 @@
memorySourceFiles: sourceFiles, options: [Flags.analyzeOnly]);
compilerNormal.resolution.retainCachesForTesting = true;
await compilerNormal.run(entryPoint);
- compilerNormal.phase = Compiler.PHASE_DONE_RESOLVING;
- compilerNormal.openWorld.closeWorld();
- compilerNormal.backend.onResolutionComplete();
- compilerNormal.deferredLoadTask
- .onResolutionComplete(compilerNormal.mainFunction);
+ compilerNormal.closeResolution();
return compilerNormal;
});
@@ -88,11 +84,7 @@
options: [Flags.analyzeOnly]);
compilerDeserialized.resolution.retainCachesForTesting = true;
await compilerDeserialized.run(entryPoint);
- compilerDeserialized.phase = Compiler.PHASE_DONE_RESOLVING;
- compilerDeserialized.openWorld.closeWorld();
- compilerDeserialized.backend.onResolutionComplete();
- compilerDeserialized.deferredLoadTask
- .onResolutionComplete(compilerDeserialized.mainFunction);
+ compilerDeserialized.closeResolution();
return compilerDeserialized;
});
@@ -195,15 +187,16 @@
void checkElements(
Compiler compiler1, Compiler compiler2, Element element1, Element element2,
{bool verbose: false}) {
+ if (element1.isAbstract) return;
if (element1.isFunction ||
element1.isConstructor ||
(element1.isField && element1.isInstanceMember)) {
AstElement astElement1 = element1;
AstElement astElement2 = element2;
ClosureClassMap closureData1 = compiler1.closureToClassMapper
- .computeClosureToClassMapping(astElement1.resolvedAst);
+ .getClosureToClassMapping(astElement1.resolvedAst);
ClosureClassMap closureData2 = compiler2.closureToClassMapper
- .computeClosureToClassMapping(astElement2.resolvedAst);
+ .getClosureToClassMapping(astElement2.resolvedAst);
checkElementIdentities(
closureData1,
diff --git a/tests/compiler/dart2js_extra/round_constant_folding_test.dart b/tests/compiler/dart2js_extra/round_constant_folding_test.dart
new file mode 100644
index 0000000..cd2ad5a
--- /dev/null
+++ b/tests/compiler/dart2js_extra/round_constant_folding_test.dart
@@ -0,0 +1,167 @@
+// 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:expect/expect.dart';
+
+const double PD1 = 0.0;
+const double PD2 = double.MIN_POSITIVE;
+const double PD3 = 2.0 * double.MIN_POSITIVE;
+const double PD4 = 1.18e-38;
+const double PD5 = 1.18e-38 * 2;
+const double PD6 = 0.49999999999999994;
+const double PD7 = 0.5;
+const double PD8 = 0.9999999999999999;
+const double PD9 = 1.0;
+const double PD10 = 1.000000000000001;
+const double PD11 = double.MAX_FINITE;
+
+const double ND1 = -PD1;
+const double ND2 = -PD2;
+const double ND3 = -PD3;
+const double ND4 = -PD4;
+const double ND5 = -PD5;
+const double ND6 = -PD6;
+const double ND7 = -PD7;
+const double ND8 = -PD8;
+const double ND9 = -PD9;
+const double ND10 = -PD10;
+const double ND11 = -PD11;
+
+const X1 = double.INFINITY;
+const X2 = double.NEGATIVE_INFINITY;
+const X3 = double.NAN;
+
+// The following numbers are on the border of 52 bits.
+// For example: 4503599627370499 + 0.5 => 4503599627370500.
+const PQ1 = 4503599627370496.0;
+const PQ2 = 4503599627370497.0;
+const PQ3 = 4503599627370498.0;
+const PQ4 = 4503599627370499.0;
+const PQ5 = 9007199254740991.0;
+const PQ6 = 9007199254740992.0;
+
+const NQ1 = -PQ1;
+const NQ2 = -PQ2;
+const NQ3 = -PQ3;
+const NQ4 = -PQ4;
+const NQ5 = -PQ5;
+const NQ6 = -PQ6;
+
+const int PI1 = 0;
+const int PI2 = 1;
+const int PI3 = 0x1234;
+const int PI4 = 0x12345678;
+const int PI5 = 0x123456789AB;
+const int PI6 = 0x123456789ABCDEF;
+const int PI7 = 0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF;
+
+const int NI1 = 0-PI1;
+const int NI2 = -PI2;
+const int NI3 = -PI3;
+const int NI4 = -PI4;
+const int NI5 = -PI5;
+const int NI6 = -PI6;
+const int NI7 = -PI7;
+
+
+/// Ensures that the behaviour of `action()` is the same as `value.round()`.
+@NoInline() // To ensure 'value.round()' has a non-constant receiver.
+check(value, action) {
+ var result1, result2;
+ try {
+ result1 = value.round();
+ } catch (e) {
+ result1 = e;
+ }
+
+ try {
+ result2 = action();
+ } catch (e) {
+ result2 = e;
+ }
+
+ Expect.equals(result1.runtimeType, result2.runtimeType);
+ if (result1 is num) {
+ Expect.equals(result1, result2);
+ Expect.equals(result1 is int, result2 is int);
+ } else {
+ Expect.equals(result1.runtimeType, result2.runtimeType);
+ Expect.isTrue(result1 is Error);
+ }
+}
+
+@NoInline()
+void unusedCall(num x) {
+ x.round(); // This call should not be removed since it might throw.
+}
+
+main() {
+ check(PD1, () => PD1.round());
+ check(PD2, () => PD2.round());
+ check(PD3, () => PD3.round());
+ check(PD4, () => PD4.round());
+ check(PD5, () => PD5.round());
+ check(PD6, () => PD6.round());
+ check(PD7, () => PD7.round());
+ check(PD8, () => PD8.round());
+ check(PD9, () => PD9.round());
+ check(PD10, () => PD10.round());
+ check(PD11, () => PD11.round());
+
+ check(ND1, () => ND1.round());
+ check(ND2, () => ND2.round());
+ check(ND3, () => ND3.round());
+ check(ND4, () => ND4.round());
+ check(ND5, () => ND5.round());
+ check(ND6, () => ND6.round());
+ check(ND7, () => ND7.round());
+ check(ND8, () => ND8.round());
+ check(ND9, () => ND9.round());
+ check(ND10, () => ND10.round());
+ check(ND11, () => ND11.round());
+
+ check(X1, () => X1.round());
+ check(X2, () => X2.round());
+ check(X3, () => X3.round());
+
+ check(PQ1, () => PQ1.round());
+ check(PQ2, () => PQ2.round());
+ check(PQ3, () => PQ3.round());
+ check(PQ4, () => PQ4.round());
+ check(PQ5, () => PQ5.round());
+ check(PQ6, () => PQ6.round());
+
+ check(NQ1, () => NQ1.round());
+ check(NQ2, () => NQ2.round());
+ check(NQ3, () => NQ3.round());
+ check(NQ4, () => NQ4.round());
+ check(NQ5, () => NQ5.round());
+ check(NQ6, () => NQ6.round());
+
+ check(PI1, () => PI1.round());
+ check(PI2, () => PI2.round());
+ check(PI3, () => PI3.round());
+ check(PI4, () => PI4.round());
+ check(PI5, () => PI5.round());
+ check(PI6, () => PI6.round());
+ check(PI7, () => PI7.round());
+
+ check(NI1, () => NI1.round());
+ check(NI2, () => NI2.round());
+ check(NI3, () => NI3.round());
+ check(NI4, () => NI4.round());
+ check(NI5, () => NI5.round());
+ check(NI6, () => NI6.round());
+ check(NI7, () => NI7.round());
+
+ // Check that the operation is not removed if it can throw, even if the result
+ // is unused.
+ Expect.throws(() { X1.round(); });
+ Expect.throws(() { X2.round(); });
+ Expect.throws(() { X3.round(); });
+ unusedCall(0);
+ Expect.throws(() { unusedCall(X1); });
+ Expect.throws(() { unusedCall(X2); });
+ Expect.throws(() { unusedCall(X3); });
+}
diff --git a/tests/corelib/big_integer_arith_vm_test.dart b/tests/corelib/big_integer_arith_vm_test.dart
index b9696b4..7ff1863 100644
--- a/tests/corelib/big_integer_arith_vm_test.dart
+++ b/tests/corelib/big_integer_arith_vm_test.dart
@@ -5,6 +5,7 @@
// Testing Bigints with and without intrinsics.
// VMOptions=
// VMOptions=--no_intrinsify
+// VMOptions=--no-background-compilation
// VMOptions=--optimization_counter_threshold=10 --no-background_compilation
library big_integer_test;
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index 24a5cd6..a714329 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -207,3 +207,5 @@
[ $arch == simdbc || $arch == simdbc64 ]
regexp/stack-overflow_test: RuntimeError, OK # Smaller limit with irregex interpreter
+big_integer_arith_vm_test/gcd: Pass, RuntimeError # Issue #27474
+big_integer_arith_vm_test/modPow: Pass, RuntimeError # Issue #27474
diff --git a/tests/html/html.status b/tests/html/html.status
index e4544e8..4180e62 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -325,7 +325,7 @@
# Firefox Feature support statuses-
# All changes should be accompanied by platform support annotation changes.
-element_types_test/supported_details: Fail
+element_classes_test: RuntimeError # Issue 27535
element_types_test/supported_embed: Fail
element_types_test/supported_keygen: Fail
element_types_test/supported_object: Fail
@@ -419,27 +419,6 @@
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/html/js_typed_interop_test.dart b/tests/html/js_typed_interop_test.dart
index 960c0cc..bbbd867 100644
--- a/tests/html/js_typed_interop_test.dart
+++ b/tests/html/js_typed_interop_test.dart
@@ -80,7 +80,7 @@
_getA: function() { return this._a;}
};
- var selection = ["a", "b", "c", foo, bar];
+ var selection = ["a", "b", "c", foo, bar];
function returnNumArgs() { return arguments.length; };
function returnLastArg() { return arguments[arguments.length-1]; };
@@ -144,6 +144,14 @@
external get b;
}
+@JS('ClassWithConstructor')
+class ClassWithFactory {
+ external factory ClassWithFactory(aParam, bParam);
+ external getA();
+ external get a;
+ external get b;
+}
+
@JS()
class JS$_PrivateClass {
external JS$_PrivateClass(aParam, bParam);
@@ -324,6 +332,12 @@
expect(o.b, equals("bar"));
expect(o.getA(), equals("foo"));
});
+ test('external factory', () {
+ var o = new ClassWithFactory("foo", "bar");
+ expect(o.a, equals("foo"));
+ expect(o.b, equals("bar"));
+ expect(o.getA(), equals("foo"));
+ });
});
group('private class', () {
diff --git a/tests/language/deferred_not_loaded_check_test.dart b/tests/language/deferred_not_loaded_check_test.dart
index 5c48da3..70be80f 100644
--- a/tests/language/deferred_not_loaded_check_test.dart
+++ b/tests/language/deferred_not_loaded_check_test.dart
@@ -12,6 +12,12 @@
var c;
+expectSideEffect(test) {
+ c = 0;
+ test();
+ Expect.isTrue(c == 1);
+}
+
expectNoSideEffect(test) {
c = 0;
test();
@@ -28,7 +34,7 @@
}
void main() {
- expectNoSideEffect(() {
+ expectSideEffect(() {
expectThrowsNotLoaded(() {
lib.foo(sideEffect());
});
@@ -38,7 +44,7 @@
lib.C.foo(sideEffect());
});
});
- expectNoSideEffect(() {
+ expectSideEffect(() {
expectThrowsNotLoaded(() {
new lib.C(sideEffect());
});
@@ -46,7 +52,7 @@
expectThrowsNotLoaded(() {
lib.a;
});
- expectNoSideEffect(() {
+ expectSideEffect(() {
expectThrowsNotLoaded(() {
lib.a = sideEffect();
});
@@ -54,7 +60,7 @@
expectThrowsNotLoaded(() {
lib.getter;
});
- expectNoSideEffect(() {
+ expectSideEffect(() {
expectThrowsNotLoaded(() {
lib.setter = sideEffect();
});
@@ -64,7 +70,7 @@
lib.list[sideEffect()] = sideEffect();
});
});
- expectNoSideEffect(() {
+ expectSideEffect(() {
expectThrowsNotLoaded(() {
lib.closure(sideEffect());
});
diff --git a/tests/language/initializing_formal_promotion_test.dart b/tests/language/initializing_formal_promotion_test.dart
index 5f0a3b6..89ec79e 100644
--- a/tests/language/initializing_formal_promotion_test.dart
+++ b/tests/language/initializing_formal_promotion_test.dart
@@ -11,12 +11,8 @@
class A {
B x, y;
- A(this.x) {
- // Promote to subtype.
- if (x is C) y = x.x;
- // Promotion fails, not a subtype.
- if (x is A) y = x;
- }
+ // Promotion occurs for the initializing formal because C <: B.
+ A(this.x) : y = (x is C) ? x.x : x;
}
class C extends A implements B {
@@ -24,8 +20,8 @@
}
main() {
- C c2 = new C(null);
- C cc = new C(c2);
- Expect.equals(c2.y, null);
- Expect.equals(cc.y, c2);
+ C c = new C(null);
+ C cc = new C(c);
+ Expect.equals(c.y, null);
+ Expect.equals(cc.y, null);
}
diff --git a/tests/language/language.status b/tests/language/language.status
index de99e84..6b43cef 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -5,11 +5,9 @@
# This directory contains tests that are intended to show the
# current state of the language.
-[ ($compiler == dart2app || $compiler == dart2appjit) ]
-string_literals_test: Skip # Issue 27433
-
[ ($compiler == none || $compiler == precompiler || $compiler == dart2app || $compiler == dart2appjit) ]
tearoff_constructor_basic_test: Skip # Crashes in checked mode -- hausner investigating
+generic_methods_type_expression_test: RuntimeError # Issue 25869
# This is OK for now, but we may want to change the semantics to match the test.
async_star_pause_test: Fail, OK
@@ -51,14 +49,14 @@
async_star_cancel_while_paused_test: RuntimeError
[ ($compiler == none || $compiler == precompiler || $compiler == dart2app || $compiler == dart2appjit) && $checked ]
-# The generic functions tests fail in checked mode because the parsed type parameters
-# are ignored.
-generic_methods_function_type_test: RuntimeError # Issue 25869
-generic_methods_test: RuntimeError # Issue 25869
-generic_methods_new_test: RuntimeError # Issue 25869
-generic_local_functions_test: RuntimeError # Issue 25869
-generic_functions_test: RuntimeError # Issue 25869
-generic_methods_generic_function_parameter_test: RuntimeError # Issue 25869
+# These generic functions tests pass for the wrong reason in checked mode,
+# because the parsed type parameters are mapped to dynamic type.
+generic_methods_function_type_test: Pass # Issue 25869
+generic_methods_test: Pass # Issue 25869
+generic_methods_new_test: Pass # Issue 25869
+generic_local_functions_test: Pass # Issue 25869
+generic_functions_test: Pass # Issue 25869
+generic_methods_generic_function_parameter_test: Pass # Issue 25869
[ ($compiler == none || $compiler == precompiler || $compiler == dart2app || $compiler == dart2appjit) && ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_app) ]
@@ -106,6 +104,7 @@
initializing_formal_capture_test: Skip
initializing_formal_final_test: Skip
initializing_formal_type_test: Skip
+initializing_formal_promotion_test: Skip
# Experimental feature: Syntactic support for generic methods.
# Skip these in dartium, because the test framework can't pass VM flags to
@@ -180,24 +179,36 @@
super_getter_setter_test: SkipByDesign
vm/reflect_core_vm_test: SkipByDesign
-[ $noopt || $compiler == precompiler || $compiler == dart2app || $compiler == dart2appjit || $mode == product ]
-# Deferred loading happens eagerly
-regress_23408_test: Skip
-deferred_inheritance_constraints_test: Skip
-deferred_global_test: Skip
-deferred_load_constants_test: Skip
-tearoff_basic_test: Skip
-deferred_static_seperate_test: Skip
-deferred_constraints_type_annotation_test/new_before_load: Skip
-regress_22443_test: Skip
+[ $noopt ]
+# Deferred loading happens eagerly. Issue #27587
+regress_23408_test: Fail
+deferred_inheritance_constraints_test/redirecting_constructor: Fail
+deferred_global_test: Fail
+deferred_load_constants_test/02: Fail
+deferred_load_constants_test/03: Fail
+deferred_load_constants_test/05: Fail
+tearoff_basic_test: Fail
+regress_22443_test: Fail
+deferred_not_loaded_check_test: Fail
+
+[ $mode == product || $compiler == dart2appjit || $compiler == dart2app || $compiler == precompiler ]
+# Deferred loading happens eagerly. Issue #27587
+regress_23408_test: Fail
+deferred_inheritance_constraints_test/redirecting_constructor: Fail
+deferred_load_constants_test/02: Fail
+deferred_load_constants_test/03: Fail
+deferred_load_constants_test/05: Fail
+tearoff_basic_test: Fail
+deferred_not_loaded_check_test: Fail
+
+[ $compiler == precompiler ]
+# Deferred loading happens eagerly. Issue #27587
+deferred_global_test: Fail
[ $compiler == precompiler || $compiler == dart2app || $compiler == dart2appjit ]
ct_const2_test: Skip # Incompatible flag: --compile_all
hello_dart_test: Skip # Incompatible flag: --compile_all
-[ $runtime == dart_app ]
-number_identity_test: RuntimeError # Issue 26873
-
[ $compiler == precompiler ]
implicit_closure_test: Skip # Incompatible flag: --use_slow_path
deopt_inlined_function_lazy_test: Skip # Incompatible flag: --deoptimize-alot
@@ -240,11 +251,6 @@
# The following tests are supposed to fail.
library_env_test/has_mirror_support: RuntimeError, OK
-[ $arch == simdbc || $arch == simdbc64 ]
-# TODO(vegorov) Encoding limitation: StoreField bytecode only supports 256
-# fields in an object.
-large_class_declaration_test: Skip
-
[ $compiler == precompiler && $runtime == dart_precompiled && $system == android ]
vm/optimized_guarded_field_isolates_test: Skip # Issue #26373
issue23244_test: Skip # Issue #26373
@@ -297,3 +303,6 @@
# The VM doesn't enforce that potentially const expressions are actually
# const expressions when the constructor is called with `const`.
assert_initializer_test/4*: MissingCompileTimeError # Issue 392.
+
+[$runtime == vm && $compiler == none]
+duplicate_part_test/01: MissingCompileTimeError # Issue 27516
diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status
index cb9c4b0c..a064488 100644
--- a/tests/language/language_analyzer2.status
+++ b/tests/language/language_analyzer2.status
@@ -508,5 +508,6 @@
generic_methods_generic_function_parameter_test: CompiletimeError # Issue 25868
# Experimental feature: Use initializing formals in initializers and constructor body.
-initializing_formal_promotion_test: StaticWarning # Issue 26658
initializing_formal_type_test: StaticWarning # Issue 26658
+
+regress_27572_test: StaticWarning # Warning about undefined method expected.
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 03c99a9..d4b7189 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -3,6 +3,7 @@
# BSD-style license that can be found in the LICENSE file.
[ $compiler == dart2js ]
+deferred_not_loaded_check_test: Fail # Issue 27577
getter_setter_in_lib_test: Fail # Issue 23288
method_name_test: Fail # issue 25574
setter4_test: CompileTimeError # issue 13639
@@ -36,6 +37,8 @@
accessor_conflict_import_prefixed_test: RuntimeError # Issue 25626
accessor_conflict_import_test: RuntimeError # Issue 25626
+duplicate_part_test/01: MissingCompileTimeError # Issue 27517
+
[ $compiler == dart2js && $fast_startup ]
const_evaluation_test/*: Fail # mirrors not supported
deferred_constraints_constants_test/none: Fail # mirrors not supported
@@ -82,16 +85,17 @@
generic_local_functions_test: CompileTimeError # DartOptions not passed to compiler.
generic_methods_test: CompileTimeError # DartOptions not passed to compiler.
generic_sends_test: CompileTimeError # DartOptions not passed to compiler.
-generic_methods_new_test: CompiletimeError # DartOptions not passed to compiler.
-generic_methods_function_type_test: CompiletimeError # DartOptions not passed to compiler.
-generic_methods_type_expression_test: CompiletimeError # DartOptions not passed to compiler.
-generic_methods_generic_function_parameter_test: CompiletimeError # DartOptions not passed to compiler.
+generic_methods_new_test: CompileTimeError # DartOptions not passed to compiler.
+generic_methods_function_type_test: CompileTimeError # DartOptions not passed to compiler.
+generic_methods_type_expression_test: CompileTimeError # DartOptions not passed to compiler.
+generic_methods_generic_function_parameter_test: CompileTimeError # DartOptions not passed to compiler.
# Experimental feature: Use initializing formals in initializers and constructor body.
-initializing_formal_access_test: CompiletimeError # DartOptions not passed to compiler.
-initializing_formal_capture_test: CompiletimeError # DartOptions not passed to compiler.
-initializing_formal_final_test: CompiletimeError # DartOptions not passed to compiler.
-initializing_formal_type_test: CompiletimeError # DartOptions not passed to compiler.
+initializing_formal_access_test: CompileTimeError # DartOptions not passed to compiler.
+initializing_formal_capture_test: CompileTimeError # DartOptions not passed to compiler.
+initializing_formal_final_test: CompileTimeError # DartOptions not passed to compiler.
+initializing_formal_promotion_test: CompileTimeError # DartOptions not passed to compiler.
+initializing_formal_type_test: CompileTimeError # DartOptions not passed to compiler.
library_env_test/has_no_io_support: Pass # Issue 27398
library_env_test/has_io_support: RuntimeError # Issue 27398
@@ -263,6 +267,9 @@
[ $compiler == dart2js && $runtime == chrome && $system == macos ]
await_future_test: Pass, Timeout # Issue 26735
+[ $compiler == dart2js && ($runtime == chrome || $runtime == ff) && $system == windows ]
+string_literals_test: RuntimeError # Issue 27533
+
[ $compiler == dart2js && ($runtime == safari || $runtime == safarimobilesim)]
# Safari codegen bug, fixed on some versions of Safari 7.1 (Version 7.1 (9537.85.10.17.1))
call_through_getter_test: Fail, OK
diff --git a/tests/language/named_parameters_default_eq_test.dart b/tests/language/named_parameters_default_eq_test.dart
new file mode 100644
index 0000000..2afc8c4
--- /dev/null
+++ b/tests/language/named_parameters_default_eq_test.dart
@@ -0,0 +1,99 @@
+// 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.
+
+// Check that both `=` and `:` are allowed for named parameters.
+
+import "package:expect/expect.dart";
+
+// Default values are not allowed on typedefs.
+typedef int F1({x = 3, y}); /// 01: compile-time error
+
+typedef int functype({x, y, z});
+
+int topF({x = 3, y : 5, z}) => x * y * (z ?? 2);
+
+class A {
+ int x;
+ int y;
+ int z;
+ A({this.x = 3, this.y : 5, z }) : z = z ?? 2;
+ A.redirect({x = 3, y : 5, z}) : this(x: x, y: y, z: z);
+ factory A.factory({x = 3, y : 5, z}) => new A(x: x, y: y, z: z ?? 2);
+ factory A.redirectFactory({x, y, z}) = A;
+
+ // Default values are not allowed on redirecting factory constructors.
+ factory A.badRedirectFactory({x = 3, y}) = A; /// 02: compile-time error
+
+ int get value => x * y * z;
+
+ static int staticF({x = 3, y : 5, z}) => x * y * (z ?? 2);
+ int instanceF({x = 3, y : 5, z}) => x * y * (z ?? 2);
+}
+
+main() {
+ // Reference the type, or dart2js won't see that the declaration is invalid
+ F1 _ = null; /// 01: continued
+
+ var a = new A();
+
+ int local({x = 3, y : 5, z}) => x * y * (z ?? 2);
+ var expr = ({x = 3, y : 5, z}) => x * y * (z ?? 2);
+ var tearOff = a.instanceF;
+
+ test(function) {
+ Expect.equals(30, function());
+ Expect.equals(70, function(x: 7));
+ Expect.equals(42, function(y: 7));
+ Expect.equals(28, function(x: 7, y: 2));
+ Expect.equals(15, function(z: 1));
+ Expect.equals(21, function(y: 7, z: 1));
+ Expect.equals(35, function(x: 7, z: 1));
+ Expect.equals(14, function(x: 7, y: 2, z: 1));
+ Expect.isTrue(function is functype);
+ }
+
+ test(topF);
+ test(A.staticF);
+ test(a.instanceF);
+ test(local);
+ test(expr);
+ test(tearOff);
+
+ // Can't tear off constructors.
+ Expect.equals(30, new A().value);
+ Expect.equals(70, new A(x: 7).value);
+ Expect.equals(42, new A(y: 7).value);
+ Expect.equals(28, new A(x: 7, y: 2).value);
+ Expect.equals(15, new A(z: 1).value);
+ Expect.equals(21, new A(y: 7, z: 1).value);
+ Expect.equals(35, new A(x: 7, z: 1).value);
+ Expect.equals(14, new A(x: 7, y: 2, z: 1).value);
+
+ Expect.equals(30, new A.redirect().value);
+ Expect.equals(70, new A.redirect(x: 7).value);
+ Expect.equals(42, new A.redirect(y: 7).value);
+ Expect.equals(28, new A.redirect(x: 7, y: 2).value);
+ Expect.equals(15, new A.redirect(z: 1).value);
+ Expect.equals(21, new A.redirect(y: 7, z: 1).value);
+ Expect.equals(35, new A.redirect(x: 7, z: 1).value);
+ Expect.equals(14, new A.redirect(x: 7, y: 2, z: 1).value);
+
+ Expect.equals(30, new A.factory().value);
+ Expect.equals(70, new A.factory(x: 7).value);
+ Expect.equals(42, new A.factory(y: 7).value);
+ Expect.equals(28, new A.factory(x: 7, y: 2).value);
+ Expect.equals(15, new A.factory(z: 1).value);
+ Expect.equals(21, new A.factory(y: 7, z: 1).value);
+ Expect.equals(35, new A.factory(x: 7, z: 1).value);
+ Expect.equals(14, new A.factory(x: 7, y: 2, z: 1).value);
+
+ Expect.equals(30, new A.redirectFactory().value);
+ Expect.equals(70, new A.redirectFactory(x: 7).value);
+ Expect.equals(42, new A.redirectFactory(y: 7).value);
+ Expect.equals(28, new A.redirectFactory(x: 7, y: 2).value);
+ Expect.equals(15, new A.redirectFactory(z: 1).value);
+ Expect.equals(21, new A.redirectFactory(y: 7, z: 1).value);
+ Expect.equals(35, new A.redirectFactory(x: 7, z: 1).value);
+ Expect.equals(14, new A.redirectFactory(x: 7, y: 2, z: 1).value);
+}
diff --git a/tests/language/regress_27572_test.dart b/tests/language/regress_27572_test.dart
new file mode 100644
index 0000000..61cff0e
--- /dev/null
+++ b/tests/language/regress_27572_test.dart
@@ -0,0 +1,17 @@
+// 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.
+
+// Test static noSuchMethod with a prefix.
+
+import "package:expect/expect.dart";
+
+import 'dart:collection' as col;
+
+main() {
+ try {
+ col.foobar(1234567);
+ } catch(e) {
+ Expect.isTrue(e.toString().contains("1234567"));
+ }
+}
diff --git a/tests/language/try_catch_optimized5_test.dart b/tests/language/try_catch_optimized5_test.dart
new file mode 100644
index 0000000..d96b1f0
--- /dev/null
+++ b/tests/language/try_catch_optimized5_test.dart
@@ -0,0 +1,77 @@
+// 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.
+// Dart test program for testing try/catch statement without any exceptions
+// being thrown.
+// VMOptions=--optimization-counter-threshold=100 --no-background-compilation --enable-inlining-annotations
+
+// Test optional parameters updated inside try-catch
+
+import "package:expect/expect.dart";
+
+const noInline = "NeverInline";
+
+@noInline
+m1(int b) {
+ if (b == 1) throw 123;
+}
+
+
+@noInline
+m2(int b) {
+ if (b == 2) throw 456;
+}
+
+
+@noInline
+test1(int b, [int state = 0]) {
+ try {
+ state++;
+ m1(b);
+ state++;
+ m2(b);
+ state++;
+ } on dynamic catch (e, s) {
+ if (b == 1 && state != 1) throw "fail1";
+ if (b == 2 && state != 2) throw "fail2";
+ if (b == 3 && state != 3) throw "fail3";
+ if (s is! StackTrace) throw "fail4";
+ return e;
+ }
+ return "no throw";
+}
+
+@noInline
+test2(int b, [int state]) {
+ state = 0;
+ try {
+ state++;
+ m1(b);
+ state++;
+ m2(b);
+ state++;
+ } on dynamic catch (e, s) {
+ if (b == 1 && state != 1) throw "fail1";
+ if (b == 2 && state != 2) throw "fail2";
+ if (b == 3 && state != 3) throw "fail3";
+ if (s is! StackTrace) throw "fail4";
+ return e;
+ }
+ return "no throw";
+}
+
+main() {
+ for (var i=0; i<300; i++) {
+ Expect.equals("no throw", test1(0));
+ }
+ Expect.equals("no throw", test1(0));
+ Expect.equals(123, test1(1));
+ Expect.equals(456, test1(2));
+
+ for (var i=0; i<300; i++) {
+ Expect.equals("no throw", test2(0));
+ }
+ Expect.equals("no throw", test2(0));
+ Expect.equals(123, test2(1));
+ Expect.equals(456, test2(2));
+}
diff --git a/tests/language/try_catch_regress_27483_test.dart b/tests/language/try_catch_regress_27483_test.dart
new file mode 100644
index 0000000..4da202f
--- /dev/null
+++ b/tests/language/try_catch_regress_27483_test.dart
@@ -0,0 +1,51 @@
+// 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.
+// Dart test program for testing try/catch statement without any exceptions
+// being thrown.
+// VMOptions=--optimization-counter-threshold=100 --no-background-compilation --enable-inlining-annotations
+
+// Test local variables updated inside try-catch.
+
+import "package:expect/expect.dart";
+
+const noInline = "NeverInline";
+
+@noInline
+m1(int b) {
+ if (b == 1) throw 123;
+}
+
+
+@noInline
+m2(int b) {
+ if (b == 2) throw 456;
+}
+
+
+@noInline
+test(b) {
+ var state = 0;
+ try {
+ state++;
+ m1(b);
+ state++;
+ m2(b);
+ state++;
+ } on dynamic catch (e, s) {
+ if (b == 1 && state != 1) throw "fail1";
+ if (b == 2 && state != 2) throw "fail2";
+ if (b == 3 && state != 3) throw "fail3";
+ return e;
+ }
+ return "no throw";
+}
+
+main() {
+ for (var i=0; i<300; i++) {
+ Expect.equals("no throw", test(0));
+ }
+ Expect.equals("no throw", test(0));
+ Expect.equals(123, test(1));
+ Expect.equals(456, test(2));
+}
diff --git a/tests/language/vm/no_such_method_error_message_vm_test.dart b/tests/language/vm/no_such_method_error_message_vm_test.dart
index 6be2738..259a13a 100644
--- a/tests/language/vm/no_such_method_error_message_vm_test.dart
+++ b/tests/language/vm/no_such_method_error_message_vm_test.dart
@@ -6,7 +6,7 @@
import "package:expect/expect.dart";
// Test error message with noSuchMethodError: non-existent names
-// should result in a "method not found" message.
+// should result in a message that reports the missing method.
call_bar(x) => x.bar();
@@ -14,7 +14,7 @@
try {
call_bar(5);
} catch (e) {
- Expect.isTrue(e.toString().indexOf("method not found") != -1);
+ Expect.isTrue(e.toString().indexOf("has no instance method 'bar'") != -1);
}
}
diff --git a/tests/language/vm/unique_selector_test.dart b/tests/language/vm/unique_selector_test.dart
new file mode 100644
index 0000000..e26d4b5
--- /dev/null
+++ b/tests/language/vm/unique_selector_test.dart
@@ -0,0 +1,34 @@
+// 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:expect/expect.dart";
+
+class A {
+ _unique_method() => "foo";
+ bar() => "A";
+}
+
+class B {
+ noSuchMethod(invocation) => "nsm";
+ bar() => "B";
+}
+
+confuse(x) {
+ try {
+ throw x;
+ } catch (e) {
+ return e;
+ }
+ return null;
+}
+
+main() {
+ var a = confuse(new A());
+ Expect.equals("foo", a._unique_method());
+ Expect.equals("A", a.bar());
+
+ var b = confuse(new B());
+ Expect.equals("nsm", b._unique_method());
+ Expect.equals("B", b.bar()); // Don't propagate type A to b.
+}
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 99f0273..f4114a2 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -139,7 +139,7 @@
typed_data/setRange_2_test: RuntimeError # TODO(dart2js-team): Please triage this failure.
typed_data/setRange_3_test: RuntimeError # TODO(dart2js-team): Please triage this failure.
-[ $compiler == dart2js && $runtime != jsshell && $runtime != safarimobilesim && $runtime != safari && $runtime != ff && $runtime != ie10 && ($runtime != chrome || $system != linux) ]
+[ $compiler == dart2js && ($runtime == d8 || $runtime == drt || $runtime == ie11 || ($runtime == chrome && $system == macos)) ]
math/math_test: RuntimeError
math/math2_test: RuntimeError
@@ -279,6 +279,9 @@
mirrors/local_isolate_test: RuntimeError # Issue 12188
mirrors/deferred_type_test: RuntimeError, OK # Should be CompileTimeError. Issue 22072
+[ $compiler == none && $runtime == dartium && $system == macos ]
+convert/streamed_conversion_utf8_decode_test: Pass, Slow
+
[ $compiler == none && $runtime == drt && $system == windows ]
async/multiple_timer_test: Fail, Pass # See Issue 10982
async/timer_test: Fail, Pass # See Issue 10982
diff --git a/tests/standalone/env_test.dart b/tests/standalone/env_test.dart
new file mode 100644
index 0000000..6280f60
--- /dev/null
+++ b/tests/standalone/env_test.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.
+// SharedOptions=-Dvar -D -D=var -Dvar=invalid -Dvar=valid -Dvar
+
+import "package:expect/expect.dart";
+
+main() {
+ Expect.equals('valid', const String.fromEnvironment('var'));
+}
diff --git a/tests/standalone/io/file_input_stream_test.dart b/tests/standalone/io/file_input_stream_test.dart
index 25cf360..88615a6 100644
--- a/tests/standalone/io/file_input_stream_test.dart
+++ b/tests/standalone/io/file_input_stream_test.dart
@@ -2,6 +2,10 @@
// 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.
// Testing file input stream, VM-only, standalone test.
+//
+// OtherResources=readuntil_test.dat
+// OtherResources=readline_test1.dat
+// OtherResources=readline_test2.dat
import "dart:convert";
import "dart:io";
@@ -9,17 +13,12 @@
import "package:async_helper/async_helper.dart";
import "package:expect/expect.dart";
-// Helper method to be able to run the test from the runtime
-// directory, or the top directory.
String getFilename(String path) {
- var testPath = Platform.script.resolve('../../../$path');
- return new File.fromUri(testPath).existsSync()
- ? testPath.toFilePath()
- : Platform.script.resolve('../../../runtime/$path').toFilePath();
+ return Platform.script.resolve(path).toFilePath();
}
void testStringLineSplitter() {
- String fileName = getFilename("tests/standalone/io/readuntil_test.dat");
+ String fileName = getFilename("readuntil_test.dat");
// File contains "Hello Dart\nwassup!\n"
File file = new File(fileName);
int linesRead = 0;
@@ -41,7 +40,7 @@
void testOpenStreamAsync() {
asyncStart();
- String fileName = getFilename("tests/standalone/io/readuntil_test.dat");
+ String fileName = getFilename("readuntil_test.dat");
// File contains "Hello Dart\nwassup!\n"
var expected = "Hello Dart\nwassup!\n".codeUnits;
var byteCount = 0;
@@ -234,7 +233,7 @@
void testStringLineSplitterEnding(String name, int length) {
- String fileName = getFilename("tests/standalone/io/$name");
+ String fileName = getFilename(name);
// File contains 10 lines.
File file = new File(fileName);
Expect.equals(length, file.lengthSync());
diff --git a/tests/standalone/io/file_invalid_arguments_test.dart b/tests/standalone/io/file_invalid_arguments_test.dart
index 335e574..db15b77 100644
--- a/tests/standalone/io/file_invalid_arguments_test.dart
+++ b/tests/standalone/io/file_invalid_arguments_test.dart
@@ -2,6 +2,8 @@
// 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.
+// OtherResources=fixed_length_file
+
import "dart:async";
import "dart:io";
@@ -9,7 +11,7 @@
import "package:expect/expect.dart";
void testReadInvalidArgs(arg) {
- String filename = getFilename("tests/vm/data/fixed_length_file");
+ String filename = getFilename("fixed_length_file");
var file = (new File(filename)).openSync();
Expect.throws(() => file.readSync(arg),
(e) => e is ArgumentError);
@@ -20,7 +22,7 @@
}
void testReadIntoInvalidArgs(buffer, start, end) {
- String filename = getFilename("tests/vm/data/fixed_length_file");
+ String filename = getFilename("fixed_length_file");
var file = (new File(filename)).openSync();
Expect.throws(() => file.readIntoSync(buffer, start, end),
(e) => e is ArgumentError);
@@ -31,7 +33,7 @@
}
void testWriteByteInvalidArgs(value) {
- String filename = getFilename("tests/vm/data/fixed_length_file");
+ String filename = getFilename("fixed_length_file");
var file = (new File("${filename}_out")).openSync(mode: FileMode.WRITE);
Expect.throws(() => file.writeByteSync(value),
(e) => e is ArgumentError);
@@ -42,7 +44,7 @@
}
void testWriteFromInvalidArgs(buffer, start, end) {
- String filename = getFilename("tests/vm/data/fixed_length_file");
+ String filename = getFilename("fixed_length_file");
var file = (new File("${filename}_out")).openSync(mode: FileMode.WRITE);
Expect.throws(() => file.writeFromSync(buffer, start, end),
(e) => e is ArgumentError);
@@ -53,7 +55,7 @@
}
void testWriteStringInvalidArgs(string, encoding) {
- String filename = getFilename("tests/vm/data/fixed_length_file");
+ String filename = getFilename("fixed_length_file");
var file = new File("${filename}_out").openSync(mode: FileMode.WRITE);
Expect.throws(() => file.writeStringSync(string, encoding: encoding),
(e) => e is ArgumentError);
@@ -99,10 +101,7 @@
}
String getFilename(String path) {
- var testPath = Platform.script.resolve('../../../$path');
- return new File.fromUri(testPath).existsSync()
- ? testPath.toFilePath()
- : Platform.script.resolve('../../../runtime/$path').toFilePath();
+ return Platform.script.resolve(path).toFilePath();
}
main() {
diff --git a/tests/standalone/io/fixed_length_file b/tests/standalone/io/fixed_length_file
new file mode 100644
index 0000000..52ce32d
--- /dev/null
+++ b/tests/standalone/io/fixed_length_file
@@ -0,0 +1 @@
+This file should contain exactly 42 bytes.
\ No newline at end of file
diff --git a/build/util/lib/common/__init__.py b/tests/standalone/io/fixed_length_file_out
similarity index 100%
rename from build/util/lib/common/__init__.py
rename to tests/standalone/io/fixed_length_file_out
diff --git a/tests/standalone/io/http_proxy_advanced_test.dart b/tests/standalone/io/http_proxy_advanced_test.dart
index 7a349d1..8309fc7 100644
--- a/tests/standalone/io/http_proxy_advanced_test.dart
+++ b/tests/standalone/io/http_proxy_advanced_test.dart
@@ -2,6 +2,10 @@
// 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.
+// OtherResources=certificates/server_chain.pem
+// OtherResources=certificates/server_key.pem
+// OtherResources=certificates/trusted_certs.pem
+
import "package:convert/convert.dart";
import "package:crypto/crypto.dart";
import "package:expect/expect.dart";
diff --git a/tests/standalone/io/http_proxy_test.dart b/tests/standalone/io/http_proxy_test.dart
index 70a7f8c..2d2fdcb 100644
--- a/tests/standalone/io/http_proxy_test.dart
+++ b/tests/standalone/io/http_proxy_test.dart
@@ -2,6 +2,10 @@
// 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.
+// OtherResources=certificates/server_chain.pem
+// OtherResources=certificates/server_key.pem
+// OtherResources=certificates/trusted_certs.pem
+
import "package:convert/convert.dart";
import "package:crypto/crypto.dart";
import "package:expect/expect.dart";
diff --git a/tests/standalone/io/https_bad_certificate_test.dart b/tests/standalone/io/https_bad_certificate_test.dart
index cafacfb..6205bb3 100644
--- a/tests/standalone/io/https_bad_certificate_test.dart
+++ b/tests/standalone/io/https_bad_certificate_test.dart
@@ -2,6 +2,10 @@
// 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.
+// OtherResources=certificates/server_chain.pem
+// OtherResources=certificates/server_key.pem
+// OtherResources=certificates/trusted_certs.pem
+
// This test verifies that the bad certificate callback works in HttpClient.
import "dart:async";
diff --git a/tests/standalone/io/https_server_test.dart b/tests/standalone/io/https_server_test.dart
index 3f9bc52..f49ac12 100644
--- a/tests/standalone/io/https_server_test.dart
+++ b/tests/standalone/io/https_server_test.dart
@@ -1,6 +1,10 @@
// Copyright (c) 2012, 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.
+//
+// OtherResources=certificates/server_chain.pem
+// OtherResources=certificates/server_key.pem
+// OtherResources=certificates/trusted_certs.pem
import "dart:async";
import "dart:io";
diff --git a/tests/standalone/io/https_unauthorized_test.dart b/tests/standalone/io/https_unauthorized_test.dart
index a556626..f415a83 100644
--- a/tests/standalone/io/https_unauthorized_test.dart
+++ b/tests/standalone/io/https_unauthorized_test.dart
@@ -1,6 +1,9 @@
// 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.
+//
+// OtherResources=certificates/server_chain.pem
+// OtherResources=certificates/server_key.pem
// This test verifies that secure connections that fail due to
// unauthenticated certificates throw exceptions in HttpClient.
diff --git a/tests/standalone/io/raw_secure_server_closing_test.dart b/tests/standalone/io/raw_secure_server_closing_test.dart
index e6c084a..fc73018 100644
--- a/tests/standalone/io/raw_secure_server_closing_test.dart
+++ b/tests/standalone/io/raw_secure_server_closing_test.dart
@@ -6,6 +6,9 @@
// VMOptions=--short_socket_read
// VMOptions=--short_socket_write
// VMOptions=--short_socket_read --short_socket_write
+// OtherResources=certificates/server_chain.pem
+// OtherResources=certificates/server_key.pem
+// OtherResources=certificates/trusted_certs.pem
import "dart:async";
import "dart:io";
diff --git a/tests/standalone/io/raw_secure_server_socket_test.dart b/tests/standalone/io/raw_secure_server_socket_test.dart
index b9c7e9b..7b5ef57 100644
--- a/tests/standalone/io/raw_secure_server_socket_test.dart
+++ b/tests/standalone/io/raw_secure_server_socket_test.dart
@@ -6,6 +6,11 @@
// VMOptions=--short_socket_read
// VMOptions=--short_socket_write
// VMOptions=--short_socket_read --short_socket_write
+// OtherResources=certificates/server_chain.pem
+// OtherResources=certificates/server_key.pem
+// OtherResources=certificates/trusted_certs.pem
+// OtherResources=certificates/untrusted_server_chain.pem
+// OtherResources=certificates/untrusted_server_key.pem
import "dart:async";
import "dart:io";
diff --git a/tests/standalone/io/raw_secure_socket_pause_test.dart b/tests/standalone/io/raw_secure_socket_pause_test.dart
index 0073cda..5d9b8f6 100644
--- a/tests/standalone/io/raw_secure_socket_pause_test.dart
+++ b/tests/standalone/io/raw_secure_socket_pause_test.dart
@@ -6,6 +6,9 @@
// VMOptions=--short_socket_read
// VMOptions=--short_socket_write
// VMOptions=--short_socket_read --short_socket_write
+// OtherResources=certificates/server_chain.pem
+// OtherResources=certificates/server_key.pem
+// OtherResources=certificates/trusted_certs.pem
import "package:expect/expect.dart";
import "package:path/path.dart";
diff --git a/tests/standalone/io/raw_secure_socket_test.dart b/tests/standalone/io/raw_secure_socket_test.dart
index df3994e..5af28f9 100644
--- a/tests/standalone/io/raw_secure_socket_test.dart
+++ b/tests/standalone/io/raw_secure_socket_test.dart
@@ -6,6 +6,9 @@
// VMOptions=--short_socket_read
// VMOptions=--short_socket_write
// VMOptions=--short_socket_read --short_socket_write
+// OtherResources=certificates/server_chain.pem
+// OtherResources=certificates/server_key.pem
+// OtherResources=certificates/trusted_certs.pem
import "package:expect/expect.dart";
import "package:path/path.dart";
diff --git a/tests/standalone/io/read_into_const_list_test.dart b/tests/standalone/io/read_into_const_list_test.dart
index 3eb624a..11e56ce 100644
--- a/tests/standalone/io/read_into_const_list_test.dart
+++ b/tests/standalone/io/read_into_const_list_test.dart
@@ -1,6 +1,8 @@
// Copyright (c) 2012, 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.
+//
+// OtherResources=readline_test1.dat
// Regression test for missing immutability check in the ListSet
// methods in the API. This allowed overwriting const Lists.
@@ -9,19 +11,15 @@
import "dart:io";
String getFilename(String path) {
- var testPath = Platform.script.resolve('../../../$path');
- return new File.fromUri(testPath).existsSync()
- ? testPath.toFilePath()
- : Platform.script.resolve('../../../runtime/$path').toFilePath();
+ return Platform.script.resolve(path).toFilePath();
}
-
void main() {
var a = const [0];
var b = const [0];
Expect.identical(a, b);
- String filename = getFilename("bin/file_test.cc");
+ String filename = getFilename("readline_test1.dat");
File file = new File(filename);
file.open().then((input) {
try {
diff --git a/tests/standalone/io/regress_21160_test.dart b/tests/standalone/io/regress_21160_test.dart
index b3d39f1..c4c4f13 100644
--- a/tests/standalone/io/regress_21160_test.dart
+++ b/tests/standalone/io/regress_21160_test.dart
@@ -2,6 +2,10 @@
// 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.
+// OtherResources=certificates/server_chain.pem
+// OtherResources=certificates/server_key.pem
+// OtherResources=certificates/trusted_certs.pem
+
import "package:expect/expect.dart";
import "package:path/path.dart";
import "package:async_helper/async_helper.dart";
diff --git a/tests/standalone/io/resolve_symbolic_links_test.dart b/tests/standalone/io/resolve_symbolic_links_test.dart
index 690cbc5..4d3f22e 100644
--- a/tests/standalone/io/resolve_symbolic_links_test.dart
+++ b/tests/standalone/io/resolve_symbolic_links_test.dart
@@ -11,7 +11,8 @@
import 'dart:io';
main() {
- String testsDir = Platform.script.resolve('../..').toFilePath();
+ String testsDir = Directory.current.uri.resolve('tests').toFilePath();
+
// All of these tests test that resolveSymbolicLinks gives a path
// that points to the same place as the original, and that it removes
// all links, .., and . segments, and that it produces an absolute path.
diff --git a/tests/standalone/io/secure_bad_certificate_test.dart b/tests/standalone/io/secure_bad_certificate_test.dart
index 7b28284..c4e81cc 100644
--- a/tests/standalone/io/secure_bad_certificate_test.dart
+++ b/tests/standalone/io/secure_bad_certificate_test.dart
@@ -2,6 +2,10 @@
// 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.
+// OtherResources=certificates/server_chain.pem
+// OtherResources=certificates/server_key.pem
+// OtherResources=certificates/trusted_certs.pem
+
// This test verifies that the bad certificate callback works.
import "dart:async";
diff --git a/tests/standalone/io/secure_client_raw_server_test.dart b/tests/standalone/io/secure_client_raw_server_test.dart
index e8cb63d..20f7a3f 100644
--- a/tests/standalone/io/secure_client_raw_server_test.dart
+++ b/tests/standalone/io/secure_client_raw_server_test.dart
@@ -6,6 +6,9 @@
// VMOptions=--short_socket_read
// VMOptions=--short_socket_write
// VMOptions=--short_socket_read --short_socket_write
+// OtherResources=certificates/server_chain.pem
+// OtherResources=certificates/server_key.pem
+// OtherResources=certificates/trusted_certs.pem
import "dart:async";
import "dart:io";
diff --git a/tests/standalone/io/secure_client_server_test.dart b/tests/standalone/io/secure_client_server_test.dart
index 4d928ef..1c16908 100644
--- a/tests/standalone/io/secure_client_server_test.dart
+++ b/tests/standalone/io/secure_client_server_test.dart
@@ -6,6 +6,9 @@
// VMOptions=--short_socket_read
// VMOptions=--short_socket_write
// VMOptions=--short_socket_read --short_socket_write
+// OtherResources=certificates/server_chain.pem
+// OtherResources=certificates/server_key.pem
+// OtherResources=certificates/trusted_certs.pem
import "dart:async";
import "dart:io";
diff --git a/tests/standalone/io/secure_multiple_client_server_test.dart b/tests/standalone/io/secure_multiple_client_server_test.dart
index a0577df..add0c9c 100644
--- a/tests/standalone/io/secure_multiple_client_server_test.dart
+++ b/tests/standalone/io/secure_multiple_client_server_test.dart
@@ -6,6 +6,9 @@
// VMOptions=--short_socket_read
// VMOptions=--short_socket_write
// VMOptions=--short_socket_read --short_socket_write
+// OtherResources=certificates/server_chain.pem
+// OtherResources=certificates/server_key.pem
+// OtherResources=certificates/trusted_certs.pem
import "dart:async";
import "dart:io";
diff --git a/tests/standalone/io/secure_server_client_certificate_test.dart b/tests/standalone/io/secure_server_client_certificate_test.dart
index 4c16ab0..561ea33 100644
--- a/tests/standalone/io/secure_server_client_certificate_test.dart
+++ b/tests/standalone/io/secure_server_client_certificate_test.dart
@@ -2,6 +2,19 @@
// 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.
+// OtherResources=certificates/server_chain.pem
+// OtherResources=certificates/server_key.pem
+// OtherResources=certificates/trusted_certs.pem
+// OtherResources=certificates/client_authority.pem
+// OtherResources=certificates/client1.pem
+// OtherResources=certificates/client1_key.pem
+// OtherResources=certificates/server_chain.p12
+// OtherResources=certificates/server_key.p12
+// OtherResources=certificates/trusted_certs.p12
+// OtherResources=certificates/client_authority.p12
+// OtherResources=certificates/client1.p12
+// OtherResources=certificates/client1_key.p12
+
import "dart:async";
import "dart:io";
diff --git a/tests/standalone/io/secure_server_closing_test.dart b/tests/standalone/io/secure_server_closing_test.dart
index 159c6ae4..10a730d 100644
--- a/tests/standalone/io/secure_server_closing_test.dart
+++ b/tests/standalone/io/secure_server_closing_test.dart
@@ -6,6 +6,9 @@
// VMOptions=--short_socket_read
// VMOptions=--short_socket_write
// VMOptions=--short_socket_read --short_socket_write
+// OtherResources=certificates/server_chain.pem
+// OtherResources=certificates/server_key.pem
+// OtherResources=certificates/trusted_certs.pem
import "dart:async";
import "dart:io";
diff --git a/tests/standalone/io/secure_server_socket_test.dart b/tests/standalone/io/secure_server_socket_test.dart
index 2af0510..767c531 100644
--- a/tests/standalone/io/secure_server_socket_test.dart
+++ b/tests/standalone/io/secure_server_socket_test.dart
@@ -6,6 +6,9 @@
// VMOptions=--short_socket_read
// VMOptions=--short_socket_write
// VMOptions=--short_socket_read --short_socket_write
+// OtherResources=certificates/server_chain.pem
+// OtherResources=certificates/server_key.pem
+// OtherResources=certificates/trusted_certs.pem
import "dart:async";
import "dart:io";
diff --git a/tests/standalone/io/secure_session_resume_test.dart b/tests/standalone/io/secure_session_resume_test.dart
index 15f2b0b..f48a888 100644
--- a/tests/standalone/io/secure_session_resume_test.dart
+++ b/tests/standalone/io/secure_session_resume_test.dart
@@ -15,6 +15,9 @@
// VMOptions=--short_socket_read
// VMOptions=--short_socket_write
// VMOptions=--short_socket_read --short_socket_write
+// OtherResources=certificates/server_chain.pem
+// OtherResources=certificates/server_key.pem
+// OtherResources=certificates/trusted_certs.pem
import "dart:async";
import "dart:io";
diff --git a/tests/standalone/io/secure_socket_alpn_test.dart b/tests/standalone/io/secure_socket_alpn_test.dart
index 8bd4e27..6b835e6 100644
--- a/tests/standalone/io/secure_socket_alpn_test.dart
+++ b/tests/standalone/io/secure_socket_alpn_test.dart
@@ -1,6 +1,10 @@
// 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.
+//
+// OtherResources=certificates/server_chain.pem
+// OtherResources=certificates/server_key.pem
+// OtherResources=certificates/trusted_certs.pem
import 'dart:io';
import 'dart:convert';
diff --git a/tests/standalone/io/secure_socket_renegotiate_test.dart b/tests/standalone/io/secure_socket_renegotiate_test.dart
index 457cee6..e445ed4 100644
--- a/tests/standalone/io/secure_socket_renegotiate_test.dart
+++ b/tests/standalone/io/secure_socket_renegotiate_test.dart
@@ -1,6 +1,9 @@
// 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.
+//
+// OtherResources=certificates/server_chain.pem
+// OtherResources=certificates/server_key.pem
// This test verifies that client certificates work, if the client and server
// are in separate processes, and that connection renegotiation works, and
diff --git a/tests/standalone/io/secure_socket_test.dart b/tests/standalone/io/secure_socket_test.dart
index bf128df..9a92757 100644
--- a/tests/standalone/io/secure_socket_test.dart
+++ b/tests/standalone/io/secure_socket_test.dart
@@ -6,6 +6,12 @@
// VMOptions=--short_socket_read
// VMOptions=--short_socket_write
// VMOptions=--short_socket_read --short_socket_write
+// OtherResources=certificates/server_chain.pem
+// OtherResources=certificates/server_key.pem
+// OtherResources=certificates/trusted_certs.pem
+// OtherResources=certificates/server_chain.p12
+// OtherResources=certificates/server_key.p12
+// OtherResources=certificates/trusted_certs.p12
import "package:async_helper/async_helper.dart";
import "package:expect/expect.dart";
diff --git a/tests/standalone/io/security_context_argument_test.dart b/tests/standalone/io/security_context_argument_test.dart
index fc6ff1c..117d257 100644
--- a/tests/standalone/io/security_context_argument_test.dart
+++ b/tests/standalone/io/security_context_argument_test.dart
@@ -1,6 +1,15 @@
// 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.
+//
+// OtherResources=certificates/server_chain.pem
+// OtherResources=certificates/server_key.pem
+// OtherResources=certificates/server_key.p12
+// OtherResources=certificates/client1_key_malformed.pem
+// OtherResources=certificates/trusted_certs_malformed.pem
+// OtherResources=certificates/server_chain_malformed1.pem
+// OtherResources=certificates/server_chain_malformed2.pem
+// OtherResources=certificates/client_authority_malformed.pem
import "package:expect/expect.dart";
import "dart:io";
diff --git a/tests/standalone/io/socket_upgrade_to_secure_test.dart b/tests/standalone/io/socket_upgrade_to_secure_test.dart
index b4c862b..3822300 100644
--- a/tests/standalone/io/socket_upgrade_to_secure_test.dart
+++ b/tests/standalone/io/socket_upgrade_to_secure_test.dart
@@ -6,6 +6,9 @@
// VMOptions=--short_socket_read
// VMOptions=--short_socket_write
// VMOptions=--short_socket_read --short_socket_write
+// OtherResources=certificates/server_chain.pem
+// OtherResources=certificates/server_key.pem
+// OtherResources=certificates/trusted_certs.pem
import "dart:async";
import "dart:io";
diff --git a/tests/standalone/io/test_extension_test.dart b/tests/standalone/io/test_extension_test.dart
index 40d768e..cf98925 100644
--- a/tests/standalone/io/test_extension_test.dart
+++ b/tests/standalone/io/test_extension_test.dart
@@ -56,6 +56,7 @@
if (buildDirectory.endsWith('SIMARM')) return '';
if (buildDirectory.endsWith('SIMARM64')) return '';
if (buildDirectory.endsWith('SIMDBC')) return '';
+ if (buildDirectory.endsWith('SIMDBC64')) return '';
if (buildDirectory.endsWith('SIMMIPS')) return '';
if (buildDirectory.endsWith('ARM')) return '-arm';
if (buildDirectory.endsWith('ARM64')) return '-arm64';
diff --git a/tests/standalone/io/web_socket_error_test.dart b/tests/standalone/io/web_socket_error_test.dart
index 42b93d4..5003832 100644
--- a/tests/standalone/io/web_socket_error_test.dart
+++ b/tests/standalone/io/web_socket_error_test.dart
@@ -6,6 +6,8 @@
// VMOptions=--short_socket_read
// VMOptions=--short_socket_write
// VMOptions=--short_socket_read --short_socket_write
+// OtherResources=certificates/server_chain.pem
+// OtherResources=certificates/server_key.pem
library dart.io;
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index dc43ab8..5281b37 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -25,6 +25,7 @@
[ ($runtime != vm && $runtime != dart_precompiled && $runtime != dart_app) && ($runtime != drt || $compiler != none)) ]
no_assert_test: Fail, OK # This is testing a vm flag.
+env_test: Skip # This is testing a vm command line parsing scenario.
[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_app) ]
package/package_isolate_test: Fail # Issue 12474
@@ -75,6 +76,7 @@
map_insert_remove_oom_test: Skip # Issue 24571
verbose_gc_to_bmu_test: Skip
regress_26031_test: SkipByDesign # Standalone only test
+env_test: Skip # This is testing a vm command line parsing scenario.
[ $compiler == dartanalyzer || $compiler == dart2analyzer ]
issue14236_test: Skip # Analyzer can't handle Script snapshots.
diff --git a/third_party/pkg/petitparser.tar.gz.sha1 b/third_party/pkg/petitparser.tar.gz.sha1
deleted file mode 100644
index 20b3196..0000000
--- a/third_party/pkg/petitparser.tar.gz.sha1
+++ /dev/null
@@ -1 +0,0 @@
-9626eed1ad9963e782f55a943ee8a1f82ff251a1
\ No newline at end of file
diff --git a/third_party/tcmalloc/BUILD.gn b/third_party/tcmalloc/BUILD.gn
index e970559..ec423be 100644
--- a/third_party/tcmalloc/BUILD.gn
+++ b/third_party/tcmalloc/BUILD.gn
@@ -105,6 +105,12 @@
"-fpermissive",
]
+ if (!is_clang && current_cpu == "x86") {
+ cflags += [
+ "-Wno-format"
+ ]
+ }
+
set_sources_assignment_filter([
# No debug allocator.
"gperftools/src/debugallocation.cc",
diff --git a/tools/VERSION b/tools/VERSION
index ef41160..9cb94bc 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -1,3 +1,4 @@
+
# This file is used by tools/utils.py to generate version strings.
# The numbers are changed as follows:
#
@@ -25,7 +26,7 @@
#
CHANNEL dev
MAJOR 1
-MINOR 20
+MINOR 21
PATCH 0
-PRERELEASE 10
-PRERELEASE_PATCH 3
+PRERELEASE 0
+PRERELEASE_PATCH 0
diff --git a/tools/bots/ddc_tests.py b/tools/bots/ddc_tests.py
new file mode 100644
index 0000000..73f8f4a
--- /dev/null
+++ b/tools/bots/ddc_tests.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python
+#
+# 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 os
+import os.path
+import shutil
+import sys
+import subprocess
+
+import bot
+import bot_utils
+
+utils = bot_utils.GetUtils()
+
+BUILD_OS = utils.GuessOS()
+
+(bot_name, _) = bot.GetBotName()
+CHANNEL = bot_utils.GetChannelFromName(bot_name)
+
+if __name__ == '__main__':
+ print "This step should run dartdevc tests"
+ print "Current directory when running on a bot should be"
+ print "/b/build/slave/[builder name]/build/sdk"
diff --git a/tools/bots/gn_build.py b/tools/bots/gn_build.py
new file mode 100644
index 0000000..0fe2298
--- /dev/null
+++ b/tools/bots/gn_build.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+#
+# 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 os
+import os.path
+import shutil
+import sys
+import subprocess
+
+SCRIPT_DIR = os.path.dirname(sys.argv[0])
+DART_ROOT = os.path.realpath(os.path.join(SCRIPT_DIR, '..', '..'))
+
+def main(argv):
+ os.environ["DART_USE_GN"] = "1"
+ generate_buildfiles = os.path.join(
+ DART_ROOT, 'tools', 'generate_buildfiles.py')
+ gclient_result = subprocess.call(['python', generate_buildfiles])
+ if gclient_result != 0:
+ return gclient_result
+
+ build_py = os.path.join(DART_ROOT, 'tools', 'build.py')
+ build_result = subprocess.call(['python', build_py] + argv[1:])
+ if build_result != 0:
+ return build_result
+ return 0
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv))
diff --git a/tools/bots/gn_tests.py b/tools/bots/gn_tests.py
new file mode 100644
index 0000000..877b6dc
--- /dev/null
+++ b/tools/bots/gn_tests.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python
+#
+# 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 os
+import os.path
+import shutil
+import sys
+import subprocess
+
+SCRIPT_DIR = os.path.dirname(sys.argv[0])
+DART_ROOT = os.path.realpath(os.path.join(SCRIPT_DIR, '..', '..'))
+
+def main(argv):
+ test_py = os.path.join(DART_ROOT, 'tools', 'test.py')
+ build_result = subprocess.call(
+ ['python', test_py] + ['--builder-tag=no_ipv6'] + argv[1:])
+ if build_result != 0:
+ return build_result
+ return 0
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv))
diff --git a/tools/build.py b/tools/build.py
index a27dd41..4f5d2e1 100755
--- a/tools/build.py
+++ b/tools/build.py
@@ -44,6 +44,13 @@
unless you really intend to use a non-default Makefile.""" % DART_ROOT
+DART_USE_GN = "DART_USE_GN"
+
+
+def use_gn():
+ return DART_USE_GN in os.environ
+
+
def BuildOptions():
result = optparse.OptionParser(usage=usage)
result.add_option("-m", "--mode",
@@ -77,6 +84,10 @@
help='Name of the devenv.com/msbuild executable on Windows (varies for '
'different versions of Visual Studio)',
default=vs_executable)
+ result.add_option("--gn",
+ help='Build with GN/Ninja',
+ default=use_gn(),
+ action='store_true')
return result
@@ -389,86 +400,116 @@
os.system(command)
+def RunGN(target_os, mode, arch):
+ gn_os = 'host' if target_os == HOST_OS else target_os
+ gn_command = [
+ 'python',
+ os.path.join(DART_ROOT, 'tools', 'gn.py'),
+ '-m', mode,
+ '-a', arch,
+ '--os', gn_os,
+ '-v',
+ ]
+ process = subprocess.Popen(gn_command)
+ process.wait()
+ if process.returncode != 0:
+ print ("Tried to run GN, but it failed. Try running it manually: \n\t$ " +
+ ' '.join(gn_command))
+
+def BuildNinjaCommand(options, target, target_os, mode, arch):
+ out_dir = utils.GetBuildRoot(HOST_OS, mode, arch, target_os)
+ if not os.path.exists(out_dir):
+ RunGN(target_os, mode, arch)
+ command = ['ninja', '-C', out_dir]
+ if options.verbose:
+ command += ['-v']
+ command += [target]
+ return command
+
+
filter_xcodebuild_output = False
def BuildOneConfig(options, target, target_os, mode, arch, override_tools):
global filter_xcodebuild_output
start_time = time.time()
- os.environ['DART_BUILD_MODE'] = mode
+ args = []
build_config = utils.GetBuildConf(mode, arch, target_os)
- if HOST_OS == 'macos':
- filter_xcodebuild_output = True
- project_file = 'dart.xcodeproj'
- if os.path.exists('dart-%s.gyp' % CurrentDirectoryBaseName()):
- project_file = 'dart-%s.xcodeproj' % CurrentDirectoryBaseName()
- args = ['xcodebuild',
- '-project',
- project_file,
- '-target',
- target,
- '-configuration',
- build_config,
- 'SYMROOT=%s' % os.path.abspath('xcodebuild')
- ]
- elif HOST_OS == 'win32':
- project_file = 'dart.sln'
- if os.path.exists('dart-%s.gyp' % CurrentDirectoryBaseName()):
- project_file = 'dart-%s.sln' % CurrentDirectoryBaseName()
- # Select a platform suffix to pass to devenv.
- if arch == 'ia32':
- platform_suffix = 'Win32'
- elif arch == 'x64':
- platform_suffix = 'x64'
- else:
- print 'Unsupported arch for MSVC build: %s' % arch
- return 1
- config_name = '%s|%s' % (build_config, platform_suffix)
- if target == 'all':
- args = [options.devenv + os.sep + options.executable,
- '/build',
- config_name,
- project_file
- ]
- else:
- args = [options.devenv + os.sep + options.executable,
- '/build',
- config_name,
- '/project',
- target,
- project_file
- ]
+ if options.gn:
+ args = BuildNinjaCommand(options, target, target_os, mode, arch)
else:
- make = 'make'
- if HOST_OS == 'freebsd':
- make = 'gmake'
- # work around lack of flock
- os.environ['LINK'] = '$(CXX)'
- args = [make,
- '-j',
- options.j,
- 'BUILDTYPE=' + build_config,
- ]
- if target_os != HOST_OS:
- args += ['builddir_name=' + utils.GetBuildDir(HOST_OS)]
- if options.verbose:
- args += ['V=1']
-
- args += [target]
-
- toolsOverride = None
- if override_tools:
- toolsOverride = SetTools(arch, target_os, options)
- if toolsOverride:
- for k, v in toolsOverride.iteritems():
- args.append( k + "=" + v)
- if options.verbose:
- print k + " = " + v
- if not os.path.isfile(toolsOverride['CC.target']):
- if arch == 'arm':
- print arm_cc_error
+ os.environ['DART_BUILD_MODE'] = mode
+ if HOST_OS == 'macos':
+ filter_xcodebuild_output = True
+ project_file = 'dart.xcodeproj'
+ if os.path.exists('dart-%s.gyp' % CurrentDirectoryBaseName()):
+ project_file = 'dart-%s.xcodeproj' % CurrentDirectoryBaseName()
+ args = ['xcodebuild',
+ '-project',
+ project_file,
+ '-target',
+ target,
+ '-configuration',
+ build_config,
+ 'SYMROOT=%s' % os.path.abspath('xcodebuild')
+ ]
+ elif HOST_OS == 'win32':
+ project_file = 'dart.sln'
+ if os.path.exists('dart-%s.gyp' % CurrentDirectoryBaseName()):
+ project_file = 'dart-%s.sln' % CurrentDirectoryBaseName()
+ # Select a platform suffix to pass to devenv.
+ if arch == 'ia32':
+ platform_suffix = 'Win32'
+ elif arch == 'x64':
+ platform_suffix = 'x64'
else:
- print "Couldn't find compiler: %s" % toolsOverride['CC.target']
- return 1
+ print 'Unsupported arch for MSVC build: %s' % arch
+ return 1
+ config_name = '%s|%s' % (build_config, platform_suffix)
+ if target == 'all':
+ args = [options.devenv + os.sep + options.executable,
+ '/build',
+ config_name,
+ project_file
+ ]
+ else:
+ args = [options.devenv + os.sep + options.executable,
+ '/build',
+ config_name,
+ '/project',
+ target,
+ project_file
+ ]
+ else:
+ make = 'make'
+ if HOST_OS == 'freebsd':
+ make = 'gmake'
+ # work around lack of flock
+ os.environ['LINK'] = '$(CXX)'
+ args = [make,
+ '-j',
+ options.j,
+ 'BUILDTYPE=' + build_config,
+ ]
+ if target_os != HOST_OS:
+ args += ['builddir_name=' + utils.GetBuildDir(HOST_OS)]
+ if options.verbose:
+ args += ['V=1']
+ args += [target]
+
+ toolsOverride = None
+ if override_tools:
+ toolsOverride = SetTools(arch, target_os, options)
+ if toolsOverride:
+ for k, v in toolsOverride.iteritems():
+ args.append( k + "=" + v)
+ if options.verbose:
+ print k + " = " + v
+ if not os.path.isfile(toolsOverride['CC.target']):
+ if arch == 'arm':
+ print arm_cc_error
+ else:
+ print "Couldn't find compiler: %s" % toolsOverride['CC.target']
+ return 1
print ' '.join(args)
process = None
@@ -501,9 +542,6 @@
if BuildOneConfig(options, 'runtime', target_os, mode, arch, True) != 0:
return 1
- # TODO(zra): verify that no platform specific details leak into the snapshots
- # created for pub, dart2js, etc.
-
# Copy dart-sdk from the host build products dir to the target build
# products dir, and copy the dart binary for target to the sdk bin/ dir.
src = os.path.join(
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py
index 55b64ee..100bdec 100755
--- a/tools/clang/scripts/update.py
+++ b/tools/clang/scripts/update.py
@@ -3,12 +3,12 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-"""Windows can't run .sh files, so this is a Python implementation of
-update.sh. This script should replace update.sh on all platforms eventually."""
+"""This script is used to download prebuilt clang binaries.
+
+It is also used by package.py to build the prebuilt clang binaries."""
import argparse
-import contextlib
-import cStringIO
+import distutils.spawn
import glob
import os
import pipes
@@ -18,26 +18,25 @@
import stat
import sys
import tarfile
+import tempfile
import time
import urllib2
import zipfile
+
# Do NOT CHANGE this if you don't know what you're doing -- see
-# https://code.google.com/p/chromium/wiki/UpdatingClang
+# https://chromium.googlesource.com/chromium/src/+/master/docs/updating_clang.md
# Reverting problematic clang rolls is safe, though.
-# Note: this revision is only used for Windows. Other platforms use update.sh.
-# TODO(thakis): Use the same revision on Windows and non-Windows.
-# TODO(thakis): Remove update.sh, use update.py everywhere.
-LLVM_WIN_REVISION = '242415'
+CLANG_REVISION = '282487'
use_head_revision = 'LLVM_FORCE_HEAD_REVISION' in os.environ
if use_head_revision:
- LLVM_WIN_REVISION = 'HEAD'
+ CLANG_REVISION = 'HEAD'
# This is incremented when pushing a new build of Clang at the same revision.
CLANG_SUB_REVISION=1
-PACKAGE_VERSION = "%s-%s" % (LLVM_WIN_REVISION, CLANG_SUB_REVISION)
+PACKAGE_VERSION = "%s-%s" % (CLANG_REVISION, CLANG_SUB_REVISION)
# Path constants. (All of these should be absolute paths.)
THIS_DIR = os.path.abspath(os.path.dirname(__file__))
@@ -47,71 +46,135 @@
LLVM_BOOTSTRAP_DIR = os.path.join(THIRD_PARTY_DIR, 'llvm-bootstrap')
LLVM_BOOTSTRAP_INSTALL_DIR = os.path.join(THIRD_PARTY_DIR,
'llvm-bootstrap-install')
+LLVM_LTO_GOLD_PLUGIN_DIR = os.path.join(THIRD_PARTY_DIR, 'llvm-lto-gold-plugin')
CHROME_TOOLS_SHIM_DIR = os.path.join(LLVM_DIR, 'tools', 'chrometools')
LLVM_BUILD_DIR = os.path.join(CHROMIUM_DIR, 'third_party', 'llvm-build',
'Release+Asserts')
-COMPILER_RT_BUILD_DIR = os.path.join(LLVM_BUILD_DIR, '32bit-compiler-rt')
+COMPILER_RT_BUILD_DIR = os.path.join(LLVM_BUILD_DIR, 'compiler-rt')
CLANG_DIR = os.path.join(LLVM_DIR, 'tools', 'clang')
LLD_DIR = os.path.join(LLVM_DIR, 'tools', 'lld')
-COMPILER_RT_DIR = os.path.join(LLVM_DIR, 'projects', 'compiler-rt')
+# compiler-rt is built as part of the regular LLVM build on Windows to get
+# the 64-bit runtime, and out-of-tree elsewhere.
+# TODO(thakis): Try to unify this.
+if sys.platform == 'win32':
+ COMPILER_RT_DIR = os.path.join(LLVM_DIR, 'projects', 'compiler-rt')
+else:
+ COMPILER_RT_DIR = os.path.join(LLVM_DIR, 'compiler-rt')
LIBCXX_DIR = os.path.join(LLVM_DIR, 'projects', 'libcxx')
LIBCXXABI_DIR = os.path.join(LLVM_DIR, 'projects', 'libcxxabi')
LLVM_BUILD_TOOLS_DIR = os.path.abspath(
os.path.join(LLVM_DIR, '..', 'llvm-build-tools'))
-STAMP_FILE = os.path.join(LLVM_DIR, '..', 'llvm-build', 'cr_build_revision')
+STAMP_FILE = os.path.normpath(
+ os.path.join(LLVM_DIR, '..', 'llvm-build', 'cr_build_revision'))
BINUTILS_DIR = os.path.join(THIRD_PARTY_DIR, 'binutils')
-VERSION = '3.8.0'
+BINUTILS_BIN_DIR = os.path.join(BINUTILS_DIR, BINUTILS_DIR,
+ 'Linux_x64', 'Release', 'bin')
+BFD_PLUGINS_DIR = os.path.join(BINUTILS_DIR, 'Linux_x64', 'Release',
+ 'lib', 'bfd-plugins')
+VERSION = '4.0.0'
+ANDROID_NDK_DIR = os.path.join(
+ CHROMIUM_DIR, 'third_party', 'android_tools', 'ndk')
# URL for pre-built binaries.
-CDS_URL = 'https://commondatastorage.googleapis.com/chromium-browser-clang'
+CDS_URL = os.environ.get('CDS_CLANG_BUCKET_OVERRIDE',
+ 'https://commondatastorage.googleapis.com/chromium-browser-clang')
LLVM_REPO_URL='https://llvm.org/svn/llvm-project'
if 'LLVM_REPO_URL' in os.environ:
LLVM_REPO_URL = os.environ['LLVM_REPO_URL']
+# Bump after VC updates.
+DIA_DLL = {
+ '2013': 'msdia120.dll',
+ '2015': 'msdia140.dll',
+}
+
def DownloadUrl(url, output_file):
"""Download url into output_file."""
CHUNK_SIZE = 4096
TOTAL_DOTS = 10
- sys.stdout.write('Downloading %s ' % url)
- sys.stdout.flush()
- response = urllib2.urlopen(url)
- total_size = int(response.info().getheader('Content-Length').strip())
- bytes_done = 0
- dots_printed = 0
+ num_retries = 3
+ retry_wait_s = 5 # Doubled at each retry.
+
while True:
- chunk = response.read(CHUNK_SIZE)
- if not chunk:
- break
- output_file.write(chunk)
- bytes_done += len(chunk)
- num_dots = TOTAL_DOTS * bytes_done / total_size
- sys.stdout.write('.' * (num_dots - dots_printed))
- sys.stdout.flush()
- dots_printed = num_dots
- print ' Done.'
+ try:
+ sys.stdout.write('Downloading %s ' % url)
+ sys.stdout.flush()
+ response = urllib2.urlopen(url)
+ total_size = int(response.info().getheader('Content-Length').strip())
+ bytes_done = 0
+ dots_printed = 0
+ while True:
+ chunk = response.read(CHUNK_SIZE)
+ if not chunk:
+ break
+ output_file.write(chunk)
+ bytes_done += len(chunk)
+ num_dots = TOTAL_DOTS * bytes_done / total_size
+ sys.stdout.write('.' * (num_dots - dots_printed))
+ sys.stdout.flush()
+ dots_printed = num_dots
+ if bytes_done != total_size:
+ raise urllib2.URLError("only got %d of %d bytes" %
+ (bytes_done, total_size))
+ print ' Done.'
+ return
+ except urllib2.URLError as e:
+ sys.stdout.write('\n')
+ print e
+ if num_retries == 0 or isinstance(e, urllib2.HTTPError) and e.code == 404:
+ raise e
+ num_retries -= 1
+ print 'Retrying in %d s ...' % retry_wait_s
+ time.sleep(retry_wait_s)
+ retry_wait_s *= 2
-def ReadStampFile():
+def EnsureDirExists(path):
+ if not os.path.exists(path):
+ print "Creating directory %s" % path
+ os.makedirs(path)
+
+
+def DownloadAndUnpack(url, output_dir):
+ with tempfile.TemporaryFile() as f:
+ DownloadUrl(url, f)
+ f.seek(0)
+ EnsureDirExists(output_dir)
+ if url.endswith('.zip'):
+ zipfile.ZipFile(f).extractall(path=output_dir)
+ else:
+ tarfile.open(mode='r:gz', fileobj=f).extractall(path=output_dir)
+
+
+def ReadStampFile(path=STAMP_FILE):
"""Return the contents of the stamp file, or '' if it doesn't exist."""
try:
- with open(STAMP_FILE, 'r') as f:
- return f.read()
+ with open(path, 'r') as f:
+ return f.read().rstrip()
except IOError:
return ''
-def WriteStampFile(s):
+def WriteStampFile(s, path=STAMP_FILE):
"""Write s to the stamp file."""
- if not os.path.exists(os.path.dirname(STAMP_FILE)):
- os.makedirs(os.path.dirname(STAMP_FILE))
- with open(STAMP_FILE, 'w') as f:
+ EnsureDirExists(os.path.dirname(path))
+ with open(path, 'w') as f:
f.write(s)
+ f.write('\n')
def GetSvnRevision(svn_repo):
"""Returns current revision of the svn repo at svn_repo."""
+ if sys.platform == 'darwin':
+ # mac_files toolchain must be set for hermetic builds.
+ root = os.path.dirname(os.path.dirname(os.path.dirname(
+ os.path.dirname(__file__))))
+ sys.path.append(os.path.join(root, 'build'))
+ import mac_toolchain
+
+ mac_toolchain.SetToolchainEnvironment()
svn_info = subprocess.check_output('svn info ' + svn_repo, shell=True)
m = re.search(r'Revision: (\d+)', svn_info)
return m.group(1)
@@ -129,6 +192,15 @@
shutil.rmtree(dir, onerror=ChmodAndRetry)
+def RmCmakeCache(dir):
+ """Delete CMake cache related files from dir."""
+ for dirpath, dirs, files in os.walk(dir):
+ if 'CMakeCache.txt' in files:
+ os.remove(os.path.join(dirpath, 'CMakeCache.txt'))
+ if 'CMakeFiles' in dirs:
+ RmTree(os.path.join(dirpath, 'CMakeFiles'))
+
+
def RunCommand(command, msvc_arch=None, env=None, fail_hard=True):
"""Run command and return success (True) or failure; or if fail_hard is
True, exit on failure. If msvc_arch is set, runs the command in a
@@ -163,15 +235,15 @@
def CopyFile(src, dst):
"""Copy a file from src to dst."""
- shutil.copy(src, dst)
print "Copying %s to %s" % (src, dst)
+ shutil.copy(src, dst)
def CopyDirectoryContents(src, dst, filename_filter=None):
"""Copy the files from directory src to dst
with an optional filename filter."""
- if not os.path.exists(dst):
- os.makedirs(dst)
+ dst = os.path.realpath(dst) # realpath() in case dst ends in /..
+ EnsureDirExists(dst)
for root, _, files in os.walk(src):
for f in files:
if filename_filter and not re.match(filename_filter, f):
@@ -181,9 +253,9 @@
def Checkout(name, url, dir):
"""Checkout the SVN module at url into dir. Use name for the log message."""
- print "Checking out %s r%s into '%s'" % (name, LLVM_WIN_REVISION, dir)
+ print "Checking out %s r%s into '%s'" % (name, CLANG_REVISION, dir)
- command = ['svn', 'checkout', '--force', url + '@' + LLVM_WIN_REVISION, dir]
+ command = ['svn', 'checkout', '--force', url + '@' + CLANG_REVISION, dir]
if RunCommand(command, fail_hard=False):
return
@@ -195,120 +267,9 @@
RunCommand(command)
-def RevertPreviouslyPatchedFiles():
- print 'Reverting previously patched files'
- files = [
- '%(clang)s/test/Index/crash-recovery-modules.m',
- '%(clang)s/unittests/libclang/LibclangTest.cpp',
- '%(compiler_rt)s/lib/asan/asan_rtl.cc',
- '%(compiler_rt)s/test/asan/TestCases/Linux/new_array_cookie_test.cc',
- '%(llvm)s/test/DebugInfo/gmlt.ll',
- '%(llvm)s/lib/CodeGen/SpillPlacement.cpp',
- '%(llvm)s/lib/CodeGen/SpillPlacement.h',
- '%(llvm)s/lib/Transforms/Instrumentation/MemorySanitizer.cpp',
- '%(clang)s/test/Driver/env.c',
- '%(clang)s/lib/Frontend/InitPreprocessor.cpp',
- '%(clang)s/test/Frontend/exceptions.c',
- '%(clang)s/test/Preprocessor/predefined-exceptions.m',
- '%(llvm)s/test/Bindings/Go/go.test',
- '%(clang)s/lib/Parse/ParseExpr.cpp',
- '%(clang)s/lib/Parse/ParseTemplate.cpp',
- '%(clang)s/lib/Sema/SemaDeclCXX.cpp',
- '%(clang)s/lib/Sema/SemaExprCXX.cpp',
- '%(clang)s/test/SemaCXX/default2.cpp',
- '%(clang)s/test/SemaCXX/typo-correction-delayed.cpp',
- '%(compiler_rt)s/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc',
- '%(compiler_rt)s/test/tsan/signal_segv_handler.cc',
- '%(compiler_rt)s/lib/sanitizer_common/sanitizer_coverage_libcdep.cc',
- '%(compiler_rt)s/cmake/config-ix.cmake',
- '%(compiler_rt)s/CMakeLists.txt',
- '%(compiler_rt)s/lib/ubsan/ubsan_platform.h',
- ]
- for f in files:
- f = f % {
- 'clang': CLANG_DIR,
- 'compiler_rt': COMPILER_RT_DIR,
- 'llvm': LLVM_DIR,
- }
- if os.path.exists(f):
- os.remove(f) # For unversioned files.
- RunCommand(['svn', 'revert', f])
-
-
-def ApplyLocalPatches():
- # There's no patch program on Windows by default. We don't need patches on
- # Windows yet, and maybe this not working on Windows will motivate us to
- # remove patches over time.
- assert sys.platform != 'win32'
-
- # Apply patch for tests failing with --disable-pthreads (llvm.org/PR11974)
- clang_patches = [ r"""\
---- test/Index/crash-recovery-modules.m (revision 202554)
-+++ test/Index/crash-recovery-modules.m (working copy)
-@@ -12,6 +12,8 @@
-
- // REQUIRES: crash-recovery
- // REQUIRES: shell
-+// XFAIL: *
-+// (PR11974)
-
- @import Crash;
-""", r"""\
---- unittests/libclang/LibclangTest.cpp (revision 215949)
-+++ unittests/libclang/LibclangTest.cpp (working copy)
-@@ -431,7 +431,7 @@
- EXPECT_EQ(0U, clang_getNumDiagnostics(ClangTU));
- }
-
--TEST_F(LibclangReparseTest, ReparseWithModule) {
-+TEST_F(LibclangReparseTest, DISABLED_ReparseWithModule) {
- const char *HeaderTop = "#ifndef H\n#define H\nstruct Foo { int bar;";
- const char *HeaderBottom = "\n};\n#endif\n";
- const char *MFile = "#include \"HeaderFile.h\"\nint main() {"
-"""
- ]
-
- # This Go bindings test doesn't work after bootstrap on Linux, PR21552.
- llvm_patches = [ r"""\
---- test/Bindings/Go/go.test (revision 223109)
-+++ test/Bindings/Go/go.test (working copy)
-@@ -1,3 +1,3 @@
--; RUN: llvm-go test llvm.org/llvm/bindings/go/llvm
-+; RUN: true
-
- ; REQUIRES: shell
-"""
- ]
-
- # The UBSan run-time, which is now bundled with the ASan run-time, doesn't
- # work on Mac OS X 10.8 (PR23539).
- compiler_rt_patches = [ r"""\
---- CMakeLists.txt (revision 241602)
-+++ CMakeLists.txt (working copy)
-@@ -305,6 +305,7 @@
- list(APPEND SANITIZER_COMMON_SUPPORTED_OS iossim)
- endif()
- endif()
-+ set(SANITIZER_MIN_OSX_VERSION "10.7")
- if(SANITIZER_MIN_OSX_VERSION VERSION_LESS "10.7")
- message(FATAL_ERROR "Too old OS X version: ${SANITIZER_MIN_OSX_VERSION}")
- endif()
-"""
- ]
-
- for path, patches in [(LLVM_DIR, llvm_patches),
- (CLANG_DIR, clang_patches),
- (COMPILER_RT_DIR, compiler_rt_patches)]:
- print 'Applying patches in', path
- for patch in patches:
- print patch
- p = subprocess.Popen( ['patch', '-p0', '-d', path], stdin=subprocess.PIPE)
- (stdout, stderr) = p.communicate(input=patch)
- if p.returncode != 0:
- raise RuntimeError('stdout %s, stderr %s' % (stdout, stderr))
-
-
def DeleteChromeToolsShim():
+ OLD_SHIM_DIR = os.path.join(LLVM_DIR, 'tools', 'zzz-chrometools')
+ shutil.rmtree(OLD_SHIM_DIR, ignore_errors=True)
shutil.rmtree(CHROME_TOOLS_SHIM_DIR, ignore_errors=True)
@@ -337,30 +298,53 @@
f.write('endif (CHROMIUM_TOOLS_SRC)\n')
+def DownloadHostGcc(args):
+ """Downloads gcc 4.8.5 and makes sure args.gcc_toolchain is set."""
+ if not sys.platform.startswith('linux') or args.gcc_toolchain:
+ return
+ # Unconditionally download a prebuilt gcc to guarantee the included libstdc++
+ # works on Ubuntu Precise.
+ gcc_dir = os.path.join(LLVM_BUILD_TOOLS_DIR, 'gcc485precise')
+ if not os.path.exists(gcc_dir):
+ print 'Downloading pre-built GCC 4.8.5...'
+ DownloadAndUnpack(
+ CDS_URL + '/tools/gcc485precise.tgz', LLVM_BUILD_TOOLS_DIR)
+ args.gcc_toolchain = gcc_dir
+
+
def AddCMakeToPath():
"""Download CMake and add it to PATH."""
if sys.platform == 'win32':
- zip_name = 'cmake-3.2.2-win32-x86.zip'
+ zip_name = 'cmake-3.4.3-win32-x86.zip'
cmake_dir = os.path.join(LLVM_BUILD_TOOLS_DIR,
- 'cmake-3.2.2-win32-x86', 'bin')
+ 'cmake-3.4.3-win32-x86', 'bin')
else:
suffix = 'Darwin' if sys.platform == 'darwin' else 'Linux'
- zip_name = 'cmake310_%s.tgz' % suffix
- cmake_dir = os.path.join(LLVM_BUILD_TOOLS_DIR, 'cmake310', 'bin')
+ zip_name = 'cmake343_%s.tgz' % suffix
+ cmake_dir = os.path.join(LLVM_BUILD_TOOLS_DIR, 'cmake343', 'bin')
if not os.path.exists(cmake_dir):
- if not os.path.exists(LLVM_BUILD_TOOLS_DIR):
- os.makedirs(LLVM_BUILD_TOOLS_DIR)
- # The cmake archive is smaller than 20 MB, small enough to keep in memory:
- with contextlib.closing(cStringIO.StringIO()) as f:
- DownloadUrl(CDS_URL + '/tools/' + zip_name, f)
- f.seek(0)
- if zip_name.endswith('.zip'):
- zipfile.ZipFile(f).extractall(path=LLVM_BUILD_TOOLS_DIR)
- else:
- tarfile.open(mode='r:gz', fileobj=f).extractall(path=
- LLVM_BUILD_TOOLS_DIR)
+ DownloadAndUnpack(CDS_URL + '/tools/' + zip_name, LLVM_BUILD_TOOLS_DIR)
os.environ['PATH'] = cmake_dir + os.pathsep + os.environ.get('PATH', '')
+
+def AddGnuWinToPath():
+ """Download some GNU win tools and add them to PATH."""
+ if sys.platform != 'win32':
+ return
+
+ gnuwin_dir = os.path.join(LLVM_BUILD_TOOLS_DIR, 'gnuwin')
+ GNUWIN_VERSION = '5'
+ GNUWIN_STAMP = os.path.join(gnuwin_dir, 'stamp')
+ if ReadStampFile(GNUWIN_STAMP) == GNUWIN_VERSION:
+ print 'GNU Win tools already up to date.'
+ else:
+ zip_name = 'gnuwin-%s.zip' % GNUWIN_VERSION
+ DownloadAndUnpack(CDS_URL + '/tools/' + zip_name, LLVM_BUILD_TOOLS_DIR)
+ WriteStampFile(GNUWIN_VERSION, GNUWIN_STAMP)
+
+ os.environ['PATH'] = gnuwin_dir + os.pathsep + os.environ.get('PATH', '')
+
+
vs_version = None
def GetVSVersion():
global vs_version
@@ -377,99 +361,152 @@
# or a system-wide installation otherwise.
sys.path.append(os.path.join(CHROMIUM_DIR, 'tools', 'gyp', 'pylib'))
import gyp.MSVSVersion
- vs_version = gyp.MSVSVersion.SelectVisualStudioVersion('2013')
+ vs_version = gyp.MSVSVersion.SelectVisualStudioVersion(
+ vs_toolchain.GetVisualStudioVersion())
return vs_version
+def CopyDiaDllTo(target_dir):
+ # This script always wants to use the 64-bit msdia*.dll.
+ dia_path = os.path.join(GetVSVersion().Path(), 'DIA SDK', 'bin', 'amd64')
+ dia_dll = os.path.join(dia_path, DIA_DLL[GetVSVersion().ShortName()])
+ CopyFile(dia_dll, target_dir)
+
+
+def VeryifyVersionOfBuiltClangMatchesVERSION():
+ """Checks that `clang --version` outputs VERSION. If this fails, VERSION
+ in this file is out-of-date and needs to be updated (possibly in an
+ `if use_head_revision:` block in main() first)."""
+ clang = os.path.join(LLVM_BUILD_DIR, 'bin', 'clang')
+ if sys.platform == 'win32':
+ # TODO: Parse `clang-cl /?` output for built clang's version and check that
+ # to check the binary we're actually shipping? But clang-cl.exe is just
+ # a copy of clang.exe, so this does check the same thing.
+ clang += '.exe'
+ version_out = subprocess.check_output([clang, '--version'])
+ version_out = re.match(r'clang version ([0-9.]+)', version_out).group(1)
+ if version_out != VERSION:
+ print ('unexpected clang version %s (not %s), update VERSION in update.py'
+ % (version_out, VERSION))
+ sys.exit(1)
+
+
def UpdateClang(args):
print 'Updating Clang to %s...' % PACKAGE_VERSION
- if ReadStampFile() == PACKAGE_VERSION:
- print 'Already up to date.'
- return 0
+
+ need_gold_plugin = 'LLVM_DOWNLOAD_GOLD_PLUGIN' in os.environ or (
+ sys.platform.startswith('linux') and
+ 'buildtype=Official' in os.environ.get('GYP_DEFINES', '') and
+ 'branding=Chrome' in os.environ.get('GYP_DEFINES', ''))
+
+ if ReadStampFile() == PACKAGE_VERSION and not args.force_local_build:
+ print 'Clang is already up to date.'
+ if not need_gold_plugin or os.path.exists(
+ os.path.join(LLVM_BUILD_DIR, "lib/LLVMgold.so")):
+ return 0
# Reset the stamp file in case the build is unsuccessful.
WriteStampFile('')
if not args.force_local_build:
cds_file = "clang-%s.tgz" % PACKAGE_VERSION
- cds_full_url = CDS_URL + '/Win/' + cds_file
+ if sys.platform == 'win32' or sys.platform == 'cygwin':
+ cds_full_url = CDS_URL + '/Win/' + cds_file
+ elif sys.platform == 'darwin':
+ cds_full_url = CDS_URL + '/Mac/' + cds_file
+ else:
+ assert sys.platform.startswith('linux')
+ cds_full_url = CDS_URL + '/Linux_x64/' + cds_file
- # Check if there's a prebuilt binary and if so just fetch that. That's
- # faster, and goma relies on having matching binary hashes on client and
- # server too.
- print 'Trying to download prebuilt clang'
+ print 'Downloading prebuilt clang'
+ if os.path.exists(LLVM_BUILD_DIR):
+ RmTree(LLVM_BUILD_DIR)
+ try:
+ DownloadAndUnpack(cds_full_url, LLVM_BUILD_DIR)
+ print 'clang %s unpacked' % PACKAGE_VERSION
+ if sys.platform == 'win32':
+ CopyDiaDllTo(os.path.join(LLVM_BUILD_DIR, 'bin'))
+ # Download the gold plugin if requested to by an environment variable.
+ # This is used by the CFI ClusterFuzz bot, and it's required for official
+ # builds on linux.
+ if need_gold_plugin:
+ RunCommand(['python', CHROMIUM_DIR+'/build/download_gold_plugin.py'])
+ WriteStampFile(PACKAGE_VERSION)
+ return 0
+ except urllib2.URLError:
+ print 'Failed to download prebuilt clang %s' % cds_file
+ print 'Use --force-local-build if you want to build locally.'
+ print 'Exiting.'
+ return 1
- # clang packages are smaller than 50 MB, small enough to keep in memory.
- with contextlib.closing(cStringIO.StringIO()) as f:
- try:
- DownloadUrl(cds_full_url, f)
- f.seek(0)
- tarfile.open(mode='r:gz', fileobj=f).extractall(path=LLVM_BUILD_DIR)
- print 'clang %s unpacked' % PACKAGE_VERSION
- # Download the gold plugin if requested to by an environment variable.
- # This is used by the CFI ClusterFuzz bot.
- if 'LLVM_DOWNLOAD_GOLD_PLUGIN' in os.environ:
- RunCommand(['python', CHROMIUM_DIR+'/build/download_gold_plugin.py'])
- WriteStampFile(PACKAGE_VERSION)
- return 0
- except urllib2.HTTPError:
- print 'Did not find prebuilt clang %s, building locally' % cds_file
+ if args.with_android and not os.path.exists(ANDROID_NDK_DIR):
+ print 'Android NDK not found at ' + ANDROID_NDK_DIR
+ print 'The Android NDK is needed to build a Clang whose -fsanitize=address'
+ print 'works on Android. See '
+ print 'https://www.chromium.org/developers/how-tos/android-build-instructions'
+ print 'for how to install the NDK, or pass --without-android.'
+ return 1
+ DownloadHostGcc(args)
AddCMakeToPath()
+ AddGnuWinToPath()
- RevertPreviouslyPatchedFiles()
DeleteChromeToolsShim()
Checkout('LLVM', LLVM_REPO_URL + '/llvm/trunk', LLVM_DIR)
Checkout('Clang', LLVM_REPO_URL + '/cfe/trunk', CLANG_DIR)
- if sys.platform == 'win32':
+ if sys.platform == 'win32' or use_head_revision:
Checkout('LLD', LLVM_REPO_URL + '/lld/trunk', LLD_DIR)
Checkout('compiler-rt', LLVM_REPO_URL + '/compiler-rt/trunk', COMPILER_RT_DIR)
if sys.platform == 'darwin':
# clang needs a libc++ checkout, else -stdlib=libc++ won't find includes
# (i.e. this is needed for bootstrap builds).
Checkout('libcxx', LLVM_REPO_URL + '/libcxx/trunk', LIBCXX_DIR)
- # While we're bundling our own libc++ on OS X, we need to compile libc++abi
- # into it too (since OS X 10.6 doesn't have libc++abi.dylib either).
- Checkout('libcxxabi', LLVM_REPO_URL + '/libcxxabi/trunk', LIBCXXABI_DIR)
-
- if args.with_patches and sys.platform != 'win32':
- ApplyLocalPatches()
+ # We used to check out libcxxabi on OS X; we no longer need that.
+ if os.path.exists(LIBCXXABI_DIR):
+ RmTree(LIBCXXABI_DIR)
cc, cxx = None, None
- cflags = cxxflags = ldflags = []
+ libstdcpp = None
+ if args.gcc_toolchain: # This option is only used on Linux.
+ # Use the specified gcc installation for building.
+ cc = os.path.join(args.gcc_toolchain, 'bin', 'gcc')
+ cxx = os.path.join(args.gcc_toolchain, 'bin', 'g++')
- # LLVM uses C++11 starting in llvm 3.5. On Linux, this means libstdc++4.7+ is
- # needed, on OS X it requires libc++. clang only automatically links to libc++
- # when targeting OS X 10.9+, so add stdlib=libc++ explicitly so clang can run
- # on OS X versions as old as 10.7.
- # TODO(thakis): Some bots are still on 10.6 (nacl...), so for now bundle
- # libc++.dylib. Remove this once all bots are on 10.7+, then use
- # -DLLVM_ENABLE_LIBCXX=ON and change deployment_target to 10.7.
- deployment_target = ''
+ if not os.access(cc, os.X_OK):
+ print 'Invalid --gcc-toolchain: "%s"' % args.gcc_toolchain
+ print '"%s" does not appear to be valid.' % cc
+ return 1
- if sys.platform == 'darwin':
- # When building on 10.9, /usr/include usually doesn't exist, and while
- # Xcode's clang automatically sets a sysroot, self-built clangs don't.
- cflags = ['-isysroot', subprocess.check_output(
- ['xcrun', '--show-sdk-path']).rstrip()]
- cxxflags = ['-stdlib=libc++', '-nostdinc++',
- '-I' + os.path.join(LIBCXX_DIR, 'include')] + cflags
- if args.bootstrap:
- deployment_target = '10.6'
+ # Set LD_LIBRARY_PATH to make auxiliary targets (tablegen, bootstrap
+ # compiler, etc.) find the .so.
+ libstdcpp = subprocess.check_output(
+ [cxx, '-print-file-name=libstdc++.so.6']).rstrip()
+ os.environ['LD_LIBRARY_PATH'] = os.path.dirname(libstdcpp)
+
+ cflags = []
+ cxxflags = []
+ ldflags = []
base_cmake_args = ['-GNinja',
'-DCMAKE_BUILD_TYPE=Release',
'-DLLVM_ENABLE_ASSERTIONS=ON',
'-DLLVM_ENABLE_THREADS=OFF',
+ '-DLLVM_ENABLE_TIMESTAMPS=OFF',
+ # Statically link MSVCRT to avoid DLL dependencies.
+ '-DLLVM_USE_CRT_RELEASE=MT',
]
+ binutils_incdir = ''
+ if sys.platform.startswith('linux'):
+ binutils_incdir = os.path.join(BINUTILS_DIR, 'Linux_x64/Release/include')
+
if args.bootstrap:
print 'Building bootstrap compiler'
- if not os.path.exists(LLVM_BOOTSTRAP_DIR):
- os.makedirs(LLVM_BOOTSTRAP_DIR)
+ EnsureDirExists(LLVM_BOOTSTRAP_DIR)
os.chdir(LLVM_BOOTSTRAP_DIR)
bootstrap_args = base_cmake_args + [
+ '-DLLVM_BINUTILS_INCDIR=' + binutils_incdir,
'-DLLVM_TARGETS_TO_BUILD=host',
'-DCMAKE_INSTALL_PREFIX=' + LLVM_BOOTSTRAP_INSTALL_DIR,
'-DCMAKE_C_FLAGS=' + ' '.join(cflags),
@@ -477,11 +514,18 @@
]
if cc is not None: bootstrap_args.append('-DCMAKE_C_COMPILER=' + cc)
if cxx is not None: bootstrap_args.append('-DCMAKE_CXX_COMPILER=' + cxx)
+ RmCmakeCache('.')
RunCommand(['cmake'] + bootstrap_args + [LLVM_DIR], msvc_arch='x64')
RunCommand(['ninja'], msvc_arch='x64')
if args.run_tests:
+ if sys.platform == 'win32':
+ CopyDiaDllTo(os.path.join(LLVM_BOOTSTRAP_DIR, 'bin'))
RunCommand(['ninja', 'check-all'], msvc_arch='x64')
RunCommand(['ninja', 'install'], msvc_arch='x64')
+ if args.gcc_toolchain:
+ # Copy that gcc's stdlibc++.so.6 to the build dir, so the bootstrap
+ # compiler can start.
+ CopyFile(libstdcpp, os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'lib'))
if sys.platform == 'win32':
cc = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'clang-cl.exe')
@@ -493,61 +537,78 @@
else:
cc = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'clang')
cxx = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'clang++')
+
+ if args.gcc_toolchain:
+ # Tell the bootstrap compiler to use a specific gcc prefix to search
+ # for standard library headers and shared object files.
+ cflags = ['--gcc-toolchain=' + args.gcc_toolchain]
+ cxxflags = ['--gcc-toolchain=' + args.gcc_toolchain]
print 'Building final compiler'
- if sys.platform == 'darwin':
- # Build libc++.dylib while some bots are still on OS X 10.6.
- libcxxbuild = os.path.join(LLVM_BUILD_DIR, 'libcxxbuild')
- if os.path.isdir(libcxxbuild):
- RmTree(libcxxbuild)
- libcxxflags = ['-O3', '-std=c++11', '-fstrict-aliasing']
+ # Build LLVM gold plugin with LTO. That speeds up the linker by ~10%.
+ # We only use LTO for Linux now.
+ if args.bootstrap and args.lto_gold_plugin:
+ print 'Building LTO LLVM Gold plugin'
+ if os.path.exists(LLVM_LTO_GOLD_PLUGIN_DIR):
+ RmTree(LLVM_LTO_GOLD_PLUGIN_DIR)
+ EnsureDirExists(LLVM_LTO_GOLD_PLUGIN_DIR)
+ os.chdir(LLVM_LTO_GOLD_PLUGIN_DIR)
- # libcxx and libcxxabi both have a file stdexcept.cpp, so put their .o files
- # into different subdirectories.
- os.makedirs(os.path.join(libcxxbuild, 'libcxx'))
- os.chdir(os.path.join(libcxxbuild, 'libcxx'))
- RunCommand(['c++', '-c'] + cxxflags + libcxxflags +
- glob.glob(os.path.join(LIBCXX_DIR, 'src', '*.cpp')))
+ # Create a symlink to LLVMgold.so build in the previous step so that ar
+ # and ranlib could find it while linking LLVMgold.so with LTO.
+ EnsureDirExists(BFD_PLUGINS_DIR)
+ RunCommand(['ln', '-sf',
+ os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'lib', 'LLVMgold.so'),
+ os.path.join(BFD_PLUGINS_DIR, 'LLVMgold.so')])
- os.makedirs(os.path.join(libcxxbuild, 'libcxxabi'))
- os.chdir(os.path.join(libcxxbuild, 'libcxxabi'))
- RunCommand(['c++', '-c'] + cxxflags + libcxxflags +
- glob.glob(os.path.join(LIBCXXABI_DIR, 'src', '*.cpp')) +
- ['-I' + os.path.join(LIBCXXABI_DIR, 'include')])
+ lto_cflags = ['-flto']
+ lto_ldflags = ['-fuse-ld=gold']
+ if args.gcc_toolchain:
+ # Tell the bootstrap compiler to use a specific gcc prefix to search
+ # for standard library headers and shared object files.
+ lto_cflags += ['--gcc-toolchain=' + args.gcc_toolchain]
+ lto_cmake_args = base_cmake_args + [
+ '-DLLVM_BINUTILS_INCDIR=' + binutils_incdir,
+ '-DCMAKE_C_COMPILER=' + cc,
+ '-DCMAKE_CXX_COMPILER=' + cxx,
+ '-DCMAKE_C_FLAGS=' + ' '.join(lto_cflags),
+ '-DCMAKE_CXX_FLAGS=' + ' '.join(lto_cflags),
+ '-DCMAKE_EXE_LINKER_FLAGS=' + ' '.join(lto_ldflags),
+ '-DCMAKE_SHARED_LINKER_FLAGS=' + ' '.join(lto_ldflags),
+ '-DCMAKE_MODULE_LINKER_FLAGS=' + ' '.join(lto_ldflags)]
- os.chdir(libcxxbuild)
- libdir = os.path.join(LIBCXX_DIR, 'lib')
- RunCommand(['cc'] + glob.glob('libcxx/*.o') + glob.glob('libcxxabi/*.o') +
- ['-o', 'libc++.1.dylib', '-dynamiclib', '-nodefaultlibs',
- '-current_version', '1', '-compatibility_version', '1', '-lSystem',
- '-install_name', '@executable_path/libc++.dylib',
- '-Wl,-unexported_symbols_list,' + libdir + '/libc++unexp.exp',
- '-Wl,-force_symbols_not_weak_list,' + libdir + '/notweak.exp',
- '-Wl,-force_symbols_weak_list,' + libdir + '/weak.exp'])
- if os.path.exists('libc++.dylib'):
- os.remove('libc++.dylib')
- os.symlink('libc++.1.dylib', 'libc++.dylib')
- ldflags += ['-stdlib=libc++', '-L' + libcxxbuild]
+ # We need to use the proper binutils which support LLVM Gold plugin.
+ lto_env = os.environ.copy()
+ lto_env['PATH'] = BINUTILS_BIN_DIR + os.pathsep + lto_env.get('PATH', '')
- if args.bootstrap:
- # Now that the libc++ headers have been installed and libc++.dylib is
- # built, delete the libc++ checkout again so that it's not part of the
- # main build below -- the libc++(abi) tests don't pass on OS X in
- # bootstrap builds (http://llvm.org/PR24068)
- RmTree(LIBCXX_DIR)
- RmTree(LIBCXXABI_DIR)
- cxxflags = ['-stdlib=libc++', '-nostdinc++',
- '-I' + os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR,
- 'include/c++/v1')
- ] + cflags
+ RmCmakeCache('.')
+ RunCommand(['cmake'] + lto_cmake_args + [LLVM_DIR], env=lto_env)
+ RunCommand(['ninja', 'LLVMgold'], env=lto_env)
+
+
+ # LLVM uses C++11 starting in llvm 3.5. On Linux, this means libstdc++4.7+ is
+ # needed, on OS X it requires libc++. clang only automatically links to libc++
+ # when targeting OS X 10.9+, so add stdlib=libc++ explicitly so clang can run
+ # on OS X versions as old as 10.7.
+ deployment_target = ''
+
+ if sys.platform == 'darwin' and args.bootstrap:
+ # When building on 10.9, /usr/include usually doesn't exist, and while
+ # Xcode's clang automatically sets a sysroot, self-built clangs don't.
+ cflags = ['-isysroot', subprocess.check_output(
+ ['xcrun', '--show-sdk-path']).rstrip()]
+ cxxflags = ['-stdlib=libc++'] + cflags
+ ldflags += ['-stdlib=libc++']
+ deployment_target = '10.7'
+ # Running libc++ tests takes a long time. Since it was only needed for
+ # the install step above, don't build it as part of the main build.
+ # This makes running package.py over 10% faster (30 min instead of 34 min)
+ RmTree(LIBCXX_DIR)
# Build clang.
- binutils_incdir = ''
- if sys.platform.startswith('linux'):
- binutils_incdir = os.path.join(BINUTILS_DIR, 'Linux_x64/Release/include')
# If building at head, define a macro that plugins can use for #ifdefing
- # out code that builds at head, but not at LLVM_WIN_REVISION or vice versa.
+ # out code that builds at head, but not at CLANG_REVISION or vice versa.
if use_head_revision:
cflags += ['-DLLVM_FORCE_HEAD_REVISION']
cxxflags += ['-DLLVM_FORCE_HEAD_REVISION']
@@ -559,7 +620,13 @@
deployment_env = os.environ.copy()
deployment_env['MACOSX_DEPLOYMENT_TARGET'] = deployment_target
- cmake_args = base_cmake_args + [
+ cmake_args = []
+ # TODO(thakis): Unconditionally append this to base_cmake_args instead once
+ # compiler-rt can build with clang-cl on Windows (http://llvm.org/PR23698)
+ cc_args = base_cmake_args if sys.platform != 'win32' else cmake_args
+ if cc is not None: cc_args.append('-DCMAKE_C_COMPILER=' + cc)
+ if cxx is not None: cc_args.append('-DCMAKE_CXX_COMPILER=' + cxx)
+ cmake_args += base_cmake_args + [
'-DLLVM_BINUTILS_INCDIR=' + binutils_incdir,
'-DCMAKE_C_FLAGS=' + ' '.join(cflags),
'-DCMAKE_CXX_FLAGS=' + ' '.join(cxxflags),
@@ -567,19 +634,26 @@
'-DCMAKE_SHARED_LINKER_FLAGS=' + ' '.join(ldflags),
'-DCMAKE_MODULE_LINKER_FLAGS=' + ' '.join(ldflags),
'-DCMAKE_INSTALL_PREFIX=' + LLVM_BUILD_DIR,
+ # TODO(thakis): Remove this once official builds pass -Wl,--build-id
+ # explicitly, https://crbug.com/622775
+ '-DENABLE_LINKER_BUILD_ID=ON',
'-DCHROMIUM_TOOLS_SRC=%s' % os.path.join(CHROMIUM_DIR, 'tools', 'clang'),
'-DCHROMIUM_TOOLS=%s' % ';'.join(args.tools)]
- # TODO(thakis): Unconditionally append this to base_cmake_args instead once
- # compiler-rt can build with clang-cl on Windows (http://llvm.org/PR23698)
- cc_args = base_cmake_args if sys.platform != 'win32' else cmake_args
- if cc is not None: cc_args.append('-DCMAKE_C_COMPILER=' + cc)
- if cxx is not None: cc_args.append('-DCMAKE_CXX_COMPILER=' + cxx)
- if not os.path.exists(LLVM_BUILD_DIR):
- os.makedirs(LLVM_BUILD_DIR)
+ EnsureDirExists(LLVM_BUILD_DIR)
os.chdir(LLVM_BUILD_DIR)
+ RmCmakeCache('.')
RunCommand(['cmake'] + cmake_args + [LLVM_DIR],
msvc_arch='x64', env=deployment_env)
+
+ if args.gcc_toolchain:
+ # Copy in the right stdlibc++.so.6 so clang can start.
+ if not os.path.exists(os.path.join(LLVM_BUILD_DIR, 'lib')):
+ os.mkdir(os.path.join(LLVM_BUILD_DIR, 'lib'))
+ libstdcpp = subprocess.check_output(
+ [cxx] + cxxflags + ['-print-file-name=libstdc++.so.6']).rstrip()
+ CopyFile(libstdcpp, os.path.join(LLVM_BUILD_DIR, 'lib'))
+
RunCommand(['ninja'], msvc_arch='x64')
if args.tools:
@@ -587,17 +661,21 @@
RunCommand(['ninja', 'cr-install'], msvc_arch='x64')
if sys.platform == 'darwin':
- CopyFile(os.path.join(LLVM_BUILD_DIR, 'libc++.1.dylib'),
- os.path.join(LLVM_BUILD_DIR, 'bin'))
# See http://crbug.com/256342
RunCommand(['strip', '-x', os.path.join(LLVM_BUILD_DIR, 'bin', 'clang')])
elif sys.platform.startswith('linux'):
RunCommand(['strip', os.path.join(LLVM_BUILD_DIR, 'bin', 'clang')])
- # Do an x86 build of compiler-rt to get the 32-bit ASan run-time.
+ VeryifyVersionOfBuiltClangMatchesVERSION()
+
+ # Do an out-of-tree build of compiler-rt.
+ # On Windows, this is used to get the 32-bit ASan run-time.
# TODO(hans): Remove once the regular build above produces this.
- if not os.path.exists(COMPILER_RT_BUILD_DIR):
- os.makedirs(COMPILER_RT_BUILD_DIR)
+ # On Mac and Linux, this is used to get the regular 64-bit run-time.
+ # Do a clobbered build due to cmake changes.
+ if os.path.isdir(COMPILER_RT_BUILD_DIR):
+ RmTree(COMPILER_RT_BUILD_DIR)
+ os.makedirs(COMPILER_RT_BUILD_DIR)
os.chdir(COMPILER_RT_BUILD_DIR)
# TODO(thakis): Add this once compiler-rt can build with clang-cl (see
# above).
@@ -608,13 +686,21 @@
compiler_rt_args = base_cmake_args + [
'-DCMAKE_C_FLAGS=' + ' '.join(cflags),
'-DCMAKE_CXX_FLAGS=' + ' '.join(cxxflags)]
+ if sys.platform == 'darwin':
+ compiler_rt_args += ['-DCOMPILER_RT_ENABLE_IOS=ON']
if sys.platform != 'win32':
compiler_rt_args += ['-DLLVM_CONFIG_PATH=' +
- os.path.join(LLVM_BUILD_DIR, 'bin', 'llvm-config')]
- RunCommand(['cmake'] + compiler_rt_args + [LLVM_DIR],
- msvc_arch='x86', env=deployment_env)
+ os.path.join(LLVM_BUILD_DIR, 'bin', 'llvm-config'),
+ '-DSANITIZER_MIN_OSX_VERSION="10.7"']
+ # compiler-rt is part of the llvm checkout on Windows but a stand-alone
+ # directory elsewhere, see the TODO above COMPILER_RT_DIR.
+ RmCmakeCache('.')
+ RunCommand(['cmake'] + compiler_rt_args +
+ [LLVM_DIR if sys.platform == 'win32' else COMPILER_RT_DIR],
+ msvc_arch='x86', env=deployment_env)
RunCommand(['ninja', 'compiler-rt'], msvc_arch='x86')
+ # Copy select output to the main tree.
# TODO(hans): Make this (and the .gypi and .isolate files) version number
# independent.
if sys.platform == 'win32':
@@ -624,17 +710,35 @@
else:
assert sys.platform.startswith('linux')
platform = 'linux'
- asan_rt_lib_src_dir = os.path.join(COMPILER_RT_BUILD_DIR, 'lib', 'clang',
- VERSION, 'lib', platform)
+ asan_rt_lib_src_dir = os.path.join(COMPILER_RT_BUILD_DIR, 'lib', platform)
+ if sys.platform == 'win32':
+ # TODO(thakis): This too is due to compiler-rt being part of the checkout
+ # on Windows, see TODO above COMPILER_RT_DIR.
+ asan_rt_lib_src_dir = os.path.join(COMPILER_RT_BUILD_DIR, 'lib', 'clang',
+ VERSION, 'lib', platform)
asan_rt_lib_dst_dir = os.path.join(LLVM_BUILD_DIR, 'lib', 'clang',
VERSION, 'lib', platform)
- CopyDirectoryContents(asan_rt_lib_src_dir, asan_rt_lib_dst_dir,
- r'^.*-i386\.lib$')
- CopyDirectoryContents(asan_rt_lib_src_dir, asan_rt_lib_dst_dir,
- r'^.*-i386\.dll$')
+ # Blacklists:
+ CopyDirectoryContents(os.path.join(asan_rt_lib_src_dir, '..', '..'),
+ os.path.join(asan_rt_lib_dst_dir, '..', '..'),
+ r'^.*blacklist\.txt$')
+ # Headers:
+ if sys.platform != 'win32':
+ CopyDirectoryContents(
+ os.path.join(COMPILER_RT_BUILD_DIR, 'include/sanitizer'),
+ os.path.join(LLVM_BUILD_DIR, 'lib/clang', VERSION, 'include/sanitizer'))
+ # Static and dynamic libraries:
+ CopyDirectoryContents(asan_rt_lib_src_dir, asan_rt_lib_dst_dir)
+ if sys.platform == 'darwin':
+ for dylib in glob.glob(os.path.join(asan_rt_lib_dst_dir, '*.dylib')):
+ # Fix LC_ID_DYLIB for the ASan dynamic libraries to be relative to
+ # @executable_path.
+ # TODO(glider): this is transitional. We'll need to fix the dylib
+ # name either in our build system, or in Clang. See also
+ # http://crbug.com/344836.
+ subprocess.call(['install_name_tool', '-id',
+ '@executable_path/' + os.path.basename(dylib), dylib])
- CopyFile(os.path.join(asan_rt_lib_src_dir, '..', '..', 'asan_blacklist.txt'),
- os.path.join(asan_rt_lib_dst_dir, '..', '..'))
if sys.platform == 'win32':
# Make an extra copy of the sanitizer headers, to be put on the include path
@@ -644,22 +748,69 @@
aux_sanitizer_include_dir = os.path.join(LLVM_BUILD_DIR, 'lib', 'clang',
VERSION, 'include_sanitizer',
'sanitizer')
- if not os.path.exists(aux_sanitizer_include_dir):
- os.makedirs(aux_sanitizer_include_dir)
+ EnsureDirExists(aux_sanitizer_include_dir)
for _, _, files in os.walk(sanitizer_include_dir):
for f in files:
CopyFile(os.path.join(sanitizer_include_dir, f),
aux_sanitizer_include_dir)
+ if args.with_android:
+ make_toolchain = os.path.join(
+ ANDROID_NDK_DIR, 'build', 'tools', 'make_standalone_toolchain.py')
+ for target_arch in ['aarch64', 'arm', 'i686']:
+ # Make standalone Android toolchain for target_arch.
+ toolchain_dir = os.path.join(
+ LLVM_BUILD_DIR, 'android-toolchain-' + target_arch)
+ RunCommand([
+ make_toolchain,
+ '--api=' + ('21' if target_arch == 'aarch64' else '19'),
+ '--force',
+ '--install-dir=%s' % toolchain_dir,
+ '--stl=stlport',
+ '--arch=' + {
+ 'aarch64': 'arm64',
+ 'arm': 'arm',
+ 'i686': 'x86',
+ }[target_arch]])
+ # Android NDK r9d copies a broken unwind.h into the toolchain, see
+ # http://crbug.com/357890
+ for f in glob.glob(os.path.join(toolchain_dir, 'include/c++/*/unwind.h')):
+ os.remove(f)
+
+ # Build ASan runtime for Android in a separate build tree.
+ build_dir = os.path.join(LLVM_BUILD_DIR, 'android-' + target_arch)
+ if not os.path.exists(build_dir):
+ os.mkdir(os.path.join(build_dir))
+ os.chdir(build_dir)
+ cflags = ['--target=%s-linux-androideabi' % target_arch,
+ '--sysroot=%s/sysroot' % toolchain_dir,
+ '-B%s' % toolchain_dir]
+ android_args = base_cmake_args + [
+ '-DCMAKE_C_COMPILER=' + os.path.join(LLVM_BUILD_DIR, 'bin/clang'),
+ '-DCMAKE_CXX_COMPILER=' + os.path.join(LLVM_BUILD_DIR, 'bin/clang++'),
+ '-DLLVM_CONFIG_PATH=' + os.path.join(LLVM_BUILD_DIR, 'bin/llvm-config'),
+ '-DCMAKE_C_FLAGS=' + ' '.join(cflags),
+ '-DCMAKE_CXX_FLAGS=' + ' '.join(cflags),
+ '-DANDROID=1']
+ RmCmakeCache('.')
+ RunCommand(['cmake'] + android_args + [COMPILER_RT_DIR])
+ RunCommand(['ninja', 'libclang_rt.asan-%s-android.so' % target_arch])
+
+ # And copy it into the main build tree.
+ runtime = 'libclang_rt.asan-%s-android.so' % target_arch
+ for root, _, files in os.walk(build_dir):
+ if runtime in files:
+ shutil.copy(os.path.join(root, runtime), asan_rt_lib_dst_dir)
+
# Run tests.
if args.run_tests or use_head_revision:
os.chdir(LLVM_BUILD_DIR)
- RunCommand(GetVSVersion().SetupScript('x64') +
- ['&&', 'ninja', 'cr-check-all'])
+ RunCommand(['ninja', 'cr-check-all'], msvc_arch='x64')
if args.run_tests:
+ if sys.platform == 'win32':
+ CopyDiaDllTo(os.path.join(LLVM_BUILD_DIR, 'bin'))
os.chdir(LLVM_BUILD_DIR)
- RunCommand(GetVSVersion().SetupScript('x64') +
- ['&&', 'ninja', 'check-all'])
+ RunCommand(['ninja', 'check-all'], msvc_arch='x64')
WriteStampFile(PACKAGE_VERSION)
print 'Clang update was successful.'
@@ -667,31 +818,6 @@
def main():
- if not sys.platform in ['win32', 'cygwin']:
- # For non-Windows, fall back to update.sh.
- # TODO(hans): Make update.py replace update.sh completely.
-
- # This script is called by gclient. gclient opens its hooks subprocesses
- # with (stdout=subprocess.PIPE, stderr=subprocess.STDOUT) and then does
- # custom output processing that breaks printing '\r' characters for
- # single-line updating status messages as printed by curl and wget.
- # Work around this by setting stderr of the update.sh process to stdin (!):
- # gclient doesn't redirect stdin, and while stdin itself is read-only, a
- # dup()ed sys.stdin is writable, try
- # fd2 = os.dup(sys.stdin.fileno()); os.write(fd2, 'hi')
- # TODO: Fix gclient instead, http://crbug.com/95350
- if '--no-stdin-hack' in sys.argv:
- sys.argv.remove('--no-stdin-hack')
- stderr = None
- else:
- try:
- stderr = os.fdopen(os.dup(sys.stdin.fileno()))
- except:
- stderr = sys.stderr
- return subprocess.call(
- [os.path.join(os.path.dirname(__file__), 'update.sh')] + sys.argv[1:],
- stderr=stderr)
-
parser = argparse.ArgumentParser(description='Build Clang.')
parser.add_argument('--bootstrap', action='store_true',
help='first build clang with CC, then with itself.')
@@ -699,6 +825,14 @@
help="run only if the script thinks clang is needed")
parser.add_argument('--force-local-build', action='store_true',
help="don't try to download prebuild binaries")
+ parser.add_argument('--gcc-toolchain', help='set the version for which gcc '
+ 'version be used for building; --gcc-toolchain=/opt/foo '
+ 'picks /opt/foo/bin/gcc')
+ parser.add_argument('--lto-gold-plugin', action='store_true',
+ help='build LLVM Gold plugin with LTO')
+ parser.add_argument('--llvm-force-head-revision', action='store_true',
+ help=('use the revision in the repo when printing '
+ 'the revision'))
parser.add_argument('--print-revision', action='store_true',
help='print current clang revision and exit.')
parser.add_argument('--print-clang-version', action='store_true',
@@ -708,16 +842,19 @@
parser.add_argument('--tools', nargs='*',
help='select which chrome tools to build',
default=['plugins', 'blink_gc_plugin'])
- parser.add_argument('--without-patches', action='store_false',
- help="don't apply patches (default)", dest='with_patches',
- default=True)
-
- # For now, these flags are only used for the non-Windows flow, but argparser
- # gets mad if it sees a flag it doesn't recognize.
- parser.add_argument('--no-stdin-hack', action='store_true')
-
+ parser.add_argument('--without-android', action='store_false',
+ help='don\'t build Android ASan runtime (linux only)',
+ dest='with_android',
+ default=sys.platform.startswith('linux'))
args = parser.parse_args()
+ if args.lto_gold_plugin and not args.bootstrap:
+ print '--lto-gold-plugin requires --bootstrap'
+ return 1
+ if args.lto_gold_plugin and not sys.platform.startswith('linux'):
+ print '--lto-gold-plugin is only effective on Linux. Ignoring the option.'
+ args.lto_gold_plugin = False
+
if args.if_needed:
is_clang_required = False
# clang is always used on Mac and Linux.
@@ -727,7 +864,7 @@
if re.search(r'\b(clang|asan|lsan|msan|tsan)=1',
os.environ.get('GYP_DEFINES', '')):
is_clang_required = True
- # clang previously downloaded, keep it up-to-date.
+ # clang previously downloaded, keep it up to date.
# If you don't want this, delete third_party/llvm-build on your machine.
if os.path.isdir(LLVM_BUILD_DIR):
is_clang_required = True
@@ -737,9 +874,9 @@
print 'Skipping Clang update (make_clang_dir= was set in GYP_DEFINES).'
return 0
- global LLVM_WIN_REVISION, PACKAGE_VERSION
+ global CLANG_REVISION, PACKAGE_VERSION
if args.print_revision:
- if use_head_revision:
+ if use_head_revision or args.llvm_force_head_revision:
print GetSvnRevision(LLVM_DIR)
else:
print PACKAGE_VERSION
@@ -757,12 +894,13 @@
if use_head_revision:
# Use a real revision number rather than HEAD to make sure that the stamp
# file logic works.
- LLVM_WIN_REVISION = GetSvnRevision(LLVM_REPO_URL)
- PACKAGE_VERSION = LLVM_WIN_REVISION + '-0'
+ CLANG_REVISION = GetSvnRevision(LLVM_REPO_URL)
+ PACKAGE_VERSION = CLANG_REVISION + '-0'
args.force_local_build = True
- # Skip local patches when using HEAD: they probably don't apply anymore.
- args.with_patches = False
+ if 'OS=android' not in os.environ.get('GYP_DEFINES', ''):
+ # Only build the Android ASan rt on ToT bots when targetting Android.
+ args.with_android = False
return UpdateClang(args)
diff --git a/tools/create_sdk.py b/tools/create_sdk.py
index 85ba811..54cb4dd 100755
--- a/tools/create_sdk.py
+++ b/tools/create_sdk.py
@@ -47,6 +47,7 @@
# ......_internal/
#.........spec.sum
#.........strong.sum
+#.........dev_compiler/
# ......analysis_server/
# ......analyzer/
# ......async/
@@ -169,6 +170,9 @@
copyfile(join(snapshots, 'strong.sum'),
join(lib, '_internal', 'strong.sum'))
+def CopyDevCompilerSdk(home, lib):
+ copytree(join(home, 'pkg', 'dev_compiler', 'lib', 'js'),
+ join(lib, '_internal', 'dev_compiler'))
def Main():
# Pull in all of the gypi files which will be munged into the sdk.
@@ -304,6 +308,7 @@
CopyDartdocResources(HOME, SDK_tmp)
CopyAnalyzerSources(HOME, LIB)
CopyAnalysisSummaries(SNAPSHOT, LIB)
+ CopyDevCompilerSdk(HOME, LIB)
# Write the 'version' file
version = utils.GetVersion()
diff --git a/tools/dart_for_gn.py b/tools/dart_for_gn.py
new file mode 100755
index 0000000..835bbaa
--- /dev/null
+++ b/tools/dart_for_gn.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python
+# Copyright 2016 The Dart project authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+# Usage: dart_for_gn.py path_to_dart_binary [arguments]
+#
+# We have gn set up so that actions can only run python scripts.
+# We use this wrapper script when we need an action to run the Dart VM
+# The first command line argument is mandatory and should be the absolute path
+# to the Dart VM binary.
+
+import subprocess
+import sys
+
+def main(argv):
+ if len(argv) < 2:
+ print "Requires path to Dart VM binary as first argument"
+ return -1
+ command = argv[1:]
+ return subprocess.call(command)
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv))
diff --git a/tools/dartium/test.py b/tools/dartium/test.py
index ca48152..5df8c3c 100755
--- a/tools/dartium/test.py
+++ b/tools/dartium/test.py
@@ -194,7 +194,6 @@
test = os.path.join(DART_TEST_DIR, options.layout_test)
else:
test = DART_TEST_DIR
- package_root = os.path.join(build_dir, 'packages')
utils.runCommand(['python',
test_script,
test_mode,
@@ -204,8 +203,6 @@
'--builder-name', 'BuildBot',
'--additional-env-var',
'DART_FLAGS=%s' % dart_flags,
- '--additional-env-var',
- 'DART_PACKAGE_ROOT=file://%s' % package_root,
test])
# Run core dart tests
diff --git a/tools/deps/dartium.deps/DEPS b/tools/deps/dartium.deps/DEPS
index 6cee812..60e81ca 100644
--- a/tools/deps/dartium.deps/DEPS
+++ b/tools/deps/dartium.deps/DEPS
@@ -9,7 +9,7 @@
vars.update({
"dartium_chromium_commit": "7558afb6379171d7f96b2db68ae9d2b64b2c5544",
- "dartium_webkit_commit": "8c0535e2ee1f49410cb978bd7c18d4582a5fd886",
+ "dartium_webkit_commit": "4cc16a03bf8c40ec67bff039b7fc80ed608d7604",
"chromium_base_revision": "338390",
# We use mirrors of all github repos to guarantee reproducibility and
@@ -32,7 +32,7 @@
"collection_tag": "@1.9.1",
"crypto_rev" : "@2df57a1e26dd88e8d0614207d4b062c73209917d",
"csslib_tag" : "@0.12.0",
- "dart2js_info_rev" : "@0a221eaf16aec3879c45719de656680ccb80d8a1",
+ "dart2js_info_tag" : "@0.5.0",
"glob_rev": "@704cf75e4f26b417505c5c611bdaacd8808467dd",
"html_tag" : "@0.12.1+1",
"http_rev" : "@9b93e1542c753090c50b46ef1592d44bc858bfe7",
@@ -40,7 +40,7 @@
"http_parser_rev" : "@8b179e36aba985208e4c5fb15cfddd386b6370a4",
"http_throttle_rev" : "@a81f08be942cdd608883c7b67795c12226abc235",
"json_rpc_2_rev": "@a38eefd116d910199de205f962af92fed87c164c",
- "kernel_rev": "@449803b82e850a41148e636db1a6e4a848284aed",
+ "kernel_rev": "@1906e420431656d351a9f4ee9a36b8ca9a4da1db",
"logging_rev": "@85d83e002670545e9039ad3985f0018ab640e597",
"matcher_tag": "@0.12.0",
"mime_rev": "@75890811d4af5af080351ba8a2853ad4c8df98dd",
@@ -93,7 +93,7 @@
"src/dart/third_party/pkg/csslib":
(Var("github_mirror") % "csslib") + Var("csslib_tag"),
"src/dart/third_party/pkg/dart2js_info":
- (Var("github_mirror") % "dart2js_info") + Var("dart2js_info_rev"),
+ (Var("github_mirror") % "dart2js_info") + Var("dart2js_info_tag"),
"src/dart/third_party/pkg/collection":
(Var("github_mirror") % "collection") + Var("collection_tag"),
"src/dart/third_party/pkg/glob":
diff --git a/tools/find_depot_tools.py b/tools/find_depot_tools.py
new file mode 100644
index 0000000..286349b
--- /dev/null
+++ b/tools/find_depot_tools.py
@@ -0,0 +1,44 @@
+# Copyright (c) 2011 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+"""Small utility function to find depot_tools and add it to the python path.
+Will throw an ImportError exception if depot_tools can't be found since it
+imports breakpad.
+"""
+
+import os
+import sys
+
+
+def IsRealDepotTools(path):
+ return os.path.isfile(os.path.join(path, 'gclient.py'))
+
+
+def add_depot_tools_to_path():
+ """Search for depot_tools and add it to sys.path."""
+ # First look if depot_tools is already in PYTHONPATH.
+ for i in sys.path:
+ if i.rstrip(os.sep).endswith('depot_tools') and IsRealDepotTools(i):
+ return i
+ # Then look if depot_tools is in PATH, common case.
+ for i in os.environ['PATH'].split(os.pathsep):
+ if IsRealDepotTools(i):
+ sys.path.append(i.rstrip(os.sep))
+ return i
+ # Rare case, it's not even in PATH, look upward up to root.
+ root_dir = os.path.dirname(os.path.abspath(__file__))
+ previous_dir = os.path.abspath(__file__)
+ while root_dir and root_dir != previous_dir:
+ i = os.path.join(root_dir, 'depot_tools')
+ if IsRealDepotTools(i):
+ sys.path.append(i)
+ return i
+ previous_dir = root_dir
+ root_dir = os.path.dirname(root_dir)
+ print >> sys.stderr, 'Failed to find depot_tools'
+ return None
+
+add_depot_tools_to_path()
+
+# pylint: disable=W0611
+import breakpad
diff --git a/tools/generate_buildfiles.py b/tools/generate_buildfiles.py
new file mode 100644
index 0000000..391a15a
--- /dev/null
+++ b/tools/generate_buildfiles.py
@@ -0,0 +1,79 @@
+#!/usr/bin/env python
+# Copyright 2016 The Dart project authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import argparse
+import os
+import subprocess
+import sys
+import utils
+
+SCRIPT_DIR = os.path.dirname(sys.argv[0])
+DART_ROOT = os.path.realpath(os.path.join(SCRIPT_DIR, '..'))
+DART_USE_GN = "DART_USE_GN"
+
+
+def use_gn():
+ return DART_USE_GN in os.environ
+
+
+def execute(args):
+ process = subprocess.Popen(args, cwd=DART_ROOT)
+ process.wait()
+ return process.returncode
+
+
+def run_gn():
+ gn_command = [
+ 'python',
+ os.path.join(DART_ROOT, 'tools', 'gn.py'),
+ '-m', 'all',
+ '-a', 'all',
+ ]
+ return execute(gn_command)
+
+
+def run_gyp():
+ gyp_command = [
+ 'python',
+ os.path.join(DART_ROOT, 'tools', 'gyp_dart.py'),
+ ]
+ return execute(gyp_command)
+
+
+def parse_args(args):
+ args = args[1:]
+ parser = argparse.ArgumentParser(
+ description="A script to generate Dart's build files.")
+
+ parser.add_argument("-v", "--verbose",
+ help='Verbose output.',
+ default=False,
+ action="store_true")
+ parser.add_argument("--gn",
+ help='Use GN',
+ default=use_gn(),
+ action='store_true')
+ parser.add_argument("--gyp",
+ help='Use gyp',
+ default=not use_gn(),
+ action='store_true')
+
+ options = parser.parse_args(args)
+ # If gn is enabled one way or another, then disable gyp
+ if options.gn:
+ options.gyp = False
+ return options
+
+
+def main(argv):
+ options = parse_args(argv)
+ if options.gn:
+ return run_gn()
+ else:
+ return run_gyp()
+
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv))
diff --git a/tools/gn.py b/tools/gn.py
index 22f3530..2f8d664 100755
--- a/tools/gn.py
+++ b/tools/gn.py
@@ -4,19 +4,22 @@
# found in the LICENSE file.
import argparse
+import multiprocessing
+import os
import subprocess
import sys
-import os
+import time
import utils
HOST_OS = utils.GuessOS()
HOST_ARCH = utils.GuessArchitecture()
-HOST_CPUS = utils.GuessCpus()
SCRIPT_DIR = os.path.dirname(sys.argv[0])
DART_ROOT = os.path.realpath(os.path.join(SCRIPT_DIR, '..'))
-def get_out_dir(args):
- return utils.GetBuildRoot(HOST_OS, args.mode, args.arch, args.os)
+
+def get_out_dir(mode, arch, target_os):
+ return utils.GetBuildRoot(HOST_OS, mode, arch, target_os)
+
def to_command_line(gn_args):
def merge(key, value):
@@ -25,6 +28,7 @@
return '%s="%s"' % (key, value)
return [merge(x, y) for x, y in gn_args.iteritems()]
+
def host_cpu_for_arch(arch):
if arch in ['ia32', 'arm', 'armv6', 'armv5te', 'mips',
'simarm', 'simarmv6', 'simarmv5te', 'simmips', 'simdbc']:
@@ -32,7 +36,8 @@
if arch in ['x64', 'arm64', 'simarm64', 'simdbc64']:
return 'x64'
-def target_cpu_for_arch(arch, os):
+
+def target_cpu_for_arch(arch, target_os):
if arch in ['ia32', 'simarm', 'simarmv6', 'simarmv5te', 'simmips']:
return 'x86'
if arch in ['simarm64']:
@@ -40,28 +45,41 @@
if arch == 'mips':
return 'mipsel'
if arch == 'simdbc':
- return 'arm' if os == 'android' else 'x86'
+ return 'arm' if target_os == 'android' else 'x86'
if arch == 'simdbc64':
- return 'arm64' if os == 'android' else 'x64'
+ return 'arm64' if target_os == 'android' else 'x64'
return arch
-def to_gn_args(args):
+
+def host_os_for_gn(host_os):
+ if host_os.startswith('macos'):
+ return 'mac'
+ if host_os.startswith('win'):
+ return 'win'
+ return host_os
+
+
+def to_gn_args(args, mode, arch, target_os):
gn_args = {}
- if args.os == 'host':
- gn_args['target_os'] = HOST_OS
+ host_os = host_os_for_gn(HOST_OS)
+ if target_os == 'host':
+ gn_args['target_os'] = host_os
else:
- gn_args['target_os'] = args.os
+ gn_args['target_os'] = target_os
- gn_args['dart_target_arch'] = args.arch
- gn_args['target_cpu'] = target_cpu_for_arch(args.arch, args.os)
- gn_args['host_cpu'] = host_cpu_for_arch(args.arch)
+ gn_args['dart_target_arch'] = arch
+ gn_args['target_cpu'] = target_cpu_for_arch(arch, target_os)
+ gn_args['host_cpu'] = host_cpu_for_arch(arch)
# TODO(zra): This is for the observatory, which currently builds using the
# checked-in sdk. If/when the observatory no longer builds with the
# checked-in sdk, this can be removed.
+ pub = 'pub'
+ if host_os == 'win':
+ pub = pub + ".bat"
gn_args['dart_host_pub_exe'] = os.path.join(
- DART_ROOT, 'tools', 'sdks', HOST_OS, 'dart-sdk', 'bin', 'pub')
+ DART_ROOT, 'tools', 'sdks', host_os, 'dart-sdk', 'bin', pub)
# For Fuchsia support, the default is to not compile in the root
# certificates.
@@ -69,19 +87,32 @@
gn_args['dart_zlib_path'] = "//runtime/bin/zlib"
- gn_args['dart_use_tcmalloc'] = gn_args['target_os'] == 'linux'
+ # Use tcmalloc only when targeting Linux and when not using ASAN.
+ gn_args['dart_use_tcmalloc'] = (gn_args['target_os'] == 'linux'
+ and not args.asan)
- gn_args['is_debug'] = args.mode == 'debug'
- gn_args['is_release'] = args.mode == 'release'
- gn_args['is_product'] = args.mode == 'product'
- gn_args['dart_debug'] = args.mode == 'debug'
+ gn_args['is_debug'] = mode == 'debug'
+ gn_args['is_release'] = mode == 'release'
+ gn_args['is_product'] = mode == 'product'
+ gn_args['dart_debug'] = mode == 'debug'
# This setting is only meaningful for Flutter. Standalone builds of the VM
# should leave this set to 'develop', which causes the build to defer to
# 'is_debug', 'is_release' and 'is_product'.
gn_args['dart_runtime_mode'] = 'develop'
- gn_args['is_clang'] = args.clang and args.os not in ['android']
+ # TODO(zra): Investigate using clang with these configurations.
+ # Clang compiles tcmalloc's inline assembly for ia32 on Linux wrong, so we
+ # don't use clang in that configuration.
+ has_clang = (host_os != 'win'
+ and args.os not in ['android']
+ and not (gn_args['target_os'] == 'linux' and
+ gn_args['host_cpu'] == 'x86')
+ and not gn_args['target_cpu'].startswith('arm')
+ and not gn_args['target_cpu'].startswith('mips'))
+ gn_args['is_clang'] = args.clang and has_clang
+
+ gn_args['is_asan'] = args.asan and gn_args['is_clang']
if args.target_sysroot:
gn_args['target_sysroot'] = args.target_sysroot
@@ -103,37 +134,146 @@
return gn_args
+
+def process_os_option(os_name):
+ if os_name == 'host':
+ return HOST_OS
+ return os_name
+
+
+def process_options(args):
+ if args.arch == 'all':
+ args.arch = 'ia32,x64,simarm,simarm64,simmips,simdbc64'
+ if args.mode == 'all':
+ args.mode = 'debug,release,product'
+ if args.os == 'all':
+ args.os = 'host,android'
+ args.mode = args.mode.split(',')
+ args.arch = args.arch.split(',')
+ args.os = args.os.split(',')
+ for mode in args.mode:
+ if not mode in ['debug', 'release', 'product']:
+ print "Unknown mode %s" % mode
+ return False
+ for arch in args.arch:
+ archs = ['ia32', 'x64', 'simarm', 'arm', 'simarmv6', 'armv6',
+ 'simarmv5te', 'armv5te', 'simmips', 'mips', 'simarm64', 'arm64',
+ 'simdbc', 'simdbc64', 'armsimdbc']
+ if not arch in archs:
+ print "Unknown arch %s" % arch
+ return False
+ oses = [process_os_option(os_name) for os_name in args.os]
+ for os_name in oses:
+ if not os_name in ['android', 'freebsd', 'linux', 'macos', 'win32']:
+ print "Unknown os %s" % os_name
+ return False
+ if os_name != HOST_OS:
+ if os_name != 'android':
+ print "Unsupported target os %s" % os_name
+ return False
+ if not HOST_OS in ['linux']:
+ print ("Cross-compilation to %s is not supported on host os %s."
+ % (os_name, HOST_OS))
+ return False
+ if not arch in ['ia32', 'x64', 'arm', 'armv6', 'armv5te', 'arm64', 'mips',
+ 'simdbc', 'simdbc64']:
+ print ("Cross-compilation to %s is not supported for architecture %s."
+ % (os_name, arch))
+ return False
+ return True
+
+
+def os_has_ide(host_os):
+ return host_os.startswith('win') or host_os.startswith('mac')
+
+
+def ide_switch(host_os):
+ if host_os.startswith('win'):
+ return '--ide=vs'
+ elif host_os.startswith('mac'):
+ return '--ide=xcode'
+ else:
+ return '--ide=json'
+
+
def parse_args(args):
args = args[1:]
- parser = argparse.ArgumentParser(description='A script run` gn gen`.')
+ parser = argparse.ArgumentParser(description='A script to run `gn gen`.')
+ parser.add_argument("-v", "--verbose",
+ help='Verbose output.',
+ default=False, action="store_true")
parser.add_argument('--mode', '-m',
type=str,
- choices=['debug', 'release', 'product'],
+ help='Build variants (comma-separated).',
+ metavar='[all,debug,release,product]',
default='debug')
parser.add_argument('--os',
type=str,
- choices=['host', 'android'],
+ help='Target OSs (comma-separated).',
+ metavar='[all,host,android]',
default='host')
parser.add_argument('--arch', '-a',
type=str,
- choices=['ia32', 'x64', 'simarm', 'arm', 'simarmv6', 'armv6',
- 'simarmv5te', 'armv5te', 'simmips', 'mips', 'simarm64', 'arm64',
- 'simdbc', 'simdbc64'],
+ help='Target architectures (comma-separated).',
+ metavar='[all,ia32,x64,simarm,arm,simarmv6,armv6,simarmv5te,armv5te,'
+ 'simmips,mips,simarm64,arm64,simdbc,armsimdbc]',
default='x64')
+ parser.add_argument('--asan',
+ help='Build with ASAN',
+ default=False,
+ action='store_true')
+ parser.add_argument('--goma',
+ help='Use goma',
+ default=True,
+ action='store_true')
+ parser.add_argument('--no-goma',
+ help='Disable goma',
+ dest='goma',
+ action='store_false')
+ parser.add_argument('--clang',
+ help='Use Clang',
+ default=True,
+ action='store_true')
+ parser.add_argument('--no-clang',
+ help='Disable Clang',
+ dest='clang',
+ action='store_false')
+ parser.add_argument('--ide',
+ help='Generate an IDE file.',
+ default=os_has_ide(HOST_OS),
+ action='store_true')
+ parser.add_argument('--target-sysroot', '-s',
+ type=str,
+ help='Path to the toolchain sysroot')
+ parser.add_argument('--toolchain-prefix', '-t',
+ type=str,
+ help='Path to the toolchain prefix')
+ parser.add_argument('--workers', '-w',
+ type=int,
+ help='Number of simultaneous GN invocations',
+ dest='workers',
+ default=multiprocessing.cpu_count())
- parser.add_argument('--goma', default=True, action='store_true')
- parser.add_argument('--no-goma', dest='goma', action='store_false')
+ options = parser.parse_args(args)
+ if not process_options(options):
+ parser.print_help()
+ return None
+ return options
- parser.add_argument('--clang', default=True, action='store_true')
- parser.add_argument('--no-clang', dest='clang', action='store_false')
- parser.add_argument('--target-sysroot', '-s', type=str)
- parser.add_argument('--toolchain-prefix', '-t', type=str)
+def run_command(command):
+ try:
+ subprocess.check_output(
+ command, cwd=DART_ROOT, stderr=subprocess.STDOUT)
+ return 0
+ except subprocess.CalledProcessError as e:
+ return ("Command failed: " + ' '.join(command) + "\n" +
+ "output: " + e.output)
- return parser.parse_args(args)
def main(argv):
+ starttime = time.time()
args = parse_args(argv)
if sys.platform.startswith(('cygwin', 'win')):
@@ -143,19 +283,40 @@
elif sys.platform.startswith('linux'):
subdir = 'linux64'
else:
- raise Error('Unknown platform: ' + sys.platform)
+ print 'Unknown platform: ' + sys.platform
+ return 1
- command = [
- '%s/buildtools/%s/gn' % (DART_ROOT, subdir),
- 'gen',
- '--check'
- ]
- gn_args = to_command_line(to_gn_args(args))
- out_dir = get_out_dir(args)
- print "gn gen --check in %s" % out_dir
- command.append(out_dir)
- command.append('--args=%s' % ' '.join(gn_args))
- return subprocess.call(command, cwd=DART_ROOT)
+ commands = []
+ for target_os in args.os:
+ for mode in args.mode:
+ for arch in args.arch:
+ command = [
+ '%s/buildtools/%s/gn' % (DART_ROOT, subdir),
+ 'gen',
+ '--check'
+ ]
+ gn_args = to_command_line(to_gn_args(args, mode, arch, target_os))
+ out_dir = get_out_dir(mode, arch, target_os)
+ if args.verbose:
+ print "gn gen --check in %s" % out_dir
+ if args.ide:
+ command.append(ide_switch(HOST_OS))
+ command.append(out_dir)
+ command.append('--args=%s' % ' '.join(gn_args))
+ commands.append(command)
+
+ pool = multiprocessing.Pool(args.workers)
+ results = pool.map(run_command, commands, chunksize=1)
+ for r in results:
+ if r != 0:
+ print r.strip()
+ return 1
+
+ endtime = time.time()
+ if args.verbose:
+ print ("GN Time: %.3f seconds" % (endtime - starttime))
+ return 0
+
if __name__ == '__main__':
- sys.exit(main(sys.argv))
+ sys.exit(main(sys.argv))
diff --git a/tools/gyp/all.gypi b/tools/gyp/all.gypi
index 160c0bb..980b5c5 100644
--- a/tools/gyp/all.gypi
+++ b/tools/gyp/all.gypi
@@ -14,6 +14,8 @@
'dart_io_support': 1,
# Flag that tells us whether this is an ASAN build.
'asan%': 0,
+ # Flag that tells us whether this is a MSAN build.
+ 'msan%': 0,
},
'conditions': [
[ 'OS=="linux"', {
diff --git a/tools/list_dart_files.py b/tools/list_dart_files.py
new file mode 100644
index 0000000..60d2295
--- /dev/null
+++ b/tools/list_dart_files.py
@@ -0,0 +1,43 @@
+#!/usr/bin/env python
+# 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.
+
+"""Tool for listing Dart source files.
+
+Usage:
+ python tools/list_dart_files.py <directory> <root directory pattern>
+"""
+
+import os
+import re
+import sys
+
+
+def main(argv):
+ directory = argv[1]
+
+ pattern = None
+ if len(argv) > 2:
+ pattern = re.compile(argv[2])
+
+ for root, directories, files in os.walk(directory):
+ # We only care about actual source files, not generated code or tests.
+ for skip_dir in ['.git', 'gen', 'test']:
+ if skip_dir in directories:
+ directories.remove(skip_dir)
+
+ # If we are looking at the root directory, filter the immediate
+ # subdirectories by the given pattern.
+ if pattern and root == directory:
+ directories[:] = filter(pattern.match, directories)
+
+ for filename in files:
+ if filename.endswith('.dart') and not filename.endswith('_test.dart'):
+ fullname = os.path.relpath(os.path.join(root, filename))
+ fullname = fullname.replace(os.sep, '/')
+ print fullname
+
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv))
diff --git a/tools/list_files.py b/tools/list_files.py
old mode 100644
new mode 100755
index 1b10b62..ad277e8
--- a/tools/list_files.py
+++ b/tools/list_files.py
@@ -18,8 +18,8 @@
pattern = re.compile(argv[1])
for directory in argv[2:]:
for root, directories, files in os.walk(directory):
- if '.svn' in directories:
- directories.remove('.svn')
+ if '.git' in directories:
+ directories.remove('.git')
for filename in files:
fullname = os.path.relpath(os.path.join(root, filename))
fullname = fullname.replace(os.sep, '/')
diff --git a/tools/testing/dart/compiler_configuration.dart b/tools/testing/dart/compiler_configuration.dart
index d0e6f5f..6cada5b 100644
--- a/tools/testing/dart/compiler_configuration.dart
+++ b/tools/testing/dart/compiler_configuration.dart
@@ -369,10 +369,12 @@
Map<String, String> environmentOverrides) {
var exec = "$buildDir/dart_bootstrap";
var args = new List();
- args.add("--snapshot=$tempDir");
args.add("--snapshot-kind=app-aot");
if (useBlobs) {
+ args.add("--snapshot=$tempDir/out.aotsnapshot");
args.add("--use-blobs");
+ } else {
+ args.add("--snapshot=$tempDir/out.S");
}
if (isAndroid && arch == 'arm') {
args.add('--no-sim-use-hardfp');
@@ -390,15 +392,13 @@
List arguments,
Map<String, String> environmentOverrides) {
- var cc, shared, libname;
+ var cc, shared;
if (Platform.isLinux) {
cc = 'gcc';
shared = '-shared';
- libname = 'libprecompiled.so';
} else if (Platform.isMacOS) {
cc = 'clang';
shared = '-dynamiclib';
- libname = 'libprecompiled.dylib';
} else {
throw "Platform not supported: ${Platform.operatingSystem}";
}
@@ -430,8 +430,8 @@
var args = (cc_flags != null) ? [ shared, cc_flags ] : [ shared ];
args.addAll([
'-o',
- '$tempDir/$libname',
- '$tempDir/snapshot.S'
+ '$tempDir/out.aotsnapshot',
+ '$tempDir/out.S'
]);
return commandBuilder.getCompilationCommand('assemble', tempDir, !useSdk,
@@ -447,7 +447,7 @@
List arguments,
Map<String, String> environmentOverrides) {
var exec = 'rm';
- var args = ['$tempDir/snapshot.S'];
+ var args = ['$tempDir/out.S'];
return commandBuilder.getCompilationCommand(
'remove_assembly',
@@ -532,7 +532,7 @@
Map<String, String> environmentOverrides) {
var exec = "$buildDir/dart_bootstrap";
var args = new List();
- args.add("--snapshot=$tempDir");
+ args.add("--snapshot=$tempDir/out.jitsnapshot");
args.add("--snapshot-kind=app-after-run");
args.addAll(arguments);
@@ -592,7 +592,7 @@
Map<String, String> environmentOverrides) {
var exec = "$buildDir/dart";
var args = new List();
- args.add("--snapshot=$tempDir");
+ args.add("--snapshot=$tempDir/out.jitsnapshot");
args.add("--snapshot-kind=app-jit-after-run");
if (useBlobs) {
args.add("--use-blobs");
diff --git a/tools/testing/dart/runtime_configuration.dart b/tools/testing/dart/runtime_configuration.dart
index 8983cc5..5e8be6e 100644
--- a/tools/testing/dart/runtime_configuration.dart
+++ b/tools/testing/dart/runtime_configuration.dart
@@ -4,6 +4,8 @@
library runtime_configuration;
+import 'dart:io' show Platform;
+
import 'compiler_configuration.dart' show CommandArtifact;
// TODO(ahe): Remove this import, we can precompute all the values required
@@ -244,16 +246,17 @@
throw "dart_app cannot run files of type '$type'.";
}
- var augmentedArgs = new List();
- augmentedArgs.add("--run-app-snapshot=${artifact.filename}");
- if (useBlobs) {
- augmentedArgs.add("--use-blobs");
+ var args = new List();
+ args.addAll(arguments);
+ for (var i = 0; i < args.length; i++) {
+ if (args[i].endsWith(".dart")) {
+ args[i] = "${artifact.filename}/out.jitsnapshot";
+ }
}
- augmentedArgs.addAll(arguments);
return <Command>[
commandBuilder.getVmCommand(suite.dartVmBinaryFileName,
- augmentedArgs, environmentOverrides)
+ args, environmentOverrides)
];
}
}
@@ -274,16 +277,17 @@
throw "dart_precompiled cannot run files of type '$type'.";
}
- var augmentedArgs = new List();
- augmentedArgs.add("--run-app-snapshot=${artifact.filename}");
- if (useBlobs) {
- augmentedArgs.add("--use-blobs");
+ var args = new List();
+ args.addAll(arguments);
+ for (var i = 0; i < args.length; i++) {
+ if (args[i].endsWith(".dart")) {
+ args[i] = "${artifact.filename}/out.aotsnapshot";
+ }
}
- augmentedArgs.addAll(arguments);
return <Command>[
commandBuilder.getVmCommand(suite.dartPrecompiledBinaryFileName,
- augmentedArgs, environmentOverrides)
+ args, environmentOverrides)
];
}
}
diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
index 220d3eb..05f06a2 100644
--- a/tools/testing/dart/test_runner.dart
+++ b/tools/testing/dart/test_runner.dart
@@ -1870,8 +1870,11 @@
});
} else if (io.Platform.isMacOS) {
// Try to print stack traces of the timed out process.
+ // `sample` is a sampling profiler but we ask it sample for 1
+ // second with a 4 second delay between samples so that we only
+ // sample the threads once.
io.Process.run('/usr/bin/sample',
- ['${process.pid}', '1', '1', '-mayDie'])
+ ['${process.pid}', '1', '4000', '-mayDie'])
.then((result) {
io.stdout.write(result.stdout);
io.stderr.write(result.stderr);
@@ -2604,23 +2607,20 @@
.runAdbCommand(['push', '$testdir/$file', '$deviceTestDir/$file']));
}
- if (command.useBlobs) {
- steps.add(() => device.runAdbShellCommand(
- [
- '$devicedir/dart_precompiled_runtime',
- '--run-app-snapshot=$deviceTestDir',
- '--use-blobs'
- ]..addAll(arguments),
- timeout: timeoutDuration));
- } else {
- steps.add(() => device.runAdbShellCommand(
- [
- '$devicedir/dart_precompiled_runtime',
- '--run-app-snapshot=$deviceTestDir'
- ]..addAll(arguments),
- timeout: timeoutDuration));
+ var args = new List();
+ args.addAll(arguments);
+ for (var i = 0; i < args.length; i++) {
+ if (args[i].endsWith(".dart")) {
+ args[i] = "$deviceTestDir/out.aotsnapshot";
+ }
}
+ steps.add(() => device.runAdbShellCommand(
+ [
+ '$devicedir/dart_precompiled_runtime',
+ ]..addAll(args),
+ timeout: timeoutDuration));
+
var stopwatch = new Stopwatch()..start();
var writer = new StringBuffer();
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index cf6a1a0..69f077f 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -1069,6 +1069,15 @@
path = path.join(new Path(vmOptionsVarient.toString()));
}
tempDir = createCompilationOutputDirectory(path);
+
+ List<String> otherResources = info.optionsFromFile['otherResources'];
+ for (String name in otherResources) {
+ Path namePath = new Path(name);
+ String fileName = namePath.filename;
+ Path fromPath = info.filePath.directoryPath.join(namePath);
+ new File('$tempDir/$name').parent.createSync(recursive: true);
+ new File(fromPath.toNativePath()).copySync('$tempDir/$name');
+ }
}
CommandArtifact compilationArtifact =
@@ -1673,6 +1682,7 @@
RegExp sharedOptionsRegExp = new RegExp(r"// SharedOptions=(.*)");
RegExp dartOptionsRegExp = new RegExp(r"// DartOptions=(.*)");
RegExp otherScriptsRegExp = new RegExp(r"// OtherScripts=(.*)");
+ RegExp otherResourcesRegExp = new RegExp(r"// OtherResources=(.*)");
RegExp packageRootRegExp = new RegExp(r"// PackageRoot=(.*)");
RegExp packagesRegExp = new RegExp(r"// Packages=(.*)");
RegExp isolateStubsRegExp = new RegExp(r"// IsolateStubs=(.*)");
@@ -1752,6 +1762,12 @@
otherScripts.addAll(match[1].split(' ').where((e) => e != '').toList());
}
+ List<String> otherResources = new List<String>();
+ matches = otherResourcesRegExp.allMatches(contents);
+ for (var match in matches) {
+ otherResources.addAll(match[1].split(' ').where((e) => e != '').toList());
+ }
+
bool isMultitest = multiTestRegExp.hasMatch(contents);
bool isMultiHtmlTest = multiHtmlTestRegExp.hasMatch(contents);
Match isolateMatch = isolateStubsRegExp.firstMatch(contents);
@@ -1776,6 +1792,7 @@
"hasRuntimeError": false,
"hasStaticWarning": false,
"otherScripts": otherScripts,
+ "otherResources": otherResources,
"isMultitest": isMultitest,
"isMultiHtmlTest": isMultiHtmlTest,
"subtestNames": subtestNames,
@@ -1835,6 +1852,7 @@
"hasRuntimeError": hasRuntimeError,
"hasStaticWarning": hasStaticWarning,
"otherScripts": <String>[],
+ "otherResources": <String>[],
"isMultitest": isMultitest,
"isMultiHtmlTest": false,
"subtestNames": <String>[],
diff --git a/utils/analysis_server/BUILD.gn b/utils/analysis_server/BUILD.gn
new file mode 100644
index 0000000..767c81f
--- /dev/null
+++ b/utils/analysis_server/BUILD.gn
@@ -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.
+
+import("../invoke_dart.gni")
+
+application_snapshot("analysis_server") {
+ main_dart = "../../pkg/analysis_server/bin/server.dart"
+}
diff --git a/utils/compiler/BUILD.gn b/utils/compiler/BUILD.gn
new file mode 100644
index 0000000..5264505
--- /dev/null
+++ b/utils/compiler/BUILD.gn
@@ -0,0 +1,54 @@
+# 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("../create_timestamp.gni")
+import("../invoke_dart.gni")
+
+create_timestamp_file("dart2js_files_stamp") {
+ path = rebase_path("../../pkg/compiler/lib")
+ output = "$root_gen_dir/dart2js_files.stamp"
+}
+
+create_timestamp_file("runtime_lib_files_stamp") {
+ path = rebase_path("../../runtime/lib")
+ output = "$target_gen_dir/runtime_lib_files.stamp"
+}
+
+create_timestamp_file("dartdoc_files_stamp") {
+ path = rebase_path("../../sdk/lib/_internal/dartdoc")
+ output = "$target_gen_dir/dartdoc_files.stamp"
+}
+
+invoke_dart("dart2js") {
+ deps = [
+ ":dart2js_files_stamp",
+ ":runtime_lib_files_stamp",
+ ":dartdoc_files_stamp",
+ ]
+
+ inputs = [
+ "../../sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart",
+ "create_snapshot.dart",
+ "$root_gen_dir/dart2js_files.stamp",
+ "../../tools/VERSION",
+ ]
+
+ utils_output = "$root_gen_dir/utils_wrapper.dart.snapshot"
+ dart2js_output = "$root_gen_dir/dart2js.dart.snapshot"
+ outputs = [
+ utils_output,
+ dart2js_output,
+ ]
+
+ dot_packages = rebase_path("../../.packages")
+ create_snapshot = rebase_path("create_snapshot.dart")
+ output_dir = rebase_path(root_gen_dir)
+
+ args = [
+ "--packages=$dot_packages",
+ create_snapshot,
+ "--output_dir=$output_dir",
+ "--dart2js_main=pkg/compiler/lib/src/dart2js.dart",
+ ]
+}
diff --git a/utils/create_timestamp.gni b/utils/create_timestamp.gni
new file mode 100644
index 0000000..fce5c30
--- /dev/null
+++ b/utils/create_timestamp.gni
@@ -0,0 +1,33 @@
+# 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.
+
+_dart_root = rebase_path("..")
+
+template("create_timestamp_file") {
+ assert(defined(invoker.path), "Must specify 'path'")
+ assert(defined(invoker.output), "Must specify 'output'")
+ new_base = "."
+ if (defined(invoker.new_base)) {
+ new_base = invoker.new_base
+ }
+ current_base = "."
+ if (defined(invoker.current_base)) {
+ current_base = invoker.current_base
+ }
+ path = invoker.path
+ output = invoker.output
+ action(target_name) {
+ list_args = [path]
+ if (defined(invoker.pattern)) {
+ list_args += [invoker.pattern]
+ }
+ files = exec_script(
+ "$_dart_root/tools/list_dart_files.py", list_args, "list lines")
+ inputs = ["$_dart_root/tools/list_dart_files.py"] +
+ rebase_path(files, new_base, current_base)
+ outputs = [ output ]
+ script = "$_dart_root/tools/create_timestamp_file.py"
+ args = [ rebase_path(output) ]
+ }
+}
diff --git a/utils/dartanalyzer/BUILD.gn b/utils/dartanalyzer/BUILD.gn
new file mode 100644
index 0000000..8f19b1a
--- /dev/null
+++ b/utils/dartanalyzer/BUILD.gn
@@ -0,0 +1,65 @@
+# 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("../invoke_dart.gni")
+
+group("dartanalyzer") {
+ deps = [
+ ":generate_dartanalyzer_snapshot",
+ ":generate_summary_spec",
+ ":generate_summary_strong",
+ ]
+}
+
+analyzer_files = exec_script("../../tools/list_dart_files.py",
+ [rebase_path("../../pkg/analyzer")],
+ "list lines")
+
+application_snapshot("generate_dartanalyzer_snapshot") {
+ main_dart = "../../pkg/analyzer_cli/bin/analyzer.dart"
+ name = "dartanalyzer"
+ cli_files = exec_script("../../tools/list_dart_files.py",
+ [rebase_path("../../pkg/analyzer_cli")],
+ "list lines")
+ inputs = cli_files + analyzer_files
+}
+
+sdk_lib_files = exec_script("../../tools/list_dart_files.py",
+ [rebase_path("../../sdk/lib")],
+ "list lines")
+
+template("generate_summary") {
+ assert(defined(invoker.type), "Must specify the summary type")
+ type = invoker.type
+ assert((type == "spec") || (type == "strong"))
+ invoke_dart(target_name) {
+ inputs = sdk_lib_files + analyzer_files
+
+ output = "$root_gen_dir/$type.sum"
+ outputs = [
+ output
+ ]
+
+ dot_packages = rebase_path("../../.packages")
+ build_sdk_summaries =
+ rebase_path("../../pkg/analyzer/tool/summary/build_sdk_summaries.dart")
+ abs_output = rebase_path(output)
+
+ args = [
+ "--packages=$dot_packages",
+ build_sdk_summaries,
+ "build-$type",
+ abs_output,
+ rebase_path("../../sdk"),
+ ]
+ }
+}
+
+generate_summary("generate_summary_spec") {
+ type = "spec"
+}
+
+generate_summary("generate_summary_strong") {
+ type = "strong"
+}
diff --git a/utils/dartdevc/BUILD.gn b/utils/dartdevc/BUILD.gn
new file mode 100644
index 0000000..75507e7
--- /dev/null
+++ b/utils/dartdevc/BUILD.gn
@@ -0,0 +1,12 @@
+# 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("../invoke_dart.gni")
+
+application_snapshot("dartdevc") {
+ main_dart = "../../pkg/dev_compiler/bin/dartdevc.dart"
+ inputs = exec_script("../../tools/list_dart_files.py",
+ [rebase_path("../../pkg/dev_compiler/bin")],
+ "list lines")
+}
diff --git a/utils/dartdoc/BUILD.gn b/utils/dartdoc/BUILD.gn
new file mode 100644
index 0000000..d850f02
--- /dev/null
+++ b/utils/dartdoc/BUILD.gn
@@ -0,0 +1,12 @@
+# 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("../invoke_dart.gni")
+
+application_snapshot("dartdoc") {
+ main_dart = "../../third_party/pkg/dartdoc/bin/dartdoc.dart"
+ inputs = exec_script("../../tools/list_dart_files.py",
+ [rebase_path("../../third_party/pkg/dartdoc")],
+ "list lines")
+}
diff --git a/utils/dartfmt/BUILD.gn b/utils/dartfmt/BUILD.gn
new file mode 100644
index 0000000..f8c820b
--- /dev/null
+++ b/utils/dartfmt/BUILD.gn
@@ -0,0 +1,12 @@
+# 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("../invoke_dart.gni")
+
+application_snapshot("dartfmt") {
+ main_dart = "../../third_party/pkg_tested/dart_style/bin/format.dart"
+ inputs = exec_script("../../tools/list_dart_files.py",
+ [rebase_path("../../third_party/pkg_tested/dart_style")],
+ "list lines")
+}
diff --git a/utils/invoke_dart.gni b/utils/invoke_dart.gni
new file mode 100644
index 0000000..66705f7
--- /dev/null
+++ b/utils/invoke_dart.gni
@@ -0,0 +1,91 @@
+# 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.
+
+_dart_root = rebase_path("..")
+
+template("invoke_dart") {
+ assert(defined(invoker.outputs), "invoke_dart must specify outputs")
+ extra_deps = []
+ if (defined(invoker.deps)) {
+ extra_deps += invoker.deps
+ }
+
+ extra_inputs = []
+ if (defined(invoker.inputs)) {
+ extra_inputs += invoker.inputs
+ }
+
+ extra_args = []
+ if (defined(invoker.args)) {
+ extra_args += invoker.args
+ }
+
+ action(target_name) {
+ relative_dart_root = rebase_path(_dart_root, ".")
+ deps = extra_deps + [
+ "$relative_dart_root/runtime/bin:dart($host_toolchain)",
+ ]
+
+ dart_out_dir = get_label_info(
+ "$relative_dart_root/runtime/bin:dart($host_toolchain)", "root_out_dir")
+ if (is_win) {
+ dart = rebase_path("$dart_out_dir/dart.exe")
+ } else {
+ dart = rebase_path("$dart_out_dir/dart")
+ }
+
+ inputs = [
+ dart,
+ ] + extra_inputs
+
+ outputs = invoker.outputs
+
+ script = "$_dart_root/tools/dart_for_gn.py"
+ args = [
+ dart,
+ ] + extra_args
+ }
+}
+
+template("application_snapshot") {
+ assert(defined(invoker.main_dart), "Must specify 'main_dart'")
+ main_dart = invoker.main_dart
+ name = target_name
+ if (defined(invoker.name)) {
+ name = invoker.name
+ }
+ extra_deps = []
+ if (defined(invoker.deps)) {
+ extra_deps += invoker.deps
+ }
+ extra_inputs = []
+ if (defined(invoker.inputs)) {
+ extra_inputs += invoker.inputs
+ }
+ invoke_dart(target_name) {
+ deps = extra_deps + [
+ "$_dart_root/pkg:pkg_files_stamp"
+ ]
+
+ inputs = extra_inputs + [
+ "$_dart_root/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart",
+ "$root_gen_dir/pkg_files.stamp",
+ ]
+
+ output = "$root_gen_dir/$name.dart.snapshot"
+ outputs = [
+ output,
+ ]
+
+ dot_packages = rebase_path("$_dart_root/.packages")
+ abs_output = rebase_path(output)
+ main_file = rebase_path(main_dart)
+
+ args = [
+ "--packages=$dot_packages",
+ "--snapshot=$abs_output",
+ main_file
+ ]
+ }
+}
diff --git a/utils/pub/BUILD.gn b/utils/pub/BUILD.gn
new file mode 100644
index 0000000..4d604e0
--- /dev/null
+++ b/utils/pub/BUILD.gn
@@ -0,0 +1,15 @@
+# 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("../invoke_dart.gni")
+
+application_snapshot("pub") {
+ main_dart = "../../third_party/pkg/pub/bin/pub.dart"
+ deps = [
+ "../compiler:dart2js_files_stamp"
+ ]
+ inputs = [
+ "$root_gen_dir/dart2js_files.stamp"
+ ]
+}