Version 1.20.0-dev.8.0
Merge commit 'ce596133ad507f3fe118c4c79a2b909bac0f0f6a' into dev
diff --git a/.gn b/.gn
new file mode 100644
index 0000000..fc54abe
--- /dev/null
+++ b/.gn
@@ -0,0 +1,14 @@
+# 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.
+
+# This file is used by the gn meta-buildsystem find the root of the source tree
+# and to set startup options.
+
+# The location of the build configuration file.
+buildconfig = "//build/config/BUILDCONFIG.gn"
+
+# The secondary source root is a parallel directory tree where
+# GN build files are placed when they can not be placed directly
+# in the source tree, e.g. for third party source trees.
+secondary_source = "//build/secondary/"
diff --git a/.travis.yml b/.travis.yml
index 1424eaf..1a877df 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -70,6 +70,7 @@
- env: TEST=node
- env: ANALYZER=master DDC_BROWSERS=Firefox
- env: ANALYZER=master CXX=clang++
+ - env: ANALYZER=master CXX=g++
notifications:
email:
recipients:
diff --git a/BUILD.gn b/BUILD.gn
new file mode 100644
index 0000000..d86d84a
--- /dev/null
+++ b/BUILD.gn
@@ -0,0 +1,21 @@
+# Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# This target will be built if no target is specified when invoking ninja.
+group("default") {
+ deps = [
+ ":runtime",
+ ]
+}
+
+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",
+ ]
+}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index cef042e..4285fc9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -23,6 +23,7 @@
directory containing root certificate files hashed using `c_rehash`.
### Core library changes
+
* `dart:core`: Remove deprecated `Resource` class.
Use the class in `package:resource` instead.
* `dart:async`
@@ -107,14 +108,12 @@
class C extends A {}
```
-* Breaking change - ingore `dynamic` when doing inference.
+### Tool changes
- ```dart
- main() {
- dynamic d = 42;
- List<int> list = /*infer <int>*/[123, /*implicit cast*/d];
- }
- ```
+* `dartfmt` - upgraded to v0.2.10
+ * Don't crash on annotations before parameters with trailing commas.
+ * Always split enum declarations if they end in a trailing comma.
+ * Add `--set-exit-if-changed` to set the exit code on a change.
## 1.19.0
diff --git a/DEPS b/DEPS
index f2fc204..0c56803 100644
--- a/DEPS
+++ b/DEPS
@@ -30,8 +30,7 @@
"gyp_rev": "@6ee91ad8659871916f9aa840d42e1513befdf638",
"co19_rev": "@d4767b4caea3c5828ad8e053cd051d44a59061af",
- # Revisions of GN/Mojo/Flutter related dependencies.
- "base_revision": "@672b04e54b937ec899429a6bd5409c5a6300d151",
+ # Revisions of GN related dependencies.
"buildtools_revision": "@565d04e8741429fb1b4f26d102f2c6c3b849edeb",
"gperftools_revision": "@7822b5b0b9fa7e016e1f6b46ea86f26f4691a457",
@@ -45,11 +44,11 @@
"barback_tag" : "@0.15.2+9",
"bazel_worker_tag": "@0.1.1",
"boolean_selector_tag" : "@1.0.2",
- "boringssl_gen_rev": "@e3a1b341a3890ab10d372dc2fe6d1c6798828293",
+ "boringssl_gen_rev": "@1e8e5da213d0d5b1d50fcc1356c4783091bcc20d",
"boringssl_rev" : "@8d343b44bbab829d1a28fdef650ca95f7db4412e",
"charcode_tag": "@1.1.0",
"chrome_rev" : "@19997",
- "cli_util_tag" : "@0.0.1+2",
+ "cli_util_tag" : "@0.0.1+3",
"code_transformers_tag": "@v0.4.2+3",
"collection_tag": "@1.9.1",
"convert_tag": "@2.0.1",
@@ -57,7 +56,7 @@
"csslib_tag" : "@0.13.2",
"dart2js_info_tag" : "@0.2.7+1",
"dart_services_rev" : "@7aea2574e6f3924bf409a80afb8ad52aa2be4f97",
- "dart_style_tag": "@0.2.9+1",
+ "dart_style_tag": "@0.2.10",
"dartdoc_tag" : "@v0.9.7+3",
"fixnum_tag": "@0.10.5",
"func_tag": "@0.1.0",
@@ -73,8 +72,8 @@
"isolate_tag": "@0.2.3",
"jinja2_rev": "@2222b31554f03e62600cd7e383376a7c187967a1",
"json_rpc_2_tag": "@2.0.2",
- "kernel_rev": "@9677d68402ea15d0eca6430d64f631bb3e505499",
- "linter_tag": "@0.1.26",
+ "kernel_rev": "@449803b82e850a41148e636db1a6e4a848284aed",
+ "linter_tag": "@0.1.27",
"logging_tag": "@0.11.3+1",
"markdown_rev": "@4aaadf3d940bb172e1f6285af4d2b1710d309982",
"matcher_tag": "@0.12.0+2",
@@ -92,7 +91,7 @@
"pool_tag": "@1.2.4",
"protobuf_tag": "@0.5.3",
"pub_cache_tag": "@v0.1.0",
- "pub_rev": "@101aa44a4aebaefd0796ce44e6d155cd79fe2db4",
+ "pub_rev": "@4ef3e3e8ad8089733d617505cc66fa3d8049b4ae",
"pub_semver_tag": "@1.3.0",
"quiver_tag": "@0.22.0",
"resource_rev":"@a49101ba2deb29c728acba6fb86000a8f730f4b1",
@@ -131,11 +130,7 @@
Var("dart_root") + "/third_party/gyp":
Var('chromium_git') + '/external/gyp.git' + Var("gyp_rev"),
- # Stuff needed for GN/Mojo/Flutter.
- Var("dart_root") + "/base":
- Var('chromium_git') + '/external/github.com/domokit/base'
- + Var('base_revision'),
-
+ # Stuff needed for GN build.
Var("dart_root") + "/buildtools":
Var('chromium_git') + '/chromium/buildtools.git' +
Var('buildtools_revision'),
@@ -363,6 +358,83 @@
# TODO(iposva): Move the necessary tools so that hooks can be run
# without the runtime being available.
hooks = [
+ # Pull GN binaries. This needs to be before running GYP below.
+ {
+ 'name': 'gn_linux64',
+ 'pattern': '.',
+ 'action': [
+ 'download_from_google_storage',
+ '--no_auth',
+ '--no_resume',
+ '--quiet',
+ '--platform=linux*',
+ '--bucket',
+ 'chromium-gn',
+ '-s',
+ Var('dart_root') + '/buildtools/linux64/gn.sha1',
+ ],
+ },
+ {
+ 'name': 'gn_mac',
+ 'pattern': '.',
+ 'action': [
+ 'download_from_google_storage',
+ '--no_auth',
+ '--no_resume',
+ '--quiet',
+ '--platform=darwin',
+ '--bucket',
+ 'chromium-gn',
+ '-s',
+ Var('dart_root') + '/buildtools/mac/gn.sha1',
+ ],
+ },
+ {
+ 'name': 'gn_win',
+ 'pattern': '.',
+ 'action': [
+ 'download_from_google_storage',
+ '--no_auth',
+ '--no_resume',
+ '--quiet',
+ '--platform=win*',
+ '--bucket',
+ 'chromium-gn',
+ '-s',
+ Var('dart_root') + '/buildtools/win/gn.exe.sha1',
+ ],
+ },
+ # Pull clang-format binaries using checked-in hashes.
+ {
+ 'name': 'clang_format_linux',
+ 'pattern': '.',
+ 'action': [
+ 'download_from_google_storage',
+ '--no_auth',
+ '--no_resume',
+ '--quiet',
+ '--platform=linux*',
+ '--bucket',
+ 'chromium-clang-format',
+ '-s',
+ Var('dart_root') + '/buildtools/linux64/clang-format.sha1',
+ ],
+ },
+ {
+ 'name': 'clang_format_mac',
+ 'pattern': '.',
+ 'action': [
+ 'download_from_google_storage',
+ '--no_auth',
+ '--no_resume',
+ '--quiet',
+ '--platform=darwin',
+ '--bucket',
+ 'chromium-clang-format',
+ '-s',
+ Var('dart_root') + '/buildtools/mac/clang-format.sha1',
+ ],
+ },
{
'name': 'd8_testing_binaries',
'pattern': '.',
@@ -498,6 +570,12 @@
],
},
{
+ # Pull clang if needed or requested via GYP_DEFINES.
+ 'name': 'gn_clang',
+ 'pattern': '.',
+ 'action': ['python', 'sdk/tools/clang/scripts/update.py', '--if-needed'],
+ },
+ {
"pattern": ".",
"action": ["python", Var("dart_root") + "/tools/gyp_dart.py"],
},
diff --git a/build/config/BUILD.gn b/build/config/BUILD.gn
index 0af90cd..93243a1 100644
--- a/build/config/BUILD.gn
+++ b/build/config/BUILD.gn
@@ -2,433 +2,23 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import("//build/config/allocator.gni")
-import("//build/config/chrome_build.gni")
-import("//build/config/crypto.gni")
-import("//build/config/features.gni")
-import("//build/config/ui.gni")
-import("//build/module_args/v8.gni")
-
-declare_args() {
- # When set, turns off the (normally-on) iterator debugging and related stuff
- # that is normally turned on for Debug builds. These are generally useful for
- # catching bugs but in some cases may cause conflicts or excessive slowness.
- disable_iterator_debugging = false
-
- # Set to true 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.
- #
- # 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 = !is_official_build
-
- # Set to true to enable dcheck in Release builds.
- dcheck_always_on = false
-
- # Set to true to compile with the OpenGL ES 2.0 conformance tests.
- internal_gles2_conform_tests = false
-}
-
-# TODO(brettw) Most of these should be removed. Instead of global feature
-# flags, we should have more modular flags that apply only to a target and its
-# dependents. For example, depending on the "x11" meta-target should define
-# USE_X11 for all dependents so that everything that could use X11 gets the
-# define, but anything that doesn't depend on X11 doesn't see it.
-#
-# For now we define these globally to match the current GYP build.
-config("feature_flags") {
- # TODO(brettw) this probably needs to be parameterized.
- defines = [ "V8_DEPRECATION_WARNINGS" ] # Don't use deprecated V8 APIs anywhere.
-
- if (cld_version > 0) {
- defines += [ "CLD_VERSION=$cld_version" ]
- }
- if (enable_mdns) {
- defines += [ "ENABLE_MDNS=1" ]
- }
- if (enable_notifications) {
- defines += [ "ENABLE_NOTIFICATIONS" ]
- }
- if (enable_pepper_cdms) {
- # TODO(brettw) should probably be "=1"
- defines += [ "ENABLE_PEPPER_CDMS" ]
- }
- if (enable_browser_cdms) {
- # TODO(brettw) should probably be "=1"
- defines += [ "ENABLE_BROWSER_CDMS" ]
- }
- if (enable_plugins) {
- defines += [ "ENABLE_PLUGINS=1" ]
- }
- if (enable_basic_printing || enable_print_preview) {
- # Convenience define for ENABLE_BASIC_PRINTING || ENABLE_PRINT_PREVIEW.
- defines += [ "ENABLE_PRINTING=1" ]
- if (enable_basic_printing) {
- # Enable basic printing support and UI.
- defines += [ "ENABLE_BASIC_PRINTING=1" ]
- }
- if (enable_print_preview) {
- # Enable printing with print preview.
- # Can be defined without ENABLE_BASIC_PRINTING.
- defines += [ "ENABLE_PRINT_PREVIEW=1" ]
- }
- }
- if (enable_spellcheck) {
- defines += [ "ENABLE_SPELLCHECK=1" ]
- }
- if (use_platform_spellchecker) {
- defines += [ "USE_PLATFORM_SPELLCHECKER=1" ]
- }
- if (dont_embed_build_metadata) {
- defines += [ "DONT_EMBED_BUILD_METADATA" ]
- }
- if (dcheck_always_on) {
- defines += [ "DCHECK_ALWAYS_ON=1" ]
- }
- if (use_udev) {
- # TODO(brettw) should probably be "=1".
- defines += [ "USE_UDEV" ]
- }
- if (ui_compositor_image_transport) {
- # TODO(brettw) should probably be "=1".
- defines += [ "UI_COMPOSITOR_IMAGE_TRANSPORT" ]
- }
- if (use_ash) {
- defines += [ "USE_ASH=1" ]
- }
- if (use_aura) {
- defines += [ "USE_AURA=1" ]
- }
- if (use_glfw) {
- defines += [ "USE_GLFW=1" ]
- }
- if (use_pango) {
- defines += [ "USE_PANGO=1" ]
- }
- if (use_cairo) {
- defines += [ "USE_CAIRO=1" ]
- }
- if (use_clipboard_aurax11) {
- defines += [ "USE_CLIPBOARD_AURAX11=1" ]
- }
- if (use_default_render_theme) {
- defines += [ "USE_DEFAULT_RENDER_THEME=1" ]
- }
- if (use_openssl) {
- defines += [ "USE_OPENSSL=1" ]
- }
- if (use_openssl_certs) {
- defines += [ "USE_OPENSSL_CERTS=1" ]
- }
- if (use_nss_certs) {
- defines += [ "USE_NSS_CERTS=1" ]
- }
- if (use_ozone) {
- defines += [ "USE_OZONE=1" ]
- }
- if (use_x11) {
- defines += [ "USE_X11=1" ]
- }
- if (use_allocator != "tcmalloc") {
- defines += [ "NO_TCMALLOC" ]
- }
- if (is_asan || is_lsan || is_tsan || is_msan || is_ios) {
- defines += [
- "MEMORY_TOOL_REPLACES_ALLOCATOR",
- "MEMORY_SANITIZER_INITIAL_SIZE",
- ]
- }
- if (is_asan) {
- defines += [ "ADDRESS_SANITIZER" ]
- }
- if (is_lsan) {
- defines += [
- "LEAK_SANITIZER",
- "WTF_USE_LEAK_SANITIZER=1",
- ]
- }
- if (is_tsan) {
- defines += [
- "THREAD_SANITIZER",
- "DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL=1",
- "WTF_USE_DYNAMIC_ANNOTATIONS_NOIMPL=1",
- ]
- }
- if (is_msan) {
- defines += [ "MEMORY_SANITIZER" ]
- }
- if (enable_webrtc) {
- defines += [ "ENABLE_WEBRTC=1" ]
- }
- if (disable_ftp_support) {
- defines += [ "DISABLE_FTP_SUPPORT=1" ]
- }
- if (!enable_nacl) {
- defines += [ "DISABLE_NACL" ]
- }
- if (enable_extensions) {
- defines += [ "ENABLE_EXTENSIONS=1" ]
- }
- if (enable_configuration_policy) {
- defines += [ "ENABLE_CONFIGURATION_POLICY" ]
- }
- if (enable_task_manager) {
- defines += [ "ENABLE_TASK_MANAGER=1" ]
- }
- if (enable_themes) {
- defines += [ "ENABLE_THEMES=1" ]
- }
- if (enable_captive_portal_detection) {
- defines += [ "ENABLE_CAPTIVE_PORTAL_DETECTION=1" ]
- }
- if (enable_session_service) {
- defines += [ "ENABLE_SESSION_SERVICE=1" ]
- }
- if (enable_rlz) {
- defines += [ "ENABLE_RLZ" ]
- }
- if (enable_plugin_installation) {
- defines += [ "ENABLE_PLUGIN_INSTALLATION=1" ]
- }
- if (enable_app_list) {
- defines += [ "ENABLE_APP_LIST=1" ]
- }
- if (enable_settings_app) {
- defines += [ "ENABLE_SETTINGS_APP=1" ]
- }
- if (enable_supervised_users) {
- defines += [ "ENABLE_SUPERVISED_USERS=1" ]
- }
- if (enable_service_discovery) {
- defines += [ "ENABLE_SERVICE_DISCOVERY=1" ]
- }
- if (enable_autofill_dialog) {
- defines += [ "ENABLE_AUTOFILL_DIALOG=1" ]
- }
- if (enable_wifi_bootstrapping) {
- defines += [ "ENABLE_WIFI_BOOTSTRAPPING=1" ]
- }
- if (enable_image_loader_extension) {
- defines += [ "IMAGE_LOADER_EXTENSION=1" ]
- }
- if (enable_remoting) {
- defines += [ "ENABLE_REMOTING=1" ]
- }
- if (enable_google_now) {
- defines += [ "ENABLE_GOOGLE_NOW=1" ]
- }
- if (enable_one_click_signin) {
- defines += [ "ENABLE_ONE_CLICK_SIGNIN" ]
- }
- if (enable_hidpi) {
- defines += [ "ENABLE_HIDPI=1" ]
- }
- if (enable_topchrome_md) {
- defines += [ "ENABLE_TOPCHROME_MD=1" ]
- }
- if (proprietary_codecs) {
- defines += [ "USE_PROPRIETARY_CODECS" ]
- }
- if (enable_hangout_services_extension) {
- defines += [ "ENABLE_HANGOUT_SERVICES_EXTENSION=1" ]
- }
- if (v8_use_external_startup_data) {
- defines += [ "V8_USE_EXTERNAL_STARTUP_DATA" ]
- }
- if (enable_background) {
- defines += [ "ENABLE_BACKGROUND=1" ]
- }
- if (enable_pre_sync_backup) {
- defines += [ "ENABLE_PRE_SYNC_BACKUP" ]
- }
- if (enable_video_hole) {
- defines += [ "VIDEO_HOLE=1" ]
- }
- if (safe_browsing_mode == 1) {
- defines += [ "FULL_SAFE_BROWSING" ]
- defines += [ "SAFE_BROWSING_CSD" ]
- defines += [ "SAFE_BROWSING_DB_LOCAL" ]
- defines += [ "SAFE_BROWSING_SERVICE" ]
- } else if (safe_browsing_mode == 2) {
- defines += [ "MOBILE_SAFE_BROWSING" ]
- defines += [ "SAFE_BROWSING_SERVICE" ]
- } else if (safe_browsing_mode == 3) {
- defines += [ "MOBILE_SAFE_BROWSING" ]
- defines += [ "SAFE_BROWSING_DB_REMOTE" ]
- defines += [ "SAFE_BROWSING_SERVICE" ]
- }
- if (is_official_build) {
- defines += [ "OFFICIAL_BUILD" ]
- }
- if (is_chrome_branded) {
- defines += [ "GOOGLE_CHROME_BUILD" ]
- } else {
- defines += [ "CHROMIUM_BUILD" ]
- }
- if (enable_media_router) {
- defines += [ "ENABLE_MEDIA_ROUTER=1" ]
- }
- if (enable_webvr) {
- defines += [ "ENABLE_WEBVR" ]
- }
- if (is_fnl) {
- defines += [ "HAVE_SYS_QUEUE_H_=0" ]
- }
-}
-
# Debug/release ----------------------------------------------------------------
config("debug") {
defines = [
- "_DEBUG",
- "DYNAMIC_ANNOTATIONS_ENABLED=1",
- "WTF_USE_DYNAMIC_ANNOTATIONS=1",
+ "DEBUG",
]
-
- if (is_nacl) {
- defines += [ "DYNAMIC_ANNOTATIONS_PREFIX=NACL_" ]
- }
-
- if (is_win) {
- if (disable_iterator_debugging) {
- # Iterator debugging is enabled by the compiler on debug builds, and we
- # have to tell it to turn it off.
- defines += [ "_HAS_ITERATOR_DEBUGGING=0" ]
- }
- } else if (is_linux && !is_android && current_cpu == "x64" &&
- !disable_iterator_debugging) {
- # 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" ]
- }
}
config("release") {
- defines = [ "NDEBUG" ]
-
- # Sanitizers.
- # TODO(GYP) The GYP build has "release_valgrind_build == 0" for this
- # condition. When Valgrind is set up, we need to do the same here.
- if (is_tsan) {
- defines += [
- "DYNAMIC_ANNOTATIONS_ENABLED=1",
- "WTF_USE_DYNAMIC_ANNOTATIONS=1",
- ]
- } else {
- defines += [ "NVALGRIND" ]
- if (!is_nacl) {
- # NaCl always enables dynamic annotations. Currently this value is set to
- # 1 for all .nexes.
- defines += [ "DYNAMIC_ANNOTATIONS_ENABLED=0" ]
- }
- }
+ defines = [
+ "NDEBUG"
+ ]
}
-# Default libraries ------------------------------------------------------------
-
-# This config defines the default libraries applied to all targets.
-config("default_libs") {
- if (is_win) {
- # TODO(brettw) this list of defaults should probably be smaller, and
- # instead the targets that use the less common ones (e.g. wininet or
- # winspool) should include those explicitly.
- libs = [
- "advapi32.lib",
- "comdlg32.lib",
- "dbghelp.lib",
- "delayimp.lib",
- "dnsapi.lib",
- "gdi32.lib",
- "kernel32.lib",
- "msimg32.lib",
- "odbc32.lib",
- "odbccp32.lib",
- "ole32.lib",
- "oleaut32.lib",
- "psapi.lib",
- "shell32.lib",
- "shlwapi.lib",
- "user32.lib",
- "usp10.lib",
- "uuid.lib",
- "version.lib",
- "wininet.lib",
- "winmm.lib",
- "winspool.lib",
- "ws2_32.lib",
-
- # Please don't add more stuff here. We should actually be making this
- # list smaller, since all common things should be covered. If you need
- # some extra libraries, please just add a libs = [ "foo.lib" ] to your
- # target that needs it.
- ]
- } else if (is_android) {
- # Android uses -nostdlib so we need to add even libc here.
- libs = [
- # TODO(brettw) write a version of this, hopefully we can express this
- # without forking out to GCC just to get the library name. The android
- # toolchain directory should probably be extracted into a .gni file that
- # this file and the android toolchain .gn file can share.
- # # Manually link the libgcc.a that the cross compiler uses.
- # '<!(<(android_toolchain)/*-gcc -print-libgcc-file-name)',
- "c",
- "dl",
- "m",
- ]
- } else if (is_mac) {
- libs = [
- "AppKit.framework",
- "ApplicationServices.framework",
- "Carbon.framework",
- "CoreFoundation.framework",
- "Foundation.framework",
- "IOKit.framework",
- "Security.framework",
- "OpenGL.framework",
- ]
- } else if (is_ios) {
- # The libraries listed here will be specified for both the target and the
- # host. Only the common ones should be listed here.
- libs = [
- "CoreFoundation.framework",
- "CoreGraphics.framework",
- "CoreText.framework",
- "Foundation.framework",
- ]
- } else if (is_linux) {
- libs = [ "dl" ]
- }
-}
-
-# Add this config to your target to enable precompiled headers.
-#
-# On Windows, precompiled headers are done on a per-target basis. If you have
-# just a couple of files, the time it takes to precompile (~2 seconds) can
-# actually be longer than the time saved. On a Z620, a 100 file target compiles
-# about 2 seconds faster with precompiled headers, with greater savings for
-# larger targets.
-#
-# Recommend precompiled headers for targets with more than 50 .cc files.
-config("precompiled_headers") {
- # TODO(brettw) enable this when GN support in the binary has been rolled.
- #if (is_win) {
- if (false) {
- # This is a string rather than a file GN knows about. It has to match
- # exactly what's in the /FI flag below, and what might appear in the source
- # code in quotes for an #include directive.
- precompiled_header = "build/precompile.h"
-
- # This is a file that GN will compile with the above header. It will be
- # implicitly added to the sources (potentially multiple times, with one
- # variant for each language used in the target).
- precompiled_source = "//build/precompile.cc"
-
- # Force include the header.
- cflags = [ "/FI$precompiled_header" ]
- }
+config("product") {
+ defines = [
+ "NDEBUG",
+ "PRODUCT",
+ ]
}
diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn
index e22b29a..09527af 100644
--- a/build/config/BUILDCONFIG.gn
+++ b/build/config/BUILDCONFIG.gn
@@ -38,17 +38,8 @@
target_os = host_os
}
-if (target_cpu == "") {
- if (target_os == "android") {
- # If we're building for Android, we should assume that we want to
- # build for ARM by default, not the host_cpu (which is likely x64).
- # This allows us to not have to specify both target_os and target_cpu
- # on the command line.
- target_cpu = "arm"
- } else {
- target_cpu = host_cpu
- }
-}
+assert(host_cpu != "")
+assert(target_cpu != "")
if (current_cpu == "") {
current_cpu = target_cpu
@@ -110,28 +101,23 @@
# - Don't call exec_script inside declare_args. This will execute the script
# even if the value is overridden, which is wasteful. See first bullet.
+# There is no component build for the Dart VM, but build files in some
+# dependencies check this.
+is_component_build = false
+
declare_args() {
- # How many symbols to include in the build. This affects the performance of
- # the build since the symbols are large and dealing with them is slow.
- # 2 means regular build with symbols.
- # 1 means minimal symbols, usually enough for backtraces only.
- # 0 means no symbols.
- # -1 means auto-set (off in release, regular in debug).
- symbol_level = -1
-
- # Component build.
- is_component_build = false
-
# Debug build.
is_debug = true
- # Whether we're a traditional desktop unix.
- is_desktop_linux = current_os == "linux" && current_os != "chromeos"
+ # Release build.
+ is_release = false
+
+ # Product build.
+ is_product = false
# Set to true when compiling with the Clang compiler. Typically this is used
# to configure warnings.
- is_clang = current_os == "mac" || current_os == "ios" ||
- current_os == "linux" || current_os == "chromeos"
+ is_clang = current_os == "mac" || current_os == "linux"
# Compile for Address Sanitizer to find memory bugs.
is_asan = false
@@ -144,15 +130,6 @@
# Compile for Thread Sanitizer to find threading bugs.
is_tsan = false
-
- if (current_os == "chromeos") {
- # Allows the target toolchain to be injected as arguments. This is needed
- # to support the CrOS build system which supports per-build-configuration
- # toolchains.
- cros_use_custom_toolchain = false
- }
-
- # DON'T ADD MORE FLAGS HERE. Read the comment above.
}
# =============================================================================
@@ -176,7 +153,6 @@
if (current_os == "win") {
is_android = false
is_chromeos = false
- is_fnl = false
is_ios = false
is_linux = false
is_mac = false
@@ -186,7 +162,6 @@
} else if (current_os == "mac") {
is_android = false
is_chromeos = false
- is_fnl = false
is_ios = false
is_linux = false
is_mac = true
@@ -196,60 +171,15 @@
} else if (current_os == "android") {
is_android = true
is_chromeos = false
- is_fnl = false
is_ios = false
is_linux = false
is_mac = false
is_nacl = false
is_posix = true
is_win = false
-} else if (current_os == "chromeos") {
- is_android = false
- is_chromeos = true
- is_fnl = false
- is_ios = false
- is_linux = true
- is_mac = false
- is_nacl = false
- is_posix = true
- is_win = false
-} else if (current_os == "nacl") {
- # current_os == "nacl" will be passed by the nacl toolchain definition.
- # It is not set by default or on the command line. We treat is as a
- # Posix variant.
- is_android = false
- is_chromeos = false
- is_fnl = false
- is_ios = false
- is_linux = false
- is_mac = false
- is_nacl = true
- is_posix = true
- is_win = false
-} else if (current_os == "ios") {
- is_android = false
- is_chromeos = false
- is_fnl = false
- is_ios = true
- is_linux = false
- is_mac = false
- is_nacl = false
- is_posix = true
- is_win = false
} else if (current_os == "linux") {
is_android = false
is_chromeos = false
- is_fnl = false
- is_ios = false
- is_linux = true
- is_mac = false
- is_nacl = false
- is_posix = true
- is_win = false
-} else if (current_os == "fnl") {
- is_android = false
- is_chromeos = false
- is_fnl = true
is_ios = false
is_linux = true
is_mac = false
@@ -259,119 +189,6 @@
}
# =============================================================================
-# SOURCES FILTERS
-# =============================================================================
-#
-# These patterns filter out platform-specific files when assigning to the
-# sources variable. The magic variable |sources_assignment_filter| is applied
-# to each assignment or appending to the sources variable and matches are
-# automatcally removed.
-#
-# Note that the patterns are NOT regular expressions. Only "*" and "\b" (path
-# boundary = end of string or slash) are supported, and the entire string
-# muct match the pattern (so you need "*.cc" to match all .cc files, for
-# example).
-
-# DO NOT ADD MORE PATTERNS TO THIS LIST, see set_sources_assignment_filter call
-# below.
-sources_assignment_filter = []
-if (!is_posix) {
- sources_assignment_filter += [
- "*_posix.h",
- "*_posix.cc",
- "*_posix_unittest.h",
- "*_posix_unittest.cc",
- "*\bposix/*",
- ]
-}
-if (!is_win) {
- sources_assignment_filter += [
- "*_win.cc",
- "*_win.h",
- "*_win_unittest.cc",
- "*\bwin/*",
- "*.def",
- "*.rc",
- ]
-}
-if (!is_mac) {
- sources_assignment_filter += [
- "*_mac.h",
- "*_mac.cc",
- "*_mac.mm",
- "*_mac_unittest.h",
- "*_mac_unittest.cc",
- "*_mac_unittest.mm",
- "*\bmac/*",
- "*_cocoa.h",
- "*_cocoa.cc",
- "*_cocoa.mm",
- "*_cocoa_unittest.h",
- "*_cocoa_unittest.cc",
- "*_cocoa_unittest.mm",
- "*\bcocoa/*",
- ]
-}
-if (!is_ios) {
- sources_assignment_filter += [
- "*_ios.h",
- "*_ios.cc",
- "*_ios.mm",
- "*_ios_unittest.h",
- "*_ios_unittest.cc",
- "*_ios_unittest.mm",
- "*\bios/*",
- ]
-}
-if (!is_mac && !is_ios) {
- sources_assignment_filter += [ "*.mm" ]
-}
-if (!is_linux) {
- sources_assignment_filter += [
- "*_linux.h",
- "*_linux.cc",
- "*_linux_unittest.h",
- "*_linux_unittest.cc",
- "*\blinux/*",
- ]
-}
-if (!is_android) {
- sources_assignment_filter += [
- "*_android.h",
- "*_android.cc",
- "*_android_unittest.h",
- "*_android_unittest.cc",
- "*\bandroid/*",
- ]
-}
-if (!is_chromeos) {
- sources_assignment_filter += [
- "*_chromeos.h",
- "*_chromeos.cc",
- "*_chromeos_unittest.h",
- "*_chromeos_unittest.cc",
- "*\bchromeos/*",
- ]
-}
-
-# DO NOT ADD MORE PATTERNS TO THIS LIST, see set_sources_assignment_filter call
-# below.
-
-# Actually save this list.
-#
-# These patterns are executed for every file in the source tree of every run.
-# Therefore, adding more patterns slows down the build for everybody. We should
-# only add automatic patterns for configurations affecting hundreds of files
-# across many projects in the tree.
-#
-# Therefore, we only add rules to this list corresponding to platforms on the
-# Chromium waterfall. This is not for non-officially-supported platforms
-# (FreeBSD, etc.) toolkits, (X11, GTK, etc.), or features. For these cases,
-# write a conditional in the target to remove the file(s) from the list when
-# your platform/toolkit/feature doesn't apply.
-set_sources_assignment_filter(sources_assignment_filter)
-
-# =============================================================================
# BUILD OPTIONS
# =============================================================================
@@ -393,7 +210,6 @@
# Holds all configs used for making native executables and libraries, to avoid
# duplication in each target below.
_native_compiler_configs = [
- "//build/config:feature_flags",
"//build/config/compiler:compiler",
"//build/config/compiler:compiler_arm_fpu",
"//build/config/compiler:chromium_code",
@@ -413,18 +229,13 @@
if (is_posix) {
_native_compiler_configs += [
"//build/config/gcc:no_exceptions",
- "//build/config/gcc:symbol_visibility_hidden",
]
}
-if (is_fnl) {
- _native_compiler_configs += [ "//build/config/fnl:sdk" ]
-} else if (is_linux) {
+if (is_linux) {
_native_compiler_configs += [ "//build/config/linux:sdk" ]
} else if (is_mac) {
_native_compiler_configs += [ "//build/config/mac:sdk" ]
-} else if (is_ios) {
- _native_compiler_configs += [ "//build/config/ios:sdk" ]
} else if (is_android) {
_native_compiler_configs += [ "//build/config/android:sdk" ]
}
@@ -440,36 +251,18 @@
if (is_debug) {
_native_compiler_configs += [ "//build/config:debug" ]
_default_optimization_config = "//build/config/compiler:no_optimize"
-} else {
+} else if (is_release) {
_native_compiler_configs += [ "//build/config:release" ]
_default_optimization_config = "//build/config/compiler:optimize"
+} else {
+ assert(is_product)
+ _native_compiler_configs += [ "//build/config:product" ]
+ _default_optimization_config = "//build/config/compiler:optimize"
}
_native_compiler_configs += [ _default_optimization_config ]
-# If it wasn't manually set, set to an appropriate default.
-if (symbol_level == -1) {
- # Linux is slowed by having symbols as part of the target binary, whereas
- # Mac and Windows have them separate, so in Release Linux, default them off.
- if (is_debug || !is_linux) {
- symbol_level = 2
- } else if (is_asan || is_lsan || is_tsan || is_msan) {
- # Sanitizers require symbols for filename suppressions to work.
- symbol_level = 1
- } else {
- symbol_level = 0
- }
-}
-
# Symbol setup.
-if (symbol_level == 2) {
- _default_symbols_config = "//build/config/compiler:symbols"
-} else if (symbol_level == 1) {
- _default_symbols_config = "//build/config/compiler:minimal_symbols"
-} else if (symbol_level == 0) {
- _default_symbols_config = "//build/config/compiler:no_symbols"
-} else {
- assert(false, "Bad value for symbol_level.")
-}
+_default_symbols_config = "//build/config/compiler:symbols"
_native_compiler_configs += [ _default_symbols_config ]
# Windows linker setup for EXEs and DLLs.
@@ -486,8 +279,7 @@
}
# Executable defaults.
-_executable_configs =
- _native_compiler_configs + [ "//build/config:default_libs" ]
+_executable_configs = _native_compiler_configs
if (is_win) {
_executable_configs += _windows_linker_configs
} else if (is_mac) {
@@ -511,8 +303,7 @@
}
# Shared library defaults (also for components in component mode).
-_shared_library_configs =
- _native_compiler_configs + [ "//build/config:default_libs" ]
+_shared_library_configs = _native_compiler_configs
if (is_win) {
_shared_library_configs += _windows_linker_configs
} else if (is_mac) {
@@ -526,29 +317,13 @@
set_defaults("shared_library") {
configs = _shared_library_configs
}
-if (is_component_build) {
- set_defaults("component") {
- configs = _shared_library_configs
- }
-}
# Source set defaults (also for components in non-component mode).
set_defaults("source_set") {
configs = _native_compiler_configs
}
-if (!is_component_build) {
- set_defaults("component") {
- configs = _native_compiler_configs
- }
-}
-
-# Test defaults.
-set_defaults("test") {
- if (is_android) {
- configs = _shared_library_configs
- } else {
- configs = _executable_configs
- }
+set_defaults("component") {
+ configs = _native_compiler_configs
}
# ==============================================================================
@@ -570,7 +345,6 @@
set_default_toolchain("$host_toolchain")
} else if (is_android) {
if (host_os == "linux") {
- # Use clang for the x86/64 Linux host builds.
if (host_cpu == "x86" || host_cpu == "x64") {
host_toolchain = "//build/toolchain/linux:clang_$host_cpu"
} else {
@@ -594,234 +368,108 @@
host_toolchain = "//build/toolchain/linux:$host_cpu"
set_default_toolchain("//build/toolchain/linux:$current_cpu")
}
- if (is_chromeos && cros_use_custom_toolchain) {
- set_default_toolchain("//build/toolchain/cros:target")
- }
- if (is_fnl) {
- set_default_toolchain("//build/toolchain/fnl:target")
- }
} else if (is_mac) {
host_toolchain = "//build/toolchain/mac:clang_x64"
set_default_toolchain(host_toolchain)
-} else if (is_ios) {
- host_toolchain = "//build/toolchain/mac:clang_x64"
- if (use_ios_simulator) {
- set_default_toolchain("//build/toolchain/mac:ios_clang_x64")
- } else {
- set_default_toolchain("//build/toolchain/mac:ios_clang_arm")
- }
-} else if (is_nacl) {
- # TODO(GYP): This will need to change when we get NaCl working
- # on multiple platforms, but this whole block of code (how we define
- # host_toolchain) needs to be reworked regardless to key off of host_os
- # and host_cpu rather than the is_* variables.
- host_toolchain = "//build/toolchain/linux:clang_x64"
}
# ==============================================================================
# COMPONENT SETUP
# ==============================================================================
-# TODO(brettw) erase this once the built-in "component" function is removed.
-if (is_component_build) {
- component_mode = "shared_library"
-} else {
- component_mode = "source_set"
-}
+# Don't try to do component builds for the standalone Dart VM.
+assert(!is_component_build)
+component_mode = "source_set"
template("component") {
- if (is_component_build) {
- shared_library(target_name) {
- # Configs will always be defined since we set_defaults for a component
- # above. We want to use those rather than whatever came with the nested
- # shared/static library inside the component.
- configs = [] # Prevent list overwriting warning.
- configs = invoker.configs
+ source_set(target_name) {
+ # See above.
+ configs = [] # Prevent list overwriting warning.
+ configs = invoker.configs
- # The sources assignment filter will have already been applied when the
- # code was originally executed. We don't want to apply it again, since
- # the original target may have override it for some assignments.
- set_sources_assignment_filter([])
+ # See above call.
+ set_sources_assignment_filter([])
- if (defined(invoker.all_dependent_configs)) {
- all_dependent_configs = invoker.all_dependent_configs
- }
- if (defined(invoker.allow_circular_includes_from)) {
- allow_circular_includes_from = invoker.allow_circular_includes_from
- }
- if (defined(invoker.cflags)) {
- cflags = invoker.cflags
- }
- if (defined(invoker.cflags_c)) {
- cflags_c = invoker.cflags_c
- }
- if (defined(invoker.cflags_cc)) {
- cflags_cc = invoker.cflags_cc
- }
- if (defined(invoker.cflags_objc)) {
- cflags_objc = invoker.cflags_objc
- }
- if (defined(invoker.cflags_objcc)) {
- cflags_objcc = invoker.cflags_objcc
- }
- if (defined(invoker.check_includes)) {
- check_includes = invoker.check_includes
- }
- if (defined(invoker.data)) {
- data = invoker.data
- }
- if (defined(invoker.data_deps)) {
- data_deps = invoker.data_deps
- }
- if (defined(invoker.datadeps)) {
- datadeps = invoker.datadeps
- }
- if (defined(invoker.defines)) {
- defines = invoker.defines
- }
-
- # All shared libraries must have the sanitizer deps to properly link in
- # asan mode (this target will be empty in other cases).
- if (defined(invoker.deps)) {
- deps = invoker.deps + [ "//build/config/sanitizers:deps" ]
- } else {
- deps = [
- "//build/config/sanitizers:deps",
- ]
- }
- if (defined(invoker.direct_dependent_configs)) {
- direct_dependent_configs = invoker.direct_dependent_configs
- }
- if (defined(invoker.forward_dependent_configs_from)) {
- forward_dependent_configs_from = invoker.forward_dependent_configs_from
- }
- if (defined(invoker.include_dirs)) {
- include_dirs = invoker.include_dirs
- }
- if (defined(invoker.ldflags)) {
- ldflags = invoker.ldflags
- }
- if (defined(invoker.lib_dirs)) {
- lib_dirs = invoker.lib_dirs
- }
- if (defined(invoker.libs)) {
- libs = invoker.libs
- }
- if (defined(invoker.output_extension)) {
- output_extension = invoker.output_extension
- }
- if (defined(invoker.output_name)) {
- output_name = invoker.output_name
- }
- if (defined(invoker.public)) {
- public = invoker.public
- }
- if (defined(invoker.public_configs)) {
- public_configs = invoker.public_configs
- }
- if (defined(invoker.public_deps)) {
- public_deps = invoker.public_deps
- }
- if (defined(invoker.sources)) {
- sources = invoker.sources
- }
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
- if (defined(invoker.visibility)) {
- visibility = invoker.visibility
- }
+ if (defined(invoker.all_dependent_configs)) {
+ all_dependent_configs = invoker.all_dependent_configs
}
- } else {
- source_set(target_name) {
- # See above.
- configs = [] # Prevent list overwriting warning.
- configs = invoker.configs
-
- # See above call.
- set_sources_assignment_filter([])
-
- if (defined(invoker.all_dependent_configs)) {
- all_dependent_configs = invoker.all_dependent_configs
- }
- if (defined(invoker.allow_circular_includes_from)) {
- allow_circular_includes_from = invoker.allow_circular_includes_from
- }
- if (defined(invoker.cflags)) {
- cflags = invoker.cflags
- }
- if (defined(invoker.cflags_c)) {
- cflags_c = invoker.cflags_c
- }
- if (defined(invoker.cflags_cc)) {
- cflags_cc = invoker.cflags_cc
- }
- if (defined(invoker.cflags_objc)) {
- cflags_objc = invoker.cflags_objc
- }
- if (defined(invoker.cflags_objcc)) {
- cflags_objcc = invoker.cflags_objcc
- }
- if (defined(invoker.check_includes)) {
- check_includes = invoker.check_includes
- }
- if (defined(invoker.data)) {
- data = invoker.data
- }
- if (defined(invoker.data_deps)) {
- data_deps = invoker.data_deps
- }
- if (defined(invoker.datadeps)) {
- datadeps = invoker.datadeps
- }
- if (defined(invoker.defines)) {
- defines = invoker.defines
- }
- if (defined(invoker.deps)) {
- deps = invoker.deps
- }
- if (defined(invoker.direct_dependent_configs)) {
- direct_dependent_configs = invoker.direct_dependent_configs
- }
- if (defined(invoker.forward_dependent_configs_from)) {
- forward_dependent_configs_from = invoker.forward_dependent_configs_from
- }
- if (defined(invoker.include_dirs)) {
- include_dirs = invoker.include_dirs
- }
- if (defined(invoker.ldflags)) {
- ldflags = invoker.ldflags
- }
- if (defined(invoker.lib_dirs)) {
- lib_dirs = invoker.lib_dirs
- }
- if (defined(invoker.libs)) {
- libs = invoker.libs
- }
- if (defined(invoker.output_extension)) {
- output_extension = invoker.output_extension
- }
- if (defined(invoker.output_name)) {
- output_name = invoker.output_name
- }
- if (defined(invoker.public)) {
- public = invoker.public
- }
- if (defined(invoker.public_configs)) {
- public_configs = invoker.public_configs
- }
- if (defined(invoker.public_deps)) {
- public_deps = invoker.public_deps
- }
- if (defined(invoker.sources)) {
- sources = invoker.sources
- }
- if (defined(invoker.testonly)) {
- testonly = invoker.testonly
- }
- if (defined(invoker.visibility)) {
- visibility = invoker.visibility
- }
+ if (defined(invoker.allow_circular_includes_from)) {
+ allow_circular_includes_from = invoker.allow_circular_includes_from
+ }
+ if (defined(invoker.cflags)) {
+ cflags = invoker.cflags
+ }
+ if (defined(invoker.cflags_c)) {
+ cflags_c = invoker.cflags_c
+ }
+ if (defined(invoker.cflags_cc)) {
+ cflags_cc = invoker.cflags_cc
+ }
+ if (defined(invoker.cflags_objc)) {
+ cflags_objc = invoker.cflags_objc
+ }
+ if (defined(invoker.cflags_objcc)) {
+ cflags_objcc = invoker.cflags_objcc
+ }
+ if (defined(invoker.check_includes)) {
+ check_includes = invoker.check_includes
+ }
+ if (defined(invoker.data)) {
+ data = invoker.data
+ }
+ if (defined(invoker.data_deps)) {
+ data_deps = invoker.data_deps
+ }
+ if (defined(invoker.datadeps)) {
+ datadeps = invoker.datadeps
+ }
+ if (defined(invoker.defines)) {
+ defines = invoker.defines
+ }
+ if (defined(invoker.deps)) {
+ deps = invoker.deps
+ }
+ if (defined(invoker.direct_dependent_configs)) {
+ direct_dependent_configs = invoker.direct_dependent_configs
+ }
+ if (defined(invoker.forward_dependent_configs_from)) {
+ forward_dependent_configs_from = invoker.forward_dependent_configs_from
+ }
+ if (defined(invoker.include_dirs)) {
+ include_dirs = invoker.include_dirs
+ }
+ if (defined(invoker.ldflags)) {
+ ldflags = invoker.ldflags
+ }
+ if (defined(invoker.lib_dirs)) {
+ lib_dirs = invoker.lib_dirs
+ }
+ if (defined(invoker.libs)) {
+ libs = invoker.libs
+ }
+ if (defined(invoker.output_extension)) {
+ output_extension = invoker.output_extension
+ }
+ if (defined(invoker.output_name)) {
+ output_name = invoker.output_name
+ }
+ if (defined(invoker.public)) {
+ public = invoker.public
+ }
+ if (defined(invoker.public_configs)) {
+ public_configs = invoker.public_configs
+ }
+ if (defined(invoker.public_deps)) {
+ public_deps = invoker.public_deps
+ }
+ if (defined(invoker.sources)) {
+ sources = invoker.sources
+ }
+ if (defined(invoker.testonly)) {
+ testonly = invoker.testonly
+ }
+ if (defined(invoker.visibility)) {
+ visibility = invoker.visibility
}
}
}
diff --git a/build/config/allocator.gni b/build/config/allocator.gni
deleted file mode 100644
index 71418a8..0000000
--- a/build/config/allocator.gni
+++ /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.
-
-# TODO(GYP): Make tcmalloc work on win.
-if (is_android || current_cpu == "mipsel" || is_mac || is_ios || is_asan ||
- is_lsan || is_tsan || is_msan || is_win) {
- _default_allocator = "none"
-} else {
- _default_allocator = "tcmalloc"
-}
-
-declare_args() {
- # Memory allocator to use. Set to "none" to use default allocator.
- use_allocator = _default_allocator
-}
diff --git a/build/config/android/config.gni b/build/config/android/config.gni
index 5457b88..a16407b 100644
--- a/build/config/android/config.gni
+++ b/build/config/android/config.gni
@@ -51,10 +51,8 @@
# Defines the name the Android build gives to the current host CPU
# architecture, which is different than the names GN uses.
- if (host_cpu == "x64") {
+ if ((host_cpu == "x64") || (host_cpu == "x86")) {
android_host_arch = "x86_64"
- } else if (host_cpu == "x86") {
- android_host_arch = "x86"
} else {
assert(false, "Need Android toolchain support for your build CPU arch.")
}
diff --git a/build/config/chrome_build.gni b/build/config/chrome_build.gni
deleted file mode 100644
index c2132c4..0000000
--- a/build/config/chrome_build.gni
+++ /dev/null
@@ -1,19 +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() {
- # Selects the desired build flavor. Official builds get additional
- # processing to prepare for release. Normally you will want to develop and
- # test with this flag off.
- is_official_build = false
-
- # Select the desired branding flavor. False means normal Chromium branding,
- # true means official Google Chrome branding (requires extra Google-internal
- # resources).
- is_chrome_branded = false
-
- # Break chrome.dll into multple pieces based on process type. Only available
- # on Windows.
- is_multi_dll_chrome = is_win && !is_component_build
-}
diff --git a/build/config/clang/clang.gni b/build/config/clang/clang.gni
index cb84879..3893ca3 100644
--- a/build/config/clang/clang.gni
+++ b/build/config/clang/clang.gni
@@ -5,5 +5,5 @@
declare_args() {
# Indicates if the build should use the Chrome-specific plugins for enforcing
# coding guidelines, etc. Only used when compiling with Clang.
- clang_use_chrome_plugins = is_clang && !is_nacl
+ clang_use_chrome_plugins = false
}
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index 04d4bd9..5bc242f 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -3,7 +3,6 @@
# found in the LICENSE file.
import("//build/config/android/config.gni")
-import("//build/config/chrome_build.gni")
if (current_cpu == "arm") {
import("//build/config/arm.gni")
}
@@ -21,39 +20,6 @@
import("//build/config/sanitizers/sanitizers.gni")
declare_args() {
- # Normally, Android builds are lightly optimized, even for debug builds, to
- # keep binary size down. Setting this flag to true disables such optimization
- android_full_debug = false
-
- # 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 that are currently checked in). Turn this off when
- # you are using a custom toolchain and need to control -B in cflags.
- linux_use_bundled_binutils = is_linux && current_cpu == "x64"
-
- # Compile in such a way as to enable profiling of the generated code. For
- # example, don't omit the frame pointer and leave in symbols.
- enable_profiling = false
-
- # Compile in such a way as to make it possible for the profiler to unwind full
- # stack frames. Setting this flag has a large effect on the performance of the
- # generated code than just setting profiling, but gives the profiler more
- # information to analyze.
- # Requires profiling to be set to true.
- enable_full_stack_frames_for_profiling = false
-
- # Use gold for linking on 64-bit Linux only (on 32-bit it runs out of
- # address space, and it doesn't support cross-compiling).
- use_gold = is_linux && current_cpu == "x64"
-
- # 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
- use_debug_fission = is_debug && !is_win && use_gold &&
- linux_use_bundled_binutils && !use_ccache
-
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).
@@ -143,28 +109,20 @@
} else {
# Common GCC compiler flags setup.
# --------------------------------
- cflags += [ "-fno-strict-aliasing" ] # See http://crbug.com/32204
common_flags = [
# Not exporting C++ inline functions can generally be applied anywhere
# so we do so here. Normal function visibility is controlled by
# //build/config/gcc:symbol_visibility_hidden.
"-fvisibility-inlines-hidden",
+
+ # We need the frame pointer for CPU and heap profiling.
+ "-fno-omit-frame-pointer",
]
cflags_cc += common_flags
cflags_objcc += common_flags
- # Stack protection.
- if (is_mac) {
- cflags += [ "-fstack-protector-all" ]
- } else if (is_linux) {
- cflags += [
- "-fstack-protector",
- "--param=ssp-buffer-size=4",
- ]
- }
-
# Linker warnings.
- if (!(is_chromeos && current_cpu == "arm") && !is_mac && !is_ios) {
+ if ((current_cpu != "arm") && !is_mac) {
# TODO(jochen): Enable this on chromeos on arm. http://crbug.com/356580
ldflags += [ "-Wl,--fatal-warnings" ]
}
@@ -173,7 +131,6 @@
# MemorySanitizer
if (using_sanitizer) {
cflags += [
- "-fno-omit-frame-pointer",
"-gline-tables-only",
]
}
@@ -217,11 +174,6 @@
"//buildtools/third_party/libc++abi/trunk/include",
]
}
-
- if (is_fnl) {
- # TODO(kulakowski) remove when fnl no longer uses gcc
- cflags += [ "-Wno-maybe-uninitialized" ]
- }
}
if (is_clang && is_debug) {
@@ -237,7 +189,7 @@
cflags_objcc += extra_flags
}
- if (is_clang && !is_nacl) {
+ if (is_clang) {
# 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 system rebuild things when their commandline changes). Nothing
@@ -250,9 +202,9 @@
# Mac-specific compiler flags setup.
# ----------------------------------
- if (is_mac || is_ios) {
+ if (is_mac) {
# These flags are shared between the C compiler and linker.
- common_mac_flags = []
+ common_mac_flags = [ "-fno-exceptions" ]
# CPU architecture.
if (current_cpu == "x64") {
@@ -293,16 +245,21 @@
cflags += [
"-m64",
"-march=x86-64",
+ "-msse2",
]
ldflags += [ "-m64" ]
} else if (current_cpu == "x86") {
- cflags += [ "-m32" ]
+ cflags += [
+ "-m32",
+ "-msse2",
+ "-mfpmath=sse",
+ ]
ldflags += [ "-m32" ]
if (is_clang) {
cflags += [
# Else building libyuv gives clang's register allocator issues,
# see llvm.org/PR15798 / crbug.com/233709
- "-momit-leaf-frame-pointer",
+ "-mno-omit-leaf-frame-pointer",
# Align the stack on 16-byte boundaries, http://crbug.com/418554.
"-mstack-alignment=16",
@@ -310,6 +267,7 @@
]
}
} else if (current_cpu == "arm") {
+
cflags += [
"-march=$arm_arch",
"-mfloat-abi=$arm_float_abi",
@@ -339,6 +297,15 @@
]
}
} else if (current_cpu == "mipsel") {
+ # We have to explicitly request exceptions to get good heap profiles from
+ # tcmalloc.
+ if (is_debug || is_release) {
+ cflags += [
+ "-fexceptions",
+ "-funwind-tables"
+ ]
+ }
+
if (mips_arch_variant == "r6") {
cflags += [
"-mips32r6",
@@ -388,44 +355,8 @@
}
}
- defines += [ "_FILE_OFFSET_BITS=64" ]
-
- if (!is_android) {
- defines += [
- "_LARGEFILE_SOURCE",
- "_LARGEFILE64_SOURCE",
- ]
- }
-
- # Omit unwind support in official builds to save space. We can use breakpad
- # for these builds.
- if (is_chrome_branded && is_official_build) {
- cflags += [
- "-fno-unwind-tables",
- "-fno-asynchronous-unwind-tables",
- ]
- defines += [ "NO_UNWIND_TABLES" ]
- } else {
- cflags += [ "-funwind-tables" ]
- }
- }
-
- if (enable_profiling && !is_debug) {
- # The GYP build spams this define into every compilation unit, as we do
- # here, but it only appears to be used in base and a couple other places.
- # TODO(abarth): Should we move this define closer to where it's used?
- defines += [ "ENABLE_PROFILING" ]
-
- cflags += [
- "-fno-omit-frame-pointer",
- "-g",
- ]
-
- if (enable_full_stack_frames_for_profiling) {
- cflags += [
- "-fno-inline",
- "-fno-optimize-sibling-calls",
- ]
+ if (current_cpu != "mipsel") {
+ cflags += [ "-fno-exceptions" ]
}
}
@@ -434,7 +365,6 @@
if (is_linux || is_android) {
cflags += [
"-fPIC",
- "-pipe", # Use pipes for communicating between sub-processes. Faster.
]
ldflags += [
@@ -443,9 +373,6 @@
"-Wl,-z,now",
"-Wl,-z,relro",
]
- if (!using_sanitizer) {
- ldflags += [ "-Wl,-z,defs" ]
- }
}
# Linux-specific compiler flags setup.
@@ -454,46 +381,6 @@
cflags += [ "-pthread" ]
ldflags += [ "-pthread" ]
}
- if (use_gold) {
- gold_path = rebase_path("//third_party/binutils/Linux_x64/Release/bin",
- root_build_dir)
- ldflags += [
- "-B$gold_path",
-
- # 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
- "-fuse-ld=gold",
-
- # 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",
- ]
-
- if (!is_asan && !is_msan && !is_lsan && !is_tsan) {
- # TODO(brettw) common.gypi has this only for target toolset.
- ldflags += [ "-Wl,--icf=all" ]
- }
-
- # TODO(thestig): Make this flag work with GN.
- #if (!is_official_build && !is_chromeos && !(is_asan || is_lsan || is_tsan || is_msan)) {
- # ldflags += [
- # "-Wl,--detect-odr-violations",
- # ]
- #}
- }
-
- if (linux_use_bundled_binutils) {
- binutils_path = rebase_path("//third_party/binutils/Linux_x64/Release/bin",
- root_build_dir)
- cflags += [ "-B$binutils_path" ]
- }
# Clang-specific compiler flags setup.
# ------------------------------------
@@ -501,20 +388,6 @@
cflags += [ "-fcolor-diagnostics" ]
}
- # C++11 compiler flags setup.
- # ---------------------------
- if (is_linux || is_android || is_nacl) {
- # 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
- cflags_cc += [ "-std=gnu++11" ]
- } else if (!is_win) {
- cc_std = [ "-std=c++11" ]
- cflags_cc += cc_std
- cflags_objcc += cc_std
- }
-
# Android-specific flags setup.
# -----------------------------
if (is_android) {
@@ -552,17 +425,10 @@
}
ldflags += [
- "-Wl,--no-undefined",
-
# 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=libvpx_assembly_arm.a",
]
if (current_cpu == "arm") {
ldflags += [
@@ -584,7 +450,7 @@
}
config("compiler_arm_fpu") {
- if (current_cpu == "arm" && !is_ios) {
+ if (current_cpu == "arm") {
cflags = [ "-mfpu=$arm_fpu" ]
}
}
@@ -833,19 +699,11 @@
# TODO(abarth): Re-enable once https://github.com/domokit/mojo/issues/728
# is fixed.
# default_warning_flags += [ "-Wnewline-eof" ]
- if (!is_nacl) {
- # When compiling Objective-C, warns if a method is used whose
- # availability is newer than the deployment target. This is not
- # required when compiling Chrome for iOS.
- default_warning_flags += [ "-Wpartial-availability" ]
- }
- }
- if (gcc_version >= 48) {
- default_warning_flags_cc += [
- # See comment for -Wno-c++11-narrowing.
- "-Wno-narrowing",
- ]
+ # When compiling Objective-C, warns if a method is used whose
+ # availability is newer than the deployment target. This is not
+ # required when compiling Chrome for iOS.
+ default_warning_flags += [ "-Wpartial-availability" ]
}
# Suppress warnings about ABI changes on ARM (Clang doesn't give this
@@ -883,43 +741,6 @@
default_warning_flags += [ "-Wno-unused-local-typedefs" ]
}
}
-if (is_clang) {
- default_warning_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",
-
- # 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.
- # TODO(brettw) move this to that project then!
- "-Wno-char-subscripts",
-
- # 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",
-
- # 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",
- ]
-
- # NaCl's Clang compiler and Chrome's hermetic Clang compiler will almost
- # always have different versions. Certain flags may not be recognized by
- # one version or the other.
- if (!is_nacl) {
- # Flags NaCl does not recognize.
- default_warning_flags += [
- # 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",
- ]
- }
-}
# chromium_code ---------------------------------------------------------------
#
@@ -935,14 +756,8 @@
"-Wextra",
]
- # 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",
- ]
-
- if (!using_sanitizer && (!is_linux || !is_clang || is_official_build)) {
+ defines = []
+ if (!using_sanitizer && (!is_linux || !is_clang)) {
# _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
@@ -975,37 +790,6 @@
]
}
- if (is_linux) {
- # 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.
- cflags += [ "-Wno-unused-result" ]
- }
-
- if (is_clang) {
- cflags += [
- # 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",
- ]
- }
-
- if (is_linux || is_android) {
- 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 += [
- # Don't warn about hash_map in third-party code.
- "-Wno-deprecated",
- ]
- }
cflags += default_warning_flags
cflags_cc += default_warning_flags_cc
}
@@ -1029,34 +813,6 @@
}
}
-# Warnings ---------------------------------------------------------------------
-
-# This will generate warnings when using Clang if code generates exit-time
-# destructors, which will slow down closing the program.
-# TODO(thakis): Make this a blacklist instead, http://crbug.com/101600
-config("wexit_time_destructors") {
- # TODO: Enable on Windows too, http://crbug.com/404525
- if (is_clang && !is_win) {
- cflags = [ "-Wexit-time-destructors" ]
- }
-}
-
-# On Windows compiling on x64, VC will issue a warning when converting
-# size_t to int because it will truncate the value. Our code should not have
-# these warnings and one should use a static_cast or a checked_cast for the
-# conversion depending on the case. However, a lot of code still needs to be
-# fixed. Apply this config to such targets to disable the warning.
-#
-# Note that this can be applied regardless of platform and architecture to
-# clean up the call sites. This will only apply the flag when necessary.
-#
-# TODO(jschuh): crbug.com/167187 fix this and delete this config.
-config("no_size_t_to_int_warning") {
- if (is_win && current_cpu == "x64") {
- cflags = [ "/wd4267" ]
- }
-}
-
# Optimization -----------------------------------------------------------------
#
# Note that BUILDCONFIG.gn sets up a variable "default_optimization_config"
@@ -1066,9 +822,9 @@
# add back the one you want to override it with:
#
# configs -= default_optimization_config
-# configs += [ "//build/config/compiler/optimize_max" ]
+# configs += [ ":optimize_max" ]
-# Shared settings for both "optimize" and "optimize_max" configs.
+# Shared settings.
# IMPORTANT: On Windows "/O1" and "/O2" must go before the common flags.
if (is_win) {
common_optimize_on_cflags = [
@@ -1100,25 +856,15 @@
common_optimize_on_ldflags = []
if (is_android) {
- if (!using_sanitizer) {
- common_optimize_on_cflags += [ "-fomit-frame-pointer" ]
- }
-
- # TODO(jdduke) Re-enable on mips after resolving linking
- # issues with libc++ (crbug.com/456380).
- if (current_cpu != "mipsel" && current_cpu != "mips64el") {
- common_optimize_on_ldflags += [
- # Warn in case of text relocations.
- "-Wl,--warn-shared-textrel",
- ]
- }
+ common_optimize_on_ldflags += [
+ # Warn in case of text relocations.
+ "-Wl,--warn-shared-textrel",
+ ]
}
- if (is_mac || is_ios) {
- if (symbol_level == 2) {
- # Mac dead code stripping requires symbols.
- common_optimize_on_ldflags += [ "-Wl,-dead_strip" ]
- }
+ if (is_mac) {
+ # Mac dead code stripping requires symbols.
+ common_optimize_on_ldflags += [ "-Wl,-dead_strip" ]
} else {
# Non-Mac Posix linker flags.
common_optimize_on_ldflags += [
@@ -1143,10 +889,10 @@
# Favor size over speed, /O1 must be before the common flags. The GYP
# build also specifies /Os and /GF but these are implied by /O1.
cflags = [ "/O1" ] + common_optimize_on_cflags + [ "/Oi" ]
- } else if (is_android || is_ios) {
+ } else if (is_android) {
cflags = [ "-Os" ] + common_optimize_on_cflags # Favor size over speed.
} else {
- cflags = [ "-O2" ] + common_optimize_on_cflags
+ cflags = [ "-O3" ] + common_optimize_on_cflags
}
ldflags = common_optimize_on_ldflags
}
@@ -1159,7 +905,7 @@
"/Ob0", # Disable all inlining (on by default).
"/RTC1", # Runtime checks for stack frame and uninitialized variables.
]
- } else if (is_android && !android_full_debug) {
+ } else if (is_android) {
# On Android we kind of optimize some things that don't affect debugging
# much even when optimization is disabled to get the binary size down.
cflags = [
@@ -1167,41 +913,13 @@
"-fdata-sections",
"-ffunction-sections",
]
- if (!using_sanitizer) {
- cflags += [ "-fomit-frame-pointer" ]
- }
ldflags = common_optimize_on_ldflags
} else {
- cflags = [ "-O0" ]
- }
-}
-
-# Turns up the optimization level. On Windows, this implies whole program
-# optimization and link-time code generation which is very expensive and should
-# be used sparingly.
-config("optimize_max") {
- ldflags = common_optimize_on_ldflags
- if (is_win) {
- # Favor speed over size, /O2 must be before the common flags. The GYP
- # build also specifies /Ot, /Oi, and /GF, but these are implied by /O2.
- cflags = [ "/O2" ] + common_optimize_on_cflags
- if (is_official_build) {
- # TODO(GYP): TODO(dpranke): Should these only be on in an official
- # build, or on all the time? For now we'll require official build so
- # that the compile is clean.
- cflags += [
- "/GL", # Whole program optimization.
-
- # 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.
- "/wd4702",
- ]
- ldflags += [ "/LTCG" ]
- }
- } else {
- cflags = [ "-O2" ] + common_optimize_on_cflags
+ cflags = [
+ "-O1",
+ "-fdata-sections",
+ "-ffunction-sections",
+ ]
}
}
@@ -1217,27 +935,9 @@
}
ldflags = [ "/DEBUG" ]
} else {
- cflags = [ "-g2" ]
- if (use_debug_fission) {
- cflags += [ "-gsplit-dwarf" ]
- }
- }
-}
-
-config("minimal_symbols") {
- if (is_win) {
- # Linker symbols for backtraces only.
- ldflags = [ "/DEBUG" ]
- } else {
- cflags = [ "-g1" ]
- if (use_debug_fission) {
- cflags += [ "-gsplit-dwarf" ]
- }
- }
-}
-
-config("no_symbols") {
- if (!is_win) {
- cflags = [ "-g0" ]
+ cflags = [
+ "-g3",
+ "-ggdb3",
+ ]
}
}
diff --git a/build/config/crypto.gni b/build/config/crypto.gni
deleted file mode 100644
index 2cd72d3..0000000
--- a/build/config/crypto.gni
+++ /dev/null
@@ -1,29 +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 declares build flags for the SSL library configuration.
-#
-# TODO(brettw) this should probably be moved to src/crypto or somewhere, and
-# the global build dependency on it should be removed.
-#
-# PLEASE TRY TO AVOID ADDING FLAGS TO THIS FILE in cases where grit isn't
-# required. See the declare_args block of BUILDCONFIG.gn for advice on how
-# to set up feature flags.
-
-declare_args() {
- # Use OpenSSL instead of NSS. This is used for all platforms but iOS. (See
- # http://crbug.com/338886).
- use_openssl = !is_ios
-}
-
-# True when we're using 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 = is_android
-
-# True if NSS is used for certificate verification. Note that this is
-# independent from use_openssl. It is possible to use OpenSSL for the crypto
-# library, but NSS for the platform certificate library.
-use_nss_certs = false
diff --git a/build/config/features.gni b/build/config/features.gni
deleted file mode 100644
index 93b19dd..0000000
--- a/build/config/features.gni
+++ /dev/null
@@ -1,204 +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 contains Chrome-feature-related build flags (see ui.gni for
-# UI-related ones). These should theoretically be moved to the build files of
-# the features themselves.
-#
-# However, today we have many "bad" dependencies on some of these flags from,
-# e.g. base, so they need to be global to match the GYP configuration. Also,
-# anything that needs a grit define must be in either this file or ui.gni.
-#
-# PLEASE TRY TO AVOID ADDING FLAGS TO THIS FILE in cases where grit isn't
-# required. See the declare_args block of BUILDCONFIG.gn for advice on how
-# to set up feature flags.
-
-import("//build/config/chrome_build.gni")
-if (is_android) {
- import("//build/config/android/config.gni")
-}
-
-declare_args() {
- # Multicast DNS.
- enable_mdns = is_win || is_linux
-
- enable_plugins = !is_android && !is_ios
-
- # Enables Native Client support.
- # TODO(GYP): Get NaCl linking on other platforms.
- # Also, see if we can always get rid of enable_nacl_untrusted and
- # enable_pnacl and always build them if enable_nacl is true.
- # The "is_nacl" part of the condition is needed to ensure that
- # the untrusted code is built properly; arguably it should be
- # guarded by "is_nacl" directly rather than enable_nacl_untrusted, but
- # this will go away when Mac and Win are working and we can just use
- # the commented out logic.
- # Eventually we want this to be:
- # enable_nacl = !is_ios && !is_android
- enable_nacl = (is_linux && !is_chromeos && current_cpu == "x64") || is_nacl
- enable_nacl_untrusted = enable_nacl
- enable_pnacl = enable_nacl_untrusted
-
- # If debug_devtools is set to true, 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 = false
-
- # Enables WebRTC.
- # TODO(GYP) make mac and android work.
- enable_webrtc = !is_ios && !is_mac && !is_android
-
- # Enables the Media Router.
- enable_media_router = !is_ios && !is_android
-
- # Enables proprietary codecs and demuxers; e.g. H264, MOV, AAC, and MP3.
- # Android OS includes support for proprietary codecs regardless of building
- # Chromium or Google Chrome. We also ship Google Chrome and Chromecast with
- # proprietary codecs.
- # TODO(GYP) The GYP build has || chromecast==1 for this:
- proprietary_codecs = is_android || is_chrome_branded
-
- enable_configuration_policy = true
-
- # Enables support for background apps.
- enable_background = !is_ios && !is_android
-
- enable_captive_portal_detection = !is_android && !is_ios
-
- # Enables use of the session service, which is enabled by default.
- # Android stores them separately on the Java side.
- enable_session_service = !is_android && !is_ios
-
- enable_plugin_installation = is_win || is_mac
-
- enable_app_list = !is_ios && !is_android
-
- enable_supervised_users = !is_ios
-
- enable_autofill_dialog = !is_ios
-
- enable_google_now = !is_ios && !is_android
-
- enable_one_click_signin = is_win || is_mac || (is_linux && !is_chromeos)
-
- enable_remoting = !is_ios && !is_android
-
- # Enable hole punching for the protected video.
- enable_video_hole = is_android
-
- # Enables browser side Content Decryption Modules. Required for embedders
- # (e.g. Android and ChromeCast) that use a browser side CDM.
- enable_browser_cdms = is_android
-
- # 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.
- if (is_android) {
- safe_browsing_mode = 2
- } else if (is_ios) {
- safe_browsing_mode = 0
- } else {
- safe_browsing_mode = 1
- }
-}
-
-# Additional dependent variables -----------------------------------------------
-
-# 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.
-if (is_android) {
- cld_version = 1
-} else {
- cld_version = 2
-}
-
-# libudev usage. This currently only affects the content layer.
-use_udev = is_linux
-
-# Enable the spell checker.
-enable_spellcheck = !is_android
-
-# Use the operating system's spellchecker rather than hunspell.
-use_platform_spellchecker = is_android || is_mac
-
-enable_pepper_cdms = enable_plugins && (is_linux || is_mac || is_win)
-
-# Enable basic printing support and UI.
-enable_basic_printing = !is_chromeos
-
-# Enable printing with print preview. It does not imply
-# enable_basic_printing. It's possible to build Chrome with preview only.
-enable_print_preview = !is_android
-
-# The seccomp-bpf sandbox is only supported on three architectures
-# currently.
-# Do not disable seccomp_bpf anywhere without talking to
-# security@chromium.org!
-use_seccomp_bpf = (is_linux || is_android) &&
- (current_cpu == "x86" || current_cpu == "x64" ||
- current_cpu == "arm" || current_cpu == "mipsel")
-
-# Enable notifications everywhere except iOS.
-enable_notifications = !is_ios
-
-# TODO(brettw) this should be moved to net and only dependents get this define.
-disable_ftp_support = is_ios
-
-enable_web_speech = !is_android && !is_ios
-
-use_dbus = is_linux
-
-enable_extensions = !is_android && !is_ios
-
-enable_task_manager = !is_ios && !is_android
-
-use_cups = is_desktop_linux || is_mac
-
-enable_themes = !is_android && !is_ios
-
-# TODO(scottmg) remove this when we've fixed printing.
-win_pdf_metafile_for_printing = true
-
-# 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 = is_win || is_mac || is_ios || is_chromeos
-enable_rlz = is_chrome_branded && enable_rlz_support
-
-enable_settings_app = enable_app_list && !is_chromeos
-
-enable_service_discovery = enable_mdns || is_mac
-
-enable_wifi_bootstrapping = is_win || is_mac
-
-# Image loader extension is enabled on ChromeOS only.
-enable_image_loader_extension = is_chromeos
-
-# Chrome OS: whether to also build the upcoming version of
-# ChromeVox, which can then be enabled via a command-line switch.
-enable_chromevox_next = false
-
-# Use brlapi from brltty for braille display support.
-use_brlapi = is_chromeos
-
-# Option controlling the use of GConf (the classic GNOME configuration
-# system).
-# TODO(GYP) also require !embedded to enable.
-use_gconf = is_linux && !is_chromeos
-
-# Hangout services is an extension that adds extra features to Hangouts.
-# For official GYP builds, this flag is set, it will likely need to be
-# parameterized in the future for a similar use.
-enable_hangout_services_extension = false
-
-# Whether to back up data before sync.
-enable_pre_sync_backup = is_win || is_mac || (is_linux && !is_chromeos)
-
-# WebVR support disabled until platform implementations have been added
-enable_webvr = false
diff --git a/build/config/linux/BUILD.gn b/build/config/linux/BUILD.gn
index 71a73b2..4b02a25 100644
--- a/build/config/linux/BUILD.gn
+++ b/build/config/linux/BUILD.gn
@@ -2,10 +2,7 @@
# 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 != "") {
@@ -22,41 +19,3 @@
"value") ]
}
}
-
-config("fontconfig") {
- libs = [ "fontconfig" ]
-}
-
-pkg_config("freetype2") {
- packages = [ "freetype2" ]
-}
-
-config("x11") {
- libs = [
- "X11",
- "Xcomposite",
- "Xcursor",
- "Xdamage",
- "Xext",
- "Xfixes",
- "Xi",
- "Xrender",
- "Xtst",
- ]
-}
-
-config("xrandr") {
- libs = [ "Xrandr" ]
-}
-
-config("xinerama") {
- libs = [ "Xinerama" ]
-}
-
-config("xcomposite") {
- libs = [ "Xcomposite" ]
-}
-
-config("xext") {
- libs = [ "Xext" ]
-}
diff --git a/build/config/sysroot.gni b/build/config/sysroot.gni
index 5bce02e..37faae0 100644
--- a/build/config/sysroot.gni
+++ b/build/config/sysroot.gni
@@ -5,8 +5,6 @@
# This header file defines the "sysroot" variable which is the absolute path
# of the sysroot. If no sysroot applies, the variable will be an empty string.
-import("//build/config/chrome_build.gni")
-
declare_args() {
# The absolute path of the sysroot that is applied when compiling using
# the target toolchain.
@@ -32,29 +30,9 @@
} else {
sysroot = ""
}
-} else if (is_linux && is_chrome_branded && is_official_build && !is_chromeos) {
- # For official builds, use the sysroot checked into the internal source repo
- # so that the builds work on older versions of Linux.
- if (current_cpu == "x64") {
- sysroot = rebase_path("//build/linux/debian_wheezy_amd64-sysroot")
- } else if (current_cpu == "x86") {
- sysroot = rebase_path("//build/linux/debian_wheezy_i386-sysroot")
- } else {
- # Any other builds don't use a sysroot.
- sysroot = ""
- }
-} else if (is_linux && !is_chromeos) {
- if (current_cpu == "mipsel") {
- sysroot = rebase_path("//mipsel-sysroot/sysroot")
- } else {
- sysroot = ""
- }
} else if (is_mac) {
import("//build/config/mac/mac_sdk.gni")
sysroot = mac_sdk_path
-} else if (is_ios) {
- import("//build/config/ios/ios_sdk.gni")
- sysroot = ios_sdk_path
} else {
sysroot = ""
}
diff --git a/build/config/ui.gni b/build/config/ui.gni
deleted file mode 100644
index c2dff4a..0000000
--- a/build/config/ui.gni
+++ /dev/null
@@ -1,68 +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 contains UI-related build flags. It should theoretically be in the
-# src/ui directory and only things that depend on the ui module should get the
-# definitions.
-#
-# However, today we have many "bad" dependencies on some of these flags from,
-# e.g. base, so they need to be global.
-#
-# See also build/config/features.gni
-
-declare_args() {
- # Indicates if Ash is enabled. Ash is the Aura Shell which provides a
- # desktop-like environment for Aura. Requires use_aura = true
- use_ash = is_win || is_linux
-
- # Indicates if Ozone is enabled. Ozone is a low-level library layer for Linux
- # that does not require X11.
- use_ozone = false
-
- # Indicates if GLFW is enabled. GLFW is an abstraction layer for the
- # windowing system and OpenGL rendering, providing cross-platform support
- # for creating windows and OpenGL surfaces and contexts, and handling
- # window system events and input.
- use_glfw = false
-
- # Support ChromeOS touchpad gestures with ozone.
- use_evdev_gestures = false
-
- # Indicates if Aura is enabled. Aura is a low-level windowing library, sort
- # of a replacement for GDI or GTK.
- use_aura = is_win || is_linux
-
- # True means the UI is built using the "views" framework.
- toolkit_views = is_mac || is_win || is_chromeos || use_aura
-
- # Whether the entire browser uses toolkit-views on Mac instead of Cocoa.
- mac_views_browser = false
-
- # Whether we should use glib, a low level C utility library.
- use_glib = is_linux && !use_ozone
-}
-
-# Additional dependent variables -----------------------------------------------
-#
-# These variables depend on other variables and can't be set externally.
-
-use_cairo = false
-use_pango = false
-
-# Use GPU accelerated cross process image transport by default on linux builds
-# with the Aura window manager.
-ui_compositor_image_transport = use_aura && is_linux
-
-use_default_render_theme = use_aura || is_linux
-
-# Indicates if the UI toolkit depends on X11.
-use_x11 = is_linux && !use_ozone && !use_glfw
-
-use_ozone_evdev = use_ozone
-
-use_clipboard_aurax11 = is_linux && use_aura && use_x11
-
-enable_hidpi = is_mac || is_chromeos || is_win || is_linux
-
-enable_topchrome_md = false
diff --git a/build/config/win/BUILD.gn b/build/config/win/BUILD.gn
index 261a1ac..c939100 100644
--- a/build/config/win/BUILD.gn
+++ b/build/config/win/BUILD.gn
@@ -141,7 +141,7 @@
# config should be applied to large modules to turn off incremental linking
# when it won't work.
config("default_large_module_incremental_linking") {
- if (symbol_level > 0 && (current_cpu == "x86" || !is_component_build)) {
+ if (current_cpu == "x86" || !is_component_build) {
# When symbols are on, things get so large that the tools fail due to the
# size of the .ilk files.
ldflags = incremental_linking_off_switch
diff --git a/build/gyp_chromium b/build/gyp_chromium
deleted file mode 100755
index 9dac871..0000000
--- a/build/gyp_chromium
+++ /dev/null
@@ -1,333 +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 is wrapper for Chromium that adds some support for how GYP
-# is invoked by Chromium beyond what can be done in the gclient hooks.
-
-import argparse
-import glob
-import gyp_environment
-import os
-import re
-import shlex
-import subprocess
-import string
-import sys
-import vs_toolchain
-
-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', 'gyp', 'pylib'))
-import gyp
-
-# Assume this file is in a one-level-deep subdirectory of the source root.
-SRC_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
-
-# Add paths so that pymod_do_main(...) can import files.
-sys.path.insert(1, os.path.join(chrome_src, 'android_webview', 'tools'))
-sys.path.insert(1, os.path.join(chrome_src, 'build', 'android', 'gyp'))
-sys.path.insert(1, os.path.join(chrome_src, 'chrome', 'tools', 'build'))
-sys.path.insert(1, os.path.join(chrome_src, 'chromecast', 'tools', 'build'))
-sys.path.insert(1, os.path.join(chrome_src, 'ios', 'chrome', 'tools', 'build'))
-sys.path.insert(1, os.path.join(chrome_src, 'native_client', 'build'))
-sys.path.insert(1, os.path.join(chrome_src, 'native_client_sdk', 'src',
- 'build_tools'))
-sys.path.insert(1, os.path.join(chrome_src, 'remoting', 'tools', 'build'))
-sys.path.insert(1, os.path.join(chrome_src, 'third_party', 'liblouis'))
-sys.path.insert(1, os.path.join(chrome_src, 'third_party', 'WebKit',
- 'Source', 'build', 'scripts'))
-sys.path.insert(1, os.path.join(chrome_src, 'tools'))
-sys.path.insert(1, os.path.join(chrome_src, 'tools', 'generate_shim_headers'))
-sys.path.insert(1, os.path.join(chrome_src, 'tools', 'grit'))
-
-# On Windows, Psyco shortens warm runs of build/gyp_chromium by about
-# 20 seconds on a z600 machine with 12 GB of RAM, from 90 down to 70
-# seconds. Conversely, memory usage of build/gyp_chromium with Psyco
-# maxes out at about 158 MB vs. 132 MB without it.
-#
-# Psyco uses native libraries, so we need to load a different
-# installation depending on which OS we are running under. It has not
-# been tested whether using Psyco on our Mac and Linux builds is worth
-# it (the GYP running time is a lot shorter, so the JIT startup cost
-# may not be worth it).
-if sys.platform == 'win32':
- try:
- sys.path.insert(0, os.path.join(chrome_src, 'third_party', 'psyco_win32'))
- import psyco
- except:
- psyco = None
-else:
- psyco = None
-
-
-def GetSupplementalFiles():
- """Returns a list of the supplemental files that are included in all GYP
- sources."""
- return glob.glob(os.path.join(chrome_src, '*', 'supplement.gypi'))
-
-
-def ProcessGypDefinesItems(items):
- """Converts a list of strings to a list of key-value pairs."""
- result = []
- for item in items:
- tokens = item.split('=', 1)
- # Some GYP variables have hyphens, which we don't support.
- if len(tokens) == 2:
- result += [(tokens[0], tokens[1])]
- else:
- # No value supplied, treat it as a boolean and set it. Note that we
- # use the string '1' here so we have a consistent definition whether
- # you do 'foo=1' or 'foo'.
- result += [(tokens[0], '1')]
- return result
-
-
-def GetGypVars(supplemental_files):
- """Returns a dictionary of all GYP vars."""
- # Find the .gyp directory in the user's home directory.
- home_dot_gyp = os.environ.get('GYP_CONFIG_DIR', None)
- if home_dot_gyp:
- home_dot_gyp = os.path.expanduser(home_dot_gyp)
- if not home_dot_gyp:
- home_vars = ['HOME']
- if sys.platform in ('cygwin', 'win32'):
- home_vars.append('USERPROFILE')
- for home_var in home_vars:
- home = os.getenv(home_var)
- if home != None:
- home_dot_gyp = os.path.join(home, '.gyp')
- if not os.path.exists(home_dot_gyp):
- home_dot_gyp = None
- else:
- break
-
- if home_dot_gyp:
- include_gypi = os.path.join(home_dot_gyp, "include.gypi")
- if os.path.exists(include_gypi):
- supplemental_files += [include_gypi]
-
- # GYP defines from the supplemental.gypi files.
- supp_items = []
- for supplement in supplemental_files:
- with open(supplement, 'r') as f:
- try:
- file_data = eval(f.read(), {'__builtins__': None}, None)
- except SyntaxError, e:
- e.filename = os.path.abspath(supplement)
- raise
- variables = file_data.get('variables', [])
- for v in variables:
- supp_items += [(v, str(variables[v]))]
-
- # GYP defines from the environment.
- env_items = ProcessGypDefinesItems(
- shlex.split(os.environ.get('GYP_DEFINES', '')))
-
- # GYP defines from the command line.
- parser = argparse.ArgumentParser()
- parser.add_argument('-D', dest='defines', action='append', default=[])
- cmdline_input_items = parser.parse_known_args()[0].defines
- cmdline_items = ProcessGypDefinesItems(cmdline_input_items)
-
- vars_dict = dict(supp_items + env_items + cmdline_items)
- return vars_dict
-
-
-def GetOutputDirectory():
- """Returns the output directory that GYP will use."""
-
- # Handle command line generator flags.
- parser = argparse.ArgumentParser()
- parser.add_argument('-G', dest='genflags', default=[], action='append')
- genflags = parser.parse_known_args()[0].genflags
-
- # Handle generator flags from the environment.
- genflags += shlex.split(os.environ.get('GYP_GENERATOR_FLAGS', ''))
-
- needle = 'output_dir='
- for item in genflags:
- if item.startswith(needle):
- return item[len(needle):]
-
- return 'out'
-
-
-def additional_include_files(supplemental_files, args=[]):
- """
- Returns a list of additional (.gypi) files to include, without duplicating
- ones that are already specified on the command line. The list of supplemental
- include files is passed in as an argument.
- """
- # Determine the include files specified on the command line.
- # This doesn't cover all the different option formats you can use,
- # but it's mainly intended to avoid duplicating flags on the automatic
- # makefile regeneration which only uses this format.
- specified_includes = set()
- for arg in args:
- if arg.startswith('-I') and len(arg) > 2:
- specified_includes.add(os.path.realpath(arg[2:]))
-
- result = []
- def AddInclude(path):
- if os.path.realpath(path) not in specified_includes:
- result.append(path)
-
- if os.environ.get('GYP_INCLUDE_FIRST') != None:
- AddInclude(os.path.join(chrome_src, os.environ.get('GYP_INCLUDE_FIRST')))
-
- # Always include common.gypi.
- AddInclude(os.path.join(script_dir, 'common.gypi'))
-
- # Optionally add supplemental .gypi files if present.
- for supplement in supplemental_files:
- AddInclude(supplement)
-
- if os.environ.get('GYP_INCLUDE_LAST') != None:
- AddInclude(os.path.join(chrome_src, os.environ.get('GYP_INCLUDE_LAST')))
-
- return result
-
-
-if __name__ == '__main__':
- # Disabling garbage collection saves about 1 second out of 16 on a Linux
- # z620 workstation. Since this is a short-lived process it's not a problem to
- # leak a few cyclyc references in order to spare the CPU cycles for
- # scanning the heap.
- import gc
- gc.disable()
-
- args = sys.argv[1:]
-
- use_analyzer = len(args) and args[0] == '--analyzer'
- if use_analyzer:
- args.pop(0)
- os.environ['GYP_GENERATORS'] = 'analyzer'
- args.append('-Gconfig_path=' + args.pop(0))
- args.append('-Ganalyzer_output_path=' + args.pop(0))
-
- if int(os.environ.get('GYP_CHROMIUM_NO_ACTION', 0)):
- print 'Skipping gyp_chromium due to GYP_CHROMIUM_NO_ACTION env var.'
- sys.exit(0)
-
- # Use the Psyco JIT if available.
- if psyco:
- psyco.profile()
- print "Enabled Psyco JIT."
-
- # Fall back on hermetic python if we happen to get run under cygwin.
- # TODO(bradnelson): take this out once this issue is fixed:
- # http://code.google.com/p/gyp/issues/detail?id=177
- if sys.platform == 'cygwin':
- import find_depot_tools
- depot_tools_path = find_depot_tools.add_depot_tools_to_path()
- python_dir = sorted(glob.glob(os.path.join(depot_tools_path,
- 'python2*_bin')))[-1]
- env = os.environ.copy()
- env['PATH'] = python_dir + os.pathsep + env.get('PATH', '')
- cmd = [os.path.join(python_dir, 'python.exe')] + sys.argv
- sys.exit(subprocess.call(cmd, env=env))
-
- # This could give false positives since it doesn't actually do real option
- # parsing. Oh well.
- gyp_file_specified = any(arg.endswith('.gyp') for arg in args)
-
- gyp_environment.SetEnvironment()
-
- # If we didn't get a file, check an env var, and then fall back to
- # assuming 'all.gyp' from the same directory as the script.
- if not gyp_file_specified:
- gyp_file = os.environ.get('CHROMIUM_GYP_FILE')
- if gyp_file:
- # Note that CHROMIUM_GYP_FILE values can't have backslashes as
- # path separators even on Windows due to the use of shlex.split().
- args.extend(shlex.split(gyp_file))
- else:
- args.append(os.path.join(script_dir, 'all.gyp'))
-
- supplemental_includes = GetSupplementalFiles()
- gyp_vars_dict = GetGypVars(supplemental_includes)
- # There shouldn't be a circular dependency relationship between .gyp files,
- # but in Chromium's .gyp files, on non-Mac platforms, circular relationships
- # currently exist. The check for circular dependencies is currently
- # bypassed on other platforms, but is left enabled on iOS, where a violation
- # of the rule causes Xcode to misbehave badly.
- # TODO(mark): Find and kill remaining circular dependencies, and remove this
- # option. http://crbug.com/35878.
- # TODO(tc): Fix circular dependencies in ChromiumOS then add linux2 to the
- # list.
- if gyp_vars_dict.get('OS') != 'ios':
- args.append('--no-circular-check')
-
- # libtool on Mac warns about duplicate basenames in static libraries, so
- # they're disallowed in general by gyp. We are lax on this point, so disable
- # this check other than on Mac. GN does not use static libraries as heavily,
- # so over time this restriction will mostly go away anyway, even on Mac.
- # https://code.google.com/p/gyp/issues/detail?id=384
- if sys.platform != 'darwin':
- args.append('--no-duplicate-basename-check')
-
- # We explicitly don't support the make gyp generator (crbug.com/348686). Be
- # nice and fail here, rather than choking in gyp.
- if re.search(r'(^|,|\s)make($|,|\s)', os.environ.get('GYP_GENERATORS', '')):
- print 'Error: make gyp generator not supported (check GYP_GENERATORS).'
- sys.exit(1)
-
- # We explicitly don't support the native msvs gyp generator. Be nice and
- # fail here, rather than generating broken projects.
- if re.search(r'(^|,|\s)msvs($|,|\s)', os.environ.get('GYP_GENERATORS', '')):
- print 'Error: msvs gyp generator not supported (check GYP_GENERATORS).'
- print 'Did you mean to use the `msvs-ninja` generator?'
- sys.exit(1)
-
- # If CHROMIUM_GYP_SYNTAX_CHECK is set to 1, it will invoke gyp with --check
- # to enfore syntax checking.
- syntax_check = os.environ.get('CHROMIUM_GYP_SYNTAX_CHECK')
- if syntax_check and int(syntax_check):
- args.append('--check')
-
- # TODO(dmikurube): Remove these checks and messages after a while.
- if ('linux_use_tcmalloc' in gyp_vars_dict or
- 'android_use_tcmalloc' in gyp_vars_dict):
- print '*****************************************************************'
- print '"linux_use_tcmalloc" and "android_use_tcmalloc" are deprecated!'
- print '-----------------------------------------------------------------'
- print 'You specify "linux_use_tcmalloc" or "android_use_tcmalloc" in'
- print 'your GYP_DEFINES. Please switch them into "use_allocator" now.'
- print 'See http://crbug.com/345554 for the details.'
- print '*****************************************************************'
-
- # Automatically turn on crosscompile support for platforms that need it.
- # (The Chrome OS build sets CC_host / CC_target which implicitly enables
- # this mode.)
- if all(('ninja' in os.environ.get('GYP_GENERATORS', ''),
- gyp_vars_dict.get('OS') in ['android', 'ios'],
- 'GYP_CROSSCOMPILE' not in os.environ)):
- os.environ['GYP_CROSSCOMPILE'] = '1'
- if gyp_vars_dict.get('OS') == 'android':
- args.append('--check')
-
- args.extend(
- ['-I' + i for i in additional_include_files(supplemental_includes, args)])
-
- args.extend(['-D', 'gyp_output_dir=' + GetOutputDirectory()])
-
- if not use_analyzer:
- print 'Updating projects from gyp files...'
- sys.stdout.flush()
-
- # Off we go...
- gyp_rc = gyp.main(args)
-
- if not use_analyzer:
- vs2013_runtime_dll_dirs = vs_toolchain.SetEnvironmentAndGetRuntimeDllDirs()
- if vs2013_runtime_dll_dirs:
- x64_runtime, x86_runtime = vs2013_runtime_dll_dirs
- vs_toolchain.CopyVsRuntimeDlls(
- os.path.join(chrome_src, GetOutputDirectory()),
- (x86_runtime, x64_runtime))
-
- sys.exit(gyp_rc)
diff --git a/build/gyp_chromium.py b/build/gyp_chromium.py
deleted file mode 100644
index f9e8ac8..0000000
--- a/build/gyp_chromium.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# Copyright 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 (possibly, depending on python version) imported by
-# gyp_chromium when GYP_PARALLEL=1 and it creates sub-processes
-# through the multiprocessing library.
-
-# Importing in Python 2.6 (fixed in 2.7) on Windows doesn't search for
-# imports that don't end in .py (and aren't directories with an
-# __init__.py). This wrapper makes "import gyp_chromium" work with
-# those old versions and makes it possible to execute gyp_chromium.py
-# directly on Windows where the extension is useful.
-
-import os
-
-path = os.path.abspath(os.path.split(__file__)[0])
-execfile(os.path.join(path, 'gyp_chromium'))
diff --git a/build/gyp_chromium_test.py b/build/gyp_chromium_test.py
deleted file mode 100755
index 0c0e479..0000000
--- a/build/gyp_chromium_test.py
+++ /dev/null
@@ -1,66 +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 os
-import sys
-import unittest
-
-SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__))
-SRC_DIR = os.path.dirname(SCRIPT_DIR)
-
-sys.path.append(os.path.join(SRC_DIR, 'third_party', 'pymock'))
-
-import mock
-
-# TODO(sbc): Make gyp_chromium more testable by putting the code in
-# a .py file.
-gyp_chromium = __import__('gyp_chromium')
-
-
-class TestGetOutputDirectory(unittest.TestCase):
- @mock.patch('os.environ', {})
- @mock.patch('sys.argv', [__file__])
- def testDefaultValue(self):
- self.assertEqual(gyp_chromium.GetOutputDirectory(), 'out')
-
- @mock.patch('os.environ', {'GYP_GENERATOR_FLAGS': 'output_dir=envfoo'})
- @mock.patch('sys.argv', [__file__])
- def testEnvironment(self):
- self.assertEqual(gyp_chromium.GetOutputDirectory(), 'envfoo')
-
- @mock.patch('os.environ', {'GYP_GENERATOR_FLAGS': 'output_dir=envfoo'})
- @mock.patch('sys.argv', [__file__, '-Goutput_dir=cmdfoo'])
- def testGFlagOverridesEnv(self):
- self.assertEqual(gyp_chromium.GetOutputDirectory(), 'cmdfoo')
-
- @mock.patch('os.environ', {})
- @mock.patch('sys.argv', [__file__, '-G', 'output_dir=foo'])
- def testGFlagWithSpace(self):
- self.assertEqual(gyp_chromium.GetOutputDirectory(), 'foo')
-
-
-class TestGetGypVars(unittest.TestCase):
- @mock.patch('os.environ', {})
- def testDefault(self):
- self.assertEqual(gyp_chromium.GetGypVars([]), {})
-
- @mock.patch('os.environ', {})
- @mock.patch('sys.argv', [__file__, '-D', 'foo=bar'])
- def testDFlags(self):
- self.assertEqual(gyp_chromium.GetGypVars([]), {'foo': 'bar'})
-
- @mock.patch('os.environ', {})
- @mock.patch('sys.argv', [__file__, '-D', 'foo'])
- def testDFlagsNoValue(self):
- self.assertEqual(gyp_chromium.GetGypVars([]), {'foo': '1'})
-
- @mock.patch('os.environ', {})
- @mock.patch('sys.argv', [__file__, '-D', 'foo=bar', '-Dbaz'])
- def testDFlagMulti(self):
- self.assertEqual(gyp_chromium.GetGypVars([]), {'foo': 'bar', 'baz': '1'})
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/build/json_schema_api.gni b/build/json_schema_api.gni
deleted file mode 100644
index e1c2d33..0000000
--- a/build/json_schema_api.gni
+++ /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.
-
-# Defines a static library corresponding to the output of schema compiler tools
-# over a set of extensions API schemas (IDL or JSON format.) The library target
-# has implicit hard dependencies on all schema files listed by the invoker and
-# is itself a hard dependency.
-#
-# Invocations of this template may use the following variables:
-#
-# sources [required] A list of schema files to be compiled.
-#
-# root_namespace [required]
-# A Python string substituion pattern used to generate the C++
-# namespace for each API. Use %(namespace)s to replace with the API
-# namespace, like "toplevel::%(namespace)s_api".
-#
-# schema_include_rules [optional]
-# A list of paths to include when searching for referenced objects,
-# with the namespace separated by a :.
-# Example:
-# [ '/foo/bar:Foo::Bar::%(namespace)s' ]
-#
-# schemas [optional, default = false]
-# Boolean indicating if the schema files should be generated.
-#
-# bundle [optional, default = false]
-# Boolean indicating if the schema bundle files should be generated.
-#
-# bundle_registration [optional, default = false]
-# Boolean indicating if the API registration bundle files should be generated.
-#
-# impl_dir [required if bundle_registration = true, otherwise unused]
-# The path containing C++ implementations of API functions. This path is
-# used as the root path when looking for {schema}/{schema}_api.h headers
-# when generating API registration bundles. Such headers, if found, are
-# automatically included by the generated code.
-#
-# uncompiled_sources [optional, only used when bundle = true or
-# bundle_registration = true]
-# A list of schema files which should not be compiled, but which should still
-# be processed for API bundle generation.
-#
-# deps [optional]
-# If any deps are specified they will be inherited by the static library
-# target.
-#
-# generate_static_library [optional, defaults to false]
-# Produces a static library instead of a source_set.
-#
-# The generated library target also inherits the visibility and output_name
-# of its invoker.
-
-template("json_schema_api") {
- assert(defined(invoker.sources),
- "\"sources\" must be defined for the $target_name template.")
- assert(defined(invoker.root_namespace),
- "\"root_namespace\" must be defined for the $target_name template.")
-
- schemas = defined(invoker.schemas) && invoker.schemas
- bundle = defined(invoker.bundle) && invoker.bundle
- bundle_registration =
- defined(invoker.bundle_registration) && invoker.bundle_registration
-
- schema_include_rules = ""
- if (defined(invoker.schema_include_rules)) {
- schema_include_rules = invoker.schema_include_rules
- }
-
- # Keep a copy of the target_name here since it will be trampled
- # in nested targets.
- target_visibility = [ ":$target_name" ]
-
- generated_config_name = target_name + "_generated_config"
- config(generated_config_name) {
- include_dirs = [ root_gen_dir ]
- visibility = target_visibility
- }
-
- root_namespace = invoker.root_namespace
-
- compiler_root = "//tools/json_schema_compiler"
- compiler_script = "$compiler_root/compiler.py"
- compiler_sources = [
- "$compiler_root/cc_generator.py",
- "$compiler_root/code.py",
- "$compiler_root/compiler.py",
- "$compiler_root/cpp_generator.py",
- "$compiler_root/cpp_type_generator.py",
- "$compiler_root/cpp_util.py",
- "$compiler_root/h_generator.py",
- "$compiler_root/idl_schema.py",
- "$compiler_root/model.py",
- "$compiler_root/util_cc_helper.py",
- ]
-
- if (schemas) {
- schema_generator_name = target_name + "_schema_generator"
- action_foreach(schema_generator_name) {
- script = compiler_script
- sources = invoker.sources
- inputs = compiler_sources
- outputs = [
- "$target_gen_dir/{{source_name_part}}.cc",
- "$target_gen_dir/{{source_name_part}}.h",
- ]
- args = [
- "{{source}}",
- "--root=" + rebase_path("//", root_build_dir),
- "--destdir=" + rebase_path(root_gen_dir, root_build_dir),
- "--namespace=$root_namespace",
- "--generator=cpp",
- "--include-rules=$schema_include_rules",
- ]
-
- if (defined(invoker.visibility)) {
- # If visibility is restricted, add our own target to it.
- visibility = invoker.visibility + target_visibility
- }
- }
- }
-
- if (bundle) {
- uncompiled_sources = []
- if (defined(invoker.uncompiled_sources)) {
- uncompiled_sources = invoker.uncompiled_sources
- }
-
- bundle_generator_schema_name = target_name + "_bundle_generator_schema"
- action(bundle_generator_schema_name) {
- script = compiler_script
- inputs = compiler_sources + invoker.sources + uncompiled_sources
- outputs = [
- "$target_gen_dir/generated_schemas.cc",
- "$target_gen_dir/generated_schemas.h",
- ]
- args = [
- "--root=" + rebase_path("//", root_build_dir),
- "--destdir=" + rebase_path(root_gen_dir, root_build_dir),
- "--namespace=$root_namespace",
- "--generator=cpp-bundle-schema",
- "--include-rules=$schema_include_rules",
- ] + rebase_path(invoker.sources, root_build_dir) +
- rebase_path(uncompiled_sources, root_build_dir)
- }
- }
-
- if (bundle_registration) {
- uncompiled_sources = []
- if (defined(invoker.uncompiled_sources)) {
- uncompiled_sources = invoker.uncompiled_sources
- }
-
- assert(defined(invoker.impl_dir),
- "\"impl_dir\" must be defined for the $target_name template.")
-
- # Child directory inside the generated file tree.
- gen_child_dir = rebase_path(invoker.impl_dir, "//")
-
- bundle_generator_registration_name =
- target_name + "_bundle_generator_registration"
- action(bundle_generator_registration_name) {
- script = compiler_script
- inputs = compiler_sources + invoker.sources + uncompiled_sources
- outputs = [
- "$root_gen_dir/$gen_child_dir/generated_api_registration.cc",
- "$root_gen_dir/$gen_child_dir/generated_api_registration.h",
- ]
- args = [
- "--root=" + rebase_path("//", root_build_dir),
- "--destdir=" + rebase_path(root_gen_dir, root_build_dir),
- "--namespace=$root_namespace",
- "--generator=cpp-bundle-registration",
- "--impl-dir=$gen_child_dir",
- "--include-rules=$schema_include_rules",
- ] + rebase_path(invoker.sources, root_build_dir) +
- rebase_path(uncompiled_sources, root_build_dir)
- }
- }
-
- # Compute the contents of the library/source set.
- lib_sources = invoker.sources
- lib_deps = []
- lib_public_deps = []
- lib_extra_configs = []
-
- if (schemas) {
- lib_sources += get_target_outputs(":$schema_generator_name")
- lib_public_deps += [ ":$schema_generator_name" ]
- lib_deps += [ "//tools/json_schema_compiler:generated_api_util" ]
- lib_extra_configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
- }
-
- if (bundle) {
- lib_sources += get_target_outputs(":$bundle_generator_schema_name")
- lib_deps += [ ":$bundle_generator_schema_name" ]
- }
-
- if (bundle_registration) {
- lib_sources += get_target_outputs(":$bundle_generator_registration_name")
- lib_deps += [ ":$bundle_generator_registration_name" ]
- }
-
- if (defined(invoker.deps)) {
- lib_deps += invoker.deps
- }
-
- # Generate either a static library or a source set.
- if (defined(invoker.generate_static_library) &&
- invoker.generate_static_library) {
- static_library(target_name) {
- sources = lib_sources
- deps = lib_deps
- public_deps = lib_public_deps
- configs += lib_extra_configs
- public_configs = [ ":$generated_config_name" ]
-
- if (defined(invoker.visibility)) {
- visibility = invoker.visibility
- }
- if (defined(invoker.output_name)) {
- output_name = invoker.output_name
- }
- }
- } else {
- source_set(target_name) {
- sources = lib_sources
- deps = lib_deps
- public_deps = lib_public_deps
- configs += lib_extra_configs
- public_configs = [ ":$generated_config_name" ]
-
- if (defined(invoker.visibility)) {
- visibility = invoker.visibility
- }
- if (defined(invoker.output_name)) {
- output_name = invoker.output_name
- }
- }
- }
-}
diff --git a/build/json_schema_bundle_compile.gypi b/build/json_schema_bundle_compile.gypi
deleted file mode 100644
index a302013..0000000
--- a/build/json_schema_bundle_compile.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.
-
-{
- 'variables': {
- # When including this gypi, the following variables must be set:
- # schema_files:
- # An array of json or idl files that comprise the api model.
- # schema_include_rules (optional):
- # An array of paths to include when searching for referenced objects,
- # with the namespace separated by a :.
- # Example:
- # [ '/foo/bar:Foo::Bar::%(namespace)s' ]
- # cc_dir:
- # The directory to put the generated code in.
- # root_namespace:
- # A Python string substituion pattern used to generate the C++
- # namespace for each API. Use %(namespace)s to replace with the API
- # namespace, like "toplevel::%(namespace)s_api".
- #
- # Functions and namespaces can be excluded by setting "nocompile" to true.
- # The default root path of API implementation sources is
- # chrome/browser/extensions/api and can be overridden by setting "impl_dir".
- 'api_gen_dir': '<(DEPTH)/tools/json_schema_compiler',
- 'api_gen': '<(api_gen_dir)/compiler.py',
- 'generator_files': [
- '<(api_gen_dir)/cc_generator.py',
- '<(api_gen_dir)/code.py',
- '<(api_gen_dir)/compiler.py',
- '<(api_gen_dir)/cpp_bundle_generator.py',
- '<(api_gen_dir)/cpp_type_generator.py',
- '<(api_gen_dir)/cpp_util.py',
- '<(api_gen_dir)/h_generator.py',
- '<(api_gen_dir)/idl_schema.py',
- '<(api_gen_dir)/json_schema.py',
- '<(api_gen_dir)/model.py',
- '<(api_gen_dir)/util_cc_helper.py',
- ],
- 'schema_include_rules': [],
- },
- 'actions': [
- {
- 'action_name': 'genapi_bundle_schema',
- 'inputs': [
- '<@(generator_files)',
- '<@(schema_files)',
- '<@(non_compiled_schema_files)',
- ],
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/<(cc_dir)/generated_schemas.h',
- '<(SHARED_INTERMEDIATE_DIR)/<(cc_dir)/generated_schemas.cc',
- ],
- 'action': [
- 'python',
- '<(api_gen)',
- '--root=<(DEPTH)',
- '--destdir=<(SHARED_INTERMEDIATE_DIR)',
- '--namespace=<(root_namespace)',
- '--generator=cpp-bundle-schema',
- '--include-rules=<(schema_include_rules)',
- '<@(schema_files)',
- '<@(non_compiled_schema_files)',
- ],
- 'message': 'Generating C++ API bundle code for schemas',
- 'process_outputs_as_sources': 1,
- # Avoid running MIDL compiler on IDL input files.
- 'explicit_idl_action': 1,
- },
- ],
- 'include_dirs': [
- '<(SHARED_INTERMEDIATE_DIR)',
- '<(DEPTH)',
- ],
- 'direct_dependent_settings': {
- 'include_dirs': [
- '<(SHARED_INTERMEDIATE_DIR)',
- ]
- },
- # This target exports a hard dependency because it generates header
- # files.
- 'hard_dependency': 1,
-}
diff --git a/build/json_schema_bundle_registration_compile.gypi b/build/json_schema_bundle_registration_compile.gypi
deleted file mode 100644
index 8c5af4e..0000000
--- a/build/json_schema_bundle_registration_compile.gypi
+++ /dev/null
@@ -1,78 +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': {
- # When including this gypi, the following variables must be set:
- # schema_files:
- # An array of json or idl files that comprise the api model.
- # impl_dir_:
- # The root path of API implementations; also used for the
- # output location. (N.B. Named as such to prevent gyp from
- # expanding it as a relative path.)
- # root_namespace:
- # A Python string substituion pattern used to generate the C++
- # namespace for each API. Use %(namespace)s to replace with the API
- # namespace, like "toplevel::%(namespace)s_api".
- #
- # Functions and namespaces can be excluded by setting "nocompile" to true.
- 'api_gen_dir': '<(DEPTH)/tools/json_schema_compiler',
- 'api_gen': '<(api_gen_dir)/compiler.py',
- 'generator_files': [
- '<(api_gen_dir)/cc_generator.py',
- '<(api_gen_dir)/code.py',
- '<(api_gen_dir)/compiler.py',
- '<(api_gen_dir)/cpp_bundle_generator.py',
- '<(api_gen_dir)/cpp_type_generator.py',
- '<(api_gen_dir)/cpp_util.py',
- '<(api_gen_dir)/h_generator.py',
- '<(api_gen_dir)/idl_schema.py',
- '<(api_gen_dir)/json_schema.py',
- '<(api_gen_dir)/model.py',
- '<(api_gen_dir)/util_cc_helper.py',
- ],
- },
- 'actions': [
- {
- # GN version: json_schema_api.gni
- 'action_name': 'genapi_bundle_registration',
- 'inputs': [
- '<@(generator_files)',
- '<@(schema_files)',
- '<@(non_compiled_schema_files)',
- ],
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/<(impl_dir_)/generated_api_registration.h',
- '<(SHARED_INTERMEDIATE_DIR)/<(impl_dir_)/generated_api_registration.cc',
- ],
- 'action': [
- 'python',
- '<(api_gen)',
- '--root=<(DEPTH)',
- '--destdir=<(SHARED_INTERMEDIATE_DIR)',
- '--namespace=<(root_namespace)',
- '--generator=cpp-bundle-registration',
- '--impl-dir=<(impl_dir_)',
- '<@(schema_files)',
- '<@(non_compiled_schema_files)',
- ],
- 'message': 'Generating C++ API bundle code for function registration',
- 'process_outputs_as_sources': 1,
- # Avoid running MIDL compiler on IDL input files.
- 'explicit_idl_action': 1,
- },
- ],
- 'include_dirs': [
- '<(SHARED_INTERMEDIATE_DIR)',
- '<(DEPTH)',
- ],
- 'direct_dependent_settings': {
- 'include_dirs': [
- '<(SHARED_INTERMEDIATE_DIR)',
- ]
- },
- # This target exports a hard dependency because it generates header
- # files.
- 'hard_dependency': 1,
-}
diff --git a/build/json_schema_compile.gypi b/build/json_schema_compile.gypi
deleted file mode 100644
index 6e5727a..0000000
--- a/build/json_schema_compile.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.
-
-{
- 'variables': {
- # When including this gypi, the following variables must be set:
- # schema_files:
- # An array of json or idl files that comprise the api model.
- # schema_include_rules (optional):
- # An array of paths to include when searching for referenced objects,
- # with the namespace separated by a :.
- # Example:
- # [ '/foo/bar:Foo::Bar::%(namespace)s' ]
- # cc_dir:
- # The directory to put the generated code in.
- # root_namespace:
- # A Python string substituion pattern used to generate the C++
- # namespace for each API. Use %(namespace)s to replace with the API
- # namespace, like "toplevel::%(namespace)s_api".
- #
- # Functions and namespaces can be excluded by setting "nocompile" to true.
- 'api_gen_dir': '<(DEPTH)/tools/json_schema_compiler',
- 'api_gen': '<(api_gen_dir)/compiler.py',
- 'schema_include_rules': [],
- },
- 'rules': [
- {
- # GN version: json_schema_api.gni
- 'rule_name': 'genapi',
- 'msvs_external_rule': 1,
- 'extension': 'json',
- 'inputs': [
- '<(api_gen_dir)/cc_generator.py',
- '<(api_gen_dir)/code.py',
- '<(api_gen_dir)/compiler.py',
- '<(api_gen_dir)/cpp_generator.py',
- '<(api_gen_dir)/cpp_type_generator.py',
- '<(api_gen_dir)/cpp_util.py',
- '<(api_gen_dir)/h_generator.py',
- '<(api_gen_dir)/json_schema.py',
- '<(api_gen_dir)/model.py',
- '<(api_gen_dir)/util.cc',
- '<(api_gen_dir)/util.h',
- '<(api_gen_dir)/util_cc_helper.py',
- # TODO(calamity): uncomment this when gyp on windows behaves like other
- # platforms. List expansions of filepaths in inputs expand to different
- # things.
- # '<@(schema_files)',
- ],
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/<(cc_dir)/<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).cc',
- '<(SHARED_INTERMEDIATE_DIR)/<(cc_dir)/<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).h',
- ],
- 'action': [
- 'python',
- '<(api_gen)',
- '<(RULE_INPUT_PATH)',
- '--root=<(DEPTH)',
- '--destdir=<(SHARED_INTERMEDIATE_DIR)',
- '--namespace=<(root_namespace)',
- '--generator=cpp',
- '--include-rules=<(schema_include_rules)'
- ],
- 'message': 'Generating C++ code from <(RULE_INPUT_PATH) json files',
- 'process_outputs_as_sources': 1,
- },
- {
- 'rule_name': 'genapi_idl',
- 'msvs_external_rule': 1,
- 'extension': 'idl',
- 'inputs': [
- '<(api_gen_dir)/cc_generator.py',
- '<(api_gen_dir)/code.py',
- '<(api_gen_dir)/compiler.py',
- '<(api_gen_dir)/cpp_generator.py',
- '<(api_gen_dir)/cpp_type_generator.py',
- '<(api_gen_dir)/cpp_util.py',
- '<(api_gen_dir)/h_generator.py',
- '<(api_gen_dir)/idl_schema.py',
- '<(api_gen_dir)/model.py',
- '<(api_gen_dir)/util.cc',
- '<(api_gen_dir)/util.h',
- '<(api_gen_dir)/util_cc_helper.py',
- # TODO(calamity): uncomment this when gyp on windows behaves like other
- # platforms. List expansions of filepaths in inputs expand to different
- # things.
- # '<@(schema_files)',
- ],
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/<(cc_dir)/<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).cc',
- '<(SHARED_INTERMEDIATE_DIR)/<(cc_dir)/<(RULE_INPUT_DIRNAME)/<(RULE_INPUT_ROOT).h',
- ],
- 'action': [
- 'python',
- '<(api_gen)',
- '<(RULE_INPUT_PATH)',
- '--root=<(DEPTH)',
- '--destdir=<(SHARED_INTERMEDIATE_DIR)',
- '--namespace=<(root_namespace)',
- '--generator=cpp',
- '--include-rules=<(schema_include_rules)'
- ],
- 'message': 'Generating C++ code from <(RULE_INPUT_PATH) IDL files',
- 'process_outputs_as_sources': 1,
- },
- ],
- 'include_dirs': [
- '<(SHARED_INTERMEDIATE_DIR)',
- '<(DEPTH)',
- ],
- 'dependencies':[
- '<(DEPTH)/tools/json_schema_compiler/api_gen_util.gyp:api_gen_util',
- ],
- 'direct_dependent_settings': {
- 'include_dirs': [
- '<(SHARED_INTERMEDIATE_DIR)',
- ]
- },
- # This target exports a hard dependency because it generates header
- # files.
- 'hard_dependency': 1,
-}
diff --git a/build/json_to_struct.gypi b/build/json_to_struct.gypi
deleted file mode 100644
index 09c8e3e..0000000
--- a/build/json_to_struct.gypi
+++ /dev/null
@@ -1,53 +0,0 @@
-# Copyright 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': {
- # When including this gypi, the following variables must be set:
- # schema_file: a json file that comprise the structure model.
- # namespace: the C++ namespace that all generated files go under
- # cc_dir: path to generated files
- # Functions and namespaces can be excluded by setting "nocompile" to true.
- 'struct_gen_dir': '<(DEPTH)/tools/json_to_struct',
- 'struct_gen%': '<(struct_gen_dir)/json_to_struct.py',
- 'output_filename%': '<(RULE_INPUT_ROOT)',
- },
- 'rules': [
- {
- # GN version: //tools/json_to_struct/json_to_struct.gni
- 'rule_name': 'genstaticinit',
- 'extension': 'json',
- 'inputs': [
- '<(struct_gen)',
- '<(struct_gen_dir)/element_generator.py',
- '<(struct_gen_dir)/json_to_struct.py',
- '<(struct_gen_dir)/struct_generator.py',
- '<(schema_file)',
- ],
- 'outputs': [
- '<(SHARED_INTERMEDIATE_DIR)/<(cc_dir)/<(output_filename).cc',
- '<(SHARED_INTERMEDIATE_DIR)/<(cc_dir)/<(output_filename).h',
- ],
- 'action': [
- 'python',
- '<(struct_gen)',
- '<(RULE_INPUT_PATH)',
- '--destbase=<(SHARED_INTERMEDIATE_DIR)',
- '--destdir=<(cc_dir)',
- '--namespace=<(namespace)',
- '--schema=<(schema_file)',
- '--output=<(output_filename)',
- ],
- 'message': 'Generating C++ static initializers from <(RULE_INPUT_PATH)',
- 'process_outputs_as_sources': 1,
- },
- ],
- 'include_dirs': [
- '<(SHARED_INTERMEDIATE_DIR)',
- '<(DEPTH)',
- ],
- # This target exports a hard dependency because it generates header
- # files.
- 'hard_dependency': 1,
-}
diff --git a/build/module_args/dart.gni b/build/module_args/dart.gni
deleted file mode 100644
index ee6b038..0000000
--- a/build/module_args/dart.gni
+++ /dev/null
@@ -1,6 +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 variable should point to the Dart SDK.
-dart_sdk_root = "//third_party/dart-sdk/dart-sdk"
diff --git a/build/module_args/mojo.gni b/build/module_args/mojo.gni
deleted file mode 100644
index fee9114..0000000
--- a/build/module_args/mojo.gni
+++ /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.
-
-# This variable should point to the parent directory of the Mojo SDK.
-mojo_sdk_root = "//"
-
-# To build the Mojo shell from source, set this variable to true. To use the
-# prebuilt shell, omit this variable or set it to false. Note that the prebuilt
-# shell will be used only on platforms for which it is published (currently
-# Linux and Android).
-mojo_build_mojo_shell_from_source = true
-
-# To build the network service from source, set this variable to true. To use
-# the prebuilt network service, omit this variable or set it to false.
-mojo_build_network_service_from_source = true
diff --git a/build/module_args/nacl.gni b/build/module_args/nacl.gni
deleted file mode 100644
index 61e0768..0000000
--- a/build/module_args/nacl.gni
+++ /dev/null
@@ -1,6 +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.
-
-# Override nacl's build directory.
-nacl_shared_build_dir = "//build"
diff --git a/build/module_args/v8.gni b/build/module_args/v8.gni
deleted file mode 100644
index 8b5204c..0000000
--- a/build/module_args/v8.gni
+++ /dev/null
@@ -1,13 +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.
-
-if (is_android) {
- import("//build/config/android/config.gni")
-}
-
-# TODO(sky): nuke this. Temporary while sorting out http://crbug.com/465456.
-enable_correct_v8_arch = false
-
-v8_use_external_startup_data = !(is_chromeos || is_win)
-v8_extra_library_files = []
diff --git a/build/secondary/testing/gmock/BUILD.gn b/build/secondary/testing/gmock/BUILD.gn
deleted file mode 100644
index 4ec6224..0000000
--- a/build/secondary/testing/gmock/BUILD.gn
+++ /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.
-
-config("gmock_config") {
- # Gmock headers need to be able to find themselves.
- include_dirs = [ "include" ]
-}
-
-static_library("gmock") {
- # TODO http://crbug.com/412064 enable this flag all the time.
- testonly = !is_component_build
- sources = [
- # Sources based on files in r173 of gmock.
- "include/gmock/gmock-actions.h",
- "include/gmock/gmock-cardinalities.h",
- "include/gmock/gmock-generated-actions.h",
- "include/gmock/gmock-generated-function-mockers.h",
- "include/gmock/gmock-generated-matchers.h",
- "include/gmock/gmock-generated-nice-strict.h",
- "include/gmock/gmock-matchers.h",
- "include/gmock/gmock-spec-builders.h",
- "include/gmock/gmock.h",
- "include/gmock/internal/gmock-generated-internal-utils.h",
- "include/gmock/internal/gmock-internal-utils.h",
- "include/gmock/internal/gmock-port.h",
-
- #"src/gmock-all.cc", # Not needed by our build.
- "src/gmock-cardinalities.cc",
- "src/gmock-internal-utils.cc",
- "src/gmock-matchers.cc",
- "src/gmock-spec-builders.cc",
- "src/gmock.cc",
- ]
-
- # This project includes some stuff form gtest's guts.
- include_dirs = [ "../gtest/include" ]
-
- public_configs = [
- ":gmock_config",
- "//testing/gtest:gtest_config",
- ]
-}
-
-static_library("gmock_main") {
- # TODO http://crbug.com/412064 enable this flag all the time.
- testonly = !is_component_build
- sources = [
- "src/gmock_main.cc",
- ]
- deps = [
- ":gmock",
- ]
-}
diff --git a/build/secondary/testing/gtest/BUILD.gn b/build/secondary/testing/gtest/BUILD.gn
deleted file mode 100644
index 073faec..0000000
--- a/build/secondary/testing/gtest/BUILD.gn
+++ /dev/null
@@ -1,135 +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.
-
-config("gtest_config") {
- visibility = [
- ":*",
- "//testing/gmock:*", # gmock also shares this config.
- ]
-
- defines = [
- # In order to allow regex matches in gtest to be shared between Windows
- # and other systems, we tell gtest to always use it's internal engine.
- "GTEST_HAS_POSIX_RE=0",
-
- # Chrome doesn't support / require C++11, yet.
- "GTEST_LANG_CXX11=0",
- ]
-
- # Gtest headers need to be able to find themselves.
- include_dirs = [ "include" ]
-
- if (is_win) {
- cflags = [ "/wd4800" ] # Unused variable warning.
- }
-
- if (is_posix) {
- defines += [
- # gtest isn't able to figure out when RTTI is disabled for gcc
- # versions older than 4.3.2, and assumes it's enabled. Our Mac
- # and Linux builds disable RTTI, and cannot guarantee that the
- # compiler will be 4.3.2. or newer. The Mac, for example, uses
- # 4.2.1 as that is the latest available on that platform. gtest
- # must be instructed that RTTI is disabled here, and for any
- # direct dependents that might include gtest headers.
- "GTEST_HAS_RTTI=0",
- ]
- }
-
- if (is_android) {
- defines += [
- # We want gtest features that use tr1::tuple, but we currently
- # don't support the variadic templates used by libstdc++'s
- # implementation. gtest supports this scenario by providing its
- # own implementation but we must opt in to it.
- "GTEST_USE_OWN_TR1_TUPLE=1",
-
- # GTEST_USE_OWN_TR1_TUPLE only works if GTEST_HAS_TR1_TUPLE is set.
- # gtest r625 made it so that GTEST_HAS_TR1_TUPLE is set to 0
- # automatically on android, so it has to be set explicitly here.
- "GTEST_HAS_TR1_TUPLE=1",
- ]
- }
-}
-
-config("gtest_direct_config") {
- visibility = [ ":*" ]
- defines = [ "UNIT_TEST" ]
-}
-
-static_library("gtest") {
- # TODO http://crbug.com/412064 enable this flag all the time.
- testonly = !is_component_build
- sources = [
- "include/gtest/gtest-death-test.h",
- "include/gtest/gtest-message.h",
- "include/gtest/gtest-param-test.h",
- "include/gtest/gtest-printers.h",
- "include/gtest/gtest-spi.h",
- "include/gtest/gtest-test-part.h",
- "include/gtest/gtest-typed-test.h",
- "include/gtest/gtest.h",
- "include/gtest/gtest_pred_impl.h",
- "include/gtest/internal/gtest-death-test-internal.h",
- "include/gtest/internal/gtest-filepath.h",
- "include/gtest/internal/gtest-internal.h",
- "include/gtest/internal/gtest-linked_ptr.h",
- "include/gtest/internal/gtest-param-util-generated.h",
- "include/gtest/internal/gtest-param-util.h",
- "include/gtest/internal/gtest-port.h",
- "include/gtest/internal/gtest-string.h",
- "include/gtest/internal/gtest-tuple.h",
- "include/gtest/internal/gtest-type-util.h",
-
- #"gtest/src/gtest-all.cc", # Not needed by our build.
- "../multiprocess_func_list.cc",
- "../multiprocess_func_list.h",
- "../platform_test.h",
- "src/gtest-death-test.cc",
- "src/gtest-filepath.cc",
- "src/gtest-internal-inl.h",
- "src/gtest-port.cc",
- "src/gtest-printers.cc",
- "src/gtest-test-part.cc",
- "src/gtest-typed-test.cc",
- "src/gtest.cc",
- ]
-
- if (is_mac) {
- sources += [
- "../gtest_mac.h",
- "../gtest_mac.mm",
- "../platform_test_mac.mm",
- ]
- }
-
- include_dirs = [ "." ]
-
- all_dependent_configs = [ ":gtest_config" ]
- public_configs = [ ":gtest_direct_config" ]
-
- configs -= [ "//build/config/compiler:chromium_code" ]
- configs += [ "//build/config/compiler:no_chromium_code" ]
-
- config("gtest_warnings") {
- if (is_win && is_clang) {
- # The Mutex constructor initializer list in gtest-port.cc is incorrectly
- # ordered. See
- # https://groups.google.com/d/msg/googletestframework/S5uSV8L2TX8/U1FaTDa6J6sJ.
- cflags = [ "-Wno-reorder" ]
- }
- }
- configs += [ ":gtest_warnings" ]
-}
-
-source_set("gtest_main") {
- # TODO http://crbug.com/412064 enable this flag all the time.
- testonly = !is_component_build
- sources = [
- "src/gtest_main.cc",
- ]
- deps = [
- ":gtest",
- ]
-}
diff --git a/build/secondary/third_party/libjpeg_turbo/BUILD.gn b/build/secondary/third_party/libjpeg_turbo/BUILD.gn
deleted file mode 100644
index 62e60ae..0000000
--- a/build/secondary/third_party/libjpeg_turbo/BUILD.gn
+++ /dev/null
@@ -1,221 +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.
-
-# Do not use the targets in this file unless you need a certain libjpeg
-# implementation. Use the meta target //third_party:jpeg instead.
-
-import("//build/config/sanitizers/sanitizers.gni")
-
-if (current_cpu == "arm") {
- import("//build/config/arm.gni")
-}
-
-if (current_cpu == "x86" || current_cpu == "x64") {
- import("//third_party/yasm/yasm_assemble.gni")
-
- yasm_assemble("simd_asm") {
- defines = []
-
- if (current_cpu == "x86") {
- sources = [
- "simd/jccolor-mmx.asm",
- "simd/jccolor-sse2.asm",
- "simd/jcgray-mmx.asm",
- "simd/jcgray-sse2.asm",
- "simd/jchuff-sse2.asm",
- "simd/jcsample-mmx.asm",
- "simd/jcsample-sse2.asm",
- "simd/jdcolor-mmx.asm",
- "simd/jdcolor-sse2.asm",
- "simd/jdmerge-mmx.asm",
- "simd/jdmerge-sse2.asm",
- "simd/jdsample-mmx.asm",
- "simd/jdsample-sse2.asm",
- "simd/jfdctflt-3dn.asm",
- "simd/jfdctflt-sse.asm",
- "simd/jfdctfst-mmx.asm",
- "simd/jfdctfst-sse2.asm",
- "simd/jfdctint-mmx.asm",
- "simd/jfdctint-sse2.asm",
- "simd/jidctflt-3dn.asm",
- "simd/jidctflt-sse.asm",
- "simd/jidctflt-sse2.asm",
- "simd/jidctfst-mmx.asm",
- "simd/jidctfst-sse2.asm",
- "simd/jidctint-mmx.asm",
- "simd/jidctint-sse2.asm",
- "simd/jidctred-mmx.asm",
- "simd/jidctred-sse2.asm",
- "simd/jquant-3dn.asm",
- "simd/jquant-mmx.asm",
- "simd/jquant-sse.asm",
- "simd/jquantf-sse2.asm",
- "simd/jquanti-sse2.asm",
- "simd/jsimdcpu.asm",
- ]
- defines += [
- "__x86__",
- "PIC",
- ]
- } else if (current_cpu == "x64") {
- sources = [
- "simd/jccolor-sse2-64.asm",
- "simd/jcgray-sse2-64.asm",
- "simd/jchuff-sse2-64.asm",
- "simd/jcsample-sse2-64.asm",
- "simd/jdcolor-sse2-64.asm",
- "simd/jdmerge-sse2-64.asm",
- "simd/jdsample-sse2-64.asm",
- "simd/jfdctflt-sse-64.asm",
- "simd/jfdctfst-sse2-64.asm",
- "simd/jfdctint-sse2-64.asm",
- "simd/jidctflt-sse2-64.asm",
- "simd/jidctfst-sse2-64.asm",
- "simd/jidctint-sse2-64.asm",
- "simd/jidctred-sse2-64.asm",
- "simd/jquantf-sse2-64.asm",
- "simd/jquanti-sse2-64.asm",
- ]
- defines += [
- "__x86_64__",
- "PIC",
- ]
- }
-
- if (is_win) {
- defines += [ "MSVC" ]
- include_dirs = [ "win" ]
- if (current_cpu == "x86") {
- defines += [ "WIN32" ]
- } else {
- defines += [ "WIN64" ]
- }
- } else if (is_mac) {
- defines += [ "MACHO" ]
- include_dirs = [ "mac" ]
- } else if (is_linux || is_android) {
- defines += [ "ELF" ]
- include_dirs = [ "linux" ]
- }
- }
-}
-
-source_set("simd") {
- if (current_cpu == "x86") {
- deps = [
- ":simd_asm",
- ]
- sources = [
- "simd/jsimd_i386.c",
- ]
- if (is_win) {
- cflags = [ "/wd4245" ]
- }
- } else if (current_cpu == "x64") {
- deps = [
- ":simd_asm",
- ]
- sources = [
- "simd/jsimd_x86_64.c",
- ]
- } else if (current_cpu == "arm" && arm_version >= 7 &&
- (arm_use_neon || arm_optionally_use_neon)) {
- sources = [
- "simd/jsimd_arm.c",
- "simd/jsimd_arm_neon.S",
- ]
- } else {
- sources = [
- "jsimd_none.c",
- ]
- }
- if (is_win) {
- cflags = [ "/wd4245" ]
- }
-}
-
-config("libjpeg_config") {
- include_dirs = [ "." ]
-}
-
-source_set("libjpeg") {
- sources = [
- "jcapimin.c",
- "jcapistd.c",
- "jccoefct.c",
- "jccolor.c",
- "jcdctmgr.c",
- "jchuff.c",
- "jchuff.h",
- "jcinit.c",
- "jcmainct.c",
- "jcmarker.c",
- "jcmaster.c",
- "jcomapi.c",
- "jconfig.h",
- "jcparam.c",
- "jcphuff.c",
- "jcprepct.c",
- "jcsample.c",
- "jdapimin.c",
- "jdapistd.c",
- "jdatadst.c",
- "jdatasrc.c",
- "jdcoefct.c",
- "jdcolor.c",
- "jdct.h",
- "jddctmgr.c",
- "jdhuff.c",
- "jdhuff.h",
- "jdinput.c",
- "jdmainct.c",
- "jdmarker.c",
- "jdmaster.c",
- "jdmerge.c",
- "jdphuff.c",
- "jdpostct.c",
- "jdsample.c",
- "jerror.c",
- "jerror.h",
- "jfdctflt.c",
- "jfdctfst.c",
- "jfdctint.c",
- "jidctflt.c",
- "jidctfst.c",
- "jidctint.c",
- "jidctred.c",
- "jinclude.h",
- "jmemmgr.c",
- "jmemnobs.c",
- "jmemsys.h",
- "jmorecfg.h",
- "jpegint.h",
- "jpeglib.h",
- "jpeglibmangler.h",
- "jquant1.c",
- "jquant2.c",
- "jutils.c",
- "jversion.h",
- ]
-
- defines = [
- "WITH_SIMD",
- "NO_GETENV",
- ]
-
- configs -= [ "//build/config/compiler:chromium_code" ]
- configs += [ "//build/config/compiler:no_chromium_code" ]
-
- public_configs = [ ":libjpeg_config" ]
-
- # MemorySanitizer doesn't support assembly code, so keep it disabled in
- # MSan builds for now.
- if (is_msan) {
- sources += [ "jsimd_none.c" ]
- } else {
- deps = [
- ":simd",
- ]
- }
-}
diff --git a/build/secondary/third_party/libsrtp/BUILD.gn b/build/secondary/third_party/libsrtp/BUILD.gn
deleted file mode 100644
index 7601bea..0000000
--- a/build/secondary/third_party/libsrtp/BUILD.gn
+++ /dev/null
@@ -1,391 +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.
-
-declare_args() {
- use_system_libsrtp = false
- use_srtp_boringssl = true
-}
-
-config("libsrtp_config") {
- defines = [
- "HAVE_CONFIG_H",
- "HAVE_STDLIB_H",
- "HAVE_STRING_H",
- "TESTAPP_SOURCE",
- ]
-
- include_dirs = [
- "config",
- "srtp/include",
- "srtp/crypto/include",
- ]
-
- if (use_srtp_boringssl) {
- defines += [ "OPENSSL" ]
- }
-
- if (is_posix) {
- defines += [
- "HAVE_INT16_T",
- "HAVE_INT32_T",
- "HAVE_INT8_T",
- "HAVE_UINT16_T",
- "HAVE_UINT32_T",
- "HAVE_UINT64_T",
- "HAVE_UINT8_T",
- "HAVE_STDINT_H",
- "HAVE_INTTYPES_H",
- "HAVE_NETINET_IN_H",
- "HAVE_ARPA_INET_H",
- "HAVE_UNISTD_H",
- ]
- cflags = [ "-Wno-unused-variable" ]
- }
-
- if (is_win) {
- defines += [
- "HAVE_BYTESWAP_METHODS_H",
-
- # All Windows architectures are this way.
- "SIZEOF_UNSIGNED_LONG=4",
- "SIZEOF_UNSIGNED_LONG_LONG=8",
- ]
- }
-
- if (current_cpu == "x64" || current_cpu == "x86" || current_cpu == "arm") {
- defines += [
- # TODO(leozwang): CPU_RISC doesn"t work properly on android/arm
- # platform for unknown reasons, need to investigate the root cause
- # of it. CPU_RISC is used for optimization only, and CPU_CISC should
- # just work just fine, it has been tested on android/arm with srtp
- # test applications and libjingle.
- "CPU_CISC",
- ]
- }
-
- if (current_cpu == "mipsel") {
- defines += [ "CPU_RISC" ]
- }
-}
-
-config("system_libsrtp_config") {
- defines = [ "USE_SYSTEM_LIBSRTP" ]
- include_dirs = [ "/usr/include/srtp" ]
-}
-
-if (use_system_libsrtp) {
- group("libsrtp") {
- public_configs = [
- ":libsrtp_config",
- ":system_libsrtp_config",
- ]
- libs = [ "-lsrtp" ]
- }
-} else {
- static_library("libsrtp") {
- configs -= [ "//build/config/compiler:chromium_code" ]
- configs += [ "//build/config/compiler:no_chromium_code" ]
- public_configs = [ ":libsrtp_config" ]
-
- sources = [
- # includes
- "srtp/include/ekt.h",
- "srtp/include/getopt_s.h",
- "srtp/include/rtp.h",
- "srtp/include/rtp_priv.h",
- "srtp/include/srtp.h",
- "srtp/include/srtp_priv.h",
- "srtp/include/ut_sim.h",
-
- # headers
- "srtp/crypto/include/aes.h",
- "srtp/crypto/include/aes_cbc.h",
- "srtp/crypto/include/aes_icm.h",
- "srtp/crypto/include/alloc.h",
- "srtp/crypto/include/auth.h",
- "srtp/crypto/include/cipher.h",
- "srtp/crypto/include/crypto.h",
- "srtp/crypto/include/crypto_kernel.h",
- "srtp/crypto/include/crypto_math.h",
- "srtp/crypto/include/crypto_types.h",
- "srtp/crypto/include/cryptoalg.h",
- "srtp/crypto/include/datatypes.h",
- "srtp/crypto/include/err.h",
- "srtp/crypto/include/gf2_8.h",
- "srtp/crypto/include/hmac.h",
- "srtp/crypto/include/integers.h",
- "srtp/crypto/include/kernel_compat.h",
- "srtp/crypto/include/key.h",
- "srtp/crypto/include/null_auth.h",
- "srtp/crypto/include/null_cipher.h",
- "srtp/crypto/include/prng.h",
- "srtp/crypto/include/rand_source.h",
- "srtp/crypto/include/rdb.h",
- "srtp/crypto/include/rdbx.h",
- "srtp/crypto/include/sha1.h",
- "srtp/crypto/include/stat.h",
- "srtp/crypto/include/xfm.h",
-
- # sources
- "srtp/crypto/cipher/aes.c",
- "srtp/crypto/cipher/aes_cbc.c",
- "srtp/crypto/cipher/aes_icm.c",
- "srtp/crypto/cipher/cipher.c",
- "srtp/crypto/cipher/null_cipher.c",
- "srtp/crypto/hash/auth.c",
- "srtp/crypto/hash/hmac.c",
- "srtp/crypto/hash/null_auth.c",
- "srtp/crypto/hash/sha1.c",
- "srtp/crypto/kernel/alloc.c",
- "srtp/crypto/kernel/crypto_kernel.c",
- "srtp/crypto/kernel/err.c",
- "srtp/crypto/kernel/key.c",
- "srtp/crypto/math/datatypes.c",
- "srtp/crypto/math/gf2_8.c",
- "srtp/crypto/math/stat.c",
- "srtp/crypto/replay/rdb.c",
- "srtp/crypto/replay/rdbx.c",
- "srtp/crypto/replay/ut_sim.c",
- "srtp/crypto/rng/ctr_prng.c",
- "srtp/crypto/rng/prng.c",
- "srtp/crypto/rng/rand_source.c",
- "srtp/srtp/ekt.c",
- "srtp/srtp/srtp.c",
- ]
-
- if (is_clang) {
- cflags = [ "-Wno-implicit-function-declaration" ]
- }
-
- if (use_srtp_boringssl) {
- deps = [
- "//third_party/boringssl:boringssl",
- ]
- public_deps = [
- "//third_party/boringssl:boringssl",
- ]
- sources -= [
- "srtp/crypto/cipher/aes_cbc.c",
- "srtp/crypto/cipher/aes_icm.c",
- "srtp/crypto/hash/hmac.c",
- "srtp/crypto/hash/sha1.c",
- "srtp/crypto/rng/ctr_prng.c",
- "srtp/crypto/rng/prng.c",
- ]
- sources += [
- "srtp/crypto/cipher/aes_gcm_ossl.c",
- "srtp/crypto/cipher/aes_icm_ossl.c",
- "srtp/crypto/hash/hmac_ossl.c",
- "srtp/crypto/include/aes_gcm_ossl.h",
- "srtp/crypto/include/aes_icm_ossl.h",
- ]
- }
- }
-
- # TODO(GYP): A bunch of these tests don't compile (in gyp either). They're
- # not very broken, so could probably be made to work if it's useful.
- if (!is_win) {
- executable("rdbx_driver") {
- configs -= [ "//build/config/compiler:chromium_code" ]
- configs += [ "//build/config/compiler:no_chromium_code" ]
- deps = [
- ":libsrtp",
- ]
- sources = [
- "srtp/include/getopt_s.h",
- "srtp/test/getopt_s.c",
- "srtp/test/rdbx_driver.c",
- ]
- }
-
- executable("srtp_driver") {
- configs -= [ "//build/config/compiler:chromium_code" ]
- configs += [ "//build/config/compiler:no_chromium_code" ]
- deps = [
- ":libsrtp",
- ]
- sources = [
- "srtp/include/getopt_s.h",
- "srtp/include/srtp_priv.h",
- "srtp/test/getopt_s.c",
- "srtp/test/srtp_driver.c",
- ]
- }
-
- executable("roc_driver") {
- configs -= [ "//build/config/compiler:chromium_code" ]
- configs += [ "//build/config/compiler:no_chromium_code" ]
- deps = [
- ":libsrtp",
- ]
- sources = [
- "srtp/crypto/include/rdbx.h",
- "srtp/include/ut_sim.h",
- "srtp/test/roc_driver.c",
- ]
- }
-
- executable("replay_driver") {
- configs -= [ "//build/config/compiler:chromium_code" ]
- configs += [ "//build/config/compiler:no_chromium_code" ]
- deps = [
- ":libsrtp",
- ]
- sources = [
- "srtp/crypto/include/rdbx.h",
- "srtp/include/ut_sim.h",
- "srtp/test/replay_driver.c",
- ]
- }
-
- executable("rtpw") {
- configs -= [ "//build/config/compiler:chromium_code" ]
- configs += [ "//build/config/compiler:no_chromium_code" ]
- deps = [
- ":libsrtp",
- ]
- sources = [
- "srtp/crypto/include/datatypes.h",
- "srtp/include/getopt_s.h",
- "srtp/include/rtp.h",
- "srtp/include/srtp.h",
- "srtp/test/getopt_s.c",
- "srtp/test/rtp.c",
- "srtp/test/rtpw.c",
- ]
- if (is_android) {
- defines = [ "HAVE_SYS_SOCKET_H" ]
- }
- if (is_clang) {
- cflags = [ "-Wno-implicit-function-declaration" ]
- }
- }
-
- executable("srtp_test_cipher_driver") {
- configs -= [ "//build/config/compiler:chromium_code" ]
- configs += [ "//build/config/compiler:no_chromium_code" ]
- deps = [
- ":libsrtp",
- ]
- sources = [
- "srtp/crypto/test/cipher_driver.c",
- "srtp/include/getopt_s.h",
- "srtp/test/getopt_s.c",
- ]
- }
-
- executable("srtp_test_datatypes_driver") {
- configs -= [ "//build/config/compiler:chromium_code" ]
- configs += [ "//build/config/compiler:no_chromium_code" ]
- deps = [
- ":libsrtp",
- ]
- sources = [
- "srtp/crypto/test/datatypes_driver.c",
- ]
- }
-
- executable("srtp_test_stat_driver") {
- configs -= [ "//build/config/compiler:chromium_code" ]
- configs += [ "//build/config/compiler:no_chromium_code" ]
- deps = [
- ":libsrtp",
- ]
- sources = [
- "srtp/crypto/test/stat_driver.c",
- ]
- }
-
- executable("srtp_test_sha1_driver") {
- configs -= [ "//build/config/compiler:chromium_code" ]
- configs += [ "//build/config/compiler:no_chromium_code" ]
- deps = [
- ":libsrtp",
- ]
- sources = [
- "srtp/crypto/test/sha1_driver.c",
- ]
- }
-
- executable("srtp_test_kernel_driver") {
- configs -= [ "//build/config/compiler:chromium_code" ]
- configs += [ "//build/config/compiler:no_chromium_code" ]
- deps = [
- ":libsrtp",
- ]
- sources = [
- "srtp/crypto/test/kernel_driver.c",
- "srtp/include/getopt_s.h",
- "srtp/test/getopt_s.c",
- ]
- }
-
- executable("srtp_test_aes_calc") {
- configs -= [ "//build/config/compiler:chromium_code" ]
- configs += [ "//build/config/compiler:no_chromium_code" ]
- deps = [
- ":libsrtp",
- ]
- sources = [
- "srtp/crypto/test/aes_calc.c",
- ]
- }
-
- executable("srtp_test_rand_gen") {
- configs -= [ "//build/config/compiler:chromium_code" ]
- configs += [ "//build/config/compiler:no_chromium_code" ]
- deps = [
- ":libsrtp",
- ]
- sources = [
- "srtp/crypto/test/rand_gen.c",
- "srtp/include/getopt_s.h",
- "srtp/test/getopt_s.c",
- ]
- }
-
- executable("srtp_test_rand_gen_soak") {
- configs -= [ "//build/config/compiler:chromium_code" ]
- configs += [ "//build/config/compiler:no_chromium_code" ]
- deps = [
- ":libsrtp",
- ]
- sources = [
- "srtp/crypto/test/rand_gen_soak.c",
- "srtp/include/getopt_s.h",
- "srtp/test/getopt_s.c",
- ]
- }
-
- executable("srtp_test_env") {
- configs -= [ "//build/config/compiler:chromium_code" ]
- configs += [ "//build/config/compiler:no_chromium_code" ]
- deps = [
- ":libsrtp",
- ]
- sources = [
- "srtp/crypto/test/env.c",
- ]
- }
-
- group("srtp_runtest") {
- deps = [
- ":rdbx_driver",
- ":srtp_driver",
- ":roc_driver",
- ":replay_driver",
- ":rtpw",
- ":srtp_test_cipher_driver",
- ":srtp_test_datatypes_driver",
- ":srtp_test_stat_driver",
- ":srtp_test_sha1_driver",
- ":srtp_test_kernel_driver",
- ":srtp_test_aes_calc",
- ":srtp_test_rand_gen",
- ":srtp_test_rand_gen_soak",
- ":srtp_test_env",
- ]
- }
- }
-}
diff --git a/build/secondary/third_party/nss/BUILD.gn b/build/secondary/third_party/nss/BUILD.gn
deleted file mode 100644
index 25d449e..0000000
--- a/build/secondary/third_party/nss/BUILD.gn
+++ /dev/null
@@ -1,1211 +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/linux/pkg_config.gni")
-
-if (is_linux) {
- # This is a dependency on NSS with no libssl. On Linux we use a built-in SSL
- # library but the system NSS libraries. Non-Linux platforms using NSS use the
- # hermetic one in //third_party/nss.
- #
- # Generally you should depend on //crypto:platform instead of using this
- # config since that will properly pick up NSS or OpenSSL depending on
- # platform and build config.
- pkg_config("system_nss_no_ssl_config") {
- packages = [ "nss" ]
- extra_args = [
- "-v",
- "-lssl3",
- ]
- }
-} else {
- include_nss_root_certs = is_ios
- include_nss_libpkix = is_ios
-
- config("nspr_config") {
- defines = [ "NO_NSPR_10_SUPPORT" ]
- include_dirs = [
- "nspr/pr/include",
- "nspr/lib/ds",
- "nspr/lib/libc/include",
- ]
-
- if (component_mode != "shared_library") {
- defines += [ "NSPR_STATIC" ]
- }
- }
-
- component("nspr") {
- output_name = "crnspr"
- sources = [
- "nspr/lib/ds/plarena.c",
- "nspr/lib/ds/plarena.h",
- "nspr/lib/ds/plarenas.h",
- "nspr/lib/ds/plhash.c",
- "nspr/lib/ds/plhash.h",
- "nspr/lib/libc/include/plbase64.h",
- "nspr/lib/libc/include/plerror.h",
- "nspr/lib/libc/include/plgetopt.h",
- "nspr/lib/libc/include/plstr.h",
- "nspr/lib/libc/src/base64.c",
- "nspr/lib/libc/src/plerror.c",
- "nspr/lib/libc/src/plgetopt.c",
- "nspr/lib/libc/src/strcase.c",
- "nspr/lib/libc/src/strcat.c",
- "nspr/lib/libc/src/strchr.c",
- "nspr/lib/libc/src/strcmp.c",
- "nspr/lib/libc/src/strcpy.c",
- "nspr/lib/libc/src/strdup.c",
- "nspr/lib/libc/src/strlen.c",
- "nspr/lib/libc/src/strpbrk.c",
- "nspr/lib/libc/src/strstr.c",
- "nspr/lib/libc/src/strtok.c",
- "nspr/pr/include/md/_darwin.cfg",
- "nspr/pr/include/md/_darwin.h",
- "nspr/pr/include/md/_pcos.h",
- "nspr/pr/include/md/_pth.h",
- "nspr/pr/include/md/_unix_errors.h",
- "nspr/pr/include/md/_unixos.h",
- "nspr/pr/include/md/_win32_errors.h",
- "nspr/pr/include/md/_win95.cfg",
- "nspr/pr/include/md/_win95.h",
- "nspr/pr/include/md/prosdep.h",
- "nspr/pr/include/nspr.h",
- "nspr/pr/include/obsolete/pralarm.h",
- "nspr/pr/include/obsolete/probslet.h",
- "nspr/pr/include/obsolete/protypes.h",
- "nspr/pr/include/obsolete/prsem.h",
- "nspr/pr/include/pratom.h",
- "nspr/pr/include/prbit.h",
- "nspr/pr/include/prclist.h",
- "nspr/pr/include/prcmon.h",
- "nspr/pr/include/prcountr.h",
- "nspr/pr/include/prcpucfg.h",
- "nspr/pr/include/prcvar.h",
- "nspr/pr/include/prdtoa.h",
- "nspr/pr/include/prenv.h",
- "nspr/pr/include/prerr.h",
- "nspr/pr/include/prerror.h",
- "nspr/pr/include/prinet.h",
- "nspr/pr/include/prinit.h",
- "nspr/pr/include/prinrval.h",
- "nspr/pr/include/prio.h",
- "nspr/pr/include/pripcsem.h",
- "nspr/pr/include/private/pprio.h",
- "nspr/pr/include/private/pprmwait.h",
- "nspr/pr/include/private/pprthred.h",
- "nspr/pr/include/private/primpl.h",
- "nspr/pr/include/private/prpriv.h",
- "nspr/pr/include/prlink.h",
- "nspr/pr/include/prlock.h",
- "nspr/pr/include/prlog.h",
- "nspr/pr/include/prlong.h",
- "nspr/pr/include/prmem.h",
- "nspr/pr/include/prmon.h",
- "nspr/pr/include/prmwait.h",
- "nspr/pr/include/prnetdb.h",
- "nspr/pr/include/prolock.h",
- "nspr/pr/include/prpdce.h",
- "nspr/pr/include/prprf.h",
- "nspr/pr/include/prproces.h",
- "nspr/pr/include/prrng.h",
- "nspr/pr/include/prrwlock.h",
- "nspr/pr/include/prshm.h",
- "nspr/pr/include/prshma.h",
- "nspr/pr/include/prsystem.h",
- "nspr/pr/include/prthread.h",
- "nspr/pr/include/prtime.h",
- "nspr/pr/include/prtpool.h",
- "nspr/pr/include/prtrace.h",
- "nspr/pr/include/prtypes.h",
- "nspr/pr/include/prvrsion.h",
- "nspr/pr/include/prwin16.h",
- "nspr/pr/src/io/prdir.c",
- "nspr/pr/src/io/prfdcach.c",
- "nspr/pr/src/io/prfile.c",
- "nspr/pr/src/io/prio.c",
- "nspr/pr/src/io/priometh.c",
- "nspr/pr/src/io/pripv6.c",
- "nspr/pr/src/io/prlayer.c",
- "nspr/pr/src/io/prlog.c",
- "nspr/pr/src/io/prmapopt.c",
- "nspr/pr/src/io/prmmap.c",
- "nspr/pr/src/io/prmwait.c",
- "nspr/pr/src/io/prpolevt.c",
- "nspr/pr/src/io/prprf.c",
- "nspr/pr/src/io/prscanf.c",
- "nspr/pr/src/io/prsocket.c",
- "nspr/pr/src/io/prstdio.c",
- "nspr/pr/src/linking/prlink.c",
- "nspr/pr/src/malloc/prmalloc.c",
- "nspr/pr/src/malloc/prmem.c",
- "nspr/pr/src/md/prosdep.c",
- "nspr/pr/src/md/unix/darwin.c",
- "nspr/pr/src/md/unix/os_Darwin.s",
- "nspr/pr/src/md/unix/unix.c",
- "nspr/pr/src/md/unix/unix_errors.c",
- "nspr/pr/src/md/unix/uxproces.c",
- "nspr/pr/src/md/unix/uxrng.c",
- "nspr/pr/src/md/unix/uxshm.c",
- "nspr/pr/src/md/unix/uxwrap.c",
- "nspr/pr/src/md/windows/ntgc.c",
- "nspr/pr/src/md/windows/ntinrval.c",
- "nspr/pr/src/md/windows/ntmisc.c",
- "nspr/pr/src/md/windows/ntsec.c",
- "nspr/pr/src/md/windows/ntsem.c",
- "nspr/pr/src/md/windows/w32ipcsem.c",
- "nspr/pr/src/md/windows/w32poll.c",
- "nspr/pr/src/md/windows/w32rng.c",
- "nspr/pr/src/md/windows/w32shm.c",
- "nspr/pr/src/md/windows/w95cv.c",
- "nspr/pr/src/md/windows/w95dllmain.c",
- "nspr/pr/src/md/windows/w95io.c",
- "nspr/pr/src/md/windows/w95sock.c",
- "nspr/pr/src/md/windows/w95thred.c",
- "nspr/pr/src/md/windows/win32_errors.c",
- "nspr/pr/src/memory/prseg.c",
- "nspr/pr/src/memory/prshm.c",
- "nspr/pr/src/memory/prshma.c",
- "nspr/pr/src/misc/pralarm.c",
- "nspr/pr/src/misc/pratom.c",
- "nspr/pr/src/misc/praton.c",
- "nspr/pr/src/misc/prcountr.c",
- "nspr/pr/src/misc/prdtoa.c",
- "nspr/pr/src/misc/prenv.c",
- "nspr/pr/src/misc/prerr.c",
- "nspr/pr/src/misc/prerror.c",
- "nspr/pr/src/misc/prerrortable.c",
- "nspr/pr/src/misc/prinit.c",
- "nspr/pr/src/misc/prinrval.c",
- "nspr/pr/src/misc/pripc.c",
- "nspr/pr/src/misc/pripcsem.c",
- "nspr/pr/src/misc/prlog2.c",
- "nspr/pr/src/misc/prlong.c",
- "nspr/pr/src/misc/prnetdb.c",
- "nspr/pr/src/misc/prolock.c",
- "nspr/pr/src/misc/prrng.c",
- "nspr/pr/src/misc/prsystem.c",
- "nspr/pr/src/misc/prthinfo.c",
- "nspr/pr/src/misc/prtime.c",
- "nspr/pr/src/misc/prtpool.c",
- "nspr/pr/src/misc/prtrace.c",
- "nspr/pr/src/pthreads/ptio.c",
- "nspr/pr/src/pthreads/ptmisc.c",
- "nspr/pr/src/pthreads/ptsynch.c",
- "nspr/pr/src/pthreads/ptthread.c",
- "nspr/pr/src/threads/combined/prucpu.c",
- "nspr/pr/src/threads/combined/prucv.c",
- "nspr/pr/src/threads/combined/prulock.c",
- "nspr/pr/src/threads/combined/prustack.c",
- "nspr/pr/src/threads/combined/pruthr.c",
- "nspr/pr/src/threads/prcmon.c",
- "nspr/pr/src/threads/prcthr.c",
- "nspr/pr/src/threads/prdump.c",
- "nspr/pr/src/threads/prmon.c",
- "nspr/pr/src/threads/prrwlock.c",
- "nspr/pr/src/threads/prsem.c",
- "nspr/pr/src/threads/prtpd.c",
- ]
-
- public_configs = [ ":nspr_config" ]
-
- configs -= [ "//build/config/compiler:chromium_code" ]
- if (is_win) {
- configs -= [
- "//build/config/win:unicode", # Requires 8-bit mode.
- "//build/config/win:lean_and_mean", # Won"t compile with lean and mean.
- ]
- }
- configs += [
- "//build/config/compiler:no_chromium_code",
- "//build/config/compiler:no_size_t_to_int_warning",
- ]
-
- cflags = []
- defines = [
- "_NSPR_BUILD_",
- "FORCE_PR_LOG",
- ]
-
- include_dirs = [ "nspr/pr/include/private" ]
-
- if (is_win) {
- cflags = [ "/wd4554" ] # Check precidence.
- defines += [
- "XP_PC",
- "WIN32",
- "WIN95",
- "_PR_GLOBAL_THREADS_ONLY",
- "_CRT_SECURE_NO_WARNINGS",
- ]
- } else {
- sources -= [
- "nspr/pr/src/md/windows/ntgc.c",
- "nspr/pr/src/md/windows/ntinrval.c",
- "nspr/pr/src/md/windows/ntmisc.c",
- "nspr/pr/src/md/windows/ntsec.c",
- "nspr/pr/src/md/windows/ntsem.c",
- "nspr/pr/src/md/windows/w32ipcsem.c",
- "nspr/pr/src/md/windows/w32poll.c",
- "nspr/pr/src/md/windows/w32rng.c",
- "nspr/pr/src/md/windows/w32shm.c",
- "nspr/pr/src/md/windows/w95cv.c",
- "nspr/pr/src/md/windows/w95dllmain.c",
- "nspr/pr/src/md/windows/w95io.c",
- "nspr/pr/src/md/windows/w95sock.c",
- "nspr/pr/src/md/windows/w95thred.c",
- "nspr/pr/src/md/windows/win32_errors.c",
- "nspr/pr/src/threads/combined/prucpu.c",
- "nspr/pr/src/threads/combined/prucv.c",
- "nspr/pr/src/threads/combined/prulock.c",
- "nspr/pr/src/threads/combined/prustack.c",
- "nspr/pr/src/threads/combined/pruthr.c",
- ]
- }
-
- if (!is_posix) {
- sources -= [
- "nspr/pr/src/md/unix/darwin.c",
- "nspr/pr/src/md/unix/os_Darwin.s",
- "nspr/pr/src/md/unix/unix.c",
- "nspr/pr/src/md/unix/unix_errors.c",
- "nspr/pr/src/md/unix/uxproces.c",
- "nspr/pr/src/md/unix/uxrng.c",
- "nspr/pr/src/md/unix/uxshm.c",
- "nspr/pr/src/md/unix/uxwrap.c",
- "nspr/pr/src/pthreads/ptio.c",
- "nspr/pr/src/pthreads/ptmisc.c",
- "nspr/pr/src/pthreads/ptsynch.c",
- "nspr/pr/src/pthreads/ptthread.c",
- ]
- }
-
- if (current_cpu == "x86") {
- defines += [ "_X86_" ]
- } else if (current_cpu == "x64") {
- defines += [ "_AMD64_" ]
- }
-
- if (is_mac || is_ios) {
- sources -= [
- "nspr/pr/src/io/prdir.c",
- "nspr/pr/src/io/prfile.c",
- "nspr/pr/src/io/prio.c",
- "nspr/pr/src/io/prsocket.c",
- "nspr/pr/src/misc/pripcsem.c",
- "nspr/pr/src/threads/prcthr.c",
- "nspr/pr/src/threads/prdump.c",
- "nspr/pr/src/threads/prmon.c",
- "nspr/pr/src/threads/prsem.c",
- ]
- defines += [
- "XP_UNIX",
- "DARWIN",
- "XP_MACOSX",
- "_PR_PTHREADS",
- "HAVE_BSD_FLOCK",
- "HAVE_DLADDR",
- "HAVE_LCHOWN",
- "HAVE_SOCKLEN_T",
- "HAVE_STRERROR",
- ]
- }
-
- if (is_mac) {
- defines += [ "HAVE_CRT_EXTERNS_H" ]
- libs = [
- "CoreFoundation.framework",
- "CoreServices.framework",
- ]
- }
-
- if (is_clang) {
- cflags += [
- # nspr uses a bunch of deprecated functions (NSLinkModule etc) in
- # prlink.c on mac.
- "-Wno-deprecated-declarations",
-
- # nspr passes "const char*" through "void*".
- "-Wno-incompatible-pointer-types",
-
- # nspr passes "int*" through "unsigned int*".
- "-Wno-pointer-sign",
- ]
-
- # nspr uses assert(!"foo") instead of assert(false && "foo").
- configs -= [ "//build/config/clang:extra_warnings" ]
- }
- }
-
- component("nss") {
- output_name = "crnss"
- sources = [
- # Ensure at least one object file is produced, so that MSVC does not
- # warn when creating the static/shared library. See the note for
- # the "nssckbi" target for why the "nss" target was split as such.
- "nss/lib/nss/nssver.c",
- ]
-
- public_deps = [
- ":nss_static",
- ]
-
- if (include_nss_root_certs) {
- public_deps += [ ":nssckbi" ]
- }
-
- if (component_mode == "shared_library") {
- if (is_mac) {
- ldflags = [ "-all_load" ]
- } else if (is_win) {
- # Pass the def file to the linker.
- ldflags =
- [ "/DEF:" + rebase_path("nss/exports_win.def", root_build_dir) ]
- }
- }
- }
-
- config("nssckbi_config") {
- include_dirs = [ "nss/lib/ckfw/builtins" ]
- }
-
- # This is really more of a pseudo-target to work around the fact that
- # a single static_library target cannot contain two object files of the
- # same name (hash.o / hash.obj). Logically, this is part of the
- # "nss_static" target. By separating it out, it creates a possible
- # circular dependency between "nss_static" and "nssckbi" when
- # "exclude_nss_root_certs" is not specified, as "nss_static" depends on
- # the "builtinsC_GetFunctionList" exported by this target. This is an
- # artifact of how NSS is being statically built, which is not an
- # officially supported configuration - normally, "nssckbi.dll/so" would
- # depend on libnss3.dll/so, and the higher layer caller would instruct
- # libnss3.dll to dynamically load nssckbi.dll, breaking the circle.
- #
- # TODO(rsleevi): http://crbug.com/128134 - Break the circular dependency
- # without requiring nssckbi to be built as a shared library.
- source_set("nssckbi") {
- visibility = [ ":nss" ] # This target is internal implementation detail.
-
- sources = [
- "nss/lib/ckfw/builtins/anchor.c",
- "nss/lib/ckfw/builtins/bfind.c",
- "nss/lib/ckfw/builtins/binst.c",
- "nss/lib/ckfw/builtins/bobject.c",
- "nss/lib/ckfw/builtins/bsession.c",
- "nss/lib/ckfw/builtins/bslot.c",
- "nss/lib/ckfw/builtins/btoken.c",
- "nss/lib/ckfw/builtins/builtins.h",
- "nss/lib/ckfw/builtins/certdata.c",
- "nss/lib/ckfw/builtins/ckbiver.c",
- "nss/lib/ckfw/builtins/constants.c",
- "nss/lib/ckfw/builtins/nssckbi.h",
- "nss/lib/ckfw/ck.h",
- "nss/lib/ckfw/ckfw.h",
- "nss/lib/ckfw/ckfwm.h",
- "nss/lib/ckfw/ckfwtm.h",
- "nss/lib/ckfw/ckmd.h",
- "nss/lib/ckfw/ckt.h",
- "nss/lib/ckfw/crypto.c",
- "nss/lib/ckfw/find.c",
- "nss/lib/ckfw/hash.c",
- "nss/lib/ckfw/instance.c",
- "nss/lib/ckfw/mechanism.c",
- "nss/lib/ckfw/mutex.c",
- "nss/lib/ckfw/nssck.api",
- "nss/lib/ckfw/nssckepv.h",
- "nss/lib/ckfw/nssckft.h",
- "nss/lib/ckfw/nssckfw.h",
- "nss/lib/ckfw/nssckfwc.h",
- "nss/lib/ckfw/nssckfwt.h",
- "nss/lib/ckfw/nssckg.h",
- "nss/lib/ckfw/nssckmdt.h",
- "nss/lib/ckfw/nssckt.h",
- "nss/lib/ckfw/object.c",
- "nss/lib/ckfw/session.c",
- "nss/lib/ckfw/sessobj.c",
- "nss/lib/ckfw/slot.c",
- "nss/lib/ckfw/token.c",
- "nss/lib/ckfw/wrap.c",
- ]
-
- configs -= [ "//build/config/compiler:chromium_code" ]
-
- if (is_win) {
- configs -= [ "//build/config/win:unicode" ] # Requires 8-bit mode.
- }
- configs += [ "//build/config/compiler:no_chromium_code" ]
-
- include_dirs = [ "nss/lib/ckfw" ]
- public_configs = [ ":nssckbi_config" ]
-
- public_deps = [
- ":nss_static",
- ]
- }
-
- config("nss_static_config") {
- defines = [
- "NSS_STATIC",
- "NSS_USE_STATIC_LIBS",
- "USE_UTIL_DIRECTLY",
- ]
- if (is_win) {
- defines += [ "_WINDOWS" ]
- }
- include_dirs = [
- "nspr/pr/include",
- "nspr/lib/ds",
- "nspr/lib/libc/include",
- "nss/lib/base",
- "nss/lib/certdb",
- "nss/lib/certhigh",
- "nss/lib/cryptohi",
- "nss/lib/dev",
- "nss/lib/freebl",
- "nss/lib/freebl/ecl",
- "nss/lib/nss",
- "nss/lib/pk11wrap",
- "nss/lib/pkcs7",
- "nss/lib/pki",
- "nss/lib/smime",
- "nss/lib/softoken",
- "nss/lib/util",
- ]
- }
-
- if (is_win && current_cpu == "x86") {
- source_set("nss_static_avx") {
- sources = [
- "nss/lib/freebl/intel-gcm-wrap.c",
- "nss/lib/freebl/intel-gcm-x86-masm.asm",
- "nss/lib/freebl/intel-gcm.h",
- ]
- defines = [
- "_WINDOWS",
- "_X86_",
- "INTEL_GCM",
- "MP_API_COMPATIBLE",
- "MP_ASSEMBLY_DIV_2DX1D",
- "MP_ASSEMBLY_MULTIPLY",
- "MP_ASSEMBLY_SQUARE",
- "MP_NO_MP_WORD",
- "MP_USE_UINT_DIGIT",
- "NSS_DISABLE_DBM",
- "NSS_STATIC",
- "NSS_USE_STATIC_LIBS",
- "NSS_X86",
- "NSS_X86_OR_X64",
- "RIJNDAEL_INCLUDE_TABLES",
- "SHLIB_PREFIX=\"\"",
- "SHLIB_SUFFIX=\"dll\"",
- "SHLIB_VERSION=\"3\"",
- "SOFTOKEN_LIB_NAME=\"softokn3.dll\"",
- "SOFTOKEN_SHLIB_VERSION=\"3\"",
- "USE_HW_AES",
- "USE_UTIL_DIRECTLY",
- "WIN32",
- "WIN95",
- "XP_PC",
- ]
- include_dirs = [
- "nspr/pr/include",
- "nspr/lib/ds",
- "nspr/lib/libc/include",
- "nss/lib/freebl/ecl",
- "nss/lib/util",
- ]
- }
- }
-
- source_set("nss_static") {
- visibility = [ ":*" ] # Internal implementation detail.
-
- sources = [
- "nss/lib/base/arena.c",
- "nss/lib/base/base.h",
- "nss/lib/base/baset.h",
- "nss/lib/base/error.c",
- "nss/lib/base/errorval.c",
- "nss/lib/base/hash.c",
- "nss/lib/base/hashops.c",
- "nss/lib/base/item.c",
- "nss/lib/base/libc.c",
- "nss/lib/base/list.c",
- "nss/lib/base/nssbase.h",
- "nss/lib/base/nssbaset.h",
- "nss/lib/base/nssutf8.c",
- "nss/lib/base/tracker.c",
- "nss/lib/certdb/alg1485.c",
- "nss/lib/certdb/cert.h",
- "nss/lib/certdb/certdb.c",
- "nss/lib/certdb/certdb.h",
- "nss/lib/certdb/certi.h",
- "nss/lib/certdb/certt.h",
- "nss/lib/certdb/certv3.c",
- "nss/lib/certdb/certxutl.c",
- "nss/lib/certdb/certxutl.h",
- "nss/lib/certdb/crl.c",
- "nss/lib/certdb/genname.c",
- "nss/lib/certdb/genname.h",
- "nss/lib/certdb/polcyxtn.c",
- "nss/lib/certdb/secname.c",
- "nss/lib/certdb/stanpcertdb.c",
- "nss/lib/certdb/xauthkid.c",
- "nss/lib/certdb/xbsconst.c",
- "nss/lib/certdb/xconst.c",
- "nss/lib/certdb/xconst.h",
- "nss/lib/certhigh/certhigh.c",
- "nss/lib/certhigh/certhtml.c",
- "nss/lib/certhigh/certreq.c",
- "nss/lib/certhigh/certvfy.c",
- "nss/lib/certhigh/crlv2.c",
- "nss/lib/certhigh/ocsp.c",
- "nss/lib/certhigh/ocsp.h",
- "nss/lib/certhigh/ocspi.h",
- "nss/lib/certhigh/ocspsig.c",
- "nss/lib/certhigh/ocspt.h",
- "nss/lib/certhigh/ocspti.h",
- "nss/lib/certhigh/xcrldist.c",
- "nss/lib/cryptohi/cryptohi.h",
- "nss/lib/cryptohi/cryptoht.h",
- "nss/lib/cryptohi/dsautil.c",
- "nss/lib/cryptohi/key.h",
- "nss/lib/cryptohi/keyhi.h",
- "nss/lib/cryptohi/keyi.h",
- "nss/lib/cryptohi/keyt.h",
- "nss/lib/cryptohi/keythi.h",
- "nss/lib/cryptohi/sechash.c",
- "nss/lib/cryptohi/sechash.h",
- "nss/lib/cryptohi/seckey.c",
- "nss/lib/cryptohi/secsign.c",
- "nss/lib/cryptohi/secvfy.c",
- "nss/lib/dev/ckhelper.c",
- "nss/lib/dev/ckhelper.h",
- "nss/lib/dev/dev.h",
- "nss/lib/dev/devm.h",
- "nss/lib/dev/devslot.c",
- "nss/lib/dev/devt.h",
- "nss/lib/dev/devtm.h",
- "nss/lib/dev/devtoken.c",
- "nss/lib/dev/devutil.c",
- "nss/lib/dev/nssdev.h",
- "nss/lib/dev/nssdevt.h",
- "nss/lib/freebl/aeskeywrap.c",
- "nss/lib/freebl/alg2268.c",
- "nss/lib/freebl/alghmac.c",
- "nss/lib/freebl/alghmac.h",
- "nss/lib/freebl/arcfive.c",
- "nss/lib/freebl/arcfour.c",
- "nss/lib/freebl/blapi.h",
- "nss/lib/freebl/blapii.h",
- "nss/lib/freebl/blapit.h",
- "nss/lib/freebl/camellia.c",
- "nss/lib/freebl/camellia.h",
- "nss/lib/freebl/chacha20/chacha20.c",
- "nss/lib/freebl/chacha20/chacha20.h",
- "nss/lib/freebl/chacha20/chacha20_vec.c",
- "nss/lib/freebl/chacha20poly1305.c",
- "nss/lib/freebl/chacha20poly1305.h",
- "nss/lib/freebl/ctr.c",
- "nss/lib/freebl/ctr.h",
- "nss/lib/freebl/cts.c",
- "nss/lib/freebl/cts.h",
- "nss/lib/freebl/des.c",
- "nss/lib/freebl/des.h",
- "nss/lib/freebl/desblapi.c",
- "nss/lib/freebl/dh.c",
- "nss/lib/freebl/drbg.c",
- "nss/lib/freebl/dsa.c",
- "nss/lib/freebl/ec.c",
- "nss/lib/freebl/ec.h",
- "nss/lib/freebl/ecdecode.c",
- "nss/lib/freebl/ecl/ec2.h",
- "nss/lib/freebl/ecl/ec_naf.c",
- "nss/lib/freebl/ecl/ecl-curve.h",
- "nss/lib/freebl/ecl/ecl-exp.h",
- "nss/lib/freebl/ecl/ecl-priv.h",
- "nss/lib/freebl/ecl/ecl.c",
- "nss/lib/freebl/ecl/ecl.h",
- "nss/lib/freebl/ecl/ecl_curve.c",
- "nss/lib/freebl/ecl/ecl_gf.c",
- "nss/lib/freebl/ecl/ecl_mult.c",
- "nss/lib/freebl/ecl/ecp.h",
- "nss/lib/freebl/ecl/ecp_256.c",
- "nss/lib/freebl/ecl/ecp_256_32.c",
- "nss/lib/freebl/ecl/ecp_384.c",
- "nss/lib/freebl/ecl/ecp_521.c",
- "nss/lib/freebl/ecl/ecp_aff.c",
- "nss/lib/freebl/ecl/ecp_jac.c",
- "nss/lib/freebl/ecl/ecp_jm.c",
- "nss/lib/freebl/ecl/ecp_mont.c",
- "nss/lib/freebl/gcm.c",
- "nss/lib/freebl/gcm.h",
- "nss/lib/freebl/hmacct.c",
- "nss/lib/freebl/hmacct.h",
- "nss/lib/freebl/intel-aes-x86-masm.asm",
- "nss/lib/freebl/intel-aes.h",
- "nss/lib/freebl/jpake.c",
- "nss/lib/freebl/md2.c",
- "nss/lib/freebl/md5.c",
- "nss/lib/freebl/mpi/logtab.h",
- "nss/lib/freebl/mpi/mp_gf2m-priv.h",
- "nss/lib/freebl/mpi/mp_gf2m.c",
- "nss/lib/freebl/mpi/mp_gf2m.h",
- "nss/lib/freebl/mpi/mpcpucache.c",
- "nss/lib/freebl/mpi/mpi-config.h",
- "nss/lib/freebl/mpi/mpi-priv.h",
- "nss/lib/freebl/mpi/mpi.c",
- "nss/lib/freebl/mpi/mpi.h",
- "nss/lib/freebl/mpi/mpi_amd64.c",
- "nss/lib/freebl/mpi/mpi_arm.c",
- "nss/lib/freebl/mpi/mpi_arm_mac.c",
- "nss/lib/freebl/mpi/mpi_x86_asm.c",
- "nss/lib/freebl/mpi/mplogic.c",
- "nss/lib/freebl/mpi/mplogic.h",
- "nss/lib/freebl/mpi/mpmontg.c",
- "nss/lib/freebl/mpi/mpprime.c",
- "nss/lib/freebl/mpi/mpprime.h",
- "nss/lib/freebl/mpi/primes.c",
- "nss/lib/freebl/nss_build_config_mac.h",
- "nss/lib/freebl/poly1305/poly1305-donna-x64-sse2-incremental-source.c",
- "nss/lib/freebl/poly1305/poly1305.c",
- "nss/lib/freebl/poly1305/poly1305.h",
- "nss/lib/freebl/pqg.c",
- "nss/lib/freebl/pqg.h",
- "nss/lib/freebl/rawhash.c",
- "nss/lib/freebl/rijndael.c",
- "nss/lib/freebl/rijndael.h",
- "nss/lib/freebl/rijndael32.tab",
- "nss/lib/freebl/rsa.c",
- "nss/lib/freebl/rsapkcs.c",
- "nss/lib/freebl/secmpi.h",
- "nss/lib/freebl/secrng.h",
- "nss/lib/freebl/seed.c",
- "nss/lib/freebl/seed.h",
- "nss/lib/freebl/sha256.h",
- "nss/lib/freebl/sha512.c",
- "nss/lib/freebl/sha_fast.c",
- "nss/lib/freebl/sha_fast.h",
- "nss/lib/freebl/shsign.h",
- "nss/lib/freebl/shvfy.c",
- "nss/lib/freebl/sysrand.c",
- "nss/lib/freebl/tlsprfalg.c",
- "nss/lib/freebl/unix_rand.c",
- "nss/lib/freebl/win_rand.c",
- "nss/lib/nss/nss.h",
- "nss/lib/nss/nssinit.c",
- "nss/lib/nss/nssrenam.h",
- "nss/lib/nss/utilwrap.c",
- "nss/lib/pk11wrap/debug_module.c",
- "nss/lib/pk11wrap/dev3hack.c",
- "nss/lib/pk11wrap/dev3hack.h",
- "nss/lib/pk11wrap/pk11akey.c",
- "nss/lib/pk11wrap/pk11auth.c",
- "nss/lib/pk11wrap/pk11cert.c",
- "nss/lib/pk11wrap/pk11cxt.c",
- "nss/lib/pk11wrap/pk11err.c",
- "nss/lib/pk11wrap/pk11func.h",
- "nss/lib/pk11wrap/pk11kea.c",
- "nss/lib/pk11wrap/pk11list.c",
- "nss/lib/pk11wrap/pk11load.c",
- "nss/lib/pk11wrap/pk11mech.c",
- "nss/lib/pk11wrap/pk11merge.c",
- "nss/lib/pk11wrap/pk11nobj.c",
- "nss/lib/pk11wrap/pk11obj.c",
- "nss/lib/pk11wrap/pk11pars.c",
- "nss/lib/pk11wrap/pk11pbe.c",
- "nss/lib/pk11wrap/pk11pk12.c",
- "nss/lib/pk11wrap/pk11pqg.c",
- "nss/lib/pk11wrap/pk11pqg.h",
- "nss/lib/pk11wrap/pk11priv.h",
- "nss/lib/pk11wrap/pk11pub.h",
- "nss/lib/pk11wrap/pk11sdr.c",
- "nss/lib/pk11wrap/pk11sdr.h",
- "nss/lib/pk11wrap/pk11skey.c",
- "nss/lib/pk11wrap/pk11slot.c",
- "nss/lib/pk11wrap/pk11util.c",
- "nss/lib/pk11wrap/secmod.h",
- "nss/lib/pk11wrap/secmodi.h",
- "nss/lib/pk11wrap/secmodt.h",
- "nss/lib/pk11wrap/secmodti.h",
- "nss/lib/pk11wrap/secpkcs5.h",
- "nss/lib/pkcs7/certread.c",
- "nss/lib/pkcs7/p7common.c",
- "nss/lib/pkcs7/p7create.c",
- "nss/lib/pkcs7/p7decode.c",
- "nss/lib/pkcs7/p7encode.c",
- "nss/lib/pkcs7/p7local.c",
- "nss/lib/pkcs7/p7local.h",
- "nss/lib/pkcs7/pkcs7t.h",
- "nss/lib/pkcs7/secmime.c",
- "nss/lib/pkcs7/secmime.h",
- "nss/lib/pkcs7/secpkcs7.h",
- "nss/lib/pki/asymmkey.c",
- "nss/lib/pki/certdecode.c",
- "nss/lib/pki/certificate.c",
- "nss/lib/pki/cryptocontext.c",
- "nss/lib/pki/nsspki.h",
- "nss/lib/pki/nsspkit.h",
- "nss/lib/pki/pki.h",
- "nss/lib/pki/pki3hack.c",
- "nss/lib/pki/pki3hack.h",
- "nss/lib/pki/pkibase.c",
- "nss/lib/pki/pkim.h",
- "nss/lib/pki/pkistore.c",
- "nss/lib/pki/pkistore.h",
- "nss/lib/pki/pkit.h",
- "nss/lib/pki/pkitm.h",
- "nss/lib/pki/symmkey.c",
- "nss/lib/pki/tdcache.c",
- "nss/lib/pki/trustdomain.c",
- "nss/lib/smime/cms.h",
- "nss/lib/smime/cmslocal.h",
- "nss/lib/smime/cmsreclist.h",
- "nss/lib/smime/cmst.h",
- "nss/lib/smime/smime.h",
- "nss/lib/softoken/fipsaudt.c",
- "nss/lib/softoken/fipstest.c",
- "nss/lib/softoken/fipstokn.c",
- "nss/lib/softoken/jpakesftk.c",
- "nss/lib/softoken/lgglue.c",
- "nss/lib/softoken/lgglue.h",
- "nss/lib/softoken/lowkey.c",
- "nss/lib/softoken/lowkeyi.h",
- "nss/lib/softoken/lowkeyti.h",
- "nss/lib/softoken/lowpbe.c",
- "nss/lib/softoken/lowpbe.h",
- "nss/lib/softoken/padbuf.c",
- "nss/lib/softoken/pkcs11.c",
- "nss/lib/softoken/pkcs11c.c",
- "nss/lib/softoken/pkcs11i.h",
- "nss/lib/softoken/pkcs11ni.h",
- "nss/lib/softoken/pkcs11u.c",
- "nss/lib/softoken/sdb.c",
- "nss/lib/softoken/sdb.h",
- "nss/lib/softoken/sftkdb.c",
- "nss/lib/softoken/sftkdb.h",
- "nss/lib/softoken/sftkdbt.h",
- "nss/lib/softoken/sftkdbti.h",
- "nss/lib/softoken/sftkhmac.c",
- "nss/lib/softoken/sftkpars.c",
- "nss/lib/softoken/sftkpars.h",
- "nss/lib/softoken/sftkpwd.c",
- "nss/lib/softoken/softkver.c",
- "nss/lib/softoken/softkver.h",
- "nss/lib/softoken/softoken.h",
- "nss/lib/softoken/softoknt.h",
- "nss/lib/softoken/tlsprf.c",
- "nss/lib/ssl/sslerr.h",
- "nss/lib/util/SECerrs.h",
- "nss/lib/util/base64.h",
- "nss/lib/util/ciferfam.h",
- "nss/lib/util/derdec.c",
- "nss/lib/util/derenc.c",
- "nss/lib/util/dersubr.c",
- "nss/lib/util/dertime.c",
- "nss/lib/util/errstrs.c",
- "nss/lib/util/hasht.h",
- "nss/lib/util/nssb64.h",
- "nss/lib/util/nssb64d.c",
- "nss/lib/util/nssb64e.c",
- "nss/lib/util/nssb64t.h",
- "nss/lib/util/nssilckt.h",
- "nss/lib/util/nssilock.c",
- "nss/lib/util/nssilock.h",
- "nss/lib/util/nsslocks.h",
- "nss/lib/util/nssrwlk.c",
- "nss/lib/util/nssrwlk.h",
- "nss/lib/util/nssrwlkt.h",
- "nss/lib/util/nssutil.h",
- "nss/lib/util/oidstring.c",
- "nss/lib/util/pkcs11.h",
- "nss/lib/util/pkcs11f.h",
- "nss/lib/util/pkcs11n.h",
- "nss/lib/util/pkcs11p.h",
- "nss/lib/util/pkcs11t.h",
- "nss/lib/util/pkcs11u.h",
- "nss/lib/util/pkcs1sig.c",
- "nss/lib/util/pkcs1sig.h",
- "nss/lib/util/portreg.c",
- "nss/lib/util/portreg.h",
- "nss/lib/util/quickder.c",
- "nss/lib/util/secalgid.c",
- "nss/lib/util/secasn1.h",
- "nss/lib/util/secasn1d.c",
- "nss/lib/util/secasn1e.c",
- "nss/lib/util/secasn1t.h",
- "nss/lib/util/secasn1u.c",
- "nss/lib/util/seccomon.h",
- "nss/lib/util/secder.h",
- "nss/lib/util/secdert.h",
- "nss/lib/util/secdig.c",
- "nss/lib/util/secdig.h",
- "nss/lib/util/secdigt.h",
- "nss/lib/util/secerr.h",
- "nss/lib/util/secitem.c",
- "nss/lib/util/secitem.h",
- "nss/lib/util/secoid.c",
- "nss/lib/util/secoid.h",
- "nss/lib/util/secoidt.h",
- "nss/lib/util/secport.c",
- "nss/lib/util/secport.h",
- "nss/lib/util/sectime.c",
- "nss/lib/util/templates.c",
- "nss/lib/util/utf8.c",
- "nss/lib/util/utilmod.c",
- "nss/lib/util/utilmodt.h",
- "nss/lib/util/utilpars.c",
- "nss/lib/util/utilpars.h",
- "nss/lib/util/utilparst.h",
- "nss/lib/util/utilrename.h",
- ]
-
- sources -= [
- # mpi_arm.c is included by mpi_arm_mac.c.
- # NOTE: mpi_arm.c can be used directly on Linux. mpi_arm.c will need
- # to be excluded conditionally if we start to build NSS on Linux.
- "nss/lib/freebl/mpi/mpi_arm.c",
-
- # primes.c is included by mpprime.c.
- "nss/lib/freebl/mpi/primes.c",
-
- # unix_rand.c and win_rand.c are included by sysrand.c.
- "nss/lib/freebl/unix_rand.c",
- "nss/lib/freebl/win_rand.c",
-
- # debug_module.c is included by pk11load.c.
- "nss/lib/pk11wrap/debug_module.c",
- ]
-
- configs -= [ "//build/config/compiler:chromium_code" ]
- if (is_win) {
- configs -= [ "//build/config/win:unicode" ] # Requires 8-bit mode.
- }
- configs += [
- "//build/config/compiler:no_chromium_code",
- "//build/config/compiler:no_size_t_to_int_warning",
- ]
- public_configs = [ ":nss_static_config" ]
-
- cflags = []
-
- # Only need the defines and includes not in nss_static_config.
- defines = [
- "MP_API_COMPATIBLE",
- "NSS_DISABLE_DBM",
- "RIJNDAEL_INCLUDE_TABLES",
- "SHLIB_VERSION=\"3\"",
- "SOFTOKEN_SHLIB_VERSION=\"3\"",
- ]
- include_dirs = [
- "nss/lib/freebl/mpi",
- "nss/lib/ssl",
- ]
-
- if (is_win) {
- cflags += [ "/wd4101" ] # Unreferenced local variable.
- }
-
- if (include_nss_libpkix) {
- sources += [
- "nss/lib/certhigh/certvfypkix.c",
- "nss/lib/certhigh/certvfypkixprint.c",
- "nss/lib/libpkix/include/pkix.h",
- "nss/lib/libpkix/include/pkix_certsel.h",
- "nss/lib/libpkix/include/pkix_certstore.h",
- "nss/lib/libpkix/include/pkix_checker.h",
- "nss/lib/libpkix/include/pkix_crlsel.h",
- "nss/lib/libpkix/include/pkix_errorstrings.h",
- "nss/lib/libpkix/include/pkix_params.h",
- "nss/lib/libpkix/include/pkix_pl_pki.h",
- "nss/lib/libpkix/include/pkix_pl_system.h",
- "nss/lib/libpkix/include/pkix_results.h",
- "nss/lib/libpkix/include/pkix_revchecker.h",
- "nss/lib/libpkix/include/pkix_sample_modules.h",
- "nss/lib/libpkix/include/pkix_util.h",
- "nss/lib/libpkix/include/pkixt.h",
- "nss/lib/libpkix/pkix/certsel/pkix_certselector.c",
- "nss/lib/libpkix/pkix/certsel/pkix_certselector.h",
- "nss/lib/libpkix/pkix/certsel/pkix_comcertselparams.c",
- "nss/lib/libpkix/pkix/certsel/pkix_comcertselparams.h",
- "nss/lib/libpkix/pkix/checker/pkix_basicconstraintschecker.c",
- "nss/lib/libpkix/pkix/checker/pkix_basicconstraintschecker.h",
- "nss/lib/libpkix/pkix/checker/pkix_certchainchecker.c",
- "nss/lib/libpkix/pkix/checker/pkix_certchainchecker.h",
- "nss/lib/libpkix/pkix/checker/pkix_crlchecker.c",
- "nss/lib/libpkix/pkix/checker/pkix_crlchecker.h",
- "nss/lib/libpkix/pkix/checker/pkix_ekuchecker.c",
- "nss/lib/libpkix/pkix/checker/pkix_ekuchecker.h",
- "nss/lib/libpkix/pkix/checker/pkix_expirationchecker.c",
- "nss/lib/libpkix/pkix/checker/pkix_expirationchecker.h",
- "nss/lib/libpkix/pkix/checker/pkix_namechainingchecker.c",
- "nss/lib/libpkix/pkix/checker/pkix_namechainingchecker.h",
- "nss/lib/libpkix/pkix/checker/pkix_nameconstraintschecker.c",
- "nss/lib/libpkix/pkix/checker/pkix_nameconstraintschecker.h",
- "nss/lib/libpkix/pkix/checker/pkix_ocspchecker.c",
- "nss/lib/libpkix/pkix/checker/pkix_ocspchecker.h",
- "nss/lib/libpkix/pkix/checker/pkix_policychecker.c",
- "nss/lib/libpkix/pkix/checker/pkix_policychecker.h",
- "nss/lib/libpkix/pkix/checker/pkix_revocationchecker.c",
- "nss/lib/libpkix/pkix/checker/pkix_revocationchecker.h",
- "nss/lib/libpkix/pkix/checker/pkix_revocationmethod.c",
- "nss/lib/libpkix/pkix/checker/pkix_revocationmethod.h",
- "nss/lib/libpkix/pkix/checker/pkix_signaturechecker.c",
- "nss/lib/libpkix/pkix/checker/pkix_signaturechecker.h",
- "nss/lib/libpkix/pkix/checker/pkix_targetcertchecker.c",
- "nss/lib/libpkix/pkix/checker/pkix_targetcertchecker.h",
- "nss/lib/libpkix/pkix/crlsel/pkix_comcrlselparams.c",
- "nss/lib/libpkix/pkix/crlsel/pkix_comcrlselparams.h",
- "nss/lib/libpkix/pkix/crlsel/pkix_crlselector.c",
- "nss/lib/libpkix/pkix/crlsel/pkix_crlselector.h",
- "nss/lib/libpkix/pkix/params/pkix_procparams.c",
- "nss/lib/libpkix/pkix/params/pkix_procparams.h",
- "nss/lib/libpkix/pkix/params/pkix_resourcelimits.c",
- "nss/lib/libpkix/pkix/params/pkix_resourcelimits.h",
- "nss/lib/libpkix/pkix/params/pkix_trustanchor.c",
- "nss/lib/libpkix/pkix/params/pkix_trustanchor.h",
- "nss/lib/libpkix/pkix/params/pkix_valparams.c",
- "nss/lib/libpkix/pkix/params/pkix_valparams.h",
- "nss/lib/libpkix/pkix/results/pkix_buildresult.c",
- "nss/lib/libpkix/pkix/results/pkix_buildresult.h",
- "nss/lib/libpkix/pkix/results/pkix_policynode.c",
- "nss/lib/libpkix/pkix/results/pkix_policynode.h",
- "nss/lib/libpkix/pkix/results/pkix_valresult.c",
- "nss/lib/libpkix/pkix/results/pkix_valresult.h",
- "nss/lib/libpkix/pkix/results/pkix_verifynode.c",
- "nss/lib/libpkix/pkix/results/pkix_verifynode.h",
- "nss/lib/libpkix/pkix/store/pkix_store.c",
- "nss/lib/libpkix/pkix/store/pkix_store.h",
- "nss/lib/libpkix/pkix/top/pkix_build.c",
- "nss/lib/libpkix/pkix/top/pkix_build.h",
- "nss/lib/libpkix/pkix/top/pkix_lifecycle.c",
- "nss/lib/libpkix/pkix/top/pkix_lifecycle.h",
- "nss/lib/libpkix/pkix/top/pkix_validate.c",
- "nss/lib/libpkix/pkix/top/pkix_validate.h",
- "nss/lib/libpkix/pkix/util/pkix_error.c",
- "nss/lib/libpkix/pkix/util/pkix_error.h",
- "nss/lib/libpkix/pkix/util/pkix_errpaths.c",
- "nss/lib/libpkix/pkix/util/pkix_list.c",
- "nss/lib/libpkix/pkix/util/pkix_list.h",
- "nss/lib/libpkix/pkix/util/pkix_logger.c",
- "nss/lib/libpkix/pkix/util/pkix_logger.h",
- "nss/lib/libpkix/pkix/util/pkix_tools.c",
- "nss/lib/libpkix/pkix/util/pkix_tools.h",
- "nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_aiamgr.c",
- "nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_aiamgr.h",
- "nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_colcertstore.c",
- "nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_colcertstore.h",
- "nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpcertstore.c",
- "nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpcertstore.h",
- "nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpdefaultclient.c",
- "nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_httpdefaultclient.h",
- "nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_nsscontext.c",
- "nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_nsscontext.h",
- "nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_pk11certstore.c",
- "nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_pk11certstore.h",
- "nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_socket.c",
- "nss/lib/libpkix/pkix_pl_nss/module/pkix_pl_socket.h",
- "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_basicconstraints.c",
- "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_basicconstraints.h",
- "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.c",
- "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_cert.h",
- "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicyinfo.c",
- "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicyinfo.h",
- "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicymap.c",
- "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicymap.h",
- "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicyqualifier.c",
- "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_certpolicyqualifier.h",
- "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crl.c",
- "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crl.h",
- "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crldp.c",
- "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crldp.h",
- "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crlentry.c",
- "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_crlentry.h",
- "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_date.c",
- "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_date.h",
- "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_generalname.c",
- "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_generalname.h",
- "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_infoaccess.c",
- "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_infoaccess.h",
- "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_nameconstraints.c",
- "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_nameconstraints.h",
- "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspcertid.c",
- "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspcertid.h",
- "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocsprequest.c",
- "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocsprequest.h",
- "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspresponse.c",
- "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_ocspresponse.h",
- "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_publickey.c",
- "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_publickey.h",
- "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_x500name.c",
- "nss/lib/libpkix/pkix_pl_nss/pki/pkix_pl_x500name.h",
- "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_bigint.c",
- "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_bigint.h",
- "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_bytearray.c",
- "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_bytearray.h",
- "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_common.c",
- "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_common.h",
- "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_error.c",
- "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_hashtable.c",
- "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_hashtable.h",
- "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.c",
- "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_lifecycle.h",
- "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_mem.c",
- "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_mem.h",
- "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_monitorlock.c",
- "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_monitorlock.h",
- "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_mutex.c",
- "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_mutex.h",
- "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_object.c",
- "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_object.h",
- "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_oid.c",
- "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_oid.h",
- "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_primhash.c",
- "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_primhash.h",
- "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_rwlock.c",
- "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_rwlock.h",
- "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_string.c",
- "nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_string.h",
- ]
-
- # Disable the LDAP code in libpkix.
- defines += [ "NSS_PKIX_NO_LDAP" ]
-
- include_dirs += [
- "nss/lib/libpkix/include",
- "nss/lib/libpkix/pkix/certsel",
- "nss/lib/libpkix/pkix/checker",
- "nss/lib/libpkix/pkix/crlsel",
- "nss/lib/libpkix/pkix/params",
- "nss/lib/libpkix/pkix/results",
- "nss/lib/libpkix/pkix/store",
- "nss/lib/libpkix/pkix/top",
- "nss/lib/libpkix/pkix/util",
- "nss/lib/libpkix/pkix_pl_nss/module",
- "nss/lib/libpkix/pkix_pl_nss/pki",
- "nss/lib/libpkix/pkix_pl_nss/system",
- ]
- } else {
- defines += [ "NSS_DISABLE_LIBPKIX" ]
- }
-
- if (!include_nss_root_certs) {
- defines += [ "NSS_DISABLE_ROOT_CERTS" ]
- }
-
- if (current_cpu == "x64" && !is_win) {
- sources -= [
- "nss/lib/freebl/chacha20/chacha20.c",
- "nss/lib/freebl/poly1305/poly1305.c",
- ]
- } else {
- sources -= [
- "nss/lib/freebl/chacha20/chacha20_vec.c",
- "nss/lib/freebl/poly1305/poly1305-donna-x64-sse2-incremental-source.c",
- ]
- }
-
- if (is_mac || is_ios) {
- sources -= [ "nss/lib/freebl/mpi/mpi_amd64.c" ]
- cflags += [
- "-include",
- rebase_path("//third_party/nss/nss/lib/freebl/nss_build_config_mac.h",
- root_build_dir),
- ]
- defines += [
- "XP_UNIX",
- "DARWIN",
- "HAVE_STRERROR",
- "HAVE_BSD_FLOCK",
- "SHLIB_SUFFIX=\"dylib\"",
- "SHLIB_PREFIX=\"lib\"",
- "SOFTOKEN_LIB_NAME=\"libsoftokn3.dylib\"",
- ]
-
- configs -= [ "//build/config/gcc:symbol_visibility_hidden" ]
- } else {
- # Not Mac/iOS.
- sources -= [ "nss/lib/freebl/mpi/mpi_arm_mac.c" ]
- }
-
- if (is_win) {
- defines += [
- "SHLIB_SUFFIX=\"dll\"",
- "SHLIB_PREFIX=\"\"",
- "SOFTOKEN_LIB_NAME=\"softokn3.dll\"",
- "XP_PC",
- "WIN32",
- "WIN95",
- ]
-
- if (current_cpu == "x86") {
- defines += [
- "NSS_X86_OR_X64",
- "NSS_X86",
- "_X86_",
- "MP_ASSEMBLY_MULTIPLY",
- "MP_ASSEMBLY_SQUARE",
- "MP_ASSEMBLY_DIV_2DX1D",
- "MP_USE_UINT_DIGIT",
- "MP_NO_MP_WORD",
- "USE_HW_AES",
- "INTEL_GCM",
- ]
- sources -= [ "nss/lib/freebl/mpi/mpi_amd64.c" ]
- } else if (current_cpu == "x64") {
- sources -= [
- "nss/lib/freebl/intel-aes-x86-masm.asm",
- "nss/lib/freebl/mpi/mpi_amd64.c",
- "nss/lib/freebl/mpi/mpi_x86_asm.c",
- ]
- defines += [
- "NSS_USE_64",
- "NSS_X86_OR_X64",
- "NSS_X64",
- "_AMD64_",
- "MP_CHAR_STORE_SLOW",
- "MP_IS_LITTLE_ENDIAN",
- "WIN64",
- ]
- }
- } else {
- # Not Windows.
- sources -= [
- # mpi_x86_asm.c contains MSVC inline assembly code.
- "nss/lib/freebl/mpi/mpi_x86_asm.c",
- ]
- }
-
- if (is_clang) {
- cflags += [
- # nss doesn"t explicitly cast between different enum types.
- "-Wno-conversion",
-
- # nss passes "const char*" through "void*".
- "-Wno-incompatible-pointer-types",
-
- # nss prefers `a && b || c` over `(a && b) || c`.
- "-Wno-logical-op-parentheses",
-
- # nss doesn"t use exhaustive switches on enums
- "-Wno-switch",
-
- # nss has some `unsigned < 0` checks.
- "-Wno-tautological-compare",
- ]
- }
-
- public_deps = [
- ":nspr",
- ]
- deps = [
- ":nspr",
- "//third_party/sqlite",
- ]
-
- if (is_win && current_cpu == "x86") {
- deps += [ ":nss_static_avx" ]
- }
- }
-} # Windows/Mac/iOS.
diff --git a/build/secondary/tools/grit/BUILD.gn b/build/secondary/tools/grit/BUILD.gn
deleted file mode 100644
index 660bf1b..0000000
--- a/build/secondary/tools/grit/BUILD.gn
+++ /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.
-
-# This target creates a stamp file that depends on all the sources in the grit
-# directory. By depending on this, a target can force itself to be rebuilt if
-# grit itself changes.
-action("grit_sources") {
- depfile = "$target_out_dir/grit_sources.d"
- script = "//build/secondary/tools/grit/stamp_grit_sources.py"
-
- inputs = [
- "grit.py",
- ]
-
- # Note that we can't call this "grit_sources.stamp" because that file is
- # implicitly created by GN for script actions.
- outputs = [
- "$target_out_dir/grit_sources.script.stamp",
- ]
-
- args = [
- rebase_path("//tools/grit", root_build_dir),
- rebase_path(outputs[0], root_build_dir),
- rebase_path(depfile, root_build_dir),
- ]
-}
diff --git a/build/secondary/tools/grit/grit_rule.gni b/build/secondary/tools/grit/grit_rule.gni
deleted file mode 100644
index bdf812f..0000000
--- a/build/secondary/tools/grit/grit_rule.gni
+++ /dev/null
@@ -1,483 +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.
-
-# Instantiate grit. This will produce a script target to run grit, and a
-# static library that compiles the .cc files.
-#
-# Parameters
-#
-# source (required)
-# Path to .grd file.
-#
-# outputs (required)
-# List of outputs from grit, relative to the target_gen_dir. Grit will
-# verify at build time that this list is correct and will fail if there
-# is a mismatch between the outputs specified by the .grd file and the
-# outputs list here.
-#
-# To get this list, you can look in the .grd file for
-# <output filename="..." and put those filename here. The base directory
-# of the list in Grit and the output list specified in the GN grit target
-# are the same (the target_gen_dir) so you can generally copy the names
-# exactly.
-#
-# To get the list of outputs programatically, run:
-# python tools/grit/grit_info.py --outputs . path/to/your.grd
-# And strip the leading "./" from the output files.
-#
-# defines (optional)
-# Extra defines to pass to grit (on top of the global grit_defines list).
-#
-# grit_flags (optional)
-# List of strings containing extra command-line flags to pass to Grit.
-#
-# resource_ids (optional)
-# Path to a grit "firstidsfile". Default is
-# //tools/gritsettings/resource_ids. Set to "" to use the value specified
-# in the <grit> nodes of the processed files.
-#
-# output_dir (optional)
-# Directory for generated files. If you specify this, you will often
-# want to specify output_name if the target name is not particularly
-# unique, since this can cause files from multiple grit targets to
-# overwrite each other.
-#
-# output_name (optiona)
-# Provide an alternate base name for the generated files, like the .d
-# files. Normally these are based on the target name and go in the
-# output_dir, but if multiple targets with the same name end up in
-# the same output_dir, they can collide.
-#
-# depfile_dir (optional)
-# If set, used to store the depfile and corresponding stamp file.
-# Defaults to output_dir
-#
-# use_qualified_include (optional)
-# If set, output_dir is not added to include_dirs.
-#
-# configs (optional)
-# List of additional configs to be applied to the generated target.
-# deps (optional)
-# inputs (optional)
-# List of additional files, required for grit to process source file.
-# visibility (optional)
-# Normal meaning.
-#
-# Example
-#
-# grit("my_resources") {
-# # Source and outputs are required.
-# source = "myfile.grd"
-# outputs = [
-# "foo_strings.h",
-# "foo_strings.pak",
-# ]
-#
-# grit_flags = [ "-E", "foo=bar" ] # Optional extra flags.
-# # You can also put deps here if the grit source depends on generated
-# # files.
-# }
-import("//build/config/chrome_build.gni")
-import("//build/config/crypto.gni")
-import("//build/config/features.gni")
-import("//build/config/ui.gni")
-
-grit_defines = []
-
-# Mac and iOS want Title Case strings.
-use_titlecase_in_grd_files = is_mac || is_ios
-if (use_titlecase_in_grd_files) {
- grit_defines += [
- "-D",
- "use_titlecase",
- ]
-}
-
-if (is_chrome_branded) {
- grit_defines += [
- "-D",
- "_google_chrome",
- "-E",
- "CHROMIUM_BUILD=google_chrome",
- ]
-} else {
- grit_defines += [
- "-D",
- "_chromium",
- "-E",
- "CHROMIUM_BUILD=chromium",
- ]
-}
-
-if (is_chromeos) {
- grit_defines += [
- "-D",
- "chromeos",
- "-D",
- "scale_factors=2x",
- ]
-}
-
-if (is_desktop_linux) {
- grit_defines += [
- "-D",
- "desktop_linux",
- ]
-}
-
-if (toolkit_views) {
- grit_defines += [
- "-D",
- "toolkit_views",
- ]
-}
-
-if (use_aura) {
- grit_defines += [
- "-D",
- "use_aura",
- ]
-}
-
-if (use_ash) {
- grit_defines += [
- "-D",
- "use_ash",
- ]
-}
-
-if (use_nss_certs) {
- grit_defines += [
- "-D",
- "use_nss_certs",
- ]
-}
-
-if (use_ozone) {
- grit_defines += [
- "-D",
- "use_ozone",
- ]
-}
-
-if (enable_image_loader_extension) {
- grit_defines += [
- "-D",
- "image_loader_extension",
- ]
-}
-
-if (enable_remoting) {
- grit_defines += [
- "-D",
- "remoting",
- ]
-}
-
-if (is_android) {
- grit_defines += [
- "-t",
- "android",
- "-E",
- "ANDROID_JAVA_TAGGED_ONLY=true",
- ]
-}
-
-if (is_mac || is_ios) {
- grit_defines += [
- "-D",
- "scale_factors=2x",
- ]
-}
-
-if (is_ios) {
- grit_defines += [
- "-t",
- "ios",
-
- # iOS uses a whitelist to filter resources.
- "-w",
- rebase_path("//build/ios/grit_whitelist.txt", root_build_dir),
- ]
-}
-
-if (enable_extensions) {
- grit_defines += [
- "-D",
- "enable_extensions",
- ]
-}
-if (enable_media_router) {
- grit_defines += [
- "-D",
- "enable_media_router",
- ]
-}
-if (enable_plugins) {
- grit_defines += [
- "-D",
- "enable_plugins",
- ]
-}
-if (enable_basic_printing || enable_print_preview) {
- grit_defines += [
- "-D",
- "enable_printing",
- ]
- if (enable_print_preview) {
- grit_defines += [
- "-D",
- "enable_print_preview",
- ]
- }
-}
-if (enable_themes) {
- grit_defines += [
- "-D",
- "enable_themes",
- ]
-}
-if (enable_app_list) {
- grit_defines += [
- "-D",
- "enable_app_list",
- ]
-}
-if (enable_settings_app) {
- grit_defines += [
- "-D",
- "enable_settings_app",
- ]
-}
-if (enable_google_now) {
- grit_defines += [
- "-D",
- "enable_google_now",
- ]
-}
-
-# Note: use_concatenated_impulse_responses is omitted. It is never used and
-# should probably be removed from GYP build.
-if (enable_webrtc) {
- grit_defines += [
- "-D",
- "enable_webrtc",
- ]
-}
-if (enable_hangout_services_extension) {
- grit_defines += [
- "-D",
- "enable_hangout_services_extension",
- ]
-}
-if (enable_task_manager) {
- grit_defines += [
- "-D",
- "enable_task_manager",
- ]
-}
-if (enable_notifications) {
- grit_defines += [
- "-D",
- "enable_notifications",
- ]
-}
-if (enable_wifi_bootstrapping) {
- grit_defines += [
- "-D",
- "enable_wifi_bootstrapping",
- ]
-}
-if (enable_service_discovery) {
- grit_defines += [
- "-D",
- "enable_service_discovery",
- ]
-}
-if (mac_views_browser) {
- grit_defines += [
- "-D",
- "mac_views_browser",
- ]
-}
-
-grit_resource_id_file = "//tools/gritsettings/resource_ids"
-grit_info_script = "//tools/grit/grit_info.py"
-
-template("grit") {
- assert(defined(invoker.source),
- "\"source\" must be defined for the grit template $target_name")
-
- grit_inputs = [ invoker.source ]
-
- if (defined(invoker.resource_ids)) {
- resource_ids = invoker.resource_ids
- } else {
- resource_ids = grit_resource_id_file
- }
- if (resource_ids != "") {
- # The script depends on the ID file. Only add this dependency if the ID
- # file is specified.
- grit_inputs += [ resource_ids ]
- }
-
- if (defined(invoker.output_dir)) {
- output_dir = invoker.output_dir
- } else {
- output_dir = target_gen_dir
- }
-
- if (defined(invoker.output_name)) {
- grit_output_name = invoker.output_name
- } else {
- grit_output_name = target_name
- }
-
- if (defined(invoker.depfile_dir)) {
- depfile_dir = invoker.depfile_dir
- } else {
- depfile_dir = output_dir
- }
-
- # These are all passed as arguments to the script so have to be relative to
- # the build directory.
- if (resource_ids != "") {
- resource_ids = rebase_path(resource_ids, root_build_dir)
- }
- rebased_output_dir = rebase_path(output_dir, root_build_dir)
- source_path = rebase_path(invoker.source, root_build_dir)
-
- if (defined(invoker.grit_flags)) {
- grit_flags = invoker.grit_flags
- } else {
- grit_flags = [] # These are optional so default to empty list.
- }
-
- assert_files_flags = []
-
- # We want to make sure the declared outputs actually match what Grit is
- # writing. We write the list to a file (some of the output lists are long
- # enough to not fit on a Windows command line) and ask Grit to verify those
- # are the actual outputs at runtime.
- asserted_list_file =
- "$target_out_dir/${grit_output_name}_expected_outputs.txt"
- write_file(asserted_list_file,
- rebase_path(invoker.outputs, root_build_dir, output_dir))
- assert_files_flags += [ "--assert-file-list=" +
- rebase_path(asserted_list_file, root_build_dir) ]
- grit_outputs =
- get_path_info(rebase_path(invoker.outputs, ".", output_dir), "abspath")
-
- # The config and the action below get this visibility son only the generated
- # source set can depend on them. The variable "target_name" will get
- # overwritten inside the inner classes so we need to compute it here.
- target_visibility = [ ":$target_name" ]
-
- # The current grit setup makes an file in $output_dir/grit/foo.h that
- # the source code expects to include via "grit/foo.h". It would be nice to
- # change this to including absolute paths relative to the root gen directory
- # (like "mycomponent/foo.h"). This config sets up the include path.
- grit_config = target_name + "_grit_config"
- config(grit_config) {
- if (!defined(invoker.use_qualified_include) ||
- !invoker.use_qualified_include) {
- include_dirs = [ output_dir ]
- }
- visibility = target_visibility
- }
-
- grit_custom_target = target_name + "_grit"
- action(grit_custom_target) {
- script = "//tools/grit/grit.py"
- inputs = grit_inputs
-
- depfile = "$depfile_dir/${grit_output_name}_stamp.d"
- outputs = [ "${depfile}.stamp" ] + grit_outputs
-
- args = [
- "-i",
- source_path,
- "build",
- ]
- if (resource_ids != "") {
- args += [
- "-f",
- resource_ids,
- ]
- }
- args += [
- "-o",
- rebased_output_dir,
- "--depdir",
- ".",
- "--depfile",
- rebase_path(depfile, root_build_dir),
- "--write-only-new=1",
- "--depend-on-stamp",
- ] + grit_defines
-
- # Add extra defines with -D flags.
- if (defined(invoker.defines)) {
- foreach(i, invoker.defines) {
- args += [
- "-D",
- i,
- ]
- }
- }
-
- args += grit_flags + assert_files_flags
-
- if (defined(invoker.visibility)) {
- # This needs to include both what the invoker specified (since they
- # probably include generated headers from this target), as well as the
- # generated source set (since there's no guarantee that the visibility
- # specified by the invoker includes our target).
- #
- # Only define visibility at all if the invoker specified it. Otherwise,
- # we want to keep the public "no visibility specified" default.
- visibility = target_visibility + invoker.visibility
- }
-
- deps = [
- "//tools/grit:grit_sources",
- ]
- if (defined(invoker.deps)) {
- deps += invoker.deps
- }
- if (defined(invoker.inputs)) {
- inputs += invoker.inputs
- }
- }
-
- # This is the thing that people actually link with, it must be named the
- # same as the argument the template was invoked with.
- source_set(target_name) {
- # Since we generate a file, we need to be run before the targets that
- # depend on us.
- sources = grit_outputs
-
- # Deps set on the template invocation will go on the action that runs
- # grit above rather than this library. This target needs to depend on the
- # action publicly so other scripts can take the outputs from the grit
- # script as inputs.
- public_deps = [
- ":$grit_custom_target",
- ]
- public_configs = [ ":$grit_config" ]
-
- if (defined(invoker.public_configs)) {
- public_configs += invoker.public_configs
- }
-
- if (defined(invoker.configs)) {
- configs += invoker.configs
- }
-
- if (defined(invoker.visibility)) {
- visibility = invoker.visibility
- }
- output_name = grit_output_name
- }
-}
diff --git a/build/secondary/tools/grit/repack.gni b/build/secondary/tools/grit/repack.gni
deleted file mode 100644
index 1030674..0000000
--- a/build/secondary/tools/grit/repack.gni
+++ /dev/null
@@ -1,47 +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 defines a template to invoke grit repack in a consistent manner.
-#
-# Parameters:
-# sources [required]
-# List of pak files that need to be combined.
-#
-# output [required]
-# File name (single string) of the output file.
-#
-# repack_options [optional]
-# List of extra arguments to pass.
-#
-# deps [optional]
-# visibility [optional]
-# Normal meaning.
-template("repack") {
- action(target_name) {
- assert(defined(invoker.sources), "Need sources for $target_name")
- assert(defined(invoker.output), "Need output for $target_name")
-
- if (defined(invoker.visibility)) {
- visibility = invoker.visibility
- }
-
- script = "//tools/grit/grit/format/repack.py"
-
- inputs = invoker.sources
- outputs = [
- invoker.output,
- ]
-
- args = []
- if (defined(invoker.repack_options)) {
- args += invoker.repack_options
- }
- args += [ rebase_path(invoker.output, root_build_dir) ]
- args += rebase_path(invoker.sources, root_build_dir)
-
- if (defined(invoker.deps)) {
- deps = invoker.deps
- }
- }
-}
diff --git a/build/secondary/tools/grit/stamp_grit_sources.py b/build/secondary/tools/grit/stamp_grit_sources.py
deleted file mode 100644
index d43d4b8..0000000
--- a/build/secondary/tools/grit/stamp_grit_sources.py
+++ /dev/null
@@ -1,55 +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 enumerates the files in the given directory, writing an empty
-# stamp file and a .d file listing the inputs required to make the stamp. This
-# allows us to dynamically depend on the grit sources without enumerating the
-# grit directory for every invocation of grit (which is what adding the source
-# files to every .grd file's .d file would entail) or shelling out to grit
-# synchronously during GN execution to get the list (which would be slow).
-#
-# Usage:
-# stamp_grit_sources.py <directory> <stamp-file> <.d-file>
-
-import os
-import sys
-
-def GritSourceFiles(grit_root_dir):
- files = []
- for root, _, filenames in os.walk(grit_root_dir):
- grit_src = [os.path.join(root, f) for f in filenames
- if f.endswith('.py') and not f.endswith('_unittest.py')]
- files.extend(grit_src)
- files = [f.replace('\\', '/') for f in files]
- return sorted(files)
-
-
-def WriteDepFile(dep_file, stamp_file, source_files):
- with open(dep_file, "w") as f:
- f.write(stamp_file)
- f.write(": ")
- f.write(' '.join(source_files))
-
-
-def WriteStampFile(stamp_file):
- with open(stamp_file, "w"):
- pass
-
-
-def main(argv):
- if len(argv) != 4:
- print "Error: expecting 3 args."
- return 1
-
- grit_root_dir = sys.argv[1]
- stamp_file = sys.argv[2]
- dep_file = sys.argv[3]
-
- WriteStampFile(stamp_file)
- WriteDepFile(dep_file, stamp_file, GritSourceFiles(grit_root_dir))
- return 0
-
-
-if __name__ == '__main__':
- sys.exit(main(sys.argv))
diff --git a/build/toolchain/fnl/BUILD.gn b/build/toolchain/fnl/BUILD.gn
deleted file mode 100644
index 1e4a075..0000000
--- a/build/toolchain/fnl/BUILD.gn
+++ /dev/null
@@ -1,24 +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/toolchain/gcc_toolchain.gni")
-
-declare_args() {
- toolchain_prefix = ""
-}
-
-gcc_toolchain("target") {
- assert(toolchain_prefix != "", "Must provide toolchain_prefix")
-
- cc = "${toolchain_prefix}gcc"
- cxx = "${toolchain_prefix}g++"
- ar = "${toolchain_prefix}ar"
- ld = cxx
- readelf = "${toolchain_prefix}readelf"
- nm = "${toolchain_prefix}nm"
-
- toolchain_cpu = "${target_cpu}"
- toolchain_os = "linux"
- is_clang = is_clang
-}
diff --git a/build/toolchain/linux/BUILD.gn b/build/toolchain/linux/BUILD.gn
index c16e31c..ae090b0 100644
--- a/build/toolchain/linux/BUILD.gn
+++ b/build/toolchain/linux/BUILD.gn
@@ -8,6 +8,10 @@
import("//build/toolchain/gcc_toolchain.gni")
import("//build/toolchain/goma.gni")
+declare_args() {
+ toolchain_prefix = ""
+}
+
if (use_goma) {
assert(!use_ccache, "Goma and ccache can't be used together.")
compiler_prefix = "$goma_dir/gomacc "
@@ -31,14 +35,23 @@
is_clang = false
}
+gcc_toolchain("arm64") {
+ cc = "${compiler_prefix}aarch64-linux-gnu-gcc"
+ cxx = "${compiler_prefix}aarch64-linux-gnu-g++"
+
+ ar = "aarch64-linux-gnu-ar"
+ ld = cxx
+ readelf = "aarch64-linux-gnu-readelf"
+ nm = "aarch64-linux-gnu-nm"
+
+ toolchain_cpu = "arm64"
+ toolchain_os = "linux"
+ is_clang = false
+}
+
gcc_toolchain("clang_x86") {
- if (use_clang_type_profiler) {
- prefix = rebase_path("//third_party/llvm-allocated-type/Linux_ia32/bin",
- root_build_dir)
- } else {
- prefix = rebase_path("//third_party/llvm-build/Release+Asserts/bin",
- root_build_dir)
- }
+ prefix = rebase_path("//third_party/llvm-build/Release+Asserts/bin",
+ root_build_dir)
cc = "${compiler_prefix}$prefix/clang"
cxx = "${compiler_prefix}$prefix/clang++"
readelf = "readelf"
@@ -53,7 +66,7 @@
gcc_toolchain("x86") {
cc = "${compiler_prefix}gcc"
- cxx = "$compiler_prefix}g++"
+ cxx = "${compiler_prefix}g++"
readelf = "readelf"
nm = "nm"
@@ -66,13 +79,8 @@
}
gcc_toolchain("clang_x64") {
- if (use_clang_type_profiler) {
- prefix = rebase_path("//third_party/llvm-allocated-type/Linux_x64/bin",
- root_build_dir)
- } else {
- prefix = rebase_path("//third_party/llvm-build/Release+Asserts/bin",
- root_build_dir)
- }
+ prefix = rebase_path("//third_party/llvm-build/Release+Asserts/bin",
+ root_build_dir)
cc = "${compiler_prefix}$prefix/clang"
cxx = "${compiler_prefix}$prefix/clang++"
@@ -102,14 +110,14 @@
}
gcc_toolchain("mipsel") {
- cc = "mipsel-linux-gnu-gcc"
- cxx = "mipsel-linux-gnu-g++"
- ar = "mipsel-linux-gnu-ar"
+ cc = "${toolchain_prefix}gcc"
+ cxx = "${toolchain_prefix}g++"
+ ar = "${toolchain_prefix}ar"
ld = cxx
- readelf = "mipsel-linux-gnu-readelf"
- nm = "mipsel-linux-gnu-nm"
+ readelf = "${toolchain_prefix}readelf"
+ nm = "${toolchain_prefix}nm"
- toolchain_cpu = "mipsel"
+ toolchain_cpu = "${target_cpu}"
toolchain_os = "linux"
- is_clang = false
+ is_clang = is_clang
}
diff --git a/docs/language/dartLangSpec.tex b/docs/language/dartLangSpec.tex
index c1d9e6b..cfd1536 100644
--- a/docs/language/dartLangSpec.tex
+++ b/docs/language/dartLangSpec.tex
@@ -2790,7 +2790,7 @@
$\backslash$u\{$HEX\_DIGIT_1$ $HEX\_DIGIT_2$\}.
\item $\backslash$u $HEX\_DIGIT_1$ $HEX\_DIGIT_2$ $HEX\_DIGIT_3$ $HEX\_DIGIT_4$, equivalent to $\backslash$u\{$HEX\_DIGIT_1$ $HEX\_DIGIT_2$ $HEX\_DIGIT_3$ $HEX\_DIGIT_4$\}.
-\item $\backslash$u\{$HEX\_DIGIT\_SEQUENCE$\} is the unicode scalar value represented by the $HEX\_DIGIT\_SEQUENCE$. It is a compile-time error if the value of the $HEX\_DIGIT\_SEQUENCE$ is not a valid unicode scalar value.
+\item $\backslash$u\{$HEX\_DIGIT\_SEQUENCE$\} is the Unicode code point represented by the $HEX\_DIGIT\_SEQUENCE$. It is a compile-time error if the value of the $HEX\_DIGIT\_SEQUENCE$ is not a valid Unicode code point.
\item \$ indicating the beginning of an interpolated expression.
\item Otherwise, $\backslash k$ indicates the character $k$ for any $k$ not in $\{n, r, f, b, t, v, x, u\}$.
\end{itemize}
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index 6637ad7..9228c47 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -356,6 +356,7 @@
"params": {
"<b>version</b>": String
"<b>pid</b>": int
+ "<b>sessionId</b>": <span style="color:#999999">optional</span> String
}
}</pre></div>
<p>
@@ -375,6 +376,9 @@
</dd><dt class="field"><b>pid (int)</b></dt><dd>
<p>The process id of the analysis server process.</p>
+ </dd><dt class="field"><b>sessionId (<span style="color:#999999">optional</span> String)</b></dt><dd>
+
+ <p>The session id for this session.</p>
</dd></dl></dd><dt class="notification"><a name="notification_server.error">server.error</a> (<a href="#notification_server.error">#</a>)</dt><dd><div class="box"><pre>notification: {
"event": "server.error"
"params": {
diff --git a/pkg/analysis_server/lib/plugin/protocol/generated_protocol.dart b/pkg/analysis_server/lib/plugin/protocol/generated_protocol.dart
index ce67998..f3c2d98 100644
--- a/pkg/analysis_server/lib/plugin/protocol/generated_protocol.dart
+++ b/pkg/analysis_server/lib/plugin/protocol/generated_protocol.dart
@@ -267,6 +267,7 @@
* {
* "version": String
* "pid": int
+ * "sessionId": optional String
* }
*
* Clients may not extend, implement or mix-in this class.
@@ -276,6 +277,8 @@
int _pid;
+ String _sessionId;
+
/**
* The version number of the analysis server.
*/
@@ -302,9 +305,22 @@
this._pid = value;
}
- ServerConnectedParams(String version, int pid) {
+ /**
+ * The session id for this session.
+ */
+ String get sessionId => _sessionId;
+
+ /**
+ * The session id for this session.
+ */
+ void set sessionId(String value) {
+ this._sessionId = value;
+ }
+
+ ServerConnectedParams(String version, int pid, {String sessionId}) {
this.version = version;
this.pid = pid;
+ this.sessionId = sessionId;
}
factory ServerConnectedParams.fromJson(JsonDecoder jsonDecoder, String jsonPath, Object json) {
@@ -324,7 +340,11 @@
} else {
throw jsonDecoder.missingKey(jsonPath, "pid");
}
- return new ServerConnectedParams(version, pid);
+ String sessionId;
+ if (json.containsKey("sessionId")) {
+ sessionId = jsonDecoder.decodeString(jsonPath + ".sessionId", json["sessionId"]);
+ }
+ return new ServerConnectedParams(version, pid, sessionId: sessionId);
} else {
throw jsonDecoder.mismatch(jsonPath, "server.connected params", json);
}
@@ -339,6 +359,9 @@
Map<String, dynamic> result = {};
result["version"] = version;
result["pid"] = pid;
+ if (sessionId != null) {
+ result["sessionId"] = sessionId;
+ }
return result;
}
@@ -353,7 +376,8 @@
bool operator==(other) {
if (other is ServerConnectedParams) {
return version == other.version &&
- pid == other.pid;
+ pid == other.pid &&
+ sessionId == other.sessionId;
}
return false;
}
@@ -363,6 +387,7 @@
int hash = 0;
hash = JenkinsSmiHash.combine(hash, version.hashCode);
hash = JenkinsSmiHash.combine(hash, pid.hashCode);
+ hash = JenkinsSmiHash.combine(hash, sessionId.hashCode);
return JenkinsSmiHash.finish(hash);
}
}
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index aa20e42..d53d90b 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -376,8 +376,9 @@
_setupIndexInvalidation();
pubSummaryManager =
new PubSummaryManager(resourceProvider, '${io.pid}.temp');
- Notification notification =
- new ServerConnectedParams(VERSION, io.pid).toNotification();
+ Notification notification = new ServerConnectedParams(VERSION, io.pid,
+ sessionId: instrumentationService.sessionId)
+ .toNotification();
channel.sendNotification(notification);
channel.listen(handleRequest, onDone: done, onError: error);
handlers = serverPlugin.createDomains(this);
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index 7d567a9..66977c4 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -885,13 +885,11 @@
if (AnalysisEngine.isAnalysisOptionsFileName(path, pathContext)) {
var analysisContext = info.context;
if (analysisContext is context.AnalysisContextImpl) {
- // TODO(brianwilkerson) This doesn't correctly update the source factory
- // if the changes necessitate it (such as by changing the setting of the
- // strong-mode option).
Map<String, Object> options = readOptions(info.folder);
processOptionsForContext(info, options,
optionsRemoved: changeType == ChangeType.REMOVE);
- analysisContext.invalidateCachedResults();
+ analysisContext.sourceFactory = _createSourceFactory(
+ analysisContext, analysisContext.analysisOptions, info.folder);
callbacks.applyChangesToContext(info.folder, new ChangeSet());
}
}
diff --git a/pkg/analysis_server/lib/src/operation/operation_analysis.dart b/pkg/analysis_server/lib/src/operation/operation_analysis.dart
index 634ae54..dd72b49 100644
--- a/pkg/analysis_server/lib/src/operation/operation_analysis.dart
+++ b/pkg/analysis_server/lib/src/operation/operation_analysis.dart
@@ -48,12 +48,19 @@
for (String file in files) {
CompilationUnitElement unitElement = server.getCompilationUnitElement(file);
if (unitElement != null) {
- ImplementedComputer computer =
- new ImplementedComputer(searchEngine, unitElement);
- await computer.compute();
- var params = new protocol.AnalysisImplementedParams(
- file, computer.classes, computer.members);
- server.sendNotification(params.toNotification());
+ try {
+ ImplementedComputer computer =
+ new ImplementedComputer(searchEngine, unitElement);
+ await computer.compute();
+ var params = new protocol.AnalysisImplementedParams(
+ file, computer.classes, computer.members);
+ server.sendNotification(params.toNotification());
+ } catch (exception, stackTrace) {
+ server.sendServerErrorNotification(
+ 'Failed to send analysis.implemented notification.',
+ exception,
+ stackTrace);
+ }
}
}
}
diff --git a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_target.dart b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_target.dart
index 7e7ae5c..9e998e0 100644
--- a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_target.dart
+++ b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_target.dart
@@ -199,14 +199,14 @@
Token commentToken =
_getContainingCommentToken(entity.beginToken, offset);
if (commentToken != null) {
- entity = commentToken;
// If the preceding comment is dartdoc token, then update
// the containing node to be the dartdoc comment.
// Otherwise completion is not required.
Comment docComment =
_getContainingDocComment(containingNode, commentToken);
if (docComment != null) {
- containingNode = docComment;
+ return new CompletionTarget._(
+ compilationUnit, offset, docComment, commentToken, false);
} else {
return new CompletionTarget._(compilationUnit, offset,
compilationUnit, commentToken, true);
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 ceadf3c..a894518 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -1808,31 +1808,44 @@
}
void _addFix_undefinedClass_useSimilar() {
+ AstNode node = this.node;
+ // Prepare the optional import prefix name.
+ String prefixName = null;
+ if (node is SimpleIdentifier && node.staticElement is PrefixElement) {
+ AstNode parent = node.parent;
+ if (parent is PrefixedIdentifier &&
+ parent.prefix == node &&
+ parent.parent is TypeName) {
+ prefixName = (node as SimpleIdentifier).name;
+ node = parent.identifier;
+ }
+ }
+ // Process if looks like a type.
if (_mayBeTypeIdentifier(node)) {
+ // Prepare for selecting the closest element.
String name = (node as SimpleIdentifier).name;
_ClosestElementFinder finder = new _ClosestElementFinder(
name,
(Element element) => element is ClassElement,
MAX_LEVENSHTEIN_DISTANCE);
- // find closest element
- {
- // elements of this library
+ // Check elements of this library.
+ if (prefixName == null) {
for (CompilationUnitElement unit in unitLibraryElement.units) {
finder._updateList(unit.types);
}
- // elements from imports
- for (ImportElement importElement in unitLibraryElement.imports) {
- if (importElement.prefix == null) {
- Map<String, Element> namespace = getImportNamespace(importElement);
- finder._updateList(namespace.values);
- }
+ }
+ // Check elements from imports.
+ for (ImportElement importElement in unitLibraryElement.imports) {
+ if (importElement.prefix?.name == prefixName) {
+ Map<String, Element> namespace = getImportNamespace(importElement);
+ finder._updateList(namespace.values);
}
}
- // if we have close enough element, suggest to use it
+ // If we have a close enough element, suggest to use it.
if (finder._element != null) {
String closestName = finder._element.name;
_addReplaceEdit(rf.rangeNode(node), closestName);
- // add proposal
+ // Add proposal.
if (closestName != null) {
_addFix(DartFixKind.CHANGE_TO, [closestName]);
}
@@ -1942,24 +1955,39 @@
}
void _addFix_undefinedFunction_useSimilar() {
+ AstNode node = this.node;
if (node is SimpleIdentifier) {
- String name = (node as SimpleIdentifier).name;
+ // Prepare the optional import prefix name.
+ String prefixName = null;
+ {
+ AstNode invocation = node.parent;
+ if (invocation is MethodInvocation && invocation.methodName == node) {
+ Expression target = invocation.target;
+ if (target is SimpleIdentifier &&
+ target.staticElement is PrefixElement) {
+ prefixName = target.name;
+ }
+ }
+ }
+ // Prepare for selecting the closest element.
_ClosestElementFinder finder = new _ClosestElementFinder(
- name,
+ node.name,
(Element element) => element is FunctionElement,
MAX_LEVENSHTEIN_DISTANCE);
- // this library
- for (CompilationUnitElement unit in unitLibraryElement.units) {
- finder._updateList(unit.functions);
+ // Check to this library units.
+ if (prefixName == null) {
+ for (CompilationUnitElement unit in unitLibraryElement.units) {
+ finder._updateList(unit.functions);
+ }
}
- // imports
+ // Check unprefixed imports.
for (ImportElement importElement in unitLibraryElement.imports) {
- if (importElement.prefix == null) {
+ if (importElement.prefix?.name == prefixName) {
Map<String, Element> namespace = getImportNamespace(importElement);
finder._updateList(namespace.values);
}
}
- // if we have close enough element, suggest to use it
+ // If we have a close enough element, suggest to use it.
if (finder._element != null) {
String closestName = finder._element.name;
_addReplaceEdit(rf.rangeNode(node), closestName);
diff --git a/pkg/analysis_server/lib/src/services/index/index.dart b/pkg/analysis_server/lib/src/services/index/index.dart
index aa06637..dcf8ea3 100644
--- a/pkg/analysis_server/lib/src/services/index/index.dart
+++ b/pkg/analysis_server/lib/src/services/index/index.dart
@@ -4,13 +4,13 @@
import 'dart:async';
+import 'package:analysis_server/src/services/index/index_unit.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary/index_unit.dart';
import 'package:collection/collection.dart';
/**
diff --git a/pkg/analyzer/lib/src/summary/index_unit.dart b/pkg/analysis_server/lib/src/services/index/index_unit.dart
similarity index 100%
rename from pkg/analyzer/lib/src/summary/index_unit.dart
rename to pkg/analysis_server/lib/src/services/index/index_unit.dart
diff --git a/pkg/analysis_server/lib/src/status/get_handler.dart b/pkg/analysis_server/lib/src/status/get_handler.dart
index 99f88b3..b87a33e 100644
--- a/pkg/analysis_server/lib/src/status/get_handler.dart
+++ b/pkg/analysis_server/lib/src/status/get_handler.dart
@@ -46,7 +46,8 @@
import 'package:analyzer/src/task/driver.dart';
import 'package:analyzer/src/task/html.dart';
import 'package:analyzer/src/task/options.dart';
-import 'package:analyzer/src/task/options.dart' show CONFIGURED_ERROR_PROCESSORS;
+import 'package:analyzer/src/task/options.dart'
+ show CONFIGURED_ERROR_PROCESSORS;
import 'package:analyzer/task/dart.dart';
import 'package:analyzer/task/general.dart';
import 'package:analyzer/task/html.dart';
@@ -1407,7 +1408,6 @@
_writeOption(
buffer, 'Analyze functon bodies', options.analyzeFunctionBodies);
_writeOption(buffer, 'Cache size', options.cacheSize);
- _writeOption(buffer, 'Enable async support', options.enableAsync);
_writeOption(
buffer, 'Enable generic methods', options.enableGenericMethods);
_writeOption(
@@ -2180,8 +2180,8 @@
}
}
buffer.write('<p>element count: ');
- buffer.write(
- counter.counts.values.fold(0, (prev, element) => prev + element));
+ buffer.write(counter.counts.values
+ .fold(0, (int prev, int element) => prev + element));
buffer.write('</p>');
buffer.write('<p> (w/docs): ');
buffer.write(counter.elementsWithDocs);
@@ -2196,8 +2196,8 @@
buffer.write('SDK');
buffer.write('</h3></p>');
buffer.write('<p>element count: ');
- buffer.write(
- sdkCounter.counts.values.fold(0, (prev, element) => prev + element));
+ buffer.write(sdkCounter.counts.values
+ .fold(0, (int prev, int element) => prev + element));
buffer.write('</p>');
buffer.write('<p> (w/docs): ');
buffer.write(sdkCounter.elementsWithDocs);
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index 314b76f..87f62fd 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -1999,7 +1999,6 @@
- 'test/**'
language:
enableGenericMethods: true
- enableAsync: false
errors:
unused_local_variable: false
linter:
@@ -2023,7 +2022,6 @@
// * from `config.yaml`:
expect(context.analysisOptions.strongMode, isTrue);
expect(context.analysisOptions.enableSuperMixins, isTrue);
- expect(context.analysisOptions.enableAsync, isFalse);
// * from analysis options:
expect(context.analysisOptions.enableGenericMethods, isTrue);
@@ -2097,7 +2095,6 @@
- 'test/**'
language:
enableGenericMethods: true
- enableAsync: false
errors:
unused_local_variable: false
linter:
@@ -2132,7 +2129,6 @@
// * from `_embedder.yaml`:
expect(context.analysisOptions.strongMode, isTrue);
expect(context.analysisOptions.enableSuperMixins, isTrue);
- expect(context.analysisOptions.enableAsync, isFalse);
// * from analysis options:
expect(context.analysisOptions.enableGenericMethods, isTrue);
@@ -2211,7 +2207,6 @@
- 'test/**'
language:
enableGenericMethods: true
- enableAsync: false
errors:
unused_local_variable: false
linter:
@@ -2234,7 +2229,6 @@
// * from `_embedder.yaml`:
expect(context.analysisOptions.strongMode, isTrue);
expect(context.analysisOptions.enableSuperMixins, isTrue);
- expect(context.analysisOptions.enableAsync, isFalse);
// * from analysis options:
expect(context.analysisOptions.enableGenericMethods, isTrue);
@@ -2341,6 +2335,58 @@
expect(errorProcessors, isEmpty);
}
+ test_optionsFile_update_strongMode() async {
+ var file = resourceProvider.newFile(
+ '$projPath/bin/test.dart',
+ r'''
+main() {
+ var paths = <int>[];
+ var names = <String>[];
+ paths.addAll(names.map((s) => s.length));
+}
+''');
+ resourceProvider.newFile(
+ '$projPath/$optionsFileName',
+ r'''
+analyzer:
+ strong-mode: false
+''');
+ // Create the context.
+ manager.setRoots(<String>[projPath], <String>[], <String, String>{});
+ await pumpEventQueue();
+
+ AnalysisContext context = manager.getContextFor(projPath);
+ Source testSource = context.getSourcesWithFullName(file.path).single;
+
+ // Not strong mode - both in the context and the SDK context.
+ {
+ AnalysisContext sdkContext = context.sourceFactory.dartSdk.context;
+ expect(context.analysisOptions.strongMode, isFalse);
+ expect(sdkContext.analysisOptions.strongMode, isFalse);
+ expect(context.computeErrors(testSource), isEmpty);
+ }
+
+ // Update the options file - turn on 'strong-mode'.
+ resourceProvider.updateFile(
+ '$projPath/$optionsFileName',
+ r'''
+analyzer:
+ strong-mode: true
+''');
+ await pumpEventQueue();
+
+ // Strong mode - both in the context and the SDK context.
+ {
+ AnalysisContext context = manager.getContextFor(projPath);
+ AnalysisContext sdkContext = context.sourceFactory.dartSdk.context;
+ expect(context.analysisOptions.strongMode, isTrue);
+ expect(sdkContext.analysisOptions.strongMode, isTrue);
+ // The code is strong-mode clean.
+ // Verify that TypeSystem was reset.
+ expect(context.computeErrors(testSource), isEmpty);
+ }
+ }
+
test_path_filter_analysis_option() async {
// Create files.
String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
diff --git a/pkg/analysis_server/test/domain_analysis_test.dart b/pkg/analysis_server/test/domain_analysis_test.dart
index 35e9537..485227d 100644
--- a/pkg/analysis_server/test/domain_analysis_test.dart
+++ b/pkg/analysis_server/test/domain_analysis_test.dart
@@ -9,14 +9,11 @@
import 'package:analysis_server/plugin/protocol/protocol.dart';
import 'package:analysis_server/src/analysis_server.dart';
import 'package:analysis_server/src/constants.dart';
-import 'package:analysis_server/src/context_manager.dart';
import 'package:analysis_server/src/domain_analysis.dart';
import 'package:analysis_server/src/plugin/server_plugin.dart';
-import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
import 'package:analyzer/src/generated/sdk.dart';
-import 'package:path/path.dart';
import 'package:plugin/manager.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:unittest/unittest.dart';
diff --git a/pkg/analysis_server/test/integration/analysis/error_test.dart b/pkg/analysis_server/test/integration/analysis/error_test.dart
index cd490fa..b01f1d8 100644
--- a/pkg/analysis_server/test/integration/analysis/error_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/error_test.dart
@@ -45,7 +45,7 @@
void foo() {}
}
abstract class B {
- void foo();
+ void foo() {}
}
abstract class C extends B {
void bar() {
@@ -79,7 +79,7 @@
void foo() {}
}
abstract class B {
- void foo();
+ void foo() {}
}
abstract class C extends B {
void bar() {
diff --git a/pkg/analysis_server/test/integration/integration_test_methods.dart b/pkg/analysis_server/test/integration/integration_test_methods.dart
index 580499d..9e4a5ee 100644
--- a/pkg/analysis_server/test/integration/integration_test_methods.dart
+++ b/pkg/analysis_server/test/integration/integration_test_methods.dart
@@ -92,6 +92,10 @@
* pid (int)
*
* The process id of the analysis server process.
+ *
+ * sessionId (optional String)
+ *
+ * The session id for this session.
*/
Stream<ServerConnectedParams> onServerConnected;
diff --git a/pkg/analysis_server/test/integration/integration_tests.dart b/pkg/analysis_server/test/integration/integration_tests.dart
index 1893c18..f6748ed 100644
--- a/pkg/analysis_server/test/integration/integration_tests.dart
+++ b/pkg/analysis_server/test/integration/integration_tests.dart
@@ -636,6 +636,9 @@
if (Platform.packageRoot != null) {
arguments.add('--package-root=${Platform.packageRoot}');
}
+ if (Platform.packageConfig != null) {
+ arguments.add('--packages=${Platform.packageConfig}');
+ }
if (checked) {
arguments.add('--checked');
}
diff --git a/pkg/analysis_server/test/integration/protocol_matchers.dart b/pkg/analysis_server/test/integration/protocol_matchers.dart
index 5c8e84a..fef9ef3 100644
--- a/pkg/analysis_server/test/integration/protocol_matchers.dart
+++ b/pkg/analysis_server/test/integration/protocol_matchers.dart
@@ -66,12 +66,15 @@
* {
* "version": String
* "pid": int
+ * "sessionId": optional String
* }
*/
final Matcher isServerConnectedParams = new LazyMatcher(() => new MatchesJsonObject(
"server.connected params", {
"version": isString,
"pid": isInt
+ }, optionalFields: {
+ "sessionId": isString
}));
/**
diff --git a/pkg/analysis_server/test/mock_sdk.dart b/pkg/analysis_server/test/mock_sdk.dart
index 0d39a19..94d1208 100644
--- a/pkg/analysis_server/test/mock_sdk.dart
+++ b/pkg/analysis_server/test/mock_sdk.dart
@@ -126,10 +126,12 @@
abstract class Iterable<E> {
Iterator<E> get iterator;
bool get isEmpty;
+ Iterable/*<R>*/ map/*<R>*/(/*=R*/ f(E e));
}
abstract class List<E> implements Iterable<E> {
void add(E value);
+ void addAll(Iterable<E> iterable) {}
E operator [](int index);
void operator []=(int index, E value);
Iterator<E> get iterator => null;
diff --git a/pkg/analysis_server/test/services/correction/fix_test.dart b/pkg/analysis_server/test/services/correction/fix_test.dart
index 60897d9..9bc4a4f 100644
--- a/pkg/analysis_server/test/services/correction/fix_test.dart
+++ b/pkg/analysis_server/test/services/correction/fix_test.dart
@@ -3971,6 +3971,23 @@
''');
}
+ test_undefinedClass_useSimilar_BAD_prefixed() async {
+ resolveTestUnit('''
+import 'dart:async' as c;
+main() {
+ c.Fture v = null;
+}
+''');
+ await assertHasFix(
+ DartFixKind.CHANGE_TO,
+ '''
+import 'dart:async' as c;
+main() {
+ c.Future v = null;
+}
+''');
+ }
+
test_undefinedClass_useSimilar_fromImport() async {
resolveTestUnit('''
main() {
@@ -4370,6 +4387,33 @@
''');
}
+ test_undefinedFunction_useSimilar_prefixed_fromImport() async {
+ resolveTestUnit('''
+import 'dart:core' as c;
+main() {
+ c.prnt(42);
+}
+''');
+ await assertHasFix(
+ DartFixKind.CHANGE_TO,
+ '''
+import 'dart:core' as c;
+main() {
+ c.print(42);
+}
+''');
+ }
+
+ test_undefinedFunction_useSimilar_prefixed_ignoreLocal() async {
+ resolveTestUnit('''
+import 'dart:async' as c;
+main() {
+ c.main();
+}
+''');
+ await assertNoFix(DartFixKind.CHANGE_TO);
+ }
+
test_undefinedFunction_useSimilar_thisLibrary() async {
resolveTestUnit('''
myFunction() {}
diff --git a/pkg/analyzer/test/src/summary/index_unit_test.dart b/pkg/analysis_server/test/services/index/index_unit_test.dart
similarity index 99%
rename from pkg/analyzer/test/src/summary/index_unit_test.dart
rename to pkg/analysis_server/test/services/index/index_unit_test.dart
index 06f6efb..87388fd 100644
--- a/pkg/analyzer/test/src/summary/index_unit_test.dart
+++ b/pkg/analysis_server/test/services/index/index_unit_test.dart
@@ -4,15 +4,15 @@
import 'dart:convert';
+import 'package:analysis_server/src/services/index/index_unit.dart';
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/src/summary/format.dart';
import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary/index_unit.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'package:unittest/unittest.dart';
-import '../abstract_single_unit.dart';
+import '../../abstract_single_unit.dart';
main() {
groupSep = ' | ';
diff --git a/pkg/analysis_server/test/services/index/test_all.dart b/pkg/analysis_server/test/services/index/test_all.dart
index 27a2cd2..5c45ec5 100644
--- a/pkg/analysis_server/test/services/index/test_all.dart
+++ b/pkg/analysis_server/test/services/index/test_all.dart
@@ -6,6 +6,7 @@
import '../../utils.dart';
import 'index_test.dart' as index_test;
+import 'index_unit_test.dart' as index_unit_test;
/**
* Utility for manually running all tests.
@@ -14,5 +15,6 @@
initializeTestEnvironment();
group('index', () {
index_test.main();
+ index_unit_test.main();
});
}
diff --git a/pkg/analysis_server/tool/spec/generate_files b/pkg/analysis_server/tool/spec/generate_files
index 85092ea..ee9e970 100755
--- a/pkg/analysis_server/tool/spec/generate_files
+++ b/pkg/analysis_server/tool/spec/generate_files
@@ -32,27 +32,31 @@
ROOT_DIR="$(cd "${SCRIPT_DIR}/../../../.." ; pwd -P)"
-BIN_DIR="${ROOT_DIR}/sdk/bin"
-
-if [ -z "$DART_CONFIGURATION" ];
+if [[ $1 == '--arch' && $2 == 'x64' ]];
+then
+ DART_CONFIGURATION="ReleaseX64"
+elif [ -z "$DART_CONFIGURATION" ];
then
DART_CONFIGURATION="ReleaseIA32"
fi
if [[ `uname` == 'Darwin' ]];
then
- BUILD_DIR="${ROOT_DIR}/xcodebuild/$DART_CONFIGURATION"
-else
- BUILD_DIR="${ROOT_DIR}/out/$DART_CONFIGURATION"
+ if [[ $GYP_GENERATORS == 'ninja' ]];
+ then
+ BUILD_DIR="${ROOT_DIR}/out/$DART_CONFIGURATION"
+ else
+ BUILD_DIR="${ROOT_DIR}/xcodebuild/$DART_CONFIGURATION"
+ fi
fi
-PKG_DIR="${BUILD_DIR}/packages"
+PKG_FILE="${ROOT_DIR}/pkg/analysis_server/.packages"
-DART="${BIN_DIR}/dart"
+DART="${BUILD_DIR}/dart-sdk/bin/dart"
declare -a VM_OPTIONS
VM_OPTIONS+=("--checked")
-VM_OPTIONS+=("--package-root=${PKG_DIR}")
+VM_OPTIONS+=("--packages=${PKG_FILE}")
cd "${SCRIPT_DIR}"
"${DART}" "${VM_OPTIONS[@]}" "generate_all.dart"
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index cadad70..5290921 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -243,6 +243,10 @@
<ref>int</ref>
<p>The process id of the analysis server process.</p>
</field>
+ <field name="sessionId" optional="true">
+ <ref>String</ref>
+ <p>The session id for this session.</p>
+ </field>
</params>
</notification>
<notification event="error">
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index da18224..7ec7be4 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -36,6 +36,7 @@
*/
library analyzer.dart.ast.ast;
+import 'package:analyzer/dart/ast/syntactic_entity.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
@@ -510,7 +511,7 @@
*
* Clients may not extend, implement or mix-in this class.
*/
-abstract class AstNode {
+abstract class AstNode implements SyntacticEntity {
/**
* An empty list of AST nodes.
*/
@@ -536,7 +537,7 @@
* (either AST nodes or tokens) that make up the contents of this node,
* including doc comments but excluding other comments.
*/
- Iterable /* AstNode | Token */ get childEntities;
+ Iterable<SyntacticEntity> get childEntities;
/**
* Return the offset of the character immediately following the last character
@@ -546,6 +547,7 @@
* equivalent to the node's offset (because the length is zero (0) by
* definition).
*/
+ @override
int get end;
/**
@@ -560,15 +562,10 @@
*/
bool get isSynthetic;
- /**
- * Return the number of characters in the node's source range.
- */
+ @override
int get length;
- /**
- * Return the offset from the beginning of the file to the first character in
- * the node's source range.
- */
+ @override
int get offset;
/**
diff --git a/pkg/analyzer/lib/dart/ast/syntactic_entity.dart b/pkg/analyzer/lib/dart/ast/syntactic_entity.dart
new file mode 100644
index 0000000..bc8271a
--- /dev/null
+++ b/pkg/analyzer/lib/dart/ast/syntactic_entity.dart
@@ -0,0 +1,28 @@
+// 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.dart.ast.syntactic_entity;
+
+/**
+ * Interface representing a syntactic entity (either a token or an AST node)
+ * which has a location and extent in the source file.
+ */
+abstract class SyntacticEntity {
+ /**
+ * Return the offset from the beginning of the file to the character after the
+ * last character of the syntactic entity.
+ */
+ int get end;
+
+ /**
+ * Return the number of characters in the syntactic entity's source range.
+ */
+ int get length;
+
+ /**
+ * Return the offset from the beginning of the file to the first character in
+ * the syntactic entity.
+ */
+ int get offset;
+}
diff --git a/pkg/analyzer/lib/dart/ast/token.dart b/pkg/analyzer/lib/dart/ast/token.dart
index 687111a..fce7f24 100644
--- a/pkg/analyzer/lib/dart/ast/token.dart
+++ b/pkg/analyzer/lib/dart/ast/token.dart
@@ -10,6 +10,7 @@
import 'dart:collection';
+import 'package:analyzer/dart/ast/syntactic_entity.dart';
import 'package:analyzer/src/dart/ast/token.dart' show SimpleToken, TokenClass;
/**
@@ -219,16 +220,13 @@
*
* Clients may not extend, implement or mix-in this class.
*/
-abstract class Token {
+abstract class Token implements SyntacticEntity {
/**
* Initialize a newly created token to have the given [type] and [offset].
*/
factory Token(TokenType type, int offset) = SimpleToken;
- /**
- * Return the offset from the beginning of the file to the character after the
- * last character of the token.
- */
+ @override
int get end;
/**
@@ -254,9 +252,7 @@
*/
Keyword get keyword;
- /**
- * Return the number of characters in the node's source range.
- */
+ @override
int get length;
/**
@@ -269,10 +265,7 @@
*/
Token get next;
- /**
- * Return the offset from the beginning of the file to the first character in
- * the token.
- */
+ @override
int get offset;
/**
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index df7db66..cee76da 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -40,7 +40,6 @@
import 'package:analyzer/dart/constant/value.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
-import 'package:analyzer/src/generated/java_core.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source.dart';
@@ -864,12 +863,11 @@
}
/**
- * The enumeration `ElementKind` defines the various kinds of elements in the
- * element model.
+ * The kind of elements in the element model.
*
* Clients may not extend, implement or mix-in this class.
*/
-class ElementKind extends Enum<ElementKind> {
+class ElementKind implements Comparable<ElementKind> {
static const ElementKind CLASS = const ElementKind('CLASS', 0, "class");
static const ElementKind COMPILATION_UNIT =
@@ -954,6 +952,16 @@
];
/**
+ * The name of this element kind.
+ */
+ final String name;
+
+ /**
+ * The ordinal value of the element kind.
+ */
+ final int ordinal;
+
+ /**
* The name displayed in the UI for this kind of element.
*/
final String displayName;
@@ -961,8 +969,16 @@
/**
* Initialize a newly created element kind to have the given [displayName].
*/
- const ElementKind(String name, int ordinal, this.displayName)
- : super(name, ordinal);
+ const ElementKind(this.name, this.ordinal, this.displayName);
+
+ @override
+ int get hashCode => ordinal;
+
+ @override
+ int compareTo(ElementKind other) => ordinal - other.ordinal;
+
+ @override
+ String toString() => name;
/**
* Return the kind of the given [element], or [ERROR] if the element is
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 622fe9e..53a6565 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -892,7 +892,7 @@
/**
* The properties that can be associated with an [AnalysisError].
*/
-class ErrorProperty<V> extends Enum<ErrorProperty> {
+class ErrorProperty<V> implements Comparable<ErrorProperty> {
/**
* A property whose value is a list of [FieldElement]s that are final, but
* not initialized by a constructor.
@@ -921,13 +921,32 @@
UNIMPLEMENTED_METHODS
];
- const ErrorProperty(String name, int ordinal) : super(name, ordinal);
+ /**
+ * The name of this property.
+ */
+ final String name;
+
+ /**
+ * The ordinal value of the property.
+ */
+ final int ordinal;
+
+ const ErrorProperty(this.name, this.ordinal);
+
+ @override
+ int get hashCode => ordinal;
+
+ @override
+ int compareTo(ErrorProperty other) => ordinal - other.ordinal;
+
+ @override
+ String toString() => name;
}
/**
* The severity of an [ErrorCode].
*/
-class ErrorSeverity extends Enum<ErrorSeverity> {
+class ErrorSeverity implements Comparable<ErrorSeverity> {
/**
* The severity representing a non-error. This is never used for any error
* code, but is useful for clients.
@@ -955,6 +974,16 @@
static const List<ErrorSeverity> values = const [NONE, INFO, WARNING, ERROR];
/**
+ * The name of this error code.
+ */
+ final String name;
+
+ /**
+ * The ordinal value of the error code.
+ */
+ final int ordinal;
+
+ /**
* The name of the severity used when producing machine output.
*/
final String machineCode;
@@ -966,26 +995,30 @@
/**
* Initialize a newly created severity with the given names.
- *
- * Parameters:
- * 0: the name of the severity used when producing machine output
- * 1: the name of the severity used when producing readable output
*/
const ErrorSeverity(
- String name, int ordinal, this.machineCode, this.displayName)
- : super(name, ordinal);
+ this.name, this.ordinal, this.machineCode, this.displayName);
+
+ @override
+ int get hashCode => ordinal;
+
+ @override
+ int compareTo(ErrorSeverity other) => ordinal - other.ordinal;
/**
* Return the severity constant that represents the greatest severity.
*/
ErrorSeverity max(ErrorSeverity severity) =>
this.ordinal >= severity.ordinal ? this : severity;
+
+ @override
+ String toString() => name;
}
/**
* The type of an [ErrorCode].
*/
-class ErrorType extends Enum<ErrorType> {
+class ErrorType implements Comparable<ErrorType> {
/**
* Task (todo) comments in user code.
*/
@@ -1052,6 +1085,16 @@
];
/**
+ * The name of this error type.
+ */
+ final String name;
+
+ /**
+ * The ordinal value of the error type.
+ */
+ final int ordinal;
+
+ /**
* The severity of this type of error.
*/
final ErrorSeverity severity;
@@ -1060,8 +1103,16 @@
* Initialize a newly created error type to have the given [name] and
* [severity].
*/
- const ErrorType(String name, int ordinal, this.severity)
- : super(name, ordinal);
+ const ErrorType(this.name, this.ordinal, this.severity);
String get displayName => name.toLowerCase().replaceAll('_', ' ');
+
+ @override
+ int get hashCode => ordinal;
+
+ @override
+ int compareTo(ErrorType other) => ordinal - other.ordinal;
+
+ @override
+ String toString() => name;
}
diff --git a/pkg/analyzer/lib/instrumentation/file_instrumentation.dart b/pkg/analyzer/lib/instrumentation/file_instrumentation.dart
index fe36a9e..d4088f8 100644
--- a/pkg/analyzer/lib/instrumentation/file_instrumentation.dart
+++ b/pkg/analyzer/lib/instrumentation/file_instrumentation.dart
@@ -21,6 +21,9 @@
}
@override
+ String get sessionId => '';
+
+ @override
void log(String message) {
_sink.writeln(message);
}
diff --git a/pkg/analyzer/lib/instrumentation/instrumentation.dart b/pkg/analyzer/lib/instrumentation/instrumentation.dart
index eaf95ba..abc2799 100644
--- a/pkg/analyzer/lib/instrumentation/instrumentation.dart
+++ b/pkg/analyzer/lib/instrumentation/instrumentation.dart
@@ -23,6 +23,11 @@
*/
abstract class InstrumentationServer {
/**
+ * Return the identifier used to identify the current session.
+ */
+ String get sessionId;
+
+ /**
* Pass the given [message] to the instrumentation server so that it will be
* logged with other messages.
*
@@ -96,6 +101,11 @@
bool get isActive => _instrumentationServer != null;
/**
+ * Return the identifier used to identify the current session.
+ */
+ String get sessionId => _instrumentationServer?.sessionId ?? '';
+
+ /**
* The current time, expressed as a decimal encoded number of milliseconds.
*/
String get _timestamp => new DateTime.now().millisecondsSinceEpoch.toString();
@@ -357,6 +367,9 @@
MulticastInstrumentationServer(this._servers);
@override
+ String get sessionId => _servers[0].sessionId;
+
+ @override
void log(String message) {
for (InstrumentationServer server in _servers) {
server.log(message);
diff --git a/pkg/analyzer/lib/src/context/context.dart b/pkg/analyzer/lib/src/context/context.dart
index 7e8b4d3..f56c12c 100644
--- a/pkg/analyzer/lib/src/context/context.dart
+++ b/pkg/analyzer/lib/src/context/context.dart
@@ -9,7 +9,6 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/instrumentation/instrumentation.dart';
@@ -19,14 +18,12 @@
import 'package:analyzer/src/context/builder.dart' show EmbedderYamlLocator;
import 'package:analyzer/src/context/cache.dart';
import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/generated/constant.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/incremental_resolver.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/testing/ast_factory.dart';
import 'package:analyzer/src/generated/utilities_collection.dart';
import 'package:analyzer/src/task/dart.dart';
import 'package:analyzer/src/task/dart_work_manager.dart';
@@ -308,7 +305,6 @@
this._options.enableStrictCallChecks !=
options.enableStrictCallChecks ||
this._options.enableGenericMethods != options.enableGenericMethods ||
- this._options.enableAsync != options.enableAsync ||
this._options.enableSuperMixins != options.enableSuperMixins;
int cacheSize = options.cacheSize;
if (this._options.cacheSize != cacheSize) {
@@ -323,7 +319,6 @@
this._options.enableAssertInitializer = options.enableAssertInitializer;
this._options.enableAssertMessage = options.enableAssertMessage;
this._options.enableStrictCallChecks = options.enableStrictCallChecks;
- this._options.enableAsync = options.enableAsync;
this._options.enableInitializingFormalAccess =
options.enableInitializingFormalAccess;
this._options.enableSuperMixins = options.enableSuperMixins;
@@ -334,6 +329,9 @@
this._options.incrementalValidation = options.incrementalValidation;
this._options.lint = options.lint;
this._options.preserveComments = options.preserveComments;
+ if (this._options.strongMode != options.strongMode) {
+ _typeSystem = null;
+ }
this._options.strongMode = options.strongMode;
this._options.trackCacheDependencies = options.trackCacheDependencies;
this._options.finerGrainedInvalidation = options.finerGrainedInvalidation;
@@ -545,22 +543,14 @@
throw new AnalysisException("Could not create an element for dart:core");
}
- LibraryElement asyncElement;
- if (analysisOptions.enableAsync) {
- Source asyncSource = sourceFactory.forUri(DartSdk.DART_ASYNC);
- if (asyncSource == null) {
- throw new AnalysisException("Could not create a source for dart:async");
- }
- asyncElement = computeLibraryElement(asyncSource);
- if (asyncElement == null) {
- throw new AnalysisException(
- "Could not create an element for dart:async");
- }
- } else {
- Source asyncSource = sourceFactory.forUri(DartSdk.DART_ASYNC);
- asyncElement = createMockAsyncLib(coreElement, asyncSource);
+ Source asyncSource = sourceFactory.forUri(DartSdk.DART_ASYNC);
+ if (asyncSource == null) {
+ throw new AnalysisException("Could not create a source for dart:async");
}
-
+ LibraryElement asyncElement = computeLibraryElement(asyncSource);
+ if (asyncElement == null) {
+ throw new AnalysisException("Could not create an element for dart:async");
+ }
_typeProvider = new TypeProviderImpl(coreElement, asyncElement);
return _typeProvider;
}
@@ -773,55 +763,6 @@
return cache;
}
- /**
- * Create a minimalistic mock dart:async library
- * to stand in for a real one if one does not exist
- * facilitating creation a type provider without dart:async.
- */
- LibraryElement createMockAsyncLib(
- LibraryElement coreLibrary, Source asyncSource) {
- InterfaceType objType = coreLibrary.getType('Object').type;
-
- ClassElement _classElement(String typeName, [List<String> parameterNames]) {
- ClassElementImpl element =
- new ClassElementImpl.forNode(AstFactory.identifier3(typeName));
- element.supertype = objType;
- if (parameterNames != null) {
- int count = parameterNames.length;
- if (count > 0) {
- List<TypeParameterElementImpl> typeParameters =
- new List<TypeParameterElementImpl>(count);
- List<TypeParameterTypeImpl> typeArguments =
- new List<TypeParameterTypeImpl>(count);
- for (int i = 0; i < count; i++) {
- TypeParameterElementImpl typeParameter =
- new TypeParameterElementImpl.forNode(
- AstFactory.identifier3(parameterNames[i]));
- typeParameters[i] = typeParameter;
- typeArguments[i] = new TypeParameterTypeImpl(typeParameter);
- typeParameter.type = typeArguments[i];
- }
- element.typeParameters = typeParameters;
- }
- }
- return element;
- }
-
- InterfaceType futureType = _classElement('Future', ['T']).type;
- InterfaceType streamType = _classElement('Stream', ['T']).type;
- CompilationUnitElementImpl asyncUnit =
- new CompilationUnitElementImpl("mock_async.dart");
- asyncUnit.types = <ClassElement>[futureType.element, streamType.element];
- LibraryElementImpl mockLib = new LibraryElementImpl.forNode(
- this, AstFactory.libraryIdentifier2(["dart.async"]));
- asyncUnit.librarySource = asyncSource;
- asyncUnit.source = asyncSource;
- mockLib.definingCompilationUnit = asyncUnit;
- mockLib.publicNamespace =
- new NamespaceBuilder().createPublicNamespaceForLibrary(mockLib);
- return mockLib;
- }
-
@override
void dispose() {
_disposed = true;
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index eca142a..4df003d 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -7,6 +7,7 @@
import 'dart:collection';
import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/syntactic_entity.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
@@ -51,7 +52,8 @@
Token get beginToken => _strings.beginToken;
@override
- Iterable get childEntities => new ChildEntities()..addAll(_strings);
+ Iterable<SyntacticEntity> get childEntities =>
+ new ChildEntities()..addAll(_strings);
@override
Token get endToken => _strings.endToken;
@@ -262,7 +264,7 @@
Token get beginToken => atSign;
@override
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..add(atSign)
..add(_name)
..add(period)
@@ -388,7 +390,7 @@
@override
// TODO(paulberry): Add commas.
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..add(leftParenthesis)
..addAll(_arguments)
..add(rightParenthesis);
@@ -520,7 +522,7 @@
Token get beginToken => _expression.beginToken;
@override
- Iterable get childEntities =>
+ Iterable<SyntacticEntity> get childEntities =>
new ChildEntities()..add(_expression)..add(asOperator)..add(_type);
@override
@@ -623,7 +625,7 @@
Token get beginToken => assertKeyword;
@override
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..add(assertKeyword)
..add(leftParenthesis)
..add(_condition)
@@ -740,7 +742,7 @@
}
@override
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..add(_leftHandSide)
..add(operator)
..add(_rightHandSide);
@@ -992,7 +994,7 @@
}
@override
- Iterable get childEntities =>
+ Iterable<SyntacticEntity> get childEntities =>
new ChildEntities()..add(awaitKeyword)..add(_expression);
@override
@@ -1081,7 +1083,7 @@
}
@override
- Iterable get childEntities =>
+ Iterable<SyntacticEntity> get childEntities =>
new ChildEntities()..add(_leftOperand)..add(operator)..add(_rightOperand);
@override
@@ -1205,7 +1207,7 @@
}
@override
- Iterable get childEntities =>
+ Iterable<SyntacticEntity> get childEntities =>
new ChildEntities()..add(keyword)..add(star)..add(_block);
@override
@@ -1265,7 +1267,7 @@
Token get beginToken => leftBracket;
@override
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..add(leftBracket)
..addAll(_statements)
..add(rightBracket);
@@ -1314,7 +1316,8 @@
Token get beginToken => literal;
@override
- Iterable get childEntities => new ChildEntities()..add(literal);
+ Iterable<SyntacticEntity> get childEntities =>
+ new ChildEntities()..add(literal);
@override
Token get endToken => literal;
@@ -1381,7 +1384,7 @@
Token get beginToken => breakKeyword;
@override
- Iterable get childEntities =>
+ Iterable<SyntacticEntity> get childEntities =>
new ChildEntities()..add(breakKeyword)..add(_label)..add(semicolon);
@override
@@ -1450,7 +1453,7 @@
NodeList<Expression> get cascadeSections => _cascadeSections;
@override
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..add(_target)
..addAll(_cascadeSections);
@@ -1585,7 +1588,7 @@
}
@override
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..add(onKeyword)
..add(_exceptionType)
..add(catchKeyword)
@@ -1639,21 +1642,22 @@
/**
* Helper class to allow iteration of child entities of an AST node.
*/
-class ChildEntities extends Object with IterableMixin implements Iterable {
+class ChildEntities extends Object
+ with IterableMixin<SyntacticEntity>
+ implements Iterable<SyntacticEntity> {
/**
* The list of child entities to be iterated over.
*/
- List _entities = [];
+ List<SyntacticEntity> _entities = [];
@override
- Iterator get iterator => _entities.iterator;
+ Iterator<SyntacticEntity> get iterator => _entities.iterator;
/**
* Add an AST node or token as the next child entity, if it is not null.
*/
- void add(entity) {
+ void add(SyntacticEntity entity) {
if (entity != null) {
- assert(entity is Token || entity is AstNode);
_entities.add(entity);
}
}
@@ -1661,7 +1665,7 @@
/**
* Add the given items as the next child entities, if [items] is not null.
*/
- void addAll(Iterable items) {
+ void addAll(Iterable<SyntacticEntity> items) {
if (items != null) {
_entities.addAll(items);
}
@@ -1770,7 +1774,7 @@
}
@override
- Iterable get childEntities => super._childEntities
+ Iterable<SyntacticEntity> get childEntities => super._childEntities
..add(abstractKeyword)
..add(classKeyword)
..add(_name)
@@ -2003,7 +2007,7 @@
}
@override
- Iterable get childEntities => super._childEntities
+ Iterable<SyntacticEntity> get childEntities => super._childEntities
..add(typedefKeyword)
..add(_name)
..add(_typeParameters)
@@ -2150,7 +2154,8 @@
Token get beginToken => tokens[0];
@override
- Iterable get childEntities => new ChildEntities()..addAll(tokens);
+ Iterable<SyntacticEntity> get childEntities =>
+ new ChildEntities()..addAll(tokens);
@override
Token get endToken => tokens[tokens.length - 1];
@@ -2235,7 +2240,7 @@
Token get beginToken => _identifier.beginToken;
@override
- Iterable get childEntities =>
+ Iterable<SyntacticEntity> get childEntities =>
new ChildEntities()..add(newKeyword)..add(_identifier);
@override
@@ -2378,7 +2383,7 @@
}
@override
- Iterable get childEntities {
+ Iterable<SyntacticEntity> get childEntities {
ChildEntities result = new ChildEntities()..add(_scriptTag);
if (_directivesAreBeforeDeclarations) {
result..addAll(_directives)..addAll(_declarations);
@@ -2531,7 +2536,7 @@
Token get beginToken => _condition.beginToken;
@override
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..add(_condition)
..add(question)
..add(_thenExpression)
@@ -2631,7 +2636,7 @@
Token get beginToken => ifKeyword;
@override
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..add(ifKeyword)
..add(leftParenthesis)
..add(_name)
@@ -2838,7 +2843,7 @@
}
@override
- Iterable get childEntities => super._childEntities
+ Iterable<SyntacticEntity> get childEntities => super._childEntities
..add(externalKeyword)
..add(constKeyword)
..add(factoryKeyword)
@@ -2980,7 +2985,7 @@
}
@override
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..add(thisKeyword)
..add(period)
..add(_fieldName)
@@ -3075,7 +3080,7 @@
Token get beginToken => _type.beginToken;
@override
- Iterable get childEntities =>
+ Iterable<SyntacticEntity> get childEntities =>
new ChildEntities()..add(_type)..add(period)..add(_name);
@override
@@ -3160,7 +3165,7 @@
Token get beginToken => continueKeyword;
@override
- Iterable get childEntities =>
+ Iterable<SyntacticEntity> get childEntities =>
new ChildEntities()..add(continueKeyword)..add(_label)..add(semicolon);
@override
@@ -3239,7 +3244,7 @@
}
@override
- Iterable get childEntities =>
+ Iterable<SyntacticEntity> get childEntities =>
super._childEntities..add(keyword)..add(_type)..add(_identifier);
@override
@@ -3366,7 +3371,7 @@
Token get beginToken => _parameter.beginToken;
@override
- Iterable get childEntities =>
+ Iterable<SyntacticEntity> get childEntities =>
new ChildEntities()..add(_parameter)..add(separator)..add(_defaultValue);
@override
@@ -3525,7 +3530,7 @@
}
@override
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..add(doKeyword)
..add(_body)
..add(whileKeyword)
@@ -3580,7 +3585,8 @@
@override
// TODO(paulberry): add "." tokens.
- Iterable get childEntities => new ChildEntities()..addAll(_components);
+ Iterable<SyntacticEntity> get childEntities =>
+ new ChildEntities()..addAll(_components);
@override
NodeList<SimpleIdentifier> get components => _components;
@@ -3630,7 +3636,8 @@
Token get beginToken => literal;
@override
- Iterable get childEntities => new ChildEntities()..add(literal);
+ Iterable<SyntacticEntity> get childEntities =>
+ new ChildEntities()..add(literal);
@override
Token get endToken => literal;
@@ -3670,7 +3677,8 @@
Token get beginToken => semicolon;
@override
- Iterable get childEntities => new ChildEntities()..add(semicolon);
+ Iterable<SyntacticEntity> get childEntities =>
+ new ChildEntities()..add(semicolon);
@override
Token get endToken => semicolon;
@@ -3706,7 +3714,8 @@
Token get beginToken => semicolon;
@override
- Iterable get childEntities => new ChildEntities()..add(semicolon);
+ Iterable<SyntacticEntity> get childEntities =>
+ new ChildEntities()..add(semicolon);
@override
Token get endToken => semicolon;
@@ -3744,7 +3753,8 @@
}
@override
- Iterable get childEntities => super._childEntities..add(_name);
+ Iterable<SyntacticEntity> get childEntities =>
+ super._childEntities..add(_name);
@override
FieldElement get element => _name?.staticElement as FieldElement;
@@ -3825,7 +3835,7 @@
@override
// TODO(brianwilkerson) Add commas?
- Iterable get childEntities => super._childEntities
+ Iterable<SyntacticEntity> get childEntities => super._childEntities
..add(enumKeyword)
..add(_name)
..add(leftBracket)
@@ -3893,7 +3903,7 @@
combinators, semicolon);
@override
- Iterable get childEntities => super._childEntities
+ Iterable<SyntacticEntity> get childEntities => super._childEntities
..add(_uri)
..addAll(combinators)
..add(semicolon);
@@ -3972,7 +3982,7 @@
}
@override
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..add(keyword)
..add(functionDefinition)
..add(_expression)
@@ -4145,7 +4155,7 @@
Token get beginToken => _expression.beginToken;
@override
- Iterable get childEntities =>
+ Iterable<SyntacticEntity> get childEntities =>
new ChildEntities()..add(_expression)..add(semicolon);
@override
@@ -4206,7 +4216,7 @@
Token get beginToken => extendsKeyword;
@override
- Iterable get childEntities =>
+ Iterable<SyntacticEntity> get childEntities =>
new ChildEntities()..add(extendsKeyword)..add(_superclass);
@override
@@ -4268,7 +4278,7 @@
}
@override
- Iterable get childEntities =>
+ Iterable<SyntacticEntity> get childEntities =>
super._childEntities..add(staticKeyword)..add(_fieldList)..add(semicolon);
@override
@@ -4389,7 +4399,7 @@
}
@override
- Iterable get childEntities => super._childEntities
+ Iterable<SyntacticEntity> get childEntities => super._childEntities
..add(keyword)
..add(_type)
..add(thisKeyword)
@@ -4559,7 +4569,7 @@
}
@override
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..add(awaitKeyword)
..add(forKeyword)
..add(leftParenthesis)
@@ -4708,7 +4718,7 @@
Token get beginToken => leftParenthesis;
@override
- Iterable get childEntities {
+ Iterable<SyntacticEntity> get childEntities {
// TODO(paulberry): include commas.
ChildEntities result = new ChildEntities()..add(leftParenthesis);
bool leftDelimiterNeeded = leftDelimiter != null;
@@ -4860,7 +4870,7 @@
}
@override
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..add(forKeyword)
..add(leftParenthesis)
..add(_variableList)
@@ -5039,7 +5049,7 @@
}
@override
- Iterable get childEntities => super._childEntities
+ Iterable<SyntacticEntity> get childEntities => super._childEntities
..add(externalKeyword)
..add(_returnType)
..add(propertyKeyword)
@@ -5122,7 +5132,8 @@
Token get beginToken => _functionDeclaration.beginToken;
@override
- Iterable get childEntities => new ChildEntities()..add(_functionDeclaration);
+ Iterable<SyntacticEntity> get childEntities =>
+ new ChildEntities()..add(_functionDeclaration);
@override
Token get endToken => _functionDeclaration.endToken;
@@ -5209,7 +5220,7 @@
}
@override
- Iterable get childEntities =>
+ Iterable<SyntacticEntity> get childEntities =>
new ChildEntities()..add(_parameters)..add(_body);
@override
@@ -5309,7 +5320,7 @@
}
@override
- Iterable get childEntities =>
+ Iterable<SyntacticEntity> get childEntities =>
new ChildEntities()..add(_function)..add(_argumentList);
@override
@@ -5388,7 +5399,7 @@
}
@override
- Iterable get childEntities => super._childEntities
+ Iterable<SyntacticEntity> get childEntities => super._childEntities
..add(typedefKeyword)
..add(_returnType)
..add(_name)
@@ -5495,7 +5506,7 @@
}
@override
- Iterable get childEntities =>
+ Iterable<SyntacticEntity> get childEntities =>
super._childEntities..add(_returnType)..add(identifier)..add(parameters);
@override
@@ -5567,7 +5578,7 @@
}
@override
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..add(keyword)
..addAll(_hiddenNames);
@@ -5677,7 +5688,7 @@
Token get beginToken => ifKeyword;
@override
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..add(ifKeyword)
..add(leftParenthesis)
..add(_condition)
@@ -5760,7 +5771,7 @@
@override
// TODO(paulberry): add commas.
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..add(implementsKeyword)
..addAll(interfaces);
@@ -5833,7 +5844,7 @@
}
@override
- Iterable get childEntities => super._childEntities
+ Iterable<SyntacticEntity> get childEntities => super._childEntities
..add(_uri)
..add(deferredKeyword)
..add(asKeyword)
@@ -5970,7 +5981,7 @@
}
@override
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..add(_target)
..add(period)
..add(leftBracket)
@@ -6147,7 +6158,7 @@
Token get beginToken => keyword;
@override
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..add(keyword)
..add(_constructorName)
..add(_argumentList);
@@ -6216,7 +6227,8 @@
Token get beginToken => literal;
@override
- Iterable get childEntities => new ChildEntities()..add(literal);
+ Iterable<SyntacticEntity> get childEntities =>
+ new ChildEntities()..add(literal);
@override
Token get endToken => literal;
@@ -6282,7 +6294,7 @@
Token get beginToken => leftBracket;
@override
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..add(leftBracket)
..add(_expression)
..add(rightBracket);
@@ -6343,7 +6355,8 @@
Token get beginToken => contents;
@override
- Iterable get childEntities => new ChildEntities()..add(contents);
+ Iterable<SyntacticEntity> get childEntities =>
+ new ChildEntities()..add(contents);
@override
int get contentsEnd {
@@ -6459,7 +6472,7 @@
Token get beginToken => _expression.beginToken;
@override
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..add(_expression)
..add(isOperator)
..add(notOperator)
@@ -6532,7 +6545,7 @@
}
@override
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..addAll(_labels)
..add(_statement);
@@ -6593,7 +6606,8 @@
Token get beginToken => _label.beginToken;
@override
- Iterable get childEntities => new ChildEntities()..add(_label)..add(colon);
+ Iterable<SyntacticEntity> get childEntities =>
+ new ChildEntities()..add(_label)..add(colon);
@override
Token get endToken => colon;
@@ -6652,7 +6666,7 @@
}
@override
- Iterable get childEntities =>
+ Iterable<SyntacticEntity> get childEntities =>
super._childEntities..add(libraryKeyword)..add(_name)..add(semicolon);
@override
@@ -6711,7 +6725,8 @@
@override
// TODO(paulberry): add "." tokens.
- Iterable get childEntities => new ChildEntities()..addAll(_components);
+ Iterable<SyntacticEntity> get childEntities =>
+ new ChildEntities()..addAll(_components);
@override
NodeList<SimpleIdentifier> get components => _components;
@@ -6805,7 +6820,7 @@
@override
// TODO(paulberry): add commas.
- Iterable get childEntities => super._childEntities
+ Iterable<SyntacticEntity> get childEntities => super._childEntities
..add(leftBracket)
..addAll(_elements)
..add(rightBracket);
@@ -6900,7 +6915,7 @@
Token get beginToken => _key.beginToken;
@override
- Iterable get childEntities =>
+ Iterable<SyntacticEntity> get childEntities =>
new ChildEntities()..add(_key)..add(separator)..add(_value);
@override
@@ -6983,7 +6998,7 @@
@override
// TODO(paulberry): add commas.
- Iterable get childEntities => super._childEntities
+ Iterable<SyntacticEntity> get childEntities => super._childEntities
..add(leftBracket)
..addAll(entries)
..add(rightBracket);
@@ -7116,7 +7131,7 @@
}
@override
- Iterable get childEntities => super._childEntities
+ Iterable<SyntacticEntity> get childEntities => super._childEntities
..add(externalKeyword)
..add(modifierKeyword)
..add(_returnType)
@@ -7278,7 +7293,7 @@
}
@override
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..add(_target)
..add(operator)
..add(_methodName)
@@ -7401,7 +7416,7 @@
Token get beginToken => _name.beginToken;
@override
- Iterable get childEntities =>
+ Iterable<SyntacticEntity> get childEntities =>
new ChildEntities()..add(_name)..add(_expression);
@override
@@ -7558,7 +7573,7 @@
Token get beginToken => nativeKeyword;
@override
- Iterable get childEntities =>
+ Iterable<SyntacticEntity> get childEntities =>
new ChildEntities()..add(nativeKeyword)..add(_name);
@override
@@ -7622,7 +7637,7 @@
Token get beginToken => nativeKeyword;
@override
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..add(nativeKeyword)
..add(_stringLiteral)
..add(semicolon);
@@ -7928,7 +7943,8 @@
Token get beginToken => literal;
@override
- Iterable get childEntities => new ChildEntities()..add(literal);
+ Iterable<SyntacticEntity> get childEntities =>
+ new ChildEntities()..add(literal);
@override
Token get endToken => literal;
@@ -7978,7 +7994,7 @@
Token get beginToken => leftParenthesis;
@override
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..add(leftParenthesis)
..add(_expression)
..add(rightParenthesis);
@@ -8047,7 +8063,7 @@
: super(comment, metadata, partUri);
@override
- Iterable get childEntities =>
+ Iterable<SyntacticEntity> get childEntities =>
super._childEntities..add(partKeyword)..add(_uri)..add(semicolon);
@override
@@ -8114,7 +8130,7 @@
}
@override
- Iterable get childEntities => super._childEntities
+ Iterable<SyntacticEntity> get childEntities => super._childEntities
..add(partKeyword)
..add(ofKeyword)
..add(_libraryName)
@@ -8204,7 +8220,7 @@
}
@override
- Iterable get childEntities =>
+ Iterable<SyntacticEntity> get childEntities =>
new ChildEntities()..add(_operand)..add(operator);
@override
@@ -8317,7 +8333,7 @@
}
@override
- Iterable get childEntities =>
+ Iterable<SyntacticEntity> get childEntities =>
new ChildEntities()..add(_prefix)..add(period)..add(_identifier);
@override
@@ -8437,7 +8453,7 @@
}
@override
- Iterable get childEntities =>
+ Iterable<SyntacticEntity> get childEntities =>
new ChildEntities()..add(operator)..add(_operand);
@override
@@ -8542,7 +8558,7 @@
}
@override
- Iterable get childEntities =>
+ Iterable<SyntacticEntity> get childEntities =>
new ChildEntities()..add(_target)..add(operator)..add(_propertyName);
@override
@@ -8661,7 +8677,7 @@
Token get beginToken => thisKeyword;
@override
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..add(thisKeyword)
..add(period)
..add(_constructorName)
@@ -8711,7 +8727,8 @@
Token get beginToken => rethrowKeyword;
@override
- Iterable get childEntities => new ChildEntities()..add(rethrowKeyword);
+ Iterable<SyntacticEntity> get childEntities =>
+ new ChildEntities()..add(rethrowKeyword);
@override
Token get endToken => rethrowKeyword;
@@ -8765,7 +8782,7 @@
Token get beginToken => returnKeyword;
@override
- Iterable get childEntities =>
+ Iterable<SyntacticEntity> get childEntities =>
new ChildEntities()..add(returnKeyword)..add(_expression)..add(semicolon);
@override
@@ -8810,7 +8827,8 @@
Token get beginToken => scriptTag;
@override
- Iterable get childEntities => new ChildEntities()..add(scriptTag);
+ Iterable<SyntacticEntity> get childEntities =>
+ new ChildEntities()..add(scriptTag);
@override
Token get endToken => scriptTag;
@@ -8847,7 +8865,7 @@
@override
// TODO(paulberry): add commas.
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..add(keyword)
..addAll(_shownNames);
@@ -8913,7 +8931,7 @@
}
@override
- Iterable get childEntities =>
+ Iterable<SyntacticEntity> get childEntities =>
super._childEntities..add(keyword)..add(_type)..add(identifier);
@override
@@ -9000,7 +9018,8 @@
}
@override
- Iterable get childEntities => new ChildEntities()..add(token);
+ Iterable<SyntacticEntity> get childEntities =>
+ new ChildEntities()..add(token);
@override
Token get endToken => token;
@@ -9180,7 +9199,8 @@
Token get beginToken => literal;
@override
- Iterable get childEntities => new ChildEntities()..add(literal);
+ Iterable<SyntacticEntity> get childEntities =>
+ new ChildEntities()..add(literal);
@override
int get contentsEnd => offset + _helper.end;
@@ -9289,7 +9309,8 @@
Token get beginToken => _elements.beginToken;
@override
- Iterable get childEntities => new ChildEntities()..addAll(_elements);
+ Iterable<SyntacticEntity> get childEntities =>
+ new ChildEntities()..addAll(_elements);
@override
int get contentsEnd {
@@ -9526,7 +9547,7 @@
Token get beginToken => superKeyword;
@override
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..add(superKeyword)
..add(period)
..add(_constructorName)
@@ -9575,7 +9596,8 @@
Token get beginToken => superKeyword;
@override
- Iterable get childEntities => new ChildEntities()..add(superKeyword);
+ Iterable<SyntacticEntity> get childEntities =>
+ new ChildEntities()..add(superKeyword);
@override
Token get endToken => superKeyword;
@@ -9616,7 +9638,7 @@
}
@override
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..addAll(labels)
..add(keyword)
..add(_expression)
@@ -9659,7 +9681,7 @@
: super(labels, keyword, colon, statements);
@override
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..addAll(labels)
..add(keyword)
..add(colon)
@@ -9800,7 +9822,7 @@
Token get beginToken => switchKeyword;
@override
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..add(switchKeyword)
..add(leftParenthesis)
..add(_expression)
@@ -9861,7 +9883,7 @@
@override
// TODO(paulberry): add "." tokens.
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..add(poundSign)
..addAll(components);
@@ -9899,7 +9921,8 @@
Token get beginToken => thisKeyword;
@override
- Iterable get childEntities => new ChildEntities()..add(thisKeyword);
+ Iterable<SyntacticEntity> get childEntities =>
+ new ChildEntities()..add(thisKeyword);
@override
Token get endToken => thisKeyword;
@@ -9945,7 +9968,7 @@
Token get beginToken => throwKeyword;
@override
- Iterable get childEntities =>
+ Iterable<SyntacticEntity> get childEntities =>
new ChildEntities()..add(throwKeyword)..add(_expression);
@override
@@ -10011,7 +10034,7 @@
}
@override
- Iterable get childEntities =>
+ Iterable<SyntacticEntity> get childEntities =>
super._childEntities..add(_variableList)..add(semicolon);
@override
@@ -10110,7 +10133,7 @@
NodeList<CatchClause> get catchClauses => _catchClauses;
@override
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..add(tryKeyword)
..add(_body)
..addAll(_catchClauses)
@@ -10225,7 +10248,7 @@
@override
// TODO(paulberry): Add commas.
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..add(leftBracket)
..addAll(_arguments)
..add(rightBracket);
@@ -10329,7 +10352,7 @@
Token get beginToken => _name.beginToken;
@override
- Iterable get childEntities =>
+ Iterable<SyntacticEntity> get childEntities =>
new ChildEntities()..add(_name)..add(_typeArguments);
@override
@@ -10425,7 +10448,7 @@
}
@override
- Iterable get childEntities =>
+ Iterable<SyntacticEntity> get childEntities =>
super._childEntities..add(_name)..add(extendsKeyword)..add(_bound);
@override
@@ -10497,7 +10520,7 @@
Token get beginToken => leftBracket;
@override
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..add(leftBracket)
..addAll(_typeParameters)
..add(rightBracket);
@@ -10683,7 +10706,7 @@
}
@override
- Iterable get childEntities =>
+ Iterable<SyntacticEntity> get childEntities =>
super._childEntities..add(_name)..add(equals)..add(_initializer);
/**
@@ -10802,7 +10825,7 @@
@override
// TODO(paulberry): include commas.
- Iterable get childEntities => super._childEntities
+ Iterable<SyntacticEntity> get childEntities => super._childEntities
..add(keyword)
..add(_type)
..addAll(_variables);
@@ -10880,7 +10903,7 @@
Token get beginToken => _variableList.beginToken;
@override
- Iterable get childEntities =>
+ Iterable<SyntacticEntity> get childEntities =>
new ChildEntities()..add(_variableList)..add(semicolon);
@override
@@ -10957,7 +10980,7 @@
}
@override
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..add(whileKeyword)
..add(leftParenthesis)
..add(_condition)
@@ -11015,7 +11038,7 @@
@override
// TODO(paulberry): add commas.
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..add(withKeyword)
..addAll(_mixinTypes);
@@ -11080,7 +11103,7 @@
}
@override
- Iterable get childEntities => new ChildEntities()
+ Iterable<SyntacticEntity> get childEntities => new ChildEntities()
..add(yieldKeyword)
..add(star)
..add(_expression)
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 5d70df8..4118d8d 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -21,7 +21,6 @@
import 'package:analyzer/src/generated/constant.dart' show EvaluationResultImpl;
import 'package:analyzer/src/generated/engine.dart'
show AnalysisContext, AnalysisEngine;
-import 'package:analyzer/src/generated/java_core.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
@@ -700,6 +699,18 @@
return false;
}
+ /**
+ * Return `true` if the class has a `noSuchMethod()` method distinct from the
+ * one declared in class `Object`, as per the Dart Language Specification
+ * (section 10.4).
+ */
+ bool get hasNoSuchMethod {
+ MethodElement method =
+ lookUpMethod(FunctionElement.NO_SUCH_METHOD_METHOD_NAME, library);
+ ClassElement definingClass = method?.enclosingElement;
+ return definingClass != null && !definingClass.type.isObject;
+ }
+
@override
bool get hasReferenceToSuper => hasModifier(Modifier.REFERENCES_SUPER);
@@ -3074,7 +3085,7 @@
* Return `true` if this element has the given [modifier] associated with it.
*/
bool hasModifier(Modifier modifier) =>
- BooleanArray.getEnum(_modifiers, modifier);
+ BooleanArray.get(_modifiers, modifier.ordinal);
@override
bool isAccessibleIn(LibraryElement library) {
@@ -3109,7 +3120,7 @@
* correspond to the given [value].
*/
void setModifier(Modifier modifier, bool value) {
- _modifiers = BooleanArray.setEnum(_modifiers, modifier, value);
+ _modifiers = BooleanArray.set(_modifiers, modifier.ordinal, value);
}
@override
@@ -6179,12 +6190,12 @@
}
/**
- * The enumeration `Modifier` defines constants for all of the modifiers defined
- * by the Dart language and for a few additional flags that are useful.
+ * The constants for all of the modifiers defined by the Dart language and for a
+ * few additional flags that are useful.
*
* Clients may not extend, implement or mix-in this class.
*/
-class Modifier extends Enum<Modifier> {
+class Modifier implements Comparable<Modifier> {
/**
* Indicates that the modifier 'abstract' was applied to the element.
*/
@@ -6301,7 +6312,26 @@
SYNTHETIC
];
- const Modifier(String name, int ordinal) : super(name, ordinal);
+ /**
+ * The name of this modifier.
+ */
+ final String name;
+
+ /**
+ * The ordinal value of the modifier.
+ */
+ final int ordinal;
+
+ const Modifier(this.name, this.ordinal);
+
+ @override
+ int get hashCode => ordinal;
+
+ @override
+ int compareTo(Modifier other) => ordinal - other.ordinal;
+
+ @override
+ String toString() => name;
}
/**
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
index 0ee331a..29b347f 100644
--- a/pkg/analyzer/lib/src/dart/element/member.dart
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -114,9 +114,6 @@
List<DartType> parameterTypes = definingType.element.type.typeArguments;
FunctionType substitutedType =
baseType.substitute2(argumentTypes, parameterTypes);
- if (baseType == substitutedType) {
- return constructor;
- }
return new ConstructorMember(constructor, definingType, substitutedType);
}
}
@@ -408,9 +405,6 @@
TypeParameterTypeImpl.getTypes(definingType.typeParameters);
FunctionType substitutedType =
baseType.substitute2(argumentTypes, parameterTypes);
- if (baseType == substitutedType) {
- return method;
- }
return new MethodMember(method, definingType, substitutedType);
}
}
@@ -645,9 +639,6 @@
List<DartType> parameterTypes = definingType.element.type.typeArguments;
FunctionType substitutedType =
baseType.substitute2(argumentTypes, parameterTypes);
- if (baseType == substitutedType) {
- return method;
- }
return new MethodMember(method, definingType, substitutedType);
}
}
@@ -776,9 +767,6 @@
TypeParameterTypeImpl.getTypes(definingType.typeParameters);
DartType substitutedType =
baseType.substitute2(argumentTypes, parameterTypes);
- if (baseType == substitutedType) {
- return parameter;
- }
return new ParameterMember(parameter, definingType, substitutedType);
}
}
@@ -990,9 +978,6 @@
TypeParameterTypeImpl.getTypes(definingType.typeParameters);
DartType substitutedBound =
bound.substitute2(argumentTypes, parameterTypes);
- if (bound == substitutedBound) {
- return parameter;
- }
return new TypeParameterMember(parameter, definingType, substitutedBound);
}
}
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
new file mode 100644
index 0000000..31ee726
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
@@ -0,0 +1,711 @@
+// 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.
+
+/**
+ * The errors produced during sytactic analysis (scanning and parsing).
+ */
+library analyzer.src.dart.error.syntactic_errors;
+
+import 'package:analyzer/error/error.dart';
+
+/**
+ * The error codes used for errors detected by the parser. The convention for
+ * this class is for the name of the error code to indicate the problem that
+ * caused the error to be generated and for the error message to explain what
+ * is wrong and, when appropriate, how the problem can be corrected.
+ */
+class ParserErrorCode extends ErrorCode {
+ static const ParserErrorCode ABSTRACT_CLASS_MEMBER = const ParserErrorCode(
+ 'ABSTRACT_CLASS_MEMBER',
+ "Members of classes cannot be declared to be 'abstract'");
+
+ static const ParserErrorCode ABSTRACT_ENUM = const ParserErrorCode(
+ 'ABSTRACT_ENUM', "Enums cannot be declared to be 'abstract'");
+
+ static const ParserErrorCode ABSTRACT_STATIC_METHOD = const ParserErrorCode(
+ 'ABSTRACT_STATIC_METHOD',
+ "Static methods cannot be declared to be 'abstract'");
+
+ static const ParserErrorCode ABSTRACT_TOP_LEVEL_FUNCTION =
+ const ParserErrorCode('ABSTRACT_TOP_LEVEL_FUNCTION',
+ "Top-level functions cannot be declared to be 'abstract'");
+
+ static const ParserErrorCode ABSTRACT_TOP_LEVEL_VARIABLE =
+ const ParserErrorCode('ABSTRACT_TOP_LEVEL_VARIABLE',
+ "Top-level variables cannot be declared to be 'abstract'");
+
+ static const ParserErrorCode ABSTRACT_TYPEDEF = const ParserErrorCode(
+ 'ABSTRACT_TYPEDEF', "Type aliases cannot be declared to be 'abstract'");
+
+ static const ParserErrorCode ANNOTATION_ON_ENUM_CONSTANT =
+ const ParserErrorCode('ANNOTATION_ON_ENUM_CONSTANT',
+ "Enum constants cannot have annotations");
+
+ /**
+ * 16.32 Identifier Reference: It is a compile-time error if any of the
+ * identifiers async, await, or yield is used as an identifier in a function
+ * body marked with either async, async*, or sync*.
+ */
+ static const ParserErrorCode ASYNC_KEYWORD_USED_AS_IDENTIFIER =
+ const ParserErrorCode('ASYNC_KEYWORD_USED_AS_IDENTIFIER',
+ "The keywords 'async', 'await', and 'yield' may not be used as identifiers in an asynchronous or generator function.");
+
+ /**
+ * Some environments, such as Fletch, do not support async.
+ */
+ static const ParserErrorCode ASYNC_NOT_SUPPORTED = const ParserErrorCode(
+ 'ASYNC_NOT_SUPPORTED',
+ "Async and sync are not supported in this environment.");
+
+ static const ParserErrorCode BREAK_OUTSIDE_OF_LOOP = const ParserErrorCode(
+ 'BREAK_OUTSIDE_OF_LOOP',
+ "A break statement cannot be used outside of a loop or switch statement");
+
+ static const ParserErrorCode CLASS_IN_CLASS = const ParserErrorCode(
+ 'CLASS_IN_CLASS',
+ "Classes can't be declared inside other classes.",
+ "Try moving the class to the top-level.");
+
+ static const ParserErrorCode COLON_IN_PLACE_OF_IN = const ParserErrorCode(
+ 'COLON_IN_PLACE_OF_IN', "For-in loops use 'in' rather than a colon");
+
+ static const ParserErrorCode CONST_AND_FINAL = const ParserErrorCode(
+ 'CONST_AND_FINAL',
+ "Members can't be declared to be both 'const' and 'final'.",
+ "Try removing either the 'const' or 'final' keyword.");
+
+ static const ParserErrorCode CONST_AND_VAR = const ParserErrorCode(
+ 'CONST_AND_VAR',
+ "Members can't be declared to be both 'const' and 'var'.",
+ "Try removing either the 'const' or 'var' keyword.");
+
+ static const ParserErrorCode CONST_CLASS = const ParserErrorCode(
+ 'CONST_CLASS',
+ "Classes can't be declared to be 'const'.",
+ "Try removing the 'const' keyword or moving to the class' constructor(s).");
+
+ static const ParserErrorCode CONST_CONSTRUCTOR_WITH_BODY =
+ const ParserErrorCode(
+ 'CONST_CONSTRUCTOR_WITH_BODY',
+ "Const constructor can't have a body.",
+ "Try removing the 'const' keyword or the body.");
+
+ static const ParserErrorCode CONST_ENUM = const ParserErrorCode(
+ 'CONST_ENUM',
+ "Enums can't be declared to be 'const'.",
+ "Try removing the 'const' keyword.");
+
+ static const ParserErrorCode CONST_FACTORY = const ParserErrorCode(
+ 'CONST_FACTORY',
+ "Only redirecting factory constructors can be declared to be 'const'.",
+ "Try removing the 'const' keyword or replacing the body with '=' followed by a valid target.");
+
+ static const ParserErrorCode CONST_METHOD = const ParserErrorCode(
+ 'CONST_METHOD',
+ "Getters, setters and methods can't be declared to be 'const'.",
+ "Try removing the 'const' keyword.");
+
+ static const ParserErrorCode CONST_TYPEDEF = const ParserErrorCode(
+ 'CONST_TYPEDEF',
+ "Type aliases can't be declared to be 'const'.",
+ "Try removing the 'const' keyword.");
+
+ static const ParserErrorCode CONSTRUCTOR_WITH_RETURN_TYPE =
+ const ParserErrorCode(
+ 'CONSTRUCTOR_WITH_RETURN_TYPE',
+ "Constructors can't have a return type.",
+ "Try removing the return type.");
+
+ static const ParserErrorCode CONTINUE_OUTSIDE_OF_LOOP = const ParserErrorCode(
+ 'CONTINUE_OUTSIDE_OF_LOOP',
+ "A continue statement cannot be used outside of a loop or switch statement");
+
+ static const ParserErrorCode CONTINUE_WITHOUT_LABEL_IN_CASE =
+ const ParserErrorCode('CONTINUE_WITHOUT_LABEL_IN_CASE',
+ "A continue statement in a switch statement must have a label as a target");
+
+ static const ParserErrorCode DEPRECATED_CLASS_TYPE_ALIAS =
+ const ParserErrorCode('DEPRECATED_CLASS_TYPE_ALIAS',
+ "The 'typedef' mixin application was replaced with 'class'");
+
+ static const ParserErrorCode DIRECTIVE_AFTER_DECLARATION =
+ const ParserErrorCode('DIRECTIVE_AFTER_DECLARATION',
+ "Directives must appear before any declarations");
+
+ static const ParserErrorCode DUPLICATE_LABEL_IN_SWITCH_STATEMENT =
+ const ParserErrorCode('DUPLICATE_LABEL_IN_SWITCH_STATEMENT',
+ "The label {0} was already used in this switch statement");
+
+ static const ParserErrorCode DUPLICATED_MODIFIER = const ParserErrorCode(
+ 'DUPLICATED_MODIFIER', "The modifier '{0}' was already specified.");
+
+ static const ParserErrorCode EMPTY_ENUM_BODY = const ParserErrorCode(
+ 'EMPTY_ENUM_BODY', "An enum must declare at least one constant name");
+
+ static const ParserErrorCode ENUM_IN_CLASS = const ParserErrorCode(
+ 'ENUM_IN_CLASS', "Enums cannot be declared inside classes");
+
+ static const ParserErrorCode EQUALITY_CANNOT_BE_EQUALITY_OPERAND =
+ const ParserErrorCode('EQUALITY_CANNOT_BE_EQUALITY_OPERAND',
+ "Equality expression cannot be operand of another equality expression.");
+
+ static const ParserErrorCode EXPECTED_CASE_OR_DEFAULT = const ParserErrorCode(
+ 'EXPECTED_CASE_OR_DEFAULT', "Expected 'case' or 'default'");
+
+ static const ParserErrorCode EXPECTED_CLASS_MEMBER =
+ const ParserErrorCode('EXPECTED_CLASS_MEMBER', "Expected a class member");
+
+ static const ParserErrorCode EXPECTED_EXECUTABLE = const ParserErrorCode(
+ 'EXPECTED_EXECUTABLE',
+ "Expected a method, getter, setter or operator declaration");
+
+ static const ParserErrorCode EXPECTED_LIST_OR_MAP_LITERAL =
+ const ParserErrorCode(
+ 'EXPECTED_LIST_OR_MAP_LITERAL', "Expected a list or map literal");
+
+ static const ParserErrorCode EXPECTED_STRING_LITERAL = const ParserErrorCode(
+ 'EXPECTED_STRING_LITERAL', "Expected a string literal");
+
+ static const ParserErrorCode EXPECTED_TOKEN =
+ const ParserErrorCode('EXPECTED_TOKEN', "Expected to find '{0}'");
+
+ static const ParserErrorCode EXPECTED_TYPE_NAME =
+ const ParserErrorCode('EXPECTED_TYPE_NAME', "Expected a type name");
+
+ static const ParserErrorCode EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE =
+ const ParserErrorCode('EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE',
+ "Export directives must preceed part directives");
+
+ static const ParserErrorCode EXTERNAL_AFTER_CONST = const ParserErrorCode(
+ 'EXTERNAL_AFTER_CONST',
+ "The modifier 'external' should be before the modifier 'const'");
+
+ static const ParserErrorCode EXTERNAL_AFTER_FACTORY = const ParserErrorCode(
+ 'EXTERNAL_AFTER_FACTORY',
+ "The modifier 'external' should be before the modifier 'factory'");
+
+ static const ParserErrorCode EXTERNAL_AFTER_STATIC = const ParserErrorCode(
+ 'EXTERNAL_AFTER_STATIC',
+ "The modifier 'external' should be before the modifier 'static'");
+
+ static const ParserErrorCode EXTERNAL_CLASS = const ParserErrorCode(
+ 'EXTERNAL_CLASS', "Classes cannot be declared to be 'external'");
+
+ static const ParserErrorCode EXTERNAL_CONSTRUCTOR_WITH_BODY =
+ const ParserErrorCode('EXTERNAL_CONSTRUCTOR_WITH_BODY',
+ "External constructors cannot have a body");
+
+ static const ParserErrorCode EXTERNAL_ENUM = const ParserErrorCode(
+ 'EXTERNAL_ENUM', "Enums cannot be declared to be 'external'");
+
+ static const ParserErrorCode EXTERNAL_FIELD = const ParserErrorCode(
+ 'EXTERNAL_FIELD', "Fields cannot be declared to be 'external'");
+
+ static const ParserErrorCode EXTERNAL_GETTER_WITH_BODY =
+ const ParserErrorCode(
+ 'EXTERNAL_GETTER_WITH_BODY', "External getters cannot have a body");
+
+ static const ParserErrorCode EXTERNAL_METHOD_WITH_BODY =
+ const ParserErrorCode(
+ 'EXTERNAL_METHOD_WITH_BODY', "External methods cannot have a body");
+
+ static const ParserErrorCode EXTERNAL_OPERATOR_WITH_BODY =
+ const ParserErrorCode('EXTERNAL_OPERATOR_WITH_BODY',
+ "External operators cannot have a body");
+
+ static const ParserErrorCode EXTERNAL_SETTER_WITH_BODY =
+ const ParserErrorCode(
+ 'EXTERNAL_SETTER_WITH_BODY', "External setters cannot have a body");
+
+ static const ParserErrorCode EXTERNAL_TYPEDEF = const ParserErrorCode(
+ 'EXTERNAL_TYPEDEF', "Type aliases cannot be declared to be 'external'");
+
+ static const ParserErrorCode FACTORY_TOP_LEVEL_DECLARATION =
+ const ParserErrorCode('FACTORY_TOP_LEVEL_DECLARATION',
+ "Top-level declarations cannot be declared to be 'factory'");
+
+ static const ParserErrorCode FACTORY_WITH_INITIALIZERS =
+ const ParserErrorCode(
+ 'FACTORY_WITH_INITIALIZERS',
+ "A 'factory' constructor cannot have initializers",
+ "Either remove the 'factory' keyword to make this a generative "
+ "constructor or remove the initializers.");
+
+ static const ParserErrorCode FACTORY_WITHOUT_BODY = const ParserErrorCode(
+ 'FACTORY_WITHOUT_BODY',
+ "A non-redirecting 'factory' constructor must have a body");
+
+ static const ParserErrorCode FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR =
+ const ParserErrorCode('FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR',
+ "Field initializers can only be used in a constructor");
+
+ static const ParserErrorCode FINAL_AND_VAR = const ParserErrorCode(
+ 'FINAL_AND_VAR',
+ "Members cannot be declared to be both 'final' and 'var'");
+
+ static const ParserErrorCode FINAL_CLASS = const ParserErrorCode(
+ 'FINAL_CLASS', "Classes cannot be declared to be 'final'");
+
+ static const ParserErrorCode FINAL_CONSTRUCTOR = const ParserErrorCode(
+ 'FINAL_CONSTRUCTOR', "A constructor cannot be declared to be 'final'");
+
+ static const ParserErrorCode FINAL_ENUM = const ParserErrorCode(
+ 'FINAL_ENUM', "Enums cannot be declared to be 'final'");
+
+ static const ParserErrorCode FINAL_METHOD = const ParserErrorCode(
+ 'FINAL_METHOD',
+ "Getters, setters and methods cannot be declared to be 'final'");
+
+ static const ParserErrorCode FINAL_TYPEDEF = const ParserErrorCode(
+ 'FINAL_TYPEDEF', "Type aliases cannot be declared to be 'final'");
+
+ static const ParserErrorCode FUNCTION_TYPED_PARAMETER_VAR = const ParserErrorCode(
+ 'FUNCTION_TYPED_PARAMETER_VAR',
+ "Function typed parameters cannot specify 'const', 'final' or 'var' instead of return type");
+
+ static const ParserErrorCode GETTER_IN_FUNCTION = const ParserErrorCode(
+ 'GETTER_IN_FUNCTION',
+ "Getters cannot be defined within methods or functions");
+
+ static const ParserErrorCode GETTER_WITH_PARAMETERS = const ParserErrorCode(
+ 'GETTER_WITH_PARAMETERS',
+ "Getter should be declared without a parameter list");
+
+ static const ParserErrorCode ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE =
+ const ParserErrorCode('ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE',
+ "Illegal assignment to non-assignable expression");
+
+ static const ParserErrorCode IMPLEMENTS_BEFORE_EXTENDS =
+ const ParserErrorCode('IMPLEMENTS_BEFORE_EXTENDS',
+ "The extends clause must be before the implements clause");
+
+ static const ParserErrorCode IMPLEMENTS_BEFORE_WITH = const ParserErrorCode(
+ 'IMPLEMENTS_BEFORE_WITH',
+ "The with clause must be before the implements clause");
+
+ static const ParserErrorCode IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE =
+ const ParserErrorCode('IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE',
+ "Import directives must preceed part directives");
+
+ static const ParserErrorCode INITIALIZED_VARIABLE_IN_FOR_EACH =
+ const ParserErrorCode('INITIALIZED_VARIABLE_IN_FOR_EACH',
+ "The loop variable in a for-each loop cannot be initialized");
+
+ static const ParserErrorCode INVALID_AWAIT_IN_FOR = const ParserErrorCode(
+ 'INVALID_AWAIT_IN_FOR',
+ "The modifier 'await' is not allowed for a normal 'for' statement",
+ "Remove the keyword or use a for-each statement.");
+
+ static const ParserErrorCode INVALID_CODE_POINT = const ParserErrorCode(
+ 'INVALID_CODE_POINT',
+ "The escape sequence '{0}' is not a valid code point");
+
+ static const ParserErrorCode INVALID_COMMENT_REFERENCE = const ParserErrorCode(
+ 'INVALID_COMMENT_REFERENCE',
+ "Comment references should contain a possibly prefixed identifier and can start with 'new', but should not contain anything else");
+
+ static const ParserErrorCode INVALID_HEX_ESCAPE = const ParserErrorCode(
+ 'INVALID_HEX_ESCAPE',
+ "An escape sequence starting with '\\x' must be followed by 2 hexidecimal digits");
+
+ static const ParserErrorCode INVALID_LITERAL_IN_CONFIGURATION =
+ const ParserErrorCode('INVALID_LITERAL_IN_CONFIGURATION',
+ "The literal in a configuration cannot contain interpolation");
+
+ static const ParserErrorCode INVALID_OPERATOR = const ParserErrorCode(
+ 'INVALID_OPERATOR', "The string '{0}' is not a valid operator");
+
+ static const ParserErrorCode INVALID_OPERATOR_FOR_SUPER =
+ const ParserErrorCode('INVALID_OPERATOR_FOR_SUPER',
+ "The operator '{0}' cannot be used with 'super'");
+
+ static const ParserErrorCode INVALID_STAR_AFTER_ASYNC = const ParserErrorCode(
+ 'INVALID_STAR_AFTER_ASYNC',
+ "The modifier 'async*' is not allowed for an expression function body",
+ "Convert the body to a block.");
+
+ static const ParserErrorCode INVALID_SYNC = const ParserErrorCode(
+ 'INVALID_SYNC',
+ "The modifier 'sync' is not allowed for an exrpression function body",
+ "Convert the body to a block.");
+
+ static const ParserErrorCode INVALID_UNICODE_ESCAPE = const ParserErrorCode(
+ 'INVALID_UNICODE_ESCAPE',
+ "An escape sequence starting with '\\u' must be followed by 4 hexidecimal digits or from 1 to 6 digits between '{' and '}'");
+
+ static const ParserErrorCode LIBRARY_DIRECTIVE_NOT_FIRST =
+ const ParserErrorCode('LIBRARY_DIRECTIVE_NOT_FIRST',
+ "The library directive must appear before all other directives");
+
+ static const ParserErrorCode LOCAL_FUNCTION_DECLARATION_MODIFIER =
+ const ParserErrorCode('LOCAL_FUNCTION_DECLARATION_MODIFIER',
+ "Local function declarations cannot specify any modifier");
+
+ static const ParserErrorCode MISSING_ASSIGNABLE_SELECTOR =
+ const ParserErrorCode('MISSING_ASSIGNABLE_SELECTOR',
+ "Missing selector such as \".<identifier>\" or \"[0]\"");
+
+ static const ParserErrorCode MISSING_ASSIGNMENT_IN_INITIALIZER =
+ const ParserErrorCode('MISSING_ASSIGNMENT_IN_INITIALIZER',
+ "Expected an assignment after the field name");
+
+ static const ParserErrorCode MISSING_CATCH_OR_FINALLY = const ParserErrorCode(
+ 'MISSING_CATCH_OR_FINALLY',
+ "A try statement must have either a catch or finally clause");
+
+ static const ParserErrorCode MISSING_CLASS_BODY = const ParserErrorCode(
+ 'MISSING_CLASS_BODY',
+ "A class definition must have a body, even if it is empty");
+
+ static const ParserErrorCode MISSING_CLOSING_PARENTHESIS =
+ const ParserErrorCode(
+ 'MISSING_CLOSING_PARENTHESIS', "The closing parenthesis is missing");
+
+ static const ParserErrorCode MISSING_CONST_FINAL_VAR_OR_TYPE =
+ const ParserErrorCode('MISSING_CONST_FINAL_VAR_OR_TYPE',
+ "Variables must be declared using the keywords 'const', 'final', 'var' or a type name");
+
+ static const ParserErrorCode MISSING_ENUM_BODY = const ParserErrorCode(
+ 'MISSING_ENUM_BODY',
+ "An enum definition must have a body with at least one constant name");
+
+ static const ParserErrorCode MISSING_EXPRESSION_IN_INITIALIZER =
+ const ParserErrorCode('MISSING_EXPRESSION_IN_INITIALIZER',
+ "Expected an expression after the assignment operator");
+
+ static const ParserErrorCode MISSING_EXPRESSION_IN_THROW =
+ const ParserErrorCode('MISSING_EXPRESSION_IN_THROW',
+ "Missing expression after 'throw'.", "Did you mean 'rethrow'?");
+
+ static const ParserErrorCode MISSING_FUNCTION_BODY = const ParserErrorCode(
+ 'MISSING_FUNCTION_BODY', "A function body must be provided");
+
+ static const ParserErrorCode MISSING_FUNCTION_PARAMETERS =
+ const ParserErrorCode('MISSING_FUNCTION_PARAMETERS',
+ "Functions must have an explicit list of parameters");
+
+ static const ParserErrorCode MISSING_METHOD_PARAMETERS =
+ const ParserErrorCode('MISSING_METHOD_PARAMETERS',
+ "Methods must have an explicit list of parameters");
+
+ static const ParserErrorCode MISSING_GET = const ParserErrorCode(
+ 'MISSING_GET',
+ "Getters must have the keyword 'get' before the getter name");
+
+ static const ParserErrorCode MISSING_IDENTIFIER =
+ const ParserErrorCode('MISSING_IDENTIFIER', "Expected an identifier");
+
+ static const ParserErrorCode MISSING_INITIALIZER =
+ const ParserErrorCode('MISSING_INITIALIZER', "Expected an initializer");
+
+ static const ParserErrorCode MISSING_KEYWORD_OPERATOR = const ParserErrorCode(
+ 'MISSING_KEYWORD_OPERATOR',
+ "Operator declarations must be preceeded by the keyword 'operator'");
+
+ static const ParserErrorCode MISSING_NAME_IN_LIBRARY_DIRECTIVE =
+ const ParserErrorCode('MISSING_NAME_IN_LIBRARY_DIRECTIVE',
+ "Library directives must include a library name");
+
+ static const ParserErrorCode MISSING_NAME_IN_PART_OF_DIRECTIVE =
+ const ParserErrorCode('MISSING_NAME_IN_PART_OF_DIRECTIVE',
+ "Library directives must include a library name");
+
+ static const ParserErrorCode MISSING_PREFIX_IN_DEFERRED_IMPORT =
+ const ParserErrorCode('MISSING_PREFIX_IN_DEFERRED_IMPORT',
+ "Deferred imports must have a prefix");
+
+ static const ParserErrorCode MISSING_STAR_AFTER_SYNC = const ParserErrorCode(
+ 'MISSING_STAR_AFTER_SYNC',
+ "The modifier 'sync' must be followed by a star ('*')",
+ "Remove the modifier or add a star.");
+
+ static const ParserErrorCode MISSING_STATEMENT =
+ const ParserErrorCode('MISSING_STATEMENT', "Expected a statement");
+
+ static const ParserErrorCode MISSING_TERMINATOR_FOR_PARAMETER_GROUP =
+ const ParserErrorCode('MISSING_TERMINATOR_FOR_PARAMETER_GROUP',
+ "There is no '{0}' to close the parameter group");
+
+ static const ParserErrorCode MISSING_TYPEDEF_PARAMETERS =
+ const ParserErrorCode('MISSING_TYPEDEF_PARAMETERS',
+ "Type aliases for functions must have an explicit list of parameters");
+
+ static const ParserErrorCode MISSING_VARIABLE_IN_FOR_EACH = const ParserErrorCode(
+ 'MISSING_VARIABLE_IN_FOR_EACH',
+ "A loop variable must be declared in a for-each loop before the 'in', but none were found");
+
+ static const ParserErrorCode MIXED_PARAMETER_GROUPS = const ParserErrorCode(
+ 'MIXED_PARAMETER_GROUPS',
+ "Cannot have both positional and named parameters in a single parameter list");
+
+ static const ParserErrorCode MULTIPLE_EXTENDS_CLAUSES = const ParserErrorCode(
+ 'MULTIPLE_EXTENDS_CLAUSES',
+ "Each class definition can have at most one extends clause");
+
+ static const ParserErrorCode MULTIPLE_IMPLEMENTS_CLAUSES =
+ const ParserErrorCode('MULTIPLE_IMPLEMENTS_CLAUSES',
+ "Each class definition can have at most one implements clause");
+
+ static const ParserErrorCode MULTIPLE_LIBRARY_DIRECTIVES =
+ const ParserErrorCode('MULTIPLE_LIBRARY_DIRECTIVES',
+ "Only one library directive may be declared in a file");
+
+ static const ParserErrorCode MULTIPLE_NAMED_PARAMETER_GROUPS =
+ const ParserErrorCode('MULTIPLE_NAMED_PARAMETER_GROUPS',
+ "Cannot have multiple groups of named parameters in a single parameter list");
+
+ static const ParserErrorCode MULTIPLE_PART_OF_DIRECTIVES =
+ const ParserErrorCode('MULTIPLE_PART_OF_DIRECTIVES',
+ "Only one part-of directive may be declared in a file");
+
+ static const ParserErrorCode MULTIPLE_POSITIONAL_PARAMETER_GROUPS =
+ const ParserErrorCode('MULTIPLE_POSITIONAL_PARAMETER_GROUPS',
+ "Cannot have multiple groups of positional parameters in a single parameter list");
+
+ static const ParserErrorCode MULTIPLE_VARIABLES_IN_FOR_EACH =
+ const ParserErrorCode('MULTIPLE_VARIABLES_IN_FOR_EACH',
+ "A single loop variable must be declared in a for-each loop before the 'in', but {0} were found");
+
+ static const ParserErrorCode MULTIPLE_WITH_CLAUSES = const ParserErrorCode(
+ 'MULTIPLE_WITH_CLAUSES',
+ "Each class definition can have at most one with clause");
+
+ static const ParserErrorCode NAMED_FUNCTION_EXPRESSION =
+ const ParserErrorCode(
+ 'NAMED_FUNCTION_EXPRESSION', "Function expressions cannot be named");
+
+ static const ParserErrorCode NAMED_PARAMETER_OUTSIDE_GROUP =
+ const ParserErrorCode('NAMED_PARAMETER_OUTSIDE_GROUP',
+ "Named parameters must be enclosed in curly braces ('{' and '}')");
+
+ static const ParserErrorCode NATIVE_CLAUSE_IN_NON_SDK_CODE =
+ const ParserErrorCode('NATIVE_CLAUSE_IN_NON_SDK_CODE',
+ "Native clause can only be used in the SDK and code that is loaded through native extensions");
+
+ static const ParserErrorCode NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE =
+ const ParserErrorCode('NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE',
+ "Native functions can only be declared in the SDK and code that is loaded through native extensions");
+
+ static const ParserErrorCode NON_CONSTRUCTOR_FACTORY = const ParserErrorCode(
+ 'NON_CONSTRUCTOR_FACTORY',
+ "Only constructors can be declared to be a 'factory'");
+
+ static const ParserErrorCode NON_IDENTIFIER_LIBRARY_NAME =
+ const ParserErrorCode('NON_IDENTIFIER_LIBRARY_NAME',
+ "The name of a library must be an identifier");
+
+ static const ParserErrorCode NON_PART_OF_DIRECTIVE_IN_PART =
+ const ParserErrorCode('NON_PART_OF_DIRECTIVE_IN_PART',
+ "The part-of directive must be the only directive in a part");
+
+ static const ParserErrorCode NON_STRING_LITERAL_AS_URI =
+ const ParserErrorCode(
+ 'NON_STRING_LITERAL_AS_URI',
+ "The URI must be a string literal",
+ "Enclose the URI in either single or double quotes.");
+
+ static const ParserErrorCode NON_USER_DEFINABLE_OPERATOR =
+ const ParserErrorCode('NON_USER_DEFINABLE_OPERATOR',
+ "The operator '{0}' is not user definable");
+
+ static const ParserErrorCode NORMAL_BEFORE_OPTIONAL_PARAMETERS =
+ const ParserErrorCode('NORMAL_BEFORE_OPTIONAL_PARAMETERS',
+ "Normal parameters must occur before optional parameters");
+
+ static const ParserErrorCode NULLABLE_TYPE_IN_EXTENDS = const ParserErrorCode(
+ 'NULLABLE_TYPE_IN_EXTENDS',
+ "A nullable type cannot be used in an extends clause",
+ "Remove the '?' from the type name");
+
+ static const ParserErrorCode NULLABLE_TYPE_IN_IMPLEMENTS =
+ const ParserErrorCode(
+ 'NULLABLE_TYPE_IN_IMPLEMENTS',
+ "A nullable type cannot be used in an implements clause",
+ "Remove the '?' from the type name");
+
+ static const ParserErrorCode NULLABLE_TYPE_IN_WITH = const ParserErrorCode(
+ 'NULLABLE_TYPE_IN_WITH',
+ "A nullable type cannot be used in a with clause",
+ "Remove the '?' from the type name");
+
+ static const ParserErrorCode NULLABLE_TYPE_PARAMETER = const ParserErrorCode(
+ 'NULLABLE_TYPE_PARAMETER',
+ "Type parameters cannot be nullable",
+ "Remove the '?' from the type name");
+
+ static const ParserErrorCode POSITIONAL_AFTER_NAMED_ARGUMENT =
+ const ParserErrorCode('POSITIONAL_AFTER_NAMED_ARGUMENT',
+ "Positional arguments must occur before named arguments");
+
+ static const ParserErrorCode POSITIONAL_PARAMETER_OUTSIDE_GROUP =
+ const ParserErrorCode('POSITIONAL_PARAMETER_OUTSIDE_GROUP',
+ "Positional parameters must be enclosed in square brackets ('[' and ']')");
+
+ static const ParserErrorCode REDIRECTING_CONSTRUCTOR_WITH_BODY =
+ const ParserErrorCode('REDIRECTING_CONSTRUCTOR_WITH_BODY',
+ "Redirecting constructors cannot have a body");
+
+ static const ParserErrorCode REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR =
+ const ParserErrorCode('REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR',
+ "Only factory constructor can specify '=' redirection.");
+
+ static const ParserErrorCode SETTER_IN_FUNCTION = const ParserErrorCode(
+ 'SETTER_IN_FUNCTION',
+ "Setters cannot be defined within methods or functions");
+
+ static const ParserErrorCode STATIC_AFTER_CONST = const ParserErrorCode(
+ 'STATIC_AFTER_CONST',
+ "The modifier 'static' should be before the modifier 'const'");
+
+ static const ParserErrorCode STATIC_AFTER_FINAL = const ParserErrorCode(
+ 'STATIC_AFTER_FINAL',
+ "The modifier 'static' should be before the modifier 'final'");
+
+ static const ParserErrorCode STATIC_AFTER_VAR = const ParserErrorCode(
+ 'STATIC_AFTER_VAR',
+ "The modifier 'static' should be before the modifier 'var'");
+
+ static const ParserErrorCode STATIC_CONSTRUCTOR = const ParserErrorCode(
+ 'STATIC_CONSTRUCTOR', "Constructors cannot be static");
+
+ static const ParserErrorCode STATIC_GETTER_WITHOUT_BODY =
+ const ParserErrorCode(
+ 'STATIC_GETTER_WITHOUT_BODY', "A 'static' getter must have a body");
+
+ static const ParserErrorCode STATIC_OPERATOR =
+ const ParserErrorCode('STATIC_OPERATOR', "Operators cannot be static");
+
+ static const ParserErrorCode STATIC_SETTER_WITHOUT_BODY =
+ const ParserErrorCode(
+ 'STATIC_SETTER_WITHOUT_BODY', "A 'static' setter must have a body");
+
+ static const ParserErrorCode STATIC_TOP_LEVEL_DECLARATION =
+ const ParserErrorCode('STATIC_TOP_LEVEL_DECLARATION',
+ "Top-level declarations cannot be declared to be 'static'");
+
+ static const ParserErrorCode SWITCH_HAS_CASE_AFTER_DEFAULT_CASE =
+ const ParserErrorCode('SWITCH_HAS_CASE_AFTER_DEFAULT_CASE',
+ "The 'default' case should be the last case in a switch statement");
+
+ static const ParserErrorCode SWITCH_HAS_MULTIPLE_DEFAULT_CASES =
+ const ParserErrorCode('SWITCH_HAS_MULTIPLE_DEFAULT_CASES',
+ "The 'default' case can only be declared once");
+
+ static const ParserErrorCode TOP_LEVEL_OPERATOR = const ParserErrorCode(
+ 'TOP_LEVEL_OPERATOR', "Operators must be declared within a class");
+
+ static const ParserErrorCode TYPEDEF_IN_CLASS = const ParserErrorCode(
+ 'TYPEDEF_IN_CLASS',
+ "Function type aliases cannot be declared inside classes");
+
+ static const ParserErrorCode UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP =
+ const ParserErrorCode('UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP',
+ "There is no '{0}' to open a parameter group");
+
+ static const ParserErrorCode UNEXPECTED_TOKEN =
+ const ParserErrorCode('UNEXPECTED_TOKEN', "Unexpected token '{0}'");
+
+ static const ParserErrorCode WITH_BEFORE_EXTENDS = const ParserErrorCode(
+ 'WITH_BEFORE_EXTENDS',
+ "The extends clause must be before the with clause");
+
+ static const ParserErrorCode WITH_WITHOUT_EXTENDS = const ParserErrorCode(
+ '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 '='");
+
+ static const ParserErrorCode WRONG_TERMINATOR_FOR_PARAMETER_GROUP =
+ const ParserErrorCode('WRONG_TERMINATOR_FOR_PARAMETER_GROUP',
+ "Expected '{0}' to close parameter group");
+
+ static const ParserErrorCode VAR_AND_TYPE = const ParserErrorCode(
+ 'VAR_AND_TYPE',
+ "Variables cannot be declared using both 'var' and a type name; remove the 'var'");
+
+ static const ParserErrorCode VAR_AS_TYPE_NAME = const ParserErrorCode(
+ 'VAR_AS_TYPE_NAME', "The keyword 'var' cannot be used as a type name");
+
+ static const ParserErrorCode VAR_CLASS = const ParserErrorCode(
+ 'VAR_CLASS', "Classes cannot be declared to be 'var'");
+
+ static const ParserErrorCode VAR_ENUM =
+ const ParserErrorCode('VAR_ENUM', "Enums cannot be declared to be 'var'");
+
+ static const ParserErrorCode VAR_RETURN_TYPE = const ParserErrorCode(
+ 'VAR_RETURN_TYPE', "The return type cannot be 'var'");
+
+ static const ParserErrorCode VAR_TYPEDEF = const ParserErrorCode(
+ 'VAR_TYPEDEF', "Type aliases cannot be declared to be 'var'");
+
+ static const ParserErrorCode VOID_PARAMETER = const ParserErrorCode(
+ 'VOID_PARAMETER', "Parameters cannot have a type of 'void'");
+
+ static const ParserErrorCode VOID_VARIABLE = const ParserErrorCode(
+ 'VOID_VARIABLE', "Variables cannot have a type of 'void'");
+
+ /**
+ * Initialize a newly created error code to have the given [name]. The message
+ * associated with the error will be created from the given [message]
+ * template. The correction associated with the error will be created from the
+ * given [correction] template.
+ */
+ const ParserErrorCode(String name, String message, [String correction])
+ : super(name, message, correction);
+
+ @override
+ ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
+
+ @override
+ ErrorType get type => ErrorType.SYNTACTIC_ERROR;
+}
+
+/**
+ * The error codes used for errors detected by the scanner.
+ */
+class ScannerErrorCode extends ErrorCode {
+ static const ScannerErrorCode ILLEGAL_CHARACTER =
+ const ScannerErrorCode('ILLEGAL_CHARACTER', "Illegal character {0}");
+
+ static const ScannerErrorCode MISSING_DIGIT =
+ const ScannerErrorCode('MISSING_DIGIT', "Decimal digit expected");
+
+ static const ScannerErrorCode MISSING_HEX_DIGIT =
+ const ScannerErrorCode('MISSING_HEX_DIGIT', "Hexidecimal digit expected");
+
+ static const ScannerErrorCode MISSING_QUOTE =
+ const ScannerErrorCode('MISSING_QUOTE', "Expected quote (' or \")");
+
+ static const ScannerErrorCode UNABLE_GET_CONTENT = const ScannerErrorCode(
+ 'UNABLE_GET_CONTENT', "Unable to get content: {0}");
+
+ static const ScannerErrorCode UNTERMINATED_MULTI_LINE_COMMENT =
+ const ScannerErrorCode(
+ 'UNTERMINATED_MULTI_LINE_COMMENT', "Unterminated multi-line comment");
+
+ static const ScannerErrorCode UNTERMINATED_STRING_LITERAL =
+ const ScannerErrorCode(
+ 'UNTERMINATED_STRING_LITERAL', "Unterminated string literal");
+
+ /**
+ * Initialize a newly created error code to have the given [name]. The message
+ * associated with the error will be created from the given [message]
+ * template. The correction associated with the error will be created from the
+ * given [correction] template.
+ */
+ const ScannerErrorCode(String name, String message, [String correction])
+ : super(name, message, correction);
+
+ @override
+ ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
+
+ @override
+ ErrorType get type => ErrorType.SYNTACTIC_ERROR;
+}
diff --git a/pkg/analyzer/lib/src/dart/scanner/scanner.dart b/pkg/analyzer/lib/src/dart/scanner/scanner.dart
index 4ea8f2c..3c74e78 100644
--- a/pkg/analyzer/lib/src/dart/scanner/scanner.dart
+++ b/pkg/analyzer/lib/src/dart/scanner/scanner.dart
@@ -8,11 +8,14 @@
import 'package:analyzer/error/error.dart';
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/dart/ast/token.dart';
+import 'package:analyzer/src/dart/error/syntactic_errors.dart';
import 'package:analyzer/src/dart/scanner/reader.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:charcode/ascii.dart';
+export 'package:analyzer/src/dart/error/syntactic_errors.dart';
+
/**
* A state in a state machine used to scan keywords.
*/
@@ -1350,46 +1353,3 @@
StringUtilities.startsWith3(value, 0, $slash, $asterisk, $asterisk);
}
}
-
-/**
- * The error codes used for errors detected by the scanner.
- */
-class ScannerErrorCode extends ErrorCode {
- static const ScannerErrorCode ILLEGAL_CHARACTER =
- const ScannerErrorCode('ILLEGAL_CHARACTER', "Illegal character {0}");
-
- static const ScannerErrorCode MISSING_DIGIT =
- const ScannerErrorCode('MISSING_DIGIT', "Decimal digit expected");
-
- static const ScannerErrorCode MISSING_HEX_DIGIT =
- const ScannerErrorCode('MISSING_HEX_DIGIT', "Hexidecimal digit expected");
-
- static const ScannerErrorCode MISSING_QUOTE =
- const ScannerErrorCode('MISSING_QUOTE', "Expected quote (' or \")");
-
- static const ScannerErrorCode UNABLE_GET_CONTENT = const ScannerErrorCode(
- 'UNABLE_GET_CONTENT', "Unable to get content: {0}");
-
- static const ScannerErrorCode UNTERMINATED_MULTI_LINE_COMMENT =
- const ScannerErrorCode(
- 'UNTERMINATED_MULTI_LINE_COMMENT', "Unterminated multi-line comment");
-
- static const ScannerErrorCode UNTERMINATED_STRING_LITERAL =
- const ScannerErrorCode(
- 'UNTERMINATED_STRING_LITERAL', "Unterminated string literal");
-
- /**
- * Initialize a newly created error code to have the given [name]. The message
- * associated with the error will be created from the given [message]
- * template. The correction associated with the error will be created from the
- * given [correction] template.
- */
- const ScannerErrorCode(String name, String message, [String correction])
- : super(name, message, correction);
-
- @override
- ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
-
- @override
- ErrorType get type => ErrorType.SYNTACTIC_ERROR;
-}
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index d87b593..06d6ae3 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -2204,6 +2204,19 @@
*/
class HintCode extends ErrorCode {
/**
+ * When an abstract supertype member is references with `super` as its target,
+ * it cannot be overridden, so it is always a runtime error.
+ *
+ * Parameters:
+ * 0: the display name for the kind of the referenced element
+ * 1: the name of the referenced element
+ */
+ static const HintCode ABSTRACT_SUPER_MEMBER_REFERENCE = const HintCode(
+ 'ABSTRACT_SUPER_MEMBER_REFERENCE',
+ "The {0} '{1}' is always abstract in the supertype.",
+ null);
+
+ /**
* This hint is generated anywhere where the
* [StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE] would have been generated,
* if we used propagated information for the warnings.
@@ -4668,6 +4681,9 @@
static const StrongModeCode DOWN_CAST_IMPLICIT = const StrongModeCode(
ErrorType.HINT, 'DOWN_CAST_IMPLICIT', _implicitCastMessage);
+ static const StrongModeCode DOWN_CAST_IMPLICIT_ASSIGN = const StrongModeCode(
+ ErrorType.HINT, 'DOWN_CAST_IMPLICIT_ASSIGN', _implicitCastMessage);
+
static const StrongModeCode DYNAMIC_CAST = const StrongModeCode(
ErrorType.HINT, 'DYNAMIC_CAST', _implicitCastMessage);
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index ba6c884..b61eb2b 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -7,6 +7,7 @@
import 'dart:collection';
import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/syntactic_entity.dart';
import 'package:analyzer/dart/ast/token.dart';
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
@@ -1618,6 +1619,7 @@
* invoked using the call operator '()'.
*/
bool _isExecutableType(DartType type) {
+ type = type?.resolveToBound(_resolver.typeProvider.objectType);
if (type.isDynamic || type is FunctionType) {
return true;
} else if (!_enableStrictCallChecks &&
@@ -1989,7 +1991,7 @@
element2.lookUpGetter(name3, _definingLibrary);
if (getter != null) {
nameNode3.staticElement = getter;
- annotation.element = element2;
+ annotation.element = getter;
_resolveAnnotationElementGetter(annotation, getter);
return;
}
@@ -2612,7 +2614,7 @@
Element get bestElement => null;
@override
- Iterable get childEntities {
+ Iterable<SyntacticEntity> get childEntities {
// Should never be called, since a SyntheticIdentifier never appears in the
// AST--it is just used for lookup.
assert(false);
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index d4064c4..01b2ced 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -19,7 +19,6 @@
import 'package:analyzer/src/context/cache.dart';
import 'package:analyzer/src/context/context.dart';
import 'package:analyzer/src/generated/constant.dart';
-import 'package:analyzer/src/generated/java_core.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source.dart';
@@ -950,19 +949,21 @@
/**
* The levels at which a source can be analyzed.
*/
-class AnalysisLevel extends Enum<AnalysisLevel> {
+class AnalysisLevel implements Comparable<AnalysisLevel> {
/**
* Indicates a source should be fully analyzed.
*/
static const AnalysisLevel ALL = const AnalysisLevel('ALL', 0);
/**
- * Indicates a source should be resolved and that errors, warnings and hints are needed.
+ * Indicates a source should be resolved and that errors, warnings and hints
+ * are needed.
*/
static const AnalysisLevel ERRORS = const AnalysisLevel('ERRORS', 1);
/**
- * Indicates a source should be resolved, but that errors, warnings and hints are not needed.
+ * Indicates a source should be resolved, but that errors, warnings and hints
+ * are not needed.
*/
static const AnalysisLevel RESOLVED = const AnalysisLevel('RESOLVED', 2);
@@ -973,7 +974,26 @@
static const List<AnalysisLevel> values = const [ALL, ERRORS, RESOLVED, NONE];
- const AnalysisLevel(String name, int ordinal) : super(name, ordinal);
+ /**
+ * The name of this analysis level.
+ */
+ final String name;
+
+ /**
+ * The ordinal value of the analysis level.
+ */
+ final int ordinal;
+
+ const AnalysisLevel(this.name, this.ordinal);
+
+ @override
+ int get hashCode => ordinal;
+
+ @override
+ int compareTo(AnalysisLevel other) => ordinal - other.ordinal;
+
+ @override
+ String toString() => name;
}
/**
@@ -1065,6 +1085,7 @@
/**
* Return `true` to if analysis is to enable async support.
*/
+ @deprecated
bool get enableAsync;
/**
@@ -1198,12 +1219,11 @@
static const int DEFAULT_CACHE_SIZE = 64;
static const int ENABLE_ASSERT_FLAG = 0x01;
- static const int ENABLE_ASYNC_FLAG = 0x02;
- static const int ENABLE_GENERIC_METHODS_FLAG = 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;
+ 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;
/**
* The default list of non-nullable type names.
@@ -1230,9 +1250,6 @@
bool enableAssertMessage = false;
@override
- bool enableAsync = true;
-
- @override
bool enableGenericMethods = false;
@override
@@ -1333,7 +1350,6 @@
dart2jsHint = options.dart2jsHint;
enableAssertInitializer = options.enableAssertInitializer;
enableAssertMessage = options.enableAssertMessage;
- enableAsync = options.enableAsync;
enableStrictCallChecks = options.enableStrictCallChecks;
enableGenericMethods = options.enableGenericMethods;
enableInitializingFormalAccess = options.enableInitializingFormalAccess;
@@ -1388,6 +1404,13 @@
_analyzeFunctionBodiesPredicate = value;
}
+ @deprecated
+ @override
+ bool get enableAsync => true;
+
+ @deprecated
+ void set enableAsync(bool enable) {}
+
/**
* A flag indicating whether interface libraries are to be supported (DEP 40).
*/
@@ -1399,7 +1422,6 @@
@override
int encodeCrossContextOptions() =>
(enableAssertMessage ? ENABLE_ASSERT_FLAG : 0) |
- (enableAsync ? ENABLE_ASYNC_FLAG : 0) |
(enableGenericMethods ? ENABLE_GENERIC_METHODS_FLAG : 0) |
(enableStrictCallChecks ? ENABLE_STRICT_CALL_CHECKS_FLAG : 0) |
(strongMode ? ENABLE_STRONG_MODE_FLAG : 0) |
@@ -1409,7 +1431,6 @@
@override
void setCrossContextOptionsFrom(AnalysisOptions options) {
enableAssertMessage = options.enableAssertMessage;
- enableAsync = options.enableAsync;
enableGenericMethods = options.enableGenericMethods;
enableStrictCallChecks = options.enableStrictCallChecks;
enableSuperMixins = options.enableSuperMixins;
@@ -1441,9 +1462,6 @@
if (encoding & ENABLE_ASSERT_FLAG > 0) {
add('assert');
}
- if (encoding & ENABLE_ASYNC_FLAG > 0) {
- add('async');
- }
if (encoding & ENABLE_GENERIC_METHODS_FLAG > 0) {
add('genericMethods');
}
@@ -1580,7 +1598,7 @@
/**
* The possible states of cached data.
*/
-class CacheState extends Enum<CacheState> {
+class CacheState implements Comparable<CacheState> {
/**
* The data is not in the cache and the last time an attempt was made to
* compute the data an exception occurred, making it pointless to attempt to
@@ -1641,7 +1659,26 @@
VALID
];
- const CacheState(String name, int ordinal) : super(name, ordinal);
+ /**
+ * The name of this cache state.
+ */
+ final String name;
+
+ /**
+ * The ordinal value of the cache state.
+ */
+ final int ordinal;
+
+ const CacheState(this.name, this.ordinal);
+
+ @override
+ int get hashCode => ordinal;
+
+ @override
+ int compareTo(CacheState other) => ordinal - other.ordinal;
+
+ @override
+ String toString() => name;
}
/**
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 47a4979..13964ba 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -2656,7 +2656,7 @@
overriddenMember = _enclosingClass.lookUpInheritedConcreteMethod(
memberName, _currentLibrary);
}
- if (overriddenMember == null && !_hasNoSuchMethod(_enclosingClass)) {
+ if (overriddenMember == null && !_enclosingClass.hasNoSuchMethod) {
_errorReporter.reportErrorForNode(
StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER,
nameNode,
@@ -4971,7 +4971,7 @@
SimpleIdentifier classNameNode) {
if (_enclosingClass.isAbstract) {
return;
- } else if (_hasNoSuchMethod(_enclosingClass)) {
+ } else if (_enclosingClass.hasNoSuchMethod) {
return;
}
//
@@ -6098,7 +6098,7 @@
}
// If there is a noSuchMethod method, then don't report the warning,
// see dartbug.com/16078
- if (_hasNoSuchMethod(classElement)) {
+ if (_enclosingClass.hasNoSuchMethod) {
return;
}
ExecutableElement callMethod = _inheritanceManager.lookupMember(
@@ -6361,16 +6361,24 @@
}
ExecutableElement _getOverriddenMember(Element member) {
- if (member == null || _inheritanceManager == null) {
+ if (member == null) {
return null;
}
-
ClassElement classElement =
member.getAncestor((element) => element is ClassElement);
if (classElement == null) {
return null;
}
- return _inheritanceManager.lookupInheritance(classElement, member.name);
+ String name = member.name;
+ ClassElement superclass = classElement.supertype?.element;
+ while (superclass != null) {
+ ExecutableElement member = superclass.getMethod(name) ?? superclass.getGetter(name) ?? superclass.getSetter(name);
+ if (member != null) {
+ return member;
+ }
+ superclass = superclass.supertype?.element;
+ }
+ return null;
}
/**
@@ -6387,22 +6395,6 @@
}
/**
- * Return `true` if the given [classElement] has a noSuchMethod() method
- * distinct from the one declared in class Object, as per the Dart Language
- * Specification (section 10.4).
- */
- bool _hasNoSuchMethod(ClassElement classElement) {
- MethodElement method = classElement.lookUpMethod(
- FunctionElement.NO_SUCH_METHOD_METHOD_NAME, classElement.library);
- if (method == null) {
- return false;
- }
- ClassElement definingClass =
- method.getAncestor((Element element) => element is ClassElement);
- return definingClass != null && !definingClass.type.isObject;
- }
-
- /**
* Return `true` if the given [constructor] redirects to itself, directly or
* indirectly.
*/
diff --git a/pkg/analyzer/lib/src/generated/java_core.dart b/pkg/analyzer/lib/src/generated/java_core.dart
index ed0d03f..edaccce 100644
--- a/pkg/analyzer/lib/src/generated/java_core.dart
+++ b/pkg/analyzer/lib/src/generated/java_core.dart
@@ -125,6 +125,7 @@
}
}
+@deprecated
abstract class Enum<E extends Enum> implements Comparable<E> {
/// The name of this enum constant, as declared in the enum declaration.
final String name;
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index 182b2a0..fb111ff 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -13,6 +13,7 @@
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/ast/token.dart';
+import 'package:analyzer/src/dart/error/syntactic_errors.dart';
import 'package:analyzer/src/dart/scanner/reader.dart';
import 'package:analyzer/src/dart/scanner/scanner.dart';
import 'package:analyzer/src/error/codes.dart';
@@ -23,6 +24,7 @@
import 'package:analyzer/src/generated/utilities_dart.dart';
export 'package:analyzer/src/dart/ast/utilities.dart' show ResolutionCopier;
+export 'package:analyzer/src/dart/error/syntactic_errors.dart';
/**
* A simple data-holder for a method that needs to return multiple values.
@@ -70,36 +72,6 @@
}
/**
- * Wrapper around [Function] which should be called with "target" and
- * "arguments".
- */
-class MethodTrampoline {
- int parameterCount;
- Function trampoline;
- MethodTrampoline(this.parameterCount, this.trampoline);
- Object invoke(target, List arguments) {
- if (arguments.length != parameterCount) {
- throw new ArgumentError("${arguments.length} != $parameterCount");
- }
- switch (parameterCount) {
- case 0:
- return trampoline(target);
- case 1:
- return trampoline(target, arguments[0]);
- case 2:
- return trampoline(target, arguments[0], arguments[1]);
- case 3:
- return trampoline(target, arguments[0], arguments[1], arguments[2]);
- case 4:
- return trampoline(
- target, arguments[0], arguments[1], arguments[2], arguments[3]);
- default:
- throw new ArgumentError("Not implemented for > 4 arguments");
- }
- }
-}
-
-/**
* A simple data-holder for a method that needs to return multiple values.
*/
class Modifiers {
@@ -226,11 +198,6 @@
bool _enableNnbd = false;
/**
- * A flag indicating whether the parser is to parse the async support.
- */
- bool _parseAsync = true;
-
- /**
* A flag indicating whether parser is to parse function bodies.
*/
bool _parseFunctionBodies = true;
@@ -342,10 +309,11 @@
/**
* Set whether the parser is to parse the async support.
+ *
+ * Support for removing the 'async' library has been removed.
*/
- void set parseAsync(bool parseAsync) {
- this._parseAsync = parseAsync;
- }
+ @deprecated
+ void set parseAsync(bool parseAsync) {}
@deprecated
bool get parseConditionalDirectives => true;
@@ -2754,6 +2722,7 @@
ExtendsClause parseExtendsClause() {
Token keyword = getAndAdvance();
TypeName superclass = parseTypeName(false);
+ _mustNotBeNullable(superclass, ParserErrorCode.NULLABLE_TYPE_IN_EXTENDS);
return new ExtendsClause(keyword, superclass);
}
@@ -3067,9 +3036,6 @@
if (lexeme == ASYNC) {
foundAsync = true;
keyword = getAndAdvance();
- if (!_parseAsync) {
- _reportErrorForToken(ParserErrorCode.ASYNC_NOT_SUPPORTED, keyword);
- }
if (_matches(TokenType.STAR)) {
star = getAndAdvance();
_inGenerator = true;
@@ -3079,9 +3045,6 @@
} else if (lexeme == SYNC) {
foundSync = true;
keyword = getAndAdvance();
- if (!_parseAsync) {
- _reportErrorForToken(ParserErrorCode.ASYNC_NOT_SUPPORTED, keyword);
- }
if (_matches(TokenType.STAR)) {
star = getAndAdvance();
_inGenerator = true;
@@ -3371,10 +3334,11 @@
ImplementsClause parseImplementsClause() {
Token keyword = getAndAdvance();
List<TypeName> interfaces = <TypeName>[];
- interfaces.add(parseTypeName(false));
- while (_optional(TokenType.COMMA)) {
- interfaces.add(parseTypeName(false));
- }
+ do {
+ TypeName typeName = parseTypeName(false);
+ _mustNotBeNullable(typeName, ParserErrorCode.NULLABLE_TYPE_IN_IMPLEMENTS);
+ interfaces.add(typeName);
+ } while (_optional(TokenType.COMMA));
return new ImplementsClause(keyword, interfaces);
}
@@ -4937,6 +4901,10 @@
TypeParameter parseTypeParameter() {
CommentAndMetadata commentAndMetadata = parseCommentAndMetadata();
SimpleIdentifier name = parseSimpleIdentifier(isDeclaration: true);
+ if (_matches(TokenType.QUESTION)) {
+ _reportErrorForCurrentToken(ParserErrorCode.NULLABLE_TYPE_PARAMETER);
+ _advance();
+ }
if (_matchesKeyword(Keyword.EXTENDS)) {
Token keyword = getAndAdvance();
TypeName bound = parseTypeName(false);
@@ -5170,10 +5138,12 @@
*/
WithClause parseWithClause() {
Token withKeyword = getAndAdvance();
- List<TypeName> types = <TypeName>[parseTypeName(false)];
- while (_optional(TokenType.COMMA)) {
- types.add(parseTypeName(false));
- }
+ List<TypeName> types = <TypeName>[];
+ do {
+ TypeName typeName = parseTypeName(false);
+ _mustNotBeNullable(typeName, ParserErrorCode.NULLABLE_TYPE_IN_WITH);
+ types.add(typeName);
+ } while (_optional(TokenType.COMMA));
return new WithClause(withKeyword, types);
}
@@ -5372,25 +5342,24 @@
}
/**
- * Append the character equivalent of the given [scalarValue] to the given
+ * Append the character equivalent of the given [codePoint] to the given
* [builder]. Use the [startIndex] and [endIndex] to report an error, and
- * don't append anything to the builder, if the scalar value is invalid. The
+ * don't append anything to the builder, if the code point is invalid. The
* [escapeSequence] is the escape sequence that was parsed to produce the
- * scalar value (used for error reporting).
+ * code point (used for error reporting).
*/
- void _appendScalarValue(StringBuffer buffer, String escapeSequence,
- int scalarValue, int startIndex, int endIndex) {
- if (scalarValue < 0 ||
- scalarValue > Character.MAX_CODE_POINT ||
- (scalarValue >= 0xD800 && scalarValue <= 0xDFFF)) {
+ void _appendCodePoint(StringBuffer buffer, String source, int codePoint,
+ int startIndex, int endIndex) {
+ if (codePoint < 0 || codePoint > Character.MAX_CODE_POINT) {
+ String escapeSequence = source.substring(startIndex, endIndex + 1);
_reportErrorForCurrentToken(
ParserErrorCode.INVALID_CODE_POINT, [escapeSequence]);
return;
}
- if (scalarValue < Character.MAX_VALUE) {
- buffer.writeCharCode(scalarValue);
+ if (codePoint < Character.MAX_VALUE) {
+ buffer.writeCharCode(codePoint);
} else {
- buffer.write(Character.toChars(scalarValue));
+ buffer.write(Character.toChars(codePoint));
}
}
@@ -5964,6 +5933,16 @@
_currentToken.lexeme == identifier;
/**
+ * Report an error with the given [errorCode] if the given [typeName] has been
+ * marked as nullable.
+ */
+ void _mustNotBeNullable(TypeName typeName, ParserErrorCode errorCode) {
+ if (typeName.question != null) {
+ _reportErrorForToken(errorCode, typeName.question);
+ }
+ }
+
+ /**
* If the current token has the given [type], then advance to the next token
* and return `true`. Otherwise, return `false` without advancing. This method
* should not be invoked with an argument value of [TokenType.GT].
@@ -7315,7 +7294,6 @@
parser._inInitializer = _inInitializer;
parser._inLoop = _inLoop;
parser._inSwitch = _inSwitch;
- parser._parseAsync = _parseAsync;
parser._parseFunctionBodies = _parseFunctionBodies;
try {
parseOperation(parser);
@@ -7740,8 +7718,7 @@
// Illegal escape sequence: not enough or too many hex digits
_reportErrorForCurrentToken(ParserErrorCode.INVALID_UNICODE_ESCAPE);
}
- _appendScalarValue(buffer, lexeme.substring(index, currentIndex + 1),
- value, index, currentIndex);
+ _appendCodePoint(buffer, lexeme, value, index, currentIndex);
return currentIndex + 1;
} else {
if (currentIndex + 3 >= length) {
@@ -7760,9 +7737,9 @@
// Illegal escape sequence: invalid hex digits
_reportErrorForCurrentToken(ParserErrorCode.INVALID_UNICODE_ESCAPE);
} else {
- _appendScalarValue(
+ _appendCodePoint(
buffer,
- lexeme.substring(index, currentIndex + 1),
+ lexeme,
(((((Character.digit(firstDigit, 16) << 4) +
Character.digit(secondDigit, 16)) <<
4) +
@@ -8129,640 +8106,3 @@
@override
Token copy() => new Parser_SyntheticKeywordToken(keyword, offset);
}
-
-/**
- * The error codes used for errors detected by the parser. The convention for
- * this class is for the name of the error code to indicate the problem that
- * caused the error to be generated and for the error message to explain what
- * is wrong and, when appropriate, how the problem can be corrected.
- */
-class ParserErrorCode extends ErrorCode {
- static const ParserErrorCode ABSTRACT_CLASS_MEMBER = const ParserErrorCode(
- 'ABSTRACT_CLASS_MEMBER',
- "Members of classes cannot be declared to be 'abstract'");
-
- static const ParserErrorCode ABSTRACT_ENUM = const ParserErrorCode(
- 'ABSTRACT_ENUM', "Enums cannot be declared to be 'abstract'");
-
- static const ParserErrorCode ABSTRACT_STATIC_METHOD = const ParserErrorCode(
- 'ABSTRACT_STATIC_METHOD',
- "Static methods cannot be declared to be 'abstract'");
-
- static const ParserErrorCode ABSTRACT_TOP_LEVEL_FUNCTION =
- const ParserErrorCode('ABSTRACT_TOP_LEVEL_FUNCTION',
- "Top-level functions cannot be declared to be 'abstract'");
-
- static const ParserErrorCode ABSTRACT_TOP_LEVEL_VARIABLE =
- const ParserErrorCode('ABSTRACT_TOP_LEVEL_VARIABLE',
- "Top-level variables cannot be declared to be 'abstract'");
-
- static const ParserErrorCode ABSTRACT_TYPEDEF = const ParserErrorCode(
- 'ABSTRACT_TYPEDEF', "Type aliases cannot be declared to be 'abstract'");
-
- static const ParserErrorCode ANNOTATION_ON_ENUM_CONSTANT =
- const ParserErrorCode('ANNOTATION_ON_ENUM_CONSTANT',
- "Enum constants cannot have annotations");
-
- /**
- * 16.32 Identifier Reference: It is a compile-time error if any of the
- * identifiers async, await, or yield is used as an identifier in a function
- * body marked with either async, async*, or sync*.
- */
- static const ParserErrorCode ASYNC_KEYWORD_USED_AS_IDENTIFIER =
- const ParserErrorCode('ASYNC_KEYWORD_USED_AS_IDENTIFIER',
- "The keywords 'async', 'await', and 'yield' may not be used as identifiers in an asynchronous or generator function.");
-
- /**
- * Some environments, such as Fletch, do not support async.
- */
- static const ParserErrorCode ASYNC_NOT_SUPPORTED = const ParserErrorCode(
- 'ASYNC_NOT_SUPPORTED',
- "Async and sync are not supported in this environment.");
-
- static const ParserErrorCode BREAK_OUTSIDE_OF_LOOP = const ParserErrorCode(
- 'BREAK_OUTSIDE_OF_LOOP',
- "A break statement cannot be used outside of a loop or switch statement");
-
- static const ParserErrorCode CLASS_IN_CLASS = const ParserErrorCode(
- 'CLASS_IN_CLASS',
- "Classes can't be declared inside other classes.",
- "Try moving the class to the top-level.");
-
- static const ParserErrorCode COLON_IN_PLACE_OF_IN = const ParserErrorCode(
- 'COLON_IN_PLACE_OF_IN', "For-in loops use 'in' rather than a colon");
-
- static const ParserErrorCode CONST_AND_FINAL = const ParserErrorCode(
- 'CONST_AND_FINAL',
- "Members can't be declared to be both 'const' and 'final'.",
- "Try removing either the 'const' or 'final' keyword.");
-
- static const ParserErrorCode CONST_AND_VAR = const ParserErrorCode(
- 'CONST_AND_VAR',
- "Members can't be declared to be both 'const' and 'var'.",
- "Try removing either the 'const' or 'var' keyword.");
-
- static const ParserErrorCode CONST_CLASS = const ParserErrorCode(
- 'CONST_CLASS',
- "Classes can't be declared to be 'const'.",
- "Try removing the 'const' keyword or moving to the class' constructor(s).");
-
- static const ParserErrorCode CONST_CONSTRUCTOR_WITH_BODY =
- const ParserErrorCode(
- 'CONST_CONSTRUCTOR_WITH_BODY',
- "Const constructor can't have a body.",
- "Try removing the 'const' keyword or the body.");
-
- static const ParserErrorCode CONST_ENUM = const ParserErrorCode(
- 'CONST_ENUM',
- "Enums can't be declared to be 'const'.",
- "Try removing the 'const' keyword.");
-
- static const ParserErrorCode CONST_FACTORY = const ParserErrorCode(
- 'CONST_FACTORY',
- "Only redirecting factory constructors can be declared to be 'const'.",
- "Try removing the 'const' keyword or replacing the body with '=' followed by a valid target.");
-
- static const ParserErrorCode CONST_METHOD = const ParserErrorCode(
- 'CONST_METHOD',
- "Getters, setters and methods can't be declared to be 'const'.",
- "Try removing the 'const' keyword.");
-
- static const ParserErrorCode CONST_TYPEDEF = const ParserErrorCode(
- 'CONST_TYPEDEF',
- "Type aliases can't be declared to be 'const'.",
- "Try removing the 'const' keyword.");
-
- static const ParserErrorCode CONSTRUCTOR_WITH_RETURN_TYPE =
- const ParserErrorCode(
- 'CONSTRUCTOR_WITH_RETURN_TYPE',
- "Constructors can't have a return type.",
- "Try removing the return type.");
-
- static const ParserErrorCode CONTINUE_OUTSIDE_OF_LOOP = const ParserErrorCode(
- 'CONTINUE_OUTSIDE_OF_LOOP',
- "A continue statement cannot be used outside of a loop or switch statement");
-
- static const ParserErrorCode CONTINUE_WITHOUT_LABEL_IN_CASE =
- const ParserErrorCode('CONTINUE_WITHOUT_LABEL_IN_CASE',
- "A continue statement in a switch statement must have a label as a target");
-
- static const ParserErrorCode DEPRECATED_CLASS_TYPE_ALIAS =
- const ParserErrorCode('DEPRECATED_CLASS_TYPE_ALIAS',
- "The 'typedef' mixin application was replaced with 'class'");
-
- static const ParserErrorCode DIRECTIVE_AFTER_DECLARATION =
- const ParserErrorCode('DIRECTIVE_AFTER_DECLARATION',
- "Directives must appear before any declarations");
-
- static const ParserErrorCode DUPLICATE_LABEL_IN_SWITCH_STATEMENT =
- const ParserErrorCode('DUPLICATE_LABEL_IN_SWITCH_STATEMENT',
- "The label {0} was already used in this switch statement");
-
- static const ParserErrorCode DUPLICATED_MODIFIER = const ParserErrorCode(
- 'DUPLICATED_MODIFIER', "The modifier '{0}' was already specified.");
-
- static const ParserErrorCode EMPTY_ENUM_BODY = const ParserErrorCode(
- 'EMPTY_ENUM_BODY', "An enum must declare at least one constant name");
-
- static const ParserErrorCode ENUM_IN_CLASS = const ParserErrorCode(
- 'ENUM_IN_CLASS', "Enums cannot be declared inside classes");
-
- static const ParserErrorCode EQUALITY_CANNOT_BE_EQUALITY_OPERAND =
- const ParserErrorCode('EQUALITY_CANNOT_BE_EQUALITY_OPERAND',
- "Equality expression cannot be operand of another equality expression.");
-
- static const ParserErrorCode EXPECTED_CASE_OR_DEFAULT = const ParserErrorCode(
- 'EXPECTED_CASE_OR_DEFAULT', "Expected 'case' or 'default'");
-
- static const ParserErrorCode EXPECTED_CLASS_MEMBER =
- const ParserErrorCode('EXPECTED_CLASS_MEMBER', "Expected a class member");
-
- static const ParserErrorCode EXPECTED_EXECUTABLE = const ParserErrorCode(
- 'EXPECTED_EXECUTABLE',
- "Expected a method, getter, setter or operator declaration");
-
- static const ParserErrorCode EXPECTED_LIST_OR_MAP_LITERAL =
- const ParserErrorCode(
- 'EXPECTED_LIST_OR_MAP_LITERAL', "Expected a list or map literal");
-
- static const ParserErrorCode EXPECTED_STRING_LITERAL = const ParserErrorCode(
- 'EXPECTED_STRING_LITERAL', "Expected a string literal");
-
- static const ParserErrorCode EXPECTED_TOKEN =
- const ParserErrorCode('EXPECTED_TOKEN', "Expected to find '{0}'");
-
- static const ParserErrorCode EXPECTED_TYPE_NAME =
- const ParserErrorCode('EXPECTED_TYPE_NAME', "Expected a type name");
-
- static const ParserErrorCode EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE =
- const ParserErrorCode('EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE',
- "Export directives must preceed part directives");
-
- static const ParserErrorCode EXTERNAL_AFTER_CONST = const ParserErrorCode(
- 'EXTERNAL_AFTER_CONST',
- "The modifier 'external' should be before the modifier 'const'");
-
- static const ParserErrorCode EXTERNAL_AFTER_FACTORY = const ParserErrorCode(
- 'EXTERNAL_AFTER_FACTORY',
- "The modifier 'external' should be before the modifier 'factory'");
-
- static const ParserErrorCode EXTERNAL_AFTER_STATIC = const ParserErrorCode(
- 'EXTERNAL_AFTER_STATIC',
- "The modifier 'external' should be before the modifier 'static'");
-
- static const ParserErrorCode EXTERNAL_CLASS = const ParserErrorCode(
- 'EXTERNAL_CLASS', "Classes cannot be declared to be 'external'");
-
- static const ParserErrorCode EXTERNAL_CONSTRUCTOR_WITH_BODY =
- const ParserErrorCode('EXTERNAL_CONSTRUCTOR_WITH_BODY',
- "External constructors cannot have a body");
-
- static const ParserErrorCode EXTERNAL_ENUM = const ParserErrorCode(
- 'EXTERNAL_ENUM', "Enums cannot be declared to be 'external'");
-
- static const ParserErrorCode EXTERNAL_FIELD = const ParserErrorCode(
- 'EXTERNAL_FIELD', "Fields cannot be declared to be 'external'");
-
- static const ParserErrorCode EXTERNAL_GETTER_WITH_BODY =
- const ParserErrorCode(
- 'EXTERNAL_GETTER_WITH_BODY', "External getters cannot have a body");
-
- static const ParserErrorCode EXTERNAL_METHOD_WITH_BODY =
- const ParserErrorCode(
- 'EXTERNAL_METHOD_WITH_BODY', "External methods cannot have a body");
-
- static const ParserErrorCode EXTERNAL_OPERATOR_WITH_BODY =
- const ParserErrorCode('EXTERNAL_OPERATOR_WITH_BODY',
- "External operators cannot have a body");
-
- static const ParserErrorCode EXTERNAL_SETTER_WITH_BODY =
- const ParserErrorCode(
- 'EXTERNAL_SETTER_WITH_BODY', "External setters cannot have a body");
-
- static const ParserErrorCode EXTERNAL_TYPEDEF = const ParserErrorCode(
- 'EXTERNAL_TYPEDEF', "Type aliases cannot be declared to be 'external'");
-
- static const ParserErrorCode FACTORY_TOP_LEVEL_DECLARATION =
- const ParserErrorCode('FACTORY_TOP_LEVEL_DECLARATION',
- "Top-level declarations cannot be declared to be 'factory'");
-
- static const ParserErrorCode FACTORY_WITH_INITIALIZERS =
- const ParserErrorCode(
- 'FACTORY_WITH_INITIALIZERS',
- "A 'factory' constructor cannot have initializers",
- "Either remove the 'factory' keyword to make this a generative "
- "constructor or remove the initializers.");
-
- static const ParserErrorCode FACTORY_WITHOUT_BODY = const ParserErrorCode(
- 'FACTORY_WITHOUT_BODY',
- "A non-redirecting 'factory' constructor must have a body");
-
- static const ParserErrorCode FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR =
- const ParserErrorCode('FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR',
- "Field initializers can only be used in a constructor");
-
- static const ParserErrorCode FINAL_AND_VAR = const ParserErrorCode(
- 'FINAL_AND_VAR',
- "Members cannot be declared to be both 'final' and 'var'");
-
- static const ParserErrorCode FINAL_CLASS = const ParserErrorCode(
- 'FINAL_CLASS', "Classes cannot be declared to be 'final'");
-
- static const ParserErrorCode FINAL_CONSTRUCTOR = const ParserErrorCode(
- 'FINAL_CONSTRUCTOR', "A constructor cannot be declared to be 'final'");
-
- static const ParserErrorCode FINAL_ENUM = const ParserErrorCode(
- 'FINAL_ENUM', "Enums cannot be declared to be 'final'");
-
- static const ParserErrorCode FINAL_METHOD = const ParserErrorCode(
- 'FINAL_METHOD',
- "Getters, setters and methods cannot be declared to be 'final'");
-
- static const ParserErrorCode FINAL_TYPEDEF = const ParserErrorCode(
- 'FINAL_TYPEDEF', "Type aliases cannot be declared to be 'final'");
-
- static const ParserErrorCode FUNCTION_TYPED_PARAMETER_VAR = const ParserErrorCode(
- 'FUNCTION_TYPED_PARAMETER_VAR',
- "Function typed parameters cannot specify 'const', 'final' or 'var' instead of return type");
-
- static const ParserErrorCode GETTER_IN_FUNCTION = const ParserErrorCode(
- 'GETTER_IN_FUNCTION',
- "Getters cannot be defined within methods or functions");
-
- static const ParserErrorCode GETTER_WITH_PARAMETERS = const ParserErrorCode(
- 'GETTER_WITH_PARAMETERS',
- "Getter should be declared without a parameter list");
-
- static const ParserErrorCode ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE =
- const ParserErrorCode('ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE',
- "Illegal assignment to non-assignable expression");
-
- static const ParserErrorCode IMPLEMENTS_BEFORE_EXTENDS =
- const ParserErrorCode('IMPLEMENTS_BEFORE_EXTENDS',
- "The extends clause must be before the implements clause");
-
- static const ParserErrorCode IMPLEMENTS_BEFORE_WITH = const ParserErrorCode(
- 'IMPLEMENTS_BEFORE_WITH',
- "The with clause must be before the implements clause");
-
- static const ParserErrorCode IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE =
- const ParserErrorCode('IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE',
- "Import directives must preceed part directives");
-
- static const ParserErrorCode INITIALIZED_VARIABLE_IN_FOR_EACH =
- const ParserErrorCode('INITIALIZED_VARIABLE_IN_FOR_EACH',
- "The loop variable in a for-each loop cannot be initialized");
-
- static const ParserErrorCode INVALID_AWAIT_IN_FOR = const ParserErrorCode(
- 'INVALID_AWAIT_IN_FOR',
- "The modifier 'await' is not allowed for a normal 'for' statement",
- "Remove the keyword or use a for-each statement.");
-
- static const ParserErrorCode INVALID_CODE_POINT = const ParserErrorCode(
- 'INVALID_CODE_POINT',
- "The escape sequence '{0}' is not a valid code point");
-
- static const ParserErrorCode INVALID_COMMENT_REFERENCE = const ParserErrorCode(
- 'INVALID_COMMENT_REFERENCE',
- "Comment references should contain a possibly prefixed identifier and can start with 'new', but should not contain anything else");
-
- static const ParserErrorCode INVALID_HEX_ESCAPE = const ParserErrorCode(
- 'INVALID_HEX_ESCAPE',
- "An escape sequence starting with '\\x' must be followed by 2 hexidecimal digits");
-
- static const ParserErrorCode INVALID_LITERAL_IN_CONFIGURATION =
- const ParserErrorCode('INVALID_LITERAL_IN_CONFIGURATION',
- "The literal in a configuration cannot contain interpolation");
-
- static const ParserErrorCode INVALID_OPERATOR = const ParserErrorCode(
- 'INVALID_OPERATOR', "The string '{0}' is not a valid operator");
-
- static const ParserErrorCode INVALID_OPERATOR_FOR_SUPER =
- const ParserErrorCode('INVALID_OPERATOR_FOR_SUPER',
- "The operator '{0}' cannot be used with 'super'");
-
- static const ParserErrorCode INVALID_STAR_AFTER_ASYNC = const ParserErrorCode(
- 'INVALID_STAR_AFTER_ASYNC',
- "The modifier 'async*' is not allowed for an expression function body",
- "Convert the body to a block.");
-
- static const ParserErrorCode INVALID_SYNC = const ParserErrorCode(
- 'INVALID_SYNC',
- "The modifier 'sync' is not allowed for an exrpression function body",
- "Convert the body to a block.");
-
- static const ParserErrorCode INVALID_UNICODE_ESCAPE = const ParserErrorCode(
- 'INVALID_UNICODE_ESCAPE',
- "An escape sequence starting with '\\u' must be followed by 4 hexidecimal digits or from 1 to 6 digits between '{' and '}'");
-
- static const ParserErrorCode LIBRARY_DIRECTIVE_NOT_FIRST =
- const ParserErrorCode('LIBRARY_DIRECTIVE_NOT_FIRST',
- "The library directive must appear before all other directives");
-
- static const ParserErrorCode LOCAL_FUNCTION_DECLARATION_MODIFIER =
- const ParserErrorCode('LOCAL_FUNCTION_DECLARATION_MODIFIER',
- "Local function declarations cannot specify any modifier");
-
- static const ParserErrorCode MISSING_ASSIGNABLE_SELECTOR =
- const ParserErrorCode('MISSING_ASSIGNABLE_SELECTOR',
- "Missing selector such as \".<identifier>\" or \"[0]\"");
-
- static const ParserErrorCode MISSING_ASSIGNMENT_IN_INITIALIZER =
- const ParserErrorCode('MISSING_ASSIGNMENT_IN_INITIALIZER',
- "Expected an assignment after the field name");
-
- static const ParserErrorCode MISSING_CATCH_OR_FINALLY = const ParserErrorCode(
- 'MISSING_CATCH_OR_FINALLY',
- "A try statement must have either a catch or finally clause");
-
- static const ParserErrorCode MISSING_CLASS_BODY = const ParserErrorCode(
- 'MISSING_CLASS_BODY',
- "A class definition must have a body, even if it is empty");
-
- static const ParserErrorCode MISSING_CLOSING_PARENTHESIS =
- const ParserErrorCode(
- 'MISSING_CLOSING_PARENTHESIS', "The closing parenthesis is missing");
-
- static const ParserErrorCode MISSING_CONST_FINAL_VAR_OR_TYPE =
- const ParserErrorCode('MISSING_CONST_FINAL_VAR_OR_TYPE',
- "Variables must be declared using the keywords 'const', 'final', 'var' or a type name");
-
- static const ParserErrorCode MISSING_ENUM_BODY = const ParserErrorCode(
- 'MISSING_ENUM_BODY',
- "An enum definition must have a body with at least one constant name");
-
- static const ParserErrorCode MISSING_EXPRESSION_IN_INITIALIZER =
- const ParserErrorCode('MISSING_EXPRESSION_IN_INITIALIZER',
- "Expected an expression after the assignment operator");
-
- static const ParserErrorCode MISSING_EXPRESSION_IN_THROW =
- const ParserErrorCode('MISSING_EXPRESSION_IN_THROW',
- "Missing expression after 'throw'.", "Did you mean 'rethrow'?");
-
- static const ParserErrorCode MISSING_FUNCTION_BODY = const ParserErrorCode(
- 'MISSING_FUNCTION_BODY', "A function body must be provided");
-
- static const ParserErrorCode MISSING_FUNCTION_PARAMETERS =
- const ParserErrorCode('MISSING_FUNCTION_PARAMETERS',
- "Functions must have an explicit list of parameters");
-
- static const ParserErrorCode MISSING_METHOD_PARAMETERS =
- const ParserErrorCode('MISSING_METHOD_PARAMETERS',
- "Methods must have an explicit list of parameters");
-
- static const ParserErrorCode MISSING_GET = const ParserErrorCode(
- 'MISSING_GET',
- "Getters must have the keyword 'get' before the getter name");
-
- static const ParserErrorCode MISSING_IDENTIFIER =
- const ParserErrorCode('MISSING_IDENTIFIER', "Expected an identifier");
-
- static const ParserErrorCode MISSING_INITIALIZER =
- const ParserErrorCode('MISSING_INITIALIZER', "Expected an initializer");
-
- static const ParserErrorCode MISSING_KEYWORD_OPERATOR = const ParserErrorCode(
- 'MISSING_KEYWORD_OPERATOR',
- "Operator declarations must be preceeded by the keyword 'operator'");
-
- static const ParserErrorCode MISSING_NAME_IN_LIBRARY_DIRECTIVE =
- const ParserErrorCode('MISSING_NAME_IN_LIBRARY_DIRECTIVE',
- "Library directives must include a library name");
-
- static const ParserErrorCode MISSING_NAME_IN_PART_OF_DIRECTIVE =
- const ParserErrorCode('MISSING_NAME_IN_PART_OF_DIRECTIVE',
- "Library directives must include a library name");
-
- static const ParserErrorCode MISSING_PREFIX_IN_DEFERRED_IMPORT =
- const ParserErrorCode('MISSING_PREFIX_IN_DEFERRED_IMPORT',
- "Deferred imports must have a prefix");
-
- static const ParserErrorCode MISSING_STAR_AFTER_SYNC = const ParserErrorCode(
- 'MISSING_STAR_AFTER_SYNC',
- "The modifier 'sync' must be followed by a star ('*')",
- "Remove the modifier or add a star.");
-
- static const ParserErrorCode MISSING_STATEMENT =
- const ParserErrorCode('MISSING_STATEMENT', "Expected a statement");
-
- static const ParserErrorCode MISSING_TERMINATOR_FOR_PARAMETER_GROUP =
- const ParserErrorCode('MISSING_TERMINATOR_FOR_PARAMETER_GROUP',
- "There is no '{0}' to close the parameter group");
-
- static const ParserErrorCode MISSING_TYPEDEF_PARAMETERS =
- const ParserErrorCode('MISSING_TYPEDEF_PARAMETERS',
- "Type aliases for functions must have an explicit list of parameters");
-
- static const ParserErrorCode MISSING_VARIABLE_IN_FOR_EACH = const ParserErrorCode(
- 'MISSING_VARIABLE_IN_FOR_EACH',
- "A loop variable must be declared in a for-each loop before the 'in', but none were found");
-
- static const ParserErrorCode MIXED_PARAMETER_GROUPS = const ParserErrorCode(
- 'MIXED_PARAMETER_GROUPS',
- "Cannot have both positional and named parameters in a single parameter list");
-
- static const ParserErrorCode MULTIPLE_EXTENDS_CLAUSES = const ParserErrorCode(
- 'MULTIPLE_EXTENDS_CLAUSES',
- "Each class definition can have at most one extends clause");
-
- static const ParserErrorCode MULTIPLE_IMPLEMENTS_CLAUSES =
- const ParserErrorCode('MULTIPLE_IMPLEMENTS_CLAUSES',
- "Each class definition can have at most one implements clause");
-
- static const ParserErrorCode MULTIPLE_LIBRARY_DIRECTIVES =
- const ParserErrorCode('MULTIPLE_LIBRARY_DIRECTIVES',
- "Only one library directive may be declared in a file");
-
- static const ParserErrorCode MULTIPLE_NAMED_PARAMETER_GROUPS =
- const ParserErrorCode('MULTIPLE_NAMED_PARAMETER_GROUPS',
- "Cannot have multiple groups of named parameters in a single parameter list");
-
- static const ParserErrorCode MULTIPLE_PART_OF_DIRECTIVES =
- const ParserErrorCode('MULTIPLE_PART_OF_DIRECTIVES',
- "Only one part-of directive may be declared in a file");
-
- static const ParserErrorCode MULTIPLE_POSITIONAL_PARAMETER_GROUPS =
- const ParserErrorCode('MULTIPLE_POSITIONAL_PARAMETER_GROUPS',
- "Cannot have multiple groups of positional parameters in a single parameter list");
-
- static const ParserErrorCode MULTIPLE_VARIABLES_IN_FOR_EACH =
- const ParserErrorCode('MULTIPLE_VARIABLES_IN_FOR_EACH',
- "A single loop variable must be declared in a for-each loop before the 'in', but {0} were found");
-
- static const ParserErrorCode MULTIPLE_WITH_CLAUSES = const ParserErrorCode(
- 'MULTIPLE_WITH_CLAUSES',
- "Each class definition can have at most one with clause");
-
- static const ParserErrorCode NAMED_FUNCTION_EXPRESSION =
- const ParserErrorCode(
- 'NAMED_FUNCTION_EXPRESSION', "Function expressions cannot be named");
-
- static const ParserErrorCode NAMED_PARAMETER_OUTSIDE_GROUP =
- const ParserErrorCode('NAMED_PARAMETER_OUTSIDE_GROUP',
- "Named parameters must be enclosed in curly braces ('{' and '}')");
-
- static const ParserErrorCode NATIVE_CLAUSE_IN_NON_SDK_CODE =
- const ParserErrorCode('NATIVE_CLAUSE_IN_NON_SDK_CODE',
- "Native clause can only be used in the SDK and code that is loaded through native extensions");
-
- static const ParserErrorCode NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE =
- const ParserErrorCode('NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE',
- "Native functions can only be declared in the SDK and code that is loaded through native extensions");
-
- static const ParserErrorCode NON_CONSTRUCTOR_FACTORY = const ParserErrorCode(
- 'NON_CONSTRUCTOR_FACTORY',
- "Only constructors can be declared to be a 'factory'");
-
- static const ParserErrorCode NON_IDENTIFIER_LIBRARY_NAME =
- const ParserErrorCode('NON_IDENTIFIER_LIBRARY_NAME',
- "The name of a library must be an identifier");
-
- static const ParserErrorCode NON_PART_OF_DIRECTIVE_IN_PART =
- const ParserErrorCode('NON_PART_OF_DIRECTIVE_IN_PART',
- "The part-of directive must be the only directive in a part");
-
- static const ParserErrorCode NON_STRING_LITERAL_AS_URI =
- const ParserErrorCode(
- 'NON_STRING_LITERAL_AS_URI',
- "The URI must be a string literal",
- "Enclose the URI in either single or double quotes.");
-
- static const ParserErrorCode NON_USER_DEFINABLE_OPERATOR =
- const ParserErrorCode('NON_USER_DEFINABLE_OPERATOR',
- "The operator '{0}' is not user definable");
-
- static const ParserErrorCode NORMAL_BEFORE_OPTIONAL_PARAMETERS =
- const ParserErrorCode('NORMAL_BEFORE_OPTIONAL_PARAMETERS',
- "Normal parameters must occur before optional parameters");
-
- static const ParserErrorCode POSITIONAL_AFTER_NAMED_ARGUMENT =
- const ParserErrorCode('POSITIONAL_AFTER_NAMED_ARGUMENT',
- "Positional arguments must occur before named arguments");
-
- static const ParserErrorCode POSITIONAL_PARAMETER_OUTSIDE_GROUP =
- const ParserErrorCode('POSITIONAL_PARAMETER_OUTSIDE_GROUP',
- "Positional parameters must be enclosed in square brackets ('[' and ']')");
-
- static const ParserErrorCode REDIRECTING_CONSTRUCTOR_WITH_BODY =
- const ParserErrorCode('REDIRECTING_CONSTRUCTOR_WITH_BODY',
- "Redirecting constructors cannot have a body");
-
- static const ParserErrorCode REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR =
- const ParserErrorCode('REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR',
- "Only factory constructor can specify '=' redirection.");
-
- static const ParserErrorCode SETTER_IN_FUNCTION = const ParserErrorCode(
- 'SETTER_IN_FUNCTION',
- "Setters cannot be defined within methods or functions");
-
- static const ParserErrorCode STATIC_AFTER_CONST = const ParserErrorCode(
- 'STATIC_AFTER_CONST',
- "The modifier 'static' should be before the modifier 'const'");
-
- static const ParserErrorCode STATIC_AFTER_FINAL = const ParserErrorCode(
- 'STATIC_AFTER_FINAL',
- "The modifier 'static' should be before the modifier 'final'");
-
- static const ParserErrorCode STATIC_AFTER_VAR = const ParserErrorCode(
- 'STATIC_AFTER_VAR',
- "The modifier 'static' should be before the modifier 'var'");
-
- static const ParserErrorCode STATIC_CONSTRUCTOR = const ParserErrorCode(
- 'STATIC_CONSTRUCTOR', "Constructors cannot be static");
-
- static const ParserErrorCode STATIC_GETTER_WITHOUT_BODY =
- const ParserErrorCode(
- 'STATIC_GETTER_WITHOUT_BODY', "A 'static' getter must have a body");
-
- static const ParserErrorCode STATIC_OPERATOR =
- const ParserErrorCode('STATIC_OPERATOR', "Operators cannot be static");
-
- static const ParserErrorCode STATIC_SETTER_WITHOUT_BODY =
- const ParserErrorCode(
- 'STATIC_SETTER_WITHOUT_BODY', "A 'static' setter must have a body");
-
- static const ParserErrorCode STATIC_TOP_LEVEL_DECLARATION =
- const ParserErrorCode('STATIC_TOP_LEVEL_DECLARATION',
- "Top-level declarations cannot be declared to be 'static'");
-
- static const ParserErrorCode SWITCH_HAS_CASE_AFTER_DEFAULT_CASE =
- const ParserErrorCode('SWITCH_HAS_CASE_AFTER_DEFAULT_CASE',
- "The 'default' case should be the last case in a switch statement");
-
- static const ParserErrorCode SWITCH_HAS_MULTIPLE_DEFAULT_CASES =
- const ParserErrorCode('SWITCH_HAS_MULTIPLE_DEFAULT_CASES',
- "The 'default' case can only be declared once");
-
- static const ParserErrorCode TOP_LEVEL_OPERATOR = const ParserErrorCode(
- 'TOP_LEVEL_OPERATOR', "Operators must be declared within a class");
-
- static const ParserErrorCode TYPEDEF_IN_CLASS = const ParserErrorCode(
- 'TYPEDEF_IN_CLASS',
- "Function type aliases cannot be declared inside classes");
-
- static const ParserErrorCode UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP =
- const ParserErrorCode('UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP',
- "There is no '{0}' to open a parameter group");
-
- static const ParserErrorCode UNEXPECTED_TOKEN =
- const ParserErrorCode('UNEXPECTED_TOKEN', "Unexpected token '{0}'");
-
- static const ParserErrorCode WITH_BEFORE_EXTENDS = const ParserErrorCode(
- 'WITH_BEFORE_EXTENDS',
- "The extends clause must be before the with clause");
-
- static const ParserErrorCode WITH_WITHOUT_EXTENDS = const ParserErrorCode(
- '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 '='");
-
- static const ParserErrorCode WRONG_TERMINATOR_FOR_PARAMETER_GROUP =
- const ParserErrorCode('WRONG_TERMINATOR_FOR_PARAMETER_GROUP',
- "Expected '{0}' to close parameter group");
-
- static const ParserErrorCode VAR_AND_TYPE = const ParserErrorCode(
- 'VAR_AND_TYPE',
- "Variables cannot be declared using both 'var' and a type name; remove the 'var'");
-
- static const ParserErrorCode VAR_AS_TYPE_NAME = const ParserErrorCode(
- 'VAR_AS_TYPE_NAME', "The keyword 'var' cannot be used as a type name");
-
- static const ParserErrorCode VAR_CLASS = const ParserErrorCode(
- 'VAR_CLASS', "Classes cannot be declared to be 'var'");
-
- static const ParserErrorCode VAR_ENUM =
- const ParserErrorCode('VAR_ENUM', "Enums cannot be declared to be 'var'");
-
- static const ParserErrorCode VAR_RETURN_TYPE = const ParserErrorCode(
- 'VAR_RETURN_TYPE', "The return type cannot be 'var'");
-
- static const ParserErrorCode VAR_TYPEDEF = const ParserErrorCode(
- 'VAR_TYPEDEF', "Type aliases cannot be declared to be 'var'");
-
- static const ParserErrorCode VOID_PARAMETER = const ParserErrorCode(
- 'VOID_PARAMETER', "Parameters cannot have a type of 'void'");
-
- static const ParserErrorCode VOID_VARIABLE = const ParserErrorCode(
- 'VOID_VARIABLE', "Variables cannot have a type of 'void'");
-
- /**
- * Initialize a newly created error code to have the given [name]. The message
- * associated with the error will be created from the given [message]
- * template. The correction associated with the error will be created from the
- * given [correction] template.
- */
- const ParserErrorCode(String name, String message, [String correction])
- : super(name, message, correction);
-
- @override
- ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
-
- @override
- ErrorType get type => ErrorType.SYNTACTIC_ERROR;
-}
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index a24bd1e..26b997d 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -27,7 +27,6 @@
import 'package:analyzer/src/generated/element_resolver.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/error_verifier.dart';
-import 'package:analyzer/src/generated/java_core.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/static_type_analyzer.dart';
import 'package:analyzer/src/generated/type_system.dart';
@@ -52,7 +51,7 @@
* The class containing the AST nodes being visited, or `null` if we are not in the scope of
* a class.
*/
- ClassElement _enclosingClass;
+ ClassElementImpl _enclosingClass;
/**
* A flag indicating whether a surrounding member (compilation unit or class)
@@ -87,12 +86,17 @@
LibraryElement _currentLibrary;
/**
+ * The inheritance manager used to find overridden methods.
+ */
+ InheritanceManager _manager;
+
+ /**
* Create a new instance of the [BestPracticesVerifier].
*
* @param errorReporter the error reporter
*/
- BestPracticesVerifier(
- this._errorReporter, TypeProvider typeProvider, this._currentLibrary,
+ BestPracticesVerifier(this._errorReporter, TypeProvider typeProvider,
+ this._currentLibrary, this._manager,
{TypeSystem typeSystem})
: _nullType = typeProvider.nullType,
_futureNullType = typeProvider.futureNullType,
@@ -159,9 +163,9 @@
@override
Object visitClassDeclaration(ClassDeclaration node) {
- ClassElement outerClass = _enclosingClass;
+ ClassElementImpl outerClass = _enclosingClass;
bool wasInDeprecatedMember = inDeprecatedMember;
- ClassElement element = node.element;
+ ClassElement element = AbstractClassElementImpl.getImpl(node.element);
if (element != null && element.isDeprecated) {
inDeprecatedMember = true;
}
@@ -283,8 +287,10 @@
@override
Object visitMethodInvocation(MethodInvocation node) {
+ Expression realTarget = node.realTarget;
+ _checkForAbstractSuperMemberReference(realTarget, node.methodName);
_checkForCanBeNullAfterNullAware(
- node.realTarget, node.operator, null, node.methodName);
+ realTarget, node.operator, null, node.methodName);
DartType staticInvokeType = node.staticInvokeType;
if (staticInvokeType is InterfaceType) {
MethodElement methodElement = staticInvokeType.lookUpMethod(
@@ -308,8 +314,10 @@
@override
Object visitPropertyAccess(PropertyAccess node) {
+ Expression realTarget = node.realTarget;
+ _checkForAbstractSuperMemberReference(realTarget, node.propertyName);
_checkForCanBeNullAfterNullAware(
- node.realTarget, node.operator, node.propertyName, null);
+ realTarget, node.operator, node.propertyName, null);
return super.visitPropertyAccess(node);
}
@@ -409,6 +417,34 @@
return false;
}
+ void _checkForAbstractSuperMemberReference(
+ Expression target, SimpleIdentifier name) {
+ if (target is SuperExpression) {
+ Element element = name.staticElement;
+ if (element is ExecutableElement && element.isAbstract) {
+ if (!_enclosingClass.hasNoSuchMethod) {
+ ExecutableElement concrete = null;
+ if (element.kind == ElementKind.METHOD) {
+ concrete = _enclosingClass.lookUpInheritedConcreteMethod(
+ element.displayName, _currentLibrary);
+ } else if (element.kind == ElementKind.GETTER) {
+ concrete = _enclosingClass.lookUpInheritedConcreteGetter(
+ element.displayName, _currentLibrary);
+ } else if (element.kind == ElementKind.SETTER) {
+ concrete = _enclosingClass.lookUpInheritedConcreteSetter(
+ element.displayName, _currentLibrary);
+ }
+ if (concrete == null) {
+ _errorReporter.reportTypeErrorForNode(
+ HintCode.ABSTRACT_SUPER_MEMBER_REFERENCE,
+ name,
+ [element.kind.displayName, name.name]);
+ }
+ }
+ }
+ }
+ }
+
/**
* This verifies that the passed expression can be assigned to its corresponding parameters.
*
@@ -4291,7 +4327,7 @@
}
// Dart best practices
unit.accept(new BestPracticesVerifier(
- errorReporter, _context.typeProvider, _library,
+ errorReporter, _context.typeProvider, _library, _manager,
typeSystem: _context.typeSystem));
unit.accept(new OverrideVerifier(errorReporter, _manager));
// Find to-do comments
@@ -5007,11 +5043,11 @@
}
/**
- * This enum holds one of four states of a field initialization state through a constructor
- * signature, not initialized, initialized in the field declaration, initialized in the field
- * formal, and finally, initialized in the initializers list.
+ * The four states of a field initialization state through a constructor
+ * signature, not initialized, initialized in the field declaration, initialized
+ * in the field formal, and finally, initialized in the initializers list.
*/
-class INIT_STATE extends Enum<INIT_STATE> {
+class INIT_STATE implements Comparable<INIT_STATE> {
static const INIT_STATE NOT_INIT = const INIT_STATE('NOT_INIT', 0);
static const INIT_STATE INIT_IN_DECLARATION =
@@ -5030,7 +5066,26 @@
INIT_IN_INITIALIZERS
];
- const INIT_STATE(String name, int ordinal) : super(name, ordinal);
+ /**
+ * The name of this init state.
+ */
+ final String name;
+
+ /**
+ * The ordinal value of the init state.
+ */
+ final int ordinal;
+
+ const INIT_STATE(this.name, this.ordinal);
+
+ @override
+ int get hashCode => ordinal;
+
+ @override
+ int compareTo(INIT_STATE other) => ordinal - other.ordinal;
+
+ @override
+ String toString() => name;
}
/**
@@ -5527,7 +5582,8 @@
/**
* Kind of the redirecting constructor.
*/
-class RedirectingConstructorKind extends Enum<RedirectingConstructorKind> {
+class RedirectingConstructorKind
+ implements Comparable<RedirectingConstructorKind> {
static const RedirectingConstructorKind CONST =
const RedirectingConstructorKind('CONST', 0);
@@ -5536,8 +5592,26 @@
static const List<RedirectingConstructorKind> values = const [CONST, NORMAL];
- const RedirectingConstructorKind(String name, int ordinal)
- : super(name, ordinal);
+ /**
+ * The name of this redirecting constructor kind.
+ */
+ final String name;
+
+ /**
+ * The ordinal value of the redirecting constructor kind.
+ */
+ final int ordinal;
+
+ const RedirectingConstructorKind(this.name, this.ordinal);
+
+ @override
+ int get hashCode => ordinal;
+
+ @override
+ int compareTo(RedirectingConstructorKind other) => ordinal - other.ordinal;
+
+ @override
+ String toString() => name;
}
/**
@@ -7283,8 +7357,13 @@
originalType is FunctionType &&
originalType.typeFormals.isNotEmpty &&
ts is StrongTypeSystemImpl) {
- contextType = ts.inferGenericFunctionCall(typeProvider, originalType,
- DartType.EMPTY_LIST, DartType.EMPTY_LIST, originalType.returnType, returnContextType);
+ contextType = ts.inferGenericFunctionCall(
+ typeProvider,
+ originalType,
+ DartType.EMPTY_LIST,
+ DartType.EMPTY_LIST,
+ originalType.returnType,
+ returnContextType);
}
InferenceContext.setType(node.argumentList, contextType);
diff --git a/pkg/analyzer/lib/src/generated/source.dart b/pkg/analyzer/lib/src/generated/source.dart
index 2fc6c2d..7f95c01 100644
--- a/pkg/analyzer/lib/src/generated/source.dart
+++ b/pkg/analyzer/lib/src/generated/source.dart
@@ -11,7 +11,6 @@
import 'package:analyzer/source/package_map_resolver.dart';
import 'package:analyzer/src/context/source.dart';
import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/java_core.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/java_io.dart' show JavaFile;
import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
@@ -688,7 +687,7 @@
* The enumeration `SourceKind` defines the different kinds of sources that are
* known to the analysis engine.
*/
-class SourceKind extends Enum<SourceKind> {
+class SourceKind implements Comparable<SourceKind> {
/**
* A source containing HTML. The HTML might or might not contain Dart scripts.
*/
@@ -716,7 +715,26 @@
static const List<SourceKind> values = const [HTML, LIBRARY, PART, UNKNOWN];
- const SourceKind(String name, int ordinal) : super(name, ordinal);
+ /**
+ * The name of this source kind.
+ */
+ final String name;
+
+ /**
+ * The ordinal value of the source kind.
+ */
+ final int ordinal;
+
+ const SourceKind(this.name, this.ordinal);
+
+ @override
+ int get hashCode => ordinal;
+
+ @override
+ int compareTo(SourceKind other) => ordinal - other.ordinal;
+
+ @override
+ String toString() => name;
}
/**
@@ -848,7 +866,7 @@
* The enumeration `UriKind` defines the different kinds of URI's that are known to the
* analysis engine. These are used to keep track of the kind of URI associated with a given source.
*/
-class UriKind extends Enum<UriKind> {
+class UriKind implements Comparable<UriKind> {
/**
* A 'dart:' URI.
*/
@@ -867,23 +885,37 @@
static const List<UriKind> values = const [DART_URI, FILE_URI, PACKAGE_URI];
/**
+ * The name of this URI kind.
+ */
+ final String name;
+
+ /**
+ * The ordinal value of the URI kind.
+ */
+ final int ordinal;
+
+ /**
* The single character encoding used to identify this kind of URI.
*/
final int encoding;
/**
* Initialize a newly created URI kind to have the given encoding.
- *
- * @param encoding the single character encoding used to identify this kind of URI.
*/
- const UriKind(String name, int ordinal, this.encoding) : super(name, ordinal);
+ const UriKind(this.name, this.ordinal, this.encoding);
+
+ @override
+ int get hashCode => ordinal;
+
+ @override
+ int compareTo(UriKind other) => ordinal - other.ordinal;
+
+ @override
+ String toString() => name;
/**
- * Return the URI kind represented by the given encoding, or `null` if there is no kind with
- * the given encoding.
- *
- * @param encoding the single character encoding used to identify the URI kind to be returned
- * @return the URI kind represented by the given encoding
+ * Return the URI kind represented by the given [encoding], or `null` if there
+ * is no kind with the given encoding.
*/
static UriKind fromEncoding(int encoding) {
while (true) {
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index fafb7b9..4ebd9b3 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -1602,10 +1602,37 @@
return type;
}
- FunctionElementImpl function = new FunctionElementImpl("", -1);
+ // TODO(jmesserly): feels like we should be able to do this with less code.
+
+ // Create fresh type formals. This avoids capture if we're inferring the
+ // constructor to the class from inside it.
+
+ // We build up a substitution for the type parameters,
+ // {variablesFresh/variables} then apply it.
+ var typeVars = <DartType>[];
+ var freshTypeVars = <DartType>[];
+ var freshVarElements = <TypeParameterElement>[];
+ for (int i = 0; i < cls.typeParameters.length; i++) {
+ var typeParamElement = cls.typeParameters[i];
+ var freshElement =
+ new TypeParameterElementImpl.synthetic(typeParamElement.name);
+ var freshTypeVar = new TypeParameterTypeImpl(freshElement);
+ freshElement.type = freshTypeVar;
+
+ typeVars.add(typeParamElement.type);
+ freshTypeVars.add(freshTypeVar);
+ freshVarElements.add(freshElement);
+
+ var bound = typeParamElement.bound ?? DynamicTypeImpl.instance;
+ freshElement.bound = bound.substitute2(freshTypeVars, typeVars);
+ }
+
+ type = type.substitute2(freshTypeVars, typeVars);
+
+ var function = new FunctionElementImpl("", -1);
function.synthetic = true;
function.returnType = type.returnType;
- function.shareTypeParameters(cls.typeParameters);
+ function.typeParameters = freshVarElements;
function.shareParameters(type.parameters);
return function.type = new FunctionTypeImpl(function);
}
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 4899d9a..0488553 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -1640,12 +1640,8 @@
// We already know L <: T2, for some L.
// So update L to reflect the new constraint LUB(L, T1) <: T2
//
-
- // Heuristic: we intentionally ignore `dynamic` when doing inference.
- if (!t1.isDynamic) {
- bound.lower =
- _typeSystem.getLeastUpperBound(_typeProvider, bound.lower, t1);
- }
+ bound.lower =
+ _typeSystem.getLeastUpperBound(_typeProvider, bound.lower, t1);
// Optimistically assume we will be able to satisfy the constraint.
return true;
}
diff --git a/pkg/analyzer/lib/src/generated/utilities_collection.dart b/pkg/analyzer/lib/src/generated/utilities_collection.dart
index cd39548..b1c5e88 100644
--- a/pkg/analyzer/lib/src/generated/utilities_collection.dart
+++ b/pkg/analyzer/lib/src/generated/utilities_collection.dart
@@ -34,17 +34,12 @@
}
/**
- * The class `BooleanArray` defines methods for operating on integers as if they were arrays
- * of booleans. These arrays can be indexed by either integers or by enumeration constants.
+ * Methods for operating on integers as if they were arrays of booleans. These
+ * arrays can be indexed by either integers or by enumeration constants.
*/
class BooleanArray {
/**
- * Return the value of the element at the given index.
- *
- * @param array the array being accessed
- * @param index the index of the element being accessed
- * @return the value of the element at the given index
- * @throws IndexOutOfBoundsException if the index is not between zero (0) and 31, inclusive
+ * Return the value of the element of the given [array] at the given [index].
*/
static bool get(int array, int index) {
_checkIndex(index);
@@ -53,22 +48,13 @@
/**
* Return the value of the element at the given index.
- *
- * @param array the array being accessed
- * @param index the index of the element being accessed
- * @return the value of the element at the given index
- * @throws IndexOutOfBoundsException if the index is not between zero (0) and 31, inclusive
*/
+ @deprecated
static bool getEnum(int array, Enum index) => get(array, index.ordinal);
/**
- * Set the value of the element at the given index to the given value.
- *
- * @param array the array being modified
- * @param index the index of the element being set
- * @param value the value to be assigned to the element
- * @return the updated value of the array
- * @throws IndexOutOfBoundsException if the index is not between zero (0) and 31, inclusive
+ * Set the value of the element of the given [array] at the given [index] to
+ * the given [value].
*/
static int set(int array, int index, bool value) {
_checkIndex(index);
@@ -81,21 +67,14 @@
/**
* Set the value of the element at the given index to the given value.
- *
- * @param array the array being modified
- * @param index the index of the element being set
- * @param value the value to be assigned to the element
- * @return the updated value of the array
- * @throws IndexOutOfBoundsException if the index is not between zero (0) and 31, inclusive
*/
+ @deprecated
static int setEnum(int array, Enum index, bool value) =>
set(array, index.ordinal, value);
/**
- * Throw an exception if the index is not within the bounds allowed for an integer-encoded array
- * of boolean values.
- *
- * @throws IndexOutOfBoundsException if the index is not between zero (0) and 31, inclusive
+ * Throw an exception if the index is not within the bounds allowed for an
+ * integer-encoded array of boolean values.
*/
static void _checkIndex(int index) {
if (index < 0 || index > 30) {
diff --git a/pkg/analyzer/lib/src/generated/utilities_dart.dart b/pkg/analyzer/lib/src/generated/utilities_dart.dart
index 3c0ab8d..8dd40df 100644
--- a/pkg/analyzer/lib/src/generated/utilities_dart.dart
+++ b/pkg/analyzer/lib/src/generated/utilities_dart.dart
@@ -8,7 +8,6 @@
import 'package:analyzer/dart/ast/token.dart' show Token;
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/src/dart/element/element.dart' show ElementImpl;
-import 'package:analyzer/src/generated/java_core.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/util/fast_uri.dart';
@@ -83,11 +82,11 @@
}
/**
- * The enumeration `ParameterKind` defines the different kinds of parameters. There are two
- * basic kinds of parameters: required and optional. Optional parameters are further divided into
- * two kinds: positional optional and named optional.
+ * The kinds of a parameter. There are two basic kinds of parameters: required
+ * and optional. Optional parameters are further divided into two kinds:
+ * positional optional and named optional.
*/
-class ParameterKind extends Enum<ParameterKind> {
+class ParameterKind implements Comparable<ParameterKind> {
static const ParameterKind REQUIRED =
const ParameterKind('REQUIRED', 0, false);
@@ -99,15 +98,31 @@
static const List<ParameterKind> values = const [REQUIRED, POSITIONAL, NAMED];
/**
+ * The name of this parameter.
+ */
+ final String name;
+
+ /**
+ * The ordinal value of the parameter.
+ */
+ final int ordinal;
+
+ /**
* A flag indicating whether this is an optional parameter.
*/
final bool isOptional;
/**
* Initialize a newly created kind with the given state.
- *
- * @param isOptional `true` if this is an optional parameter
*/
- const ParameterKind(String name, int ordinal, this.isOptional)
- : super(name, ordinal);
+ const ParameterKind(this.name, this.ordinal, this.isOptional);
+
+ @override
+ int get hashCode => ordinal;
+
+ @override
+ int compareTo(ParameterKind other) => ordinal - other.ordinal;
+
+ @override
+ String toString() => name;
}
diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/analyzer/lib/src/summary/link.dart
index f085b614..c805aeb 100644
--- a/pkg/analyzer/lib/src/summary/link.dart
+++ b/pkg/analyzer/lib/src/summary/link.dart
@@ -189,10 +189,8 @@
result.paramReference =
typeParameterContext.typeParameterNestingLevel - element.nestingLevel;
} else {
- // Out-of-scope type parameters only occur in circumstances where they
- // are irrelevant (i.e. when a type parameter is unused). So we can
- // safely convert them to `dynamic`.
- result.reference = compilationUnit.addRawReference('dynamic');
+ throw new StateError('The type parameter $type (in ${element?.location}) '
+ 'is out of scope on ${typeParameterContext?.location}.');
}
return result;
} else if (type is FunctionType) {
@@ -363,6 +361,9 @@
List<PropertyAccessorElementForLink> get accessors;
@override
+ ClassElementForLink get asClass => this;
+
+ @override
ConstructorElementForLink get asConstructor => unnamedConstructor;
@override
@@ -985,6 +986,23 @@
noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
/**
+ * Return the class element for the constructor referred to by the given
+ * [index] in [UnlinkedUnit.references]. If the reference is unresolved,
+ * return [UndefinedElementForLink.instance].
+ */
+ ReferenceableElementForLink resolveConstructorClassRef(int index) {
+ LinkedReference linkedReference = _linkedUnit.references[index];
+ if (linkedReference.kind == ReferenceKind.classOrEnum) {
+ return resolveRef(index);
+ }
+ if (index < _unlinkedUnit.references.length) {
+ UnlinkedReference unlinkedReference = _unlinkedUnit.references[index];
+ return resolveRef(unlinkedReference.prefixReference);
+ }
+ return UndefinedElementForLink.instance;
+ }
+
+ /**
* Return the element referred to by the given [index] in
* [UnlinkedUnit.references]. If the reference is unresolved,
* return [UndefinedElementForLink.instance].
@@ -2379,11 +2397,10 @@
stack.length -= numNamed + numPositional;
strPtr += numNamed;
EntityRef ref = _getNextRef();
- ConstructorElementForLink element =
- unit.resolveRef(ref.reference).asConstructor;
+ ClassElementForLink_Class element =
+ unit.resolveConstructorClassRef(ref.reference).asClass;
if (element != null) {
- ClassElementForLink_Class enclosingClass = element.enclosingClass;
- stack.add(enclosingClass.buildType((int i) {
+ stack.add(element.buildType((int i) {
// Type argument explicitly specified.
if (i < ref.typeArguments.length) {
return unit.resolveTypeRef(
@@ -4359,6 +4376,11 @@
*/
abstract class ReferenceableElementForLink implements Element {
/**
+ * If this element is a class reference, return it. Otherwise return `null`.
+ */
+ ClassElementForLink get asClass => null;
+
+ /**
* If this element can be used in a constructor invocation context,
* return the associated constructor (which may be `this` or some
* other element). Otherwise return `null`.
diff --git a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
index caa98d2..c60f8ba 100644
--- a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
@@ -181,7 +181,8 @@
// Constant expressions are always resolved in summaries.
if (result == CONSTANT_EXPRESSION_RESOLVED &&
target is ConstantEvaluationTarget) {
- entry.setValue(result, true, TargetedResult.EMPTY_LIST);
+ entry.setValue(
+ result as ResultDescriptor<bool>, true, TargetedResult.EMPTY_LIST);
return true;
}
// Provide results for Source.
@@ -200,23 +201,28 @@
result == LIBRARY_ELEMENT) {
LibraryElement libraryElement =
resynthesizer.getLibraryElement(uriString);
- entry.setValue(result, libraryElement, TargetedResult.EMPTY_LIST);
+ entry.setValue(result as ResultDescriptor<LibraryElement>,
+ libraryElement, TargetedResult.EMPTY_LIST);
return true;
} else if (result == READY_LIBRARY_ELEMENT2 ||
result == READY_LIBRARY_ELEMENT6 ||
result == READY_LIBRARY_ELEMENT7) {
- entry.setValue(result, true, TargetedResult.EMPTY_LIST);
+ entry.setValue(
+ result as ResultDescriptor<bool>, true, TargetedResult.EMPTY_LIST);
return true;
} else if (result == MODIFICATION_TIME) {
- entry.setValue(result, 0, TargetedResult.EMPTY_LIST);
+ entry.setValue(
+ result as ResultDescriptor<int>, 0, TargetedResult.EMPTY_LIST);
return true;
} else if (result == SOURCE_KIND) {
if (_dataStore.linkedMap.containsKey(uriString)) {
- entry.setValue(result, SourceKind.LIBRARY, TargetedResult.EMPTY_LIST);
+ entry.setValue(result as ResultDescriptor<SourceKind>,
+ SourceKind.LIBRARY, TargetedResult.EMPTY_LIST);
return true;
}
if (_dataStore.unlinkedMap.containsKey(uriString)) {
- entry.setValue(result, SourceKind.PART, TargetedResult.EMPTY_LIST);
+ entry.setValue(result as ResultDescriptor<SourceKind>,
+ SourceKind.PART, TargetedResult.EMPTY_LIST);
return true;
}
return false;
@@ -228,7 +234,8 @@
.map((libraryUriString) =>
context.sourceFactory.resolveUri(target, libraryUriString))
.toList(growable: false);
- entry.setValue(result, librarySources, TargetedResult.EMPTY_LIST);
+ entry.setValue(result as ResultDescriptor<List<Source>>,
+ librarySources, TargetedResult.EMPTY_LIST);
return true;
}
return false;
@@ -237,7 +244,8 @@
List<int> lineStarts = unlinkedUnit.lineStarts;
if (lineStarts.isNotEmpty) {
LineInfo lineInfo = new LineInfo(lineStarts);
- entry.setValue(result, lineInfo, TargetedResult.EMPTY_LIST);
+ entry.setValue(result as ResultDescriptor<LineInfo>, lineInfo,
+ TargetedResult.EMPTY_LIST);
return true;
}
return false;
@@ -254,7 +262,8 @@
result == CREATED_RESOLVED_UNIT9 ||
result == CREATED_RESOLVED_UNIT10 ||
result == CREATED_RESOLVED_UNIT11) {
- entry.setValue(result, true, TargetedResult.EMPTY_LIST);
+ entry.setValue(
+ result as ResultDescriptor<bool>, true, TargetedResult.EMPTY_LIST);
return true;
}
if (result == COMPILATION_UNIT_ELEMENT) {
@@ -263,13 +272,15 @@
CompilationUnitElement unit = resynthesizer.getElement(
new ElementLocationImpl.con3(<String>[libraryUri, unitUri]));
if (unit != null) {
- entry.setValue(result, unit, TargetedResult.EMPTY_LIST);
+ entry.setValue(result as ResultDescriptor<CompilationUnitElement>,
+ unit, TargetedResult.EMPTY_LIST);
return true;
}
}
} else if (target is VariableElement) {
if (result == INFERRED_STATIC_VARIABLE) {
- entry.setValue(result, target, TargetedResult.EMPTY_LIST);
+ entry.setValue(result as ResultDescriptor<VariableElement>, target,
+ TargetedResult.EMPTY_LIST);
return true;
}
}
diff --git a/pkg/analyzer/lib/src/summary/pub_summary.dart b/pkg/analyzer/lib/src/summary/pub_summary.dart
index 5891183..93e6aec 100644
--- a/pkg/analyzer/lib/src/summary/pub_summary.dart
+++ b/pkg/analyzer/lib/src/summary/pub_summary.dart
@@ -33,6 +33,12 @@
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 {
@@ -84,6 +90,12 @@
static const UNLINKED_SPEC_NAME = 'unlinked_spec.ds';
/**
+ * 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;
@@ -126,7 +138,8 @@
Completer _onUnlinkedCompleteCompleter;
PubSummaryManager(this.resourceProvider, this.tempFileName,
- {@visibleForTesting this.majorVersion:
+ {@visibleForTesting this.allowLinking: true,
+ @visibleForTesting this.majorVersion:
PackageBundleAssembler.currentMajorVersion});
/**
@@ -169,6 +182,7 @@
List<LinkedPubPackage> getLinkedBundles(AnalysisContext context) {
// Stopwatch timer = new Stopwatch()..start();
+ _GetDeclaredVariable getDeclaredVariable = context.declaredVariables.get;
SourceFactory sourceFactory = context.sourceFactory;
_ListedPackages listedPackages = new _ListedPackages(sourceFactory);
@@ -195,8 +209,8 @@
List<_LinkedNode> nodes = <_LinkedNode>[];
Map<String, _LinkedNode> packageToNode = <String, _LinkedNode>{};
unlinkedBundles.forEach((package, unlinked) {
- _LinkedNode node = new _LinkedNode(
- sdkBundle, listedPackages, package, unlinked, packageToNode);
+ _LinkedNode node = new _LinkedNode(sdkBundle, getDeclaredVariable,
+ listedPackages, package, unlinked, packageToNode);
nodes.add(node);
packageToNode[package.name] = node;
});
@@ -211,28 +225,32 @@
_readLinked(node, strong);
}
- // 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 (_LinkedNode node in nodes) {
- store.addBundle(null, node.unlinked);
- if (node.linked != null) {
- store.addBundle(null, node.linked);
+ // 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 (_LinkedNode node in nodes) {
+ store.addBundle(null, node.unlinked);
+ if (node.linked != null) {
+ store.addBundle(null, node.linked);
+ }
}
- }
- // Link each package node.
- for (_LinkedNode node in nodes) {
- if (!node.isEvaluated) {
- new _LinkedWalker(listedPackages, store, strong).walk(node);
+ // Link each package node.
+ for (_LinkedNode node in nodes) {
+ if (!node.isEvaluated) {
+ new _LinkedWalker(getDeclaredVariable, listedPackages, store, strong)
+ .walk(node);
+ }
}
- }
- // Write newly linked bundles.
- for (_LinkedNode node in nodes) {
- _writeLinked(node, strong);
+ // Write newly linked bundles.
+ for (_LinkedNode node in nodes) {
+ _writeLinked(node, strong);
+ }
}
// Create successfully linked packages.
@@ -240,7 +258,7 @@
for (_LinkedNode node in nodes) {
if (node.linked != null) {
linkedPackages.add(new LinkedPubPackage(
- node.package, node.unlinked, node.linked, node._linkedHash));
+ node.package, node.unlinked, node.linked, node.linkedHash));
}
}
@@ -604,6 +622,7 @@
*/
class _LinkedNode extends Node<_LinkedNode> {
final PackageBundle sdkBundle;
+ final _GetDeclaredVariable getDeclaredVariable;
final _ListedPackages listedPackages;
final PubPackage package;
final PackageBundle unlinked;
@@ -616,30 +635,31 @@
List<int> linkedNewBytes;
PackageBundle linked;
- _LinkedNode(this.sdkBundle, this.listedPackages, this.package, this.unlinked,
- this.packageToNode);
+ _LinkedNode(this.sdkBundle, this.getDeclaredVariable, this.listedPackages,
+ this.package, this.unlinked, this.packageToNode);
@override
bool get isEvaluated => linked != null || failed;
/**
* Return the hash string that corresponds to this linked bundle in the
- * context of its [sdkBundles] and transitive dependencies. Return `null` if
+ * context of its [sdkBundle] 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) {
- // Collect all unlinked API signatures.
+ ApiSignature signature = new ApiSignature();
+ // Add all unlinked API signatures.
List<String> signatures = <String>[];
signatures.add(sdkBundle.apiSignature);
transitiveDependencies
.map((node) => node.unlinked.apiSignature)
.forEach(signatures.add);
signatures.sort();
- // Combine sorted unlinked API signatures into a single hash.
- ApiSignature signature = new ApiSignature();
signatures.forEach(signature.addString);
+ // Combine into a single hash.
+ _appendDeclaredVariables(signature);
_linkedHash = signature.toHex();
}
return _linkedHash;
@@ -709,17 +729,47 @@
@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 (_LinkedNode 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 _LinkedWalker extends DependencyWalker<_LinkedNode> {
+ final _GetDeclaredVariable getDeclaredVariable;
final _ListedPackages listedPackages;
final SummaryDataStore store;
final bool strong;
- _LinkedWalker(this.listedPackages, this.store, this.strong);
+ _LinkedWalker(
+ this.getDeclaredVariable, this.listedPackages, this.store, this.strong);
@override
void evaluate(_LinkedNode node) {
@@ -741,10 +791,7 @@
return store.linkedMap[uri];
}, (String uri) {
return store.unlinkedMap[uri];
- }, (String name) {
- // TODO(scheglov) decide how to use declared variables in Pub
- return null;
- }, strong);
+ }, getDeclaredVariable, strong);
// Assemble linked bundles and put them into the store.
for (_LinkedNode node in scc) {
PackageBundleAssembler assembler = new PackageBundleAssembler();
diff --git a/pkg/analyzer/lib/src/summary/summary_sdk.dart b/pkg/analyzer/lib/src/summary/summary_sdk.dart
index 8d13a55..5857d8b 100644
--- a/pkg/analyzer/lib/src/summary/summary_sdk.dart
+++ b/pkg/analyzer/lib/src/summary/summary_sdk.dart
@@ -39,7 +39,8 @@
@override
bool compute(CacheEntry entry, ResultDescriptor result) {
if (result == TYPE_PROVIDER) {
- entry.setValue(result, typeProvider, TargetedResult.EMPTY_LIST);
+ entry.setValue(result as ResultDescriptor<TypeProvider>, typeProvider,
+ TargetedResult.EMPTY_LIST);
return true;
}
return super.compute(entry, result);
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index 3401fbe..01f9495 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -15,7 +15,6 @@
import 'package:analyzer/error/listener.dart';
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/src/context/cache.dart';
-import 'package:analyzer/src/context/context.dart';
import 'package:analyzer/src/dart/ast/ast.dart'
show NamespaceDirectiveImpl, UriBasedDirectiveImpl;
import 'package:analyzer/src/dart/ast/utilities.dart';
@@ -1871,22 +1870,11 @@
void internalPerform() {
LibraryElement coreLibrary = getRequiredInput(CORE_INPUT);
LibraryElement asyncLibrary = getOptionalInput(ASYNC_INPUT);
- if (asyncLibrary == null) {
- Source asyncSource = context.sourceFactory.forUri(DartSdk.DART_ASYNC);
- asyncLibrary = (context as AnalysisContextImpl)
- .createMockAsyncLib(coreLibrary, asyncSource);
- }
Namespace coreNamespace = coreLibrary.publicNamespace;
Namespace asyncNamespace = asyncLibrary.publicNamespace;
//
// Record outputs.
//
- if (!context.analysisOptions.enableAsync) {
- AnalysisContextImpl contextImpl = context;
- Source asyncSource = context.sourceFactory.forUri(DartSdk.DART_ASYNC);
- asyncLibrary = contextImpl.createMockAsyncLib(coreLibrary, asyncSource);
- asyncNamespace = asyncLibrary.publicNamespace;
- }
TypeProvider typeProvider =
new TypeProviderImpl.forNamespaces(coreNamespace, asyncNamespace);
(context as InternalAnalysisContext).typeProvider = typeProvider;
@@ -3172,7 +3160,7 @@
TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT);
unit.accept(new BestPracticesVerifier(
- errorReporter, typeProvider, libraryElement,
+ errorReporter, typeProvider, libraryElement, inheritanceManager,
typeSystem: typeSystem));
unit.accept(new OverrideVerifier(errorReporter, inheritanceManager));
// Find to-do comments.
@@ -4017,7 +4005,6 @@
Parser parser = new Parser(_source, errorListener);
AnalysisOptions options = context.analysisOptions;
parser.enableAssertInitializer = options.enableAssertInitializer;
- parser.parseAsync = options.enableAsync;
parser.parseFunctionBodies =
options.analyzeFunctionBodiesPredicate(_source);
parser.parseGenericMethods = options.enableGenericMethods;
diff --git a/pkg/analyzer/lib/src/task/options.dart b/pkg/analyzer/lib/src/task/options.dart
index 5ed99dc..4047b3b 100644
--- a/pkg/analyzer/lib/src/task/options.dart
+++ b/pkg/analyzer/lib/src/task/options.dart
@@ -498,14 +498,6 @@
context.analysisOptions = options;
}
}
- if (feature == AnalyzerOptions.enableAsync) {
- if (isFalse(value)) {
- AnalysisOptionsImpl options =
- new AnalysisOptionsImpl.from(context.analysisOptions);
- options.enableAsync = false;
- context.analysisOptions = options;
- }
- }
if (feature == AnalyzerOptions.enableStrictCallChecks) {
if (isTrue(value)) {
AnalysisOptionsImpl options =
@@ -574,8 +566,6 @@
if (boolValue != null) {
if (feature == AnalyzerOptions.enableAssertInitializer) {
options.enableAssertInitializer = boolValue;
- } else if (feature == AnalyzerOptions.enableAsync) {
- options.enableAsync = boolValue;
} else if (feature == AnalyzerOptions.enableInitializingFormalAccess) {
options.enableInitializingFormalAccess = boolValue;
} else if (feature == AnalyzerOptions.enableSuperMixins) {
diff --git a/pkg/analyzer/lib/src/task/strong/ast_properties.dart b/pkg/analyzer/lib/src/task/strong/ast_properties.dart
index 52f27f1..0f93ada 100644
--- a/pkg/analyzer/lib/src/task/strong/ast_properties.dart
+++ b/pkg/analyzer/lib/src/task/strong/ast_properties.dart
@@ -10,6 +10,7 @@
import 'package:analyzer/analyzer.dart';
import 'package:analyzer/dart/element/type.dart';
+const String _implicitAssignmentCast = '_implicitAssignmentCast';
const String _implicitCast = '_implicitCast';
const String _hasImplicitCasts = '_hasImplicitCasts';
const String _isDynamicInvoke = '_isDynamicInvoke';
@@ -37,6 +38,17 @@
node.setProperty(_implicitCast, type);
}
+/// If this op-assign has an implicit cast on the assignment, returns the type
+/// it is coerced to, otherwise returns null.
+DartType getImplicitAssignmentCast(Expression node) {
+ return node.getProperty/*<DartType>*/(_implicitAssignmentCast);
+}
+
+/// Sets the result of [getImplicitAssignmentCast] for this node.
+void setImplicitAssignmentCast(Expression node, DartType type) {
+ node.setProperty(_implicitAssignmentCast, type);
+}
+
/// True if this node is a dynamic operation that requires dispatch and/or
/// checking at runtime.
bool isDynamicInvoke(Expression node) {
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index 1183ce3..b32ff6e 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -13,7 +13,6 @@
import 'package:analyzer/dart/ast/visitor.dart';
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/error/codes.dart' show StrongModeCode;
import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
@@ -187,9 +186,7 @@
// so no need to insert an error for this here.
continue;
}
- DartType expectedType = _elementType(element);
- if (expectedType == null) expectedType = DynamicTypeImpl.instance;
- checkArgument(arg, expectedType);
+ checkArgument(arg, _elementType(element));
}
}
@@ -197,7 +194,7 @@
if (expr is ParenthesizedExpression) {
checkAssignment(expr.expression, type);
} else {
- _checkDowncast(expr, type);
+ _checkImplicitCast(expr, type);
}
}
@@ -410,7 +407,7 @@
sequenceInterface.instantiate([DynamicTypeImpl.instance]);
if (rules.isSubtypeOf(sequenceType, iterableType)) {
- _recordImplicitCast(node.iterable, iterableType, sequenceType);
+ _recordImplicitCast(node.iterable, sequenceType, from: iterableType);
elementType = DynamicTypeImpl.instance;
}
}
@@ -420,7 +417,7 @@
if (elementType != null) {
// Insert a cast from the sequence's element type to the loop variable's
// if needed.
- _checkDowncast(loopVariable, _getDefiniteType(loopVariable),
+ _checkImplicitCast(loopVariable, _getDefiniteType(loopVariable),
from: elementType);
}
}
@@ -578,7 +575,7 @@
@override
void visitPostfixExpression(PostfixExpression node) {
- _checkUnary(node, node.staticElement);
+ _checkUnary(node.operand, node.operator, node.staticElement);
node.visitChildren(this);
}
@@ -592,7 +589,7 @@
if (node.operator.type == TokenType.BANG) {
checkBoolean(node.operand);
} else {
- _checkUnary(node, node.staticElement);
+ _checkUnary(node.operand, node.operator, node.staticElement);
}
node.visitChildren(this);
}
@@ -700,72 +697,75 @@
assert(functionType.namedParameterTypes.isEmpty);
assert(functionType.optionalParameterTypes.isEmpty);
- // Check the LHS type.
+ // Refine the return type.
var rhsType = _getDefiniteType(expr.rightHandSide);
var lhsType = _getDefiniteType(expr.leftHandSide);
var returnType = rules.refineBinaryExpressionType(
typeProvider, lhsType, op, rhsType, functionType.returnType);
- if (!rules.isSubtypeOf(returnType, lhsType)) {
- final numType = typeProvider.numType;
- // TODO(jmesserly): this seems to duplicate logic in StaticTypeAnalyzer.
- // Try to fix up the numerical case if possible.
- if (rules.isSubtypeOf(lhsType, numType) &&
- rules.isSubtypeOf(lhsType, rhsType)) {
- // This is also slightly different from spec, but allows us to keep
- // compound operators in the int += num and num += dynamic cases.
- _recordImplicitCast(expr.rightHandSide, rhsType, lhsType);
- } else {
- // TODO(jmesserly): this results in a duplicate error, because
- // ErrorVerifier also reports it.
- _recordMessage(expr, StrongModeCode.STATIC_TYPE_ERROR,
- [expr, returnType, lhsType]);
- }
- } else {
- // Check the RHS type.
- //
- // This is only needed if we didn't already need a cast, and avoids
- // emitting two messages for the same expression.
- _checkDowncast(expr.rightHandSide, paramTypes.first);
- }
+ // Check the argument for an implicit cast.
+ _checkImplicitCast(expr.rightHandSide, paramTypes[0], from: rhsType);
+
+ // Check the return type for an implicit cast.
+ //
+ // If needed, mark the assignment to indicate a down cast when we assign
+ // back to it. So these two implicit casts are equivalent:
+ //
+ // y = /*implicit cast*/(y + 42);
+ // /*implicit assignment cast*/y += 42;
+ //
+ _checkImplicitCast(expr.leftHandSide, lhsType,
+ from: returnType, opAssign: true);
}
}
- /// Records a [DownCast] of [expr] from [from] to [to], if there is one.
+ /// Returns true if we need an implicit cast of [expr] from [from] type to
+ /// [to] type, otherwise returns false.
///
/// If [from] is omitted, uses the static type of [expr].
- ///
- /// If [expr] does not require a downcast because it is not related to [to]
- /// or is already a subtype of it, does nothing.
- void _checkDowncast(Expression expr, DartType to, {DartType from}) {
- if (from == null) {
- from = _getDefiniteType(expr);
- }
+ bool _needsImplicitCast(Expression expr, DartType to, {DartType from}) {
+ from ??= _getDefiniteType(expr);
- if (!_checkNonNullAssignment(expr, to, from)) return;
+ if (!_checkNonNullAssignment(expr, to, from)) return false;
// We can use anything as void.
- if (to.isVoid) return;
+ if (to.isVoid) return false;
// fromT <: toT, no coercion needed.
- if (rules.isSubtypeOf(from, to)) return;
+ if (rules.isSubtypeOf(from, to)) return false;
// Note: a function type is never assignable to a class per the Dart
// spec - even if it has a compatible call method. We disallow as
// well for consistency.
if (from is FunctionType && rules.getCallMethodType(to) != null) {
- return;
+ return false;
}
// Downcast if toT <: fromT
if (rules.isSubtypeOf(to, from)) {
- _recordImplicitCast(expr, from, to);
- return;
+ return true;
}
// Anything else is an illegal sideways cast.
// However, these will have been reported already in error_verifier, so we
// don't need to report them again.
+ return false;
+ }
+
+ /// Checks if an implicit cast of [expr] from [from] type to [to] type is
+ /// needed, and if so records it.
+ ///
+ /// If [from] is omitted, uses the static type of [expr].
+ ///
+ /// If [expr] does not require an implicit cast because it is not related to
+ /// [to] or is already a subtype of it, does nothing.
+ void _checkImplicitCast(Expression expr, DartType to,
+ {DartType from, bool opAssign: false}) {
+ from ??= _getDefiniteType(expr);
+
+ if (_needsImplicitCast(expr, to, from: from)) {
+ _recordImplicitCast(expr, to, from: from, opAssign: opAssign);
+ }
}
void _checkFieldAccess(AstNode node, AstNode target, SimpleIdentifier field) {
@@ -909,19 +909,39 @@
}
}
- void _checkUnary(
- /*PrefixExpression|PostfixExpression*/ node,
- Element element) {
- var op = node.operator;
- if (op.isUserDefinableOperator ||
- op.type == TokenType.PLUS_PLUS ||
- op.type == TokenType.MINUS_MINUS) {
+ void _checkUnary(Expression operand, Token op, MethodElement element) {
+ bool isIncrementAssign =
+ op.type == TokenType.PLUS_PLUS || op.type == TokenType.MINUS_MINUS;
+ if (op.isUserDefinableOperator || isIncrementAssign) {
if (element == null) {
- _recordDynamicInvoke(node, node.operand);
+ _recordDynamicInvoke(operand.parent, operand);
+ } else if (isIncrementAssign) {
+ // For ++ and --, even if it is not dynamic, we still need to check
+ // that the user defined method accepts an `int` as the RHS.
+ //
+ // We assume Analyzer has done this already (in ErrorVerifier).
+ //
+ // However, we also need to check the return type.
+
+ // Refine the return type.
+ var functionType = element.type;
+ var rhsType = typeProvider.intType;
+ var lhsType = _getDefiniteType(operand);
+ var returnType = rules.refineBinaryExpressionType(typeProvider, lhsType,
+ TokenType.PLUS, rhsType, functionType.returnType);
+
+ // Skip the argument check - `int` cannot be downcast.
+ //
+ // Check the return type for an implicit cast.
+ //
+ // If needed, mark the assignment to indicate a down cast when we assign
+ // back to it. So these two implicit casts are equivalent:
+ //
+ // y = /*implicit cast*/(y + 1);
+ // /*implicit assignment cast*/y++;
+ //
+ _checkImplicitCast(operand, lhsType, from: returnType, opAssign: true);
}
- // For ++ and --, even if it is not dynamic, we still need to check
- // that the user defined method accepts an `int` as the RHS.
- // We assume Analyzer has done this already.
}
}
@@ -1022,61 +1042,49 @@
if (target != null) setIsDynamicInvoke(target, true);
}
- /// Records an implicit cast for the [expression] from [fromType] to [toType].
+ /// Records an implicit cast for the [expr] from [from] to [to].
///
/// This will emit the appropriate error/warning/hint message as well as mark
/// the AST node.
- void _recordImplicitCast(
- Expression expression, DartType fromType, DartType toType) {
- // toT <:_R fromT => to <: fromT
- // NB: classes with call methods are subtypes of function
- // types, but the function type is not assignable to the class
- assert(toType.isSubtypeOf(fromType));
+ void _recordImplicitCast(Expression expr, DartType to,
+ {DartType from, bool opAssign: false}) {
+ assert(rules.isSubtypeOf(to, from));
// Inference "casts":
- if (expression is Literal || expression is FunctionExpression) {
+ if (expr is Literal || expr is FunctionExpression) {
// fromT should be an exact type - this will almost certainly fail at
// runtime.
- _recordMessage(expression, StrongModeCode.STATIC_TYPE_ERROR,
- [expression, fromType, toType]);
+ _recordMessage(expr, StrongModeCode.STATIC_TYPE_ERROR, [expr, from, to]);
return;
}
- if (expression is InstanceCreationExpression) {
- ConstructorElement e = expression.staticElement;
+ if (expr is InstanceCreationExpression) {
+ ConstructorElement e = expr.staticElement;
if (e == null || !e.isFactory) {
// fromT should be an exact type - this will almost certainly fail at
// runtime.
- _recordMessage(expression, StrongModeCode.STATIC_TYPE_ERROR,
- [expression, fromType, toType]);
+ _recordMessage(
+ expr, StrongModeCode.STATIC_TYPE_ERROR, [expr, from, to]);
return;
}
}
- if (isKnownFunction(expression)) {
- _recordMessage(expression, StrongModeCode.STATIC_TYPE_ERROR,
- [expression, fromType, toType]);
+ if (isKnownFunction(expr)) {
+ _recordMessage(expr, StrongModeCode.STATIC_TYPE_ERROR, [expr, from, to]);
return;
}
- // TODO(vsm): Change this to an assert when we have generic methods and
- // fix TypeRules._coerceTo to disallow implicit sideways casts.
- bool downCastComposite = false;
- if (!rules.isSubtypeOf(toType, fromType)) {
- assert(toType.isSubtypeOf(fromType) || fromType.isAssignableTo(toType));
- downCastComposite = true;
- }
-
// Composite cast: these are more likely to fail.
- if (!rules.isGroundType(toType)) {
+ bool downCastComposite = false;
+ if (!rules.isGroundType(to)) {
// This cast is (probably) due to our different treatment of dynamic.
// It may be more likely to fail at runtime.
- if (fromType is InterfaceType) {
+ if (from is InterfaceType) {
// For class types, we'd like to allow non-generic down casts, e.g.,
// Iterable<T> to List<T>. The intuition here is that raw (generic)
// casts are problematic, and we should complain about those.
- var typeArgs = fromType.typeArguments;
+ var typeArgs = from.typeArguments;
downCastComposite =
typeArgs.isEmpty || typeArgs.any((t) => t.isDynamic);
} else {
@@ -1084,21 +1092,25 @@
}
}
- var parent = expression.parent;
+ var parent = expr.parent;
ErrorCode errorCode;
if (downCastComposite) {
errorCode = StrongModeCode.DOWN_CAST_COMPOSITE;
- } else if (fromType.isDynamic) {
+ } else if (from.isDynamic) {
errorCode = StrongModeCode.DYNAMIC_CAST;
- } else if (parent is VariableDeclaration &&
- parent.initializer == expression) {
+ } else if (parent is VariableDeclaration && parent.initializer == expr) {
errorCode = StrongModeCode.ASSIGNMENT_CAST;
} else {
- errorCode = StrongModeCode.DOWN_CAST_IMPLICIT;
+ errorCode = opAssign
+ ? StrongModeCode.DOWN_CAST_IMPLICIT_ASSIGN
+ : StrongModeCode.DOWN_CAST_IMPLICIT;
}
-
- _recordMessage(expression, errorCode, [fromType, toType]);
- setImplicitCast(expression, toType);
+ _recordMessage(expr, errorCode, [from, to]);
+ if (opAssign) {
+ setImplicitAssignmentCast(expr, to);
+ } else {
+ setImplicitCast(expr, to);
+ }
_hasImplicitCasts = true;
}
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 5a98fbf..6521345 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
name: analyzer
-version: 0.29.0-alpha.0
+version: 0.29.0-alpha.1
author: Dart Team <misc@dartlang.org>
description: Static analyzer for Dart.
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
diff --git a/pkg/analyzer/test/enum_test.dart b/pkg/analyzer/test/enum_test.dart
deleted file mode 100644
index 6996ee0..0000000
--- a/pkg/analyzer/test/enum_test.dart
+++ /dev/null
@@ -1,210 +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.test.enum_test;
-
-import 'dart:mirrors';
-
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/error/error.dart';
-import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/java_core.dart';
-import 'package:analyzer/src/generated/resolver.dart';
-import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-import 'package:unittest/unittest.dart';
-
-import 'utils.dart';
-
-void main() {
- initializeTestEnvironment();
- defineReflectiveTests(EnumTest);
-}
-
-@reflectiveTest
-class EnumTest {
- void test_AnalysisLevel() {
- new EnumTester<AnalysisLevel>()
- ..check_getters()
- ..check_explicit_values();
- }
-
- void test_CacheState() {
- new EnumTester<CacheState>()
- ..check_getters()
- ..check_explicit_values();
- }
-
- void test_ElementKind() {
- new EnumTester<ElementKind>()
- ..check_getters()
- ..check_explicit_values();
- }
-
- void test_ErrorProperty() {
- new EnumTester<ErrorProperty>()
- ..check_getters()
- ..check_explicit_values();
- }
-
- void test_ErrorSeverity() {
- new EnumTester<ErrorSeverity>()
- ..check_getters()
- ..check_explicit_values();
- }
-
- void test_ErrorType() {
- new EnumTester<ErrorType>()
- ..check_getters()
- ..check_explicit_values();
- }
-
- void test_INIT_STATE() {
- new EnumTester<INIT_STATE>()
- ..check_getters()
- ..check_explicit_values();
- }
-
- void test_Modifier() {
- new EnumTester<Modifier>(
- ignoreGetters: ["persistedValues", "transientValues"])
- ..check_getters()
- ..check_explicit_values();
- }
-
- void test_ParameterKind() {
- new EnumTester<ParameterKind>()
- ..check_getters()
- ..check_explicit_values();
- }
-
- void test_RedirectingConstructorKind() {
- new EnumTester<RedirectingConstructorKind>()
- ..check_getters()
- ..check_explicit_values();
- }
-
- void test_SourceKind() {
- new EnumTester<SourceKind>()
- ..check_getters()
- ..check_explicit_values();
- }
-
- void test_UriKind() {
- new EnumTester<UriKind>()
- ..check_getters()
- ..check_explicit_values();
- }
-}
-
-/**
- * Helper class for testing invariants of enumerated types.
- */
-class EnumTester<C extends Enum> {
- /**
- * Set of getter names which should be ignored when looking for getters
- * representing enum values.
- */
- Set<String> _ignoreGetters = new Set<String>();
-
- EnumTester({List<String> ignoreGetters}) {
- // Always ignore a getter called "values".
- _ignoreGetters.add('values');
-
- if (ignoreGetters != null) {
- for (String getterName in ignoreGetters) {
- _ignoreGetters.add(getterName);
- }
- }
- }
-
- /**
- * Get a map from getter name to the value returned by the getter, for all
- * static getters in [C] whose name isn't in [_ignoreGetters].
- */
- Map<String, C> get _getters {
- Map<String, C> result = <String, C>{};
- ClassMirror reflectedClass = reflectClass(C);
- reflectedClass.staticMembers.forEach((Symbol symbol, MethodMirror method) {
- if (!method.isGetter) {
- return;
- }
- String name = MirrorSystem.getName(symbol);
- if (_ignoreGetters.contains(name)) {
- return;
- }
- C value = reflectedClass.getField(symbol).reflectee as C;
- result[name] = value;
- });
- return result;
- }
-
- /**
- * Check invariants on the list of enum values accessible via the static
- * getter "values".
- */
- void check_explicit_values() {
- ClassMirror reflectedClass = reflectClass(C);
- List<C> values = reflectedClass.getField(#values).reflectee as List<C>;
- Map<C, int> reverseMap = <C, int>{};
-
- // Check that "values" is a list of values of type C, with no duplicates.
- expect(values, isList);
- for (int i = 0; i < values.length; i++) {
- C value = values[i];
- expect(value, new isInstanceOf<C>(), reason: 'values[$i]');
- if (reverseMap.containsKey(value)) {
- fail('values[$i] and values[${reverseMap[value]}] both equal $value');
- }
- reverseMap[value] = i;
- }
-
- // Check that the set of values in the "values" list matches the set of
- // values accessible via static fields.
- expect(reverseMap.keys.toSet(), equals(_getters.values.toSet()));
-
- // Make sure the order of the list matches the ordinal numbers.
- for (int i = 0; i < values.length; i++) {
- expect(values[i].ordinal, equals(i), reason: 'values[$i].ordinal');
- }
- }
-
- /**
- * Check invariants on the set of enum values accessible via the static
- * getters defined in the class [C] (with the exception of a getter called
- * "values").
- */
- void check_getters() {
- Map<int, String> ordinals = <int, String>{};
- int numValues = 0;
-
- _getters.forEach((String name, C value) {
- String reason = 'getter: $name';
- ++numValues;
-
- // Check the type of the value
- expect(value, new isInstanceOf<C>(), reason: reason);
-
- // Check that the name of the getter matches the name stored in the enum.
- expect(value.name, equals(name), reason: reason);
-
- // Check that there are no duplicate ordinals.
- if (ordinals.containsKey(value.ordinal)) {
- fail(
- 'Getters $name and ${ordinals[value.ordinal]} have ordinal value ${value.ordinal}');
- }
- ordinals[value.ordinal] = name;
- });
-
- // Check that the set of ordinals runs from 0 to N-1, where N is the number
- // of enumerated values.
- Set<int> expectedOrdinals = new Set<int>();
- for (int i = 0; i < numValues; i++) {
- expectedOrdinals.add(i);
- }
- expect(ordinals.keys.toSet(), equals(expectedOrdinals));
- }
-}
diff --git a/pkg/analyzer/test/generated/analysis_context_factory.dart b/pkg/analyzer/test/generated/analysis_context_factory.dart
index 78c62e9..272e26e 100644
--- a/pkg/analyzer/test/generated/analysis_context_factory.dart
+++ b/pkg/analyzer/test/generated/analysis_context_factory.dart
@@ -90,8 +90,7 @@
ResourceProvider resourceProvider]) {
resourceProvider ??= PhysicalResourceProvider.INSTANCE;
DartSdk sdk = new _AnalysisContextFactory_initContextWithCore(
- resourceProvider, '/fake/sdk',
- enableAsync: context.analysisOptions.enableAsync);
+ resourceProvider, '/fake/sdk');
List<UriResolver> resolvers = <UriResolver>[
new DartUriResolver(sdk),
new ResourceUriResolver(resourceProvider)
@@ -184,104 +183,94 @@
//
// dart:async
//
- Source asyncSource;
- LibraryElementImpl asyncLibrary;
- if (context.analysisOptions.enableAsync) {
- asyncLibrary = new LibraryElementImpl.forNode(
- coreContext, AstFactory.libraryIdentifier2(["dart", "async"]));
- CompilationUnitElementImpl asyncUnit =
- new CompilationUnitElementImpl("async.dart");
- asyncSource = sourceFactory.forUri(DartSdk.DART_ASYNC);
- coreContext.setContents(asyncSource, "");
- asyncUnit.librarySource = asyncUnit.source = asyncSource;
- asyncLibrary.definingCompilationUnit = asyncUnit;
- // Future
- ClassElementImpl futureElement =
- ElementFactory.classElement2("Future", ["T"]);
- futureElement.enclosingElement = asyncUnit;
- // factory Future.value([value])
- ConstructorElementImpl futureConstructor =
- ElementFactory.constructorElement2(futureElement, "value");
- futureConstructor.parameters = <ParameterElement>[
- ElementFactory.positionalParameter2("value", provider.dynamicType)
- ];
- futureConstructor.factory = true;
- futureElement.constructors = <ConstructorElement>[futureConstructor];
- // Future then(onValue(T value), { Function onError });
- TypeDefiningElement futureThenR = DynamicElementImpl.instance;
- if (context.analysisOptions.strongMode) {
- futureThenR = ElementFactory.typeParameterWithType('R');
- }
- FunctionElementImpl thenOnValue = ElementFactory.functionElement3(
- 'onValue',
- DynamicElementImpl.instance,
- [futureElement.typeParameters[0]],
- null);
- thenOnValue.synthetic = true;
-
- DartType futureRType = futureElement.type.instantiate([futureThenR.type]);
- MethodElementImpl thenMethod = ElementFactory
- .methodElementWithParameters(futureElement, "then", futureRType, [
- ElementFactory.requiredParameter2("onValue", thenOnValue.type),
- ElementFactory.namedParameter2("onError", provider.functionType)
- ]);
- if (!futureThenR.type.isDynamic) {
- thenMethod.typeParameters = <TypeParameterElement>[futureThenR];
- }
- thenOnValue.enclosingElement = thenMethod;
- thenOnValue.type = new FunctionTypeImpl(thenOnValue);
- (thenMethod.parameters[0] as ParameterElementImpl).type =
- thenOnValue.type;
- thenMethod.type = new FunctionTypeImpl(thenMethod);
-
- futureElement.methods = <MethodElement>[thenMethod];
- // Completer
- ClassElementImpl completerElement =
- ElementFactory.classElement2("Completer", ["T"]);
- ConstructorElementImpl completerConstructor =
- ElementFactory.constructorElement2(completerElement, null);
- completerElement.constructors = <ConstructorElement>[
- completerConstructor
- ];
- // StreamSubscription
- ClassElementImpl streamSubscriptionElement =
- ElementFactory.classElement2("StreamSubscription", ["T"]);
- // Stream
- ClassElementImpl streamElement =
- ElementFactory.classElement2("Stream", ["T"]);
- streamElement.constructors = <ConstructorElement>[
- ElementFactory.constructorElement2(streamElement, null)
- ];
- DartType returnType = streamSubscriptionElement.type
- .instantiate(streamElement.type.typeArguments);
- FunctionElementImpl listenOnData = ElementFactory.functionElement3(
- 'onData',
- VoidTypeImpl.instance.element,
- <TypeDefiningElement>[streamElement.typeParameters[0]],
- null);
- listenOnData.synthetic = true;
- List<DartType> parameterTypes = <DartType>[
- listenOnData.type,
- ];
- // TODO(brianwilkerson) This is missing the optional parameters.
- MethodElementImpl listenMethod =
- ElementFactory.methodElement('listen', returnType, parameterTypes);
- streamElement.methods = <MethodElement>[listenMethod];
- listenMethod.type = new FunctionTypeImpl(listenMethod);
-
- FunctionElementImpl listenParamFunction = parameterTypes[0].element;
- listenParamFunction.enclosingElement = listenMethod;
- listenParamFunction.type = new FunctionTypeImpl(listenParamFunction);
- ParameterElementImpl listenParam = listenMethod.parameters[0];
- listenParam.type = listenParamFunction.type;
-
- asyncUnit.types = <ClassElement>[
- completerElement,
- futureElement,
- streamElement,
- streamSubscriptionElement
- ];
+ LibraryElementImpl asyncLibrary = new LibraryElementImpl.forNode(
+ coreContext, AstFactory.libraryIdentifier2(["dart", "async"]));
+ CompilationUnitElementImpl asyncUnit =
+ new CompilationUnitElementImpl("async.dart");
+ Source asyncSource = sourceFactory.forUri(DartSdk.DART_ASYNC);
+ coreContext.setContents(asyncSource, "");
+ asyncUnit.librarySource = asyncUnit.source = asyncSource;
+ asyncLibrary.definingCompilationUnit = asyncUnit;
+ // Future
+ ClassElementImpl futureElement =
+ ElementFactory.classElement2("Future", ["T"]);
+ futureElement.enclosingElement = asyncUnit;
+ // factory Future.value([value])
+ ConstructorElementImpl futureConstructor =
+ ElementFactory.constructorElement2(futureElement, "value");
+ futureConstructor.parameters = <ParameterElement>[
+ ElementFactory.positionalParameter2("value", provider.dynamicType)
+ ];
+ futureConstructor.factory = true;
+ futureElement.constructors = <ConstructorElement>[futureConstructor];
+ // Future then(onValue(T value), { Function onError });
+ TypeDefiningElement futureThenR = DynamicElementImpl.instance;
+ if (context.analysisOptions.strongMode) {
+ futureThenR = ElementFactory.typeParameterWithType('R');
}
+ FunctionElementImpl thenOnValue = ElementFactory.functionElement3('onValue',
+ DynamicElementImpl.instance, [futureElement.typeParameters[0]], null);
+ thenOnValue.synthetic = true;
+
+ DartType futureRType = futureElement.type.instantiate([futureThenR.type]);
+ MethodElementImpl thenMethod = ElementFactory
+ .methodElementWithParameters(futureElement, "then", futureRType, [
+ ElementFactory.requiredParameter2("onValue", thenOnValue.type),
+ ElementFactory.namedParameter2("onError", provider.functionType)
+ ]);
+ if (!futureThenR.type.isDynamic) {
+ thenMethod.typeParameters = <TypeParameterElement>[futureThenR];
+ }
+ thenOnValue.enclosingElement = thenMethod;
+ thenOnValue.type = new FunctionTypeImpl(thenOnValue);
+ (thenMethod.parameters[0] as ParameterElementImpl).type = thenOnValue.type;
+ thenMethod.type = new FunctionTypeImpl(thenMethod);
+
+ futureElement.methods = <MethodElement>[thenMethod];
+ // Completer
+ ClassElementImpl completerElement =
+ ElementFactory.classElement2("Completer", ["T"]);
+ ConstructorElementImpl completerConstructor =
+ ElementFactory.constructorElement2(completerElement, null);
+ completerElement.constructors = <ConstructorElement>[completerConstructor];
+ // StreamSubscription
+ ClassElementImpl streamSubscriptionElement =
+ ElementFactory.classElement2("StreamSubscription", ["T"]);
+ // Stream
+ ClassElementImpl streamElement =
+ ElementFactory.classElement2("Stream", ["T"]);
+ streamElement.constructors = <ConstructorElement>[
+ ElementFactory.constructorElement2(streamElement, null)
+ ];
+ DartType returnType = streamSubscriptionElement.type
+ .instantiate(streamElement.type.typeArguments);
+ FunctionElementImpl listenOnData = ElementFactory.functionElement3(
+ 'onData',
+ VoidTypeImpl.instance.element,
+ <TypeDefiningElement>[streamElement.typeParameters[0]],
+ null);
+ listenOnData.synthetic = true;
+ List<DartType> parameterTypes = <DartType>[
+ listenOnData.type,
+ ];
+ // TODO(brianwilkerson) This is missing the optional parameters.
+ MethodElementImpl listenMethod =
+ ElementFactory.methodElement('listen', returnType, parameterTypes);
+ streamElement.methods = <MethodElement>[listenMethod];
+ listenMethod.type = new FunctionTypeImpl(listenMethod);
+
+ FunctionElementImpl listenParamFunction = parameterTypes[0].element;
+ listenParamFunction.enclosingElement = listenMethod;
+ listenParamFunction.type = new FunctionTypeImpl(listenParamFunction);
+ ParameterElementImpl listenParam = listenMethod.parameters[0];
+ listenParam.type = listenParamFunction.type;
+
+ asyncUnit.types = <ClassElement>[
+ completerElement,
+ futureElement,
+ streamElement,
+ streamSubscriptionElement
+ ];
//
// dart:html
//
@@ -564,18 +553,14 @@
}
class _AnalysisContextFactory_initContextWithCore extends FolderBasedDartSdk {
- final bool enableAsync;
_AnalysisContextFactory_initContextWithCore(
- ResourceProvider resourceProvider, String sdkPath,
- {this.enableAsync: true})
+ ResourceProvider resourceProvider, String sdkPath)
: super(resourceProvider, resourceProvider.getFolder(sdkPath));
@override
LibraryMap initialLibraryMap(bool useDart2jsPaths) {
LibraryMap map = new LibraryMap();
- if (enableAsync) {
- _addLibrary(map, DartSdk.DART_ASYNC, false, "async.dart");
- }
+ _addLibrary(map, DartSdk.DART_ASYNC, false, "async.dart");
_addLibrary(map, DartSdk.DART_CORE, false, "core.dart");
_addLibrary(map, DartSdk.DART_HTML, false, "html_dartium.dart");
_addLibrary(map, AnalysisContextFactory._DART_MATH, false, "math.dart");
diff --git a/pkg/analyzer/test/generated/element_resolver_test.dart b/pkg/analyzer/test/generated/element_resolver_test.dart
index a562940..e911f73 100644
--- a/pkg/analyzer/test/generated/element_resolver_test.dart
+++ b/pkg/analyzer/test/generated/element_resolver_test.dart
@@ -23,14 +23,283 @@
import '../utils.dart';
import 'analysis_context_factory.dart';
+import 'resolver_test_case.dart';
import 'test_support.dart';
main() {
initializeTestEnvironment();
+ defineReflectiveTests(ElementResolverCodeTest);
defineReflectiveTests(ElementResolverTest);
}
@reflectiveTest
+class ElementResolverCodeTest extends ResolverTestCase {
+ void test_annotation_class_namedConstructor() {
+ addNamedSource(
+ '/a.dart',
+ r'''
+class A {
+ const A.named();
+}
+''');
+ _validateAnnotation('', '@A.named()', (SimpleIdentifier name1,
+ SimpleIdentifier name2,
+ SimpleIdentifier name3,
+ Element annotationElement) {
+ expect(name1, isNotNull);
+ expect(name1.staticElement, new isInstanceOf<ClassElement>());
+ expect(name1.staticElement.displayName, 'A');
+ expect(name2, isNotNull);
+ expect(name2.staticElement, new isInstanceOf<ConstructorElement>());
+ expect(name2.staticElement.displayName, 'named');
+ expect(name3, isNull);
+ if (annotationElement is ConstructorElement) {
+ expect(annotationElement, same(name2.staticElement));
+ expect(annotationElement.enclosingElement, name1.staticElement);
+ expect(annotationElement.displayName, 'named');
+ expect(annotationElement.parameters, isEmpty);
+ } else {
+ fail('Expected "annotationElement" is ConstructorElement, '
+ 'but (${annotationElement?.runtimeType}) $annotationElement found.');
+ }
+ });
+ }
+
+ void test_annotation_class_prefixed_namedConstructor() {
+ addNamedSource(
+ '/a.dart',
+ r'''
+class A {
+ const A.named();
+}
+''');
+ _validateAnnotation('as p', '@p.A.named()', (SimpleIdentifier name1,
+ SimpleIdentifier name2,
+ SimpleIdentifier name3,
+ Element annotationElement) {
+ expect(name1, isNotNull);
+ expect(name1.staticElement, new isInstanceOf<PrefixElement>());
+ expect(name1.staticElement.displayName, 'p');
+ expect(name2, isNotNull);
+ expect(name2.staticElement, new isInstanceOf<ClassElement>());
+ expect(name2.staticElement.displayName, 'A');
+ expect(name3, isNotNull);
+ expect(name3.staticElement, new isInstanceOf<ConstructorElement>());
+ expect(name3.staticElement.displayName, 'named');
+ if (annotationElement is ConstructorElement) {
+ expect(annotationElement, same(name3.staticElement));
+ expect(annotationElement.enclosingElement, name2.staticElement);
+ expect(annotationElement.displayName, 'named');
+ expect(annotationElement.parameters, isEmpty);
+ } else {
+ fail('Expected "annotationElement" is ConstructorElement, '
+ 'but (${annotationElement?.runtimeType}) $annotationElement found.');
+ }
+ });
+ }
+
+ void test_annotation_class_prefixed_staticConstField() {
+ addNamedSource(
+ '/a.dart',
+ r'''
+class A {
+ static const V = 0;
+}
+''');
+ _validateAnnotation('as p', '@p.A.V', (SimpleIdentifier name1,
+ SimpleIdentifier name2,
+ SimpleIdentifier name3,
+ Element annotationElement) {
+ expect(name1, isNotNull);
+ expect(name1.staticElement, new isInstanceOf<PrefixElement>());
+ expect(name1.staticElement.displayName, 'p');
+ expect(name2, isNotNull);
+ expect(name2.staticElement, new isInstanceOf<ClassElement>());
+ expect(name2.staticElement.displayName, 'A');
+ expect(name3, isNotNull);
+ expect(name3.staticElement, new isInstanceOf<PropertyAccessorElement>());
+ expect(name3.staticElement.displayName, 'V');
+ if (annotationElement is PropertyAccessorElement) {
+ expect(annotationElement, same(name3.staticElement));
+ expect(annotationElement.enclosingElement, name2.staticElement);
+ expect(annotationElement.displayName, 'V');
+ } else {
+ fail('Expected "annotationElement" is PropertyAccessorElement, '
+ 'but (${annotationElement?.runtimeType}) $annotationElement found.');
+ }
+ });
+ }
+
+ void test_annotation_class_prefixed_unnamedConstructor() {
+ addNamedSource(
+ '/a.dart',
+ r'''
+class A {
+ const A();
+}
+''');
+ _validateAnnotation('as p', '@p.A', (SimpleIdentifier name1,
+ SimpleIdentifier name2,
+ SimpleIdentifier name3,
+ Element annotationElement) {
+ expect(name1, isNotNull);
+ expect(name1.staticElement, new isInstanceOf<PrefixElement>());
+ expect(name1.staticElement.displayName, 'p');
+ expect(name2, isNotNull);
+ expect(name2.staticElement, new isInstanceOf<ClassElement>());
+ expect(name2.staticElement.displayName, 'A');
+ expect(name3, isNull);
+ if (annotationElement is ConstructorElement) {
+ expect(annotationElement.enclosingElement, name2.staticElement);
+ expect(annotationElement.displayName, '');
+ expect(annotationElement.parameters, isEmpty);
+ } else {
+ fail('Expected "annotationElement" is ConstructorElement, '
+ 'but (${annotationElement?.runtimeType}) $annotationElement found.');
+ }
+ });
+ }
+
+ void test_annotation_class_staticConstField() {
+ addNamedSource(
+ '/a.dart',
+ r'''
+class A {
+ static const V = 0;
+}
+''');
+ _validateAnnotation('', '@A.V', (SimpleIdentifier name1,
+ SimpleIdentifier name2,
+ SimpleIdentifier name3,
+ Element annotationElement) {
+ expect(name1, isNotNull);
+ expect(name1.staticElement, new isInstanceOf<ClassElement>());
+ expect(name1.staticElement.displayName, 'A');
+ expect(name2, isNotNull);
+ expect(name2.staticElement, new isInstanceOf<PropertyAccessorElement>());
+ expect(name2.staticElement.displayName, 'V');
+ expect(name3, isNull);
+ if (annotationElement is PropertyAccessorElement) {
+ expect(annotationElement, same(name2.staticElement));
+ expect(annotationElement.enclosingElement, name1.staticElement);
+ expect(annotationElement.displayName, 'V');
+ } else {
+ fail('Expected "annotationElement" is PropertyAccessorElement, '
+ 'but (${annotationElement?.runtimeType}) $annotationElement found.');
+ }
+ });
+ }
+
+ void test_annotation_class_unnamedConstructor() {
+ addNamedSource(
+ '/a.dart',
+ r'''
+class A {
+ const A();
+}
+''');
+ _validateAnnotation('', '@A', (SimpleIdentifier name1,
+ SimpleIdentifier name2,
+ SimpleIdentifier name3,
+ Element annotationElement) {
+ expect(name1, isNotNull);
+ expect(name1.staticElement, new isInstanceOf<ClassElement>());
+ expect(name1.staticElement.displayName, 'A');
+ expect(name2, isNull);
+ expect(name3, isNull);
+ if (annotationElement is ConstructorElement) {
+ expect(annotationElement.enclosingElement, name1.staticElement);
+ expect(annotationElement.displayName, '');
+ expect(annotationElement.parameters, isEmpty);
+ } else {
+ fail('Expected "annotationElement" is ConstructorElement, '
+ 'but (${annotationElement?.runtimeType}) $annotationElement found.');
+ }
+ });
+ }
+
+ void test_annotation_topLevelVariable() {
+ addNamedSource(
+ '/a.dart',
+ r'''
+const V = 0;
+''');
+ _validateAnnotation('', '@V', (SimpleIdentifier name1,
+ SimpleIdentifier name2,
+ SimpleIdentifier name3,
+ Element annotationElement) {
+ expect(name1, isNotNull);
+ expect(name1.staticElement, new isInstanceOf<PropertyAccessorElement>());
+ expect(name1.staticElement.displayName, 'V');
+ expect(name2, isNull);
+ expect(name3, isNull);
+ if (annotationElement is PropertyAccessorElement) {
+ expect(annotationElement, same(name1.staticElement));
+ expect(annotationElement.enclosingElement,
+ new isInstanceOf<CompilationUnitElement>());
+ expect(annotationElement.displayName, 'V');
+ } else {
+ fail('Expected "annotationElement" is PropertyAccessorElement, '
+ 'but (${annotationElement?.runtimeType}) $annotationElement found.');
+ }
+ });
+ }
+
+ void test_annotation_topLevelVariable_prefixed() {
+ addNamedSource(
+ '/a.dart',
+ r'''
+const V = 0;
+''');
+ _validateAnnotation('as p', '@p.V', (SimpleIdentifier name1,
+ SimpleIdentifier name2,
+ SimpleIdentifier name3,
+ Element annotationElement) {
+ expect(name1, isNotNull);
+ expect(name1.staticElement, new isInstanceOf<PrefixElement>());
+ expect(name1.staticElement.displayName, 'p');
+ expect(name2, isNotNull);
+ expect(name2.staticElement, new isInstanceOf<PropertyAccessorElement>());
+ expect(name2.staticElement.displayName, 'V');
+ expect(name3, isNull);
+ if (annotationElement is PropertyAccessorElement) {
+ expect(annotationElement, same(name2.staticElement));
+ expect(annotationElement.enclosingElement,
+ new isInstanceOf<CompilationUnitElement>());
+ expect(annotationElement.displayName, 'V');
+ } else {
+ fail('Expected "annotationElement" is PropertyAccessorElement, '
+ 'but (${annotationElement?.runtimeType}) $annotationElement found.');
+ }
+ });
+ }
+
+ void _validateAnnotation(
+ String annotationPrefix,
+ String annotationText,
+ validator(SimpleIdentifier name1, SimpleIdentifier name2,
+ SimpleIdentifier name3, Element annotationElement)) {
+ CompilationUnit unit = resolveSource('''
+import 'a.dart' $annotationPrefix;
+$annotationText
+class C {}
+''');
+ var clazz = unit.declarations.single as ClassDeclaration;
+ Annotation annotation = clazz.metadata.single;
+ Identifier name = annotation.name;
+ Element annotationElement = annotation.element;
+ if (name is SimpleIdentifier) {
+ validator(name, null, annotation.constructorName, annotationElement);
+ } else if (name is PrefixedIdentifier) {
+ validator(name.prefix, name.identifier, annotation.constructorName,
+ annotationElement);
+ } else {
+ fail('Uknown "name": ${name?.runtimeType} $name');
+ }
+ }
+}
+
+@reflectiveTest
class ElementResolverTest extends EngineTestCase {
/**
* The error listener to which errors will be reported.
diff --git a/pkg/analyzer/test/generated/hint_code_test.dart b/pkg/analyzer/test/generated/hint_code_test.dart
index 750ef78..bbec137 100644
--- a/pkg/analyzer/test/generated/hint_code_test.dart
+++ b/pkg/analyzer/test/generated/hint_code_test.dart
@@ -65,6 +65,71 @@
});
}
+ void test_abstractSuperMemberReference_getter() {
+ Source source = addSource(r'''
+abstract class A {
+ int get test;
+}
+class B extends A {
+ int get test {
+ super.test;
+ return 0;
+ }
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
+ verify([source]);
+ }
+
+ void test_abstractSuperMemberReference_method_invocation() {
+ Source source = addSource(r'''
+abstract class A {
+ void test();
+}
+class B extends A {
+ void test() {
+ super.test();
+ }
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
+ verify([source]);
+ }
+
+ void test_abstractSuperMemberReference_method_reference() {
+ Source source = addSource(r'''
+abstract class A {
+ void test();
+}
+class B extends A {
+ void test() {
+ super.test;
+ }
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
+ verify([source]);
+ }
+
+ void test_abstractSuperMemberReference_setter() {
+ Source source = addSource(r'''
+abstract class A {
+ void set test(int v);
+}
+class B extends A {
+ void set test(int v){
+ super.test = 0;
+ }
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, [HintCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
+ verify([source]);
+ }
+
void test_argumentTypeNotAssignable_functionType() {
Source source = addSource(r'''
m() {
@@ -1859,6 +1924,23 @@
verify([source]);
}
+ void test_mustCallSuper_fromInterface() {
+ Source source = addSource(r'''
+import 'package:meta/meta.dart';
+class A {
+ @mustCallSuper
+ void a() {}
+}
+class C implements A {
+ @override
+ void a() {}
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertErrors(source, []);
+ verify([source]);
+ }
+
void test_mustCallSuper_indirect() {
Source source = addSource(r'''
import 'package:meta/meta.dart';
@@ -1882,7 +1964,7 @@
verify([source]);
}
- void test_mustCallSuper_OK() {
+ void test_mustCallSuper_overridden() {
Source source = addSource(r'''
import 'package:meta/meta.dart';
class A {
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
index 21eb70a..6dd2519 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_test.dart
@@ -36,6 +36,85 @@
verify([source]);
}
+ void test_abstractSuperMemberReference_superHasNoSuchMethod() {
+ Source source = addSource('''
+abstract class A {
+ int m();
+ noSuchMethod(_) => 42;
+}
+
+class B extends A {
+ int m() => super.m();
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_abstractSuperMemberReference_superSuperHasConcrete_getter() {
+ Source source = addSource('''
+abstract class A {
+ int get m => 0;
+}
+
+abstract class B extends A {
+ int get m;
+}
+
+class C extends B {
+ int get m => super.m;
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_abstractSuperMemberReference_superSuperHasConcrete_method() {
+ Source source = addSource('''
+void main() {
+ print(new C().m());
+}
+
+abstract class A {
+ int m() => 0;
+}
+
+abstract class B extends A {
+ int m();
+}
+
+class C extends B {
+ int m() => super.m();
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ void test_abstractSuperMemberReference_superSuperHasConcrete_setter() {
+ Source source = addSource('''
+abstract class A {
+ void set m(int v) {}
+}
+
+abstract class B extends A {
+ void set m(int v);
+}
+
+class C extends B {
+ void set m(int v) {
+ super.m = 0;
+ }
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
void test_ambiguousExport() {
Source source = addSource(r'''
library L;
@@ -3164,6 +3243,23 @@
verify([source]);
}
+ void test_invocationOfNonFunction_functionTypeTypeParameter() {
+ Source source = addSource(r'''
+typedef void Action<T>(T x);
+class C<T, U extends Action<T>> {
+ T value;
+ U action;
+ C(this.value, [this.action]);
+ void act() {
+ action(value);
+ }
+}
+''');
+ computeLibrarySourceErrors(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
void test_invocationOfNonFunction_getter() {
Source source = addSource(r'''
class A {
diff --git a/pkg/analyzer/test/generated/package_test.dart b/pkg/analyzer/test/generated/package_test.dart
index 6133166..d138acd 100644
--- a/pkg/analyzer/test/generated/package_test.dart
+++ b/pkg/analyzer/test/generated/package_test.dart
@@ -171,7 +171,7 @@
DartSdk sdk = new MockSdk();
AnalysisOptionsImpl options1 = new AnalysisOptionsImpl();
AnalysisOptionsImpl options2 = new AnalysisOptionsImpl();
- options2.enableAsync = !options1.enableAsync;
+ options2.enableGenericMethods = !options1.enableGenericMethods;
PackageDescription first = new PackageDescription(packageId, sdk, options1);
PackageDescription second =
new PackageDescription(packageId, sdk, options2);
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index cfea45d..fa7e4e6 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -336,7 +336,21 @@
BinaryExpression, expression.condition);
}
- void test_conditionalExpression_precedence_nullableType() {
+ void test_conditionalExpression_precedence_nullableType_as() {
+ enableNnbd = true;
+ Expression expression = parseExpression('x as String ? (x + y) : z');
+ expect(expression, isNotNull);
+ expect(expression, new isInstanceOf<ConditionalExpression>());
+ ConditionalExpression conditional = expression;
+ Expression condition = conditional.condition;
+ expect(condition, new isInstanceOf<AsExpression>());
+ Expression thenExpression = conditional.thenExpression;
+ expect(thenExpression, new isInstanceOf<ParenthesizedExpression>());
+ Expression elseExpression = conditional.elseExpression;
+ expect(elseExpression, new isInstanceOf<SimpleIdentifier>());
+ }
+
+ void test_conditionalExpression_precedence_nullableType_is() {
enableNnbd = true;
Expression expression = parseExpression('x is String ? (x + y) : z');
expect(expression, isNotNull);
@@ -573,114 +587,6 @@
*/
@reflectiveTest
class ErrorParserTest extends ParserTestCase {
- void fail_expectedListOrMapLiteral() {
- // It isn't clear that this test can ever pass. The parser is currently
- // create a synthetic list literal in this case, but isSynthetic() isn't
- // overridden for ListLiteral. The problem is that the synthetic list
- // literals that are being created are not always zero length (because they
- // could have type parameters), which violates the contract of
- // isSynthetic().
- createParser('1');
- TypedLiteral literal = parser.parseListOrMapLiteral(null);
- expectNotNullIfNoErrors(literal);
- listener
- .assertErrorsWithCodes([ParserErrorCode.EXPECTED_LIST_OR_MAP_LITERAL]);
- expect(literal.isSynthetic, isTrue);
- }
-
- void fail_illegalAssignmentToNonAssignable_superAssigned() {
- // TODO(brianwilkerson) When this test starts to pass, remove the test
- // test_illegalAssignmentToNonAssignable_superAssigned.
- parseExpression(
- "super = x;", [ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE]);
- }
-
- void fail_invalidCommentReference__new_nonIdentifier() {
- // This test fails because the method parseCommentReference returns null.
- createParser('');
- CommentReference reference = parser.parseCommentReference('new 42', 0);
- expectNotNullIfNoErrors(reference);
- listener.assertErrorsWithCodes([ParserErrorCode.INVALID_COMMENT_REFERENCE]);
- }
-
- void fail_invalidCommentReference__new_tooMuch() {
- createParser('');
- CommentReference reference = parser.parseCommentReference('new a.b.c.d', 0);
- expectNotNullIfNoErrors(reference);
- listener.assertErrorsWithCodes([ParserErrorCode.INVALID_COMMENT_REFERENCE]);
- }
-
- void fail_invalidCommentReference__nonNew_nonIdentifier() {
- // This test fails because the method parseCommentReference returns null.
- createParser('');
- CommentReference reference = parser.parseCommentReference('42', 0);
- expectNotNullIfNoErrors(reference);
- listener.assertErrorsWithCodes([ParserErrorCode.INVALID_COMMENT_REFERENCE]);
- }
-
- void fail_invalidCommentReference__nonNew_tooMuch() {
- createParser('');
- CommentReference reference = parser.parseCommentReference('a.b.c.d', 0);
- expectNotNullIfNoErrors(reference);
- listener.assertErrorsWithCodes([ParserErrorCode.INVALID_COMMENT_REFERENCE]);
- }
-
- void fail_missingClosingParenthesis() {
- // It is possible that it is not possible to generate this error (that it's
- // being reported in code that cannot actually be reached), but that hasn't
- // been proven yet.
- createParser('(int a, int b ;');
- FormalParameterList list = parser.parseFormalParameterList();
- expectNotNullIfNoErrors(list);
- listener
- .assertErrorsWithCodes([ParserErrorCode.MISSING_CLOSING_PARENTHESIS]);
- }
-
- void fail_missingFunctionParameters_local_nonVoid_block() {
- // The parser does not recognize this as a function declaration, so it tries
- // to parse it as an expression statement. It isn't clear what the best
- // error message is in this case.
- ParserTestCase.parseStatement(
- "int f { return x;}", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
- }
-
- void fail_missingFunctionParameters_local_nonVoid_expression() {
- // The parser does not recognize this as a function declaration, so it tries
- // to parse it as an expression statement. It isn't clear what the best
- // error message is in this case.
- ParserTestCase.parseStatement(
- "int f => x;", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
- }
-
- void fail_namedFunctionExpression() {
- createParser('f() {}');
- Expression expression = parser.parsePrimaryExpression();
- expectNotNullIfNoErrors(expression);
- listener.assertErrorsWithCodes([ParserErrorCode.NAMED_FUNCTION_EXPRESSION]);
- expect(expression, new isInstanceOf<FunctionExpression>());
- }
-
- void fail_unexpectedToken_invalidPostfixExpression() {
- // Note: this might not be the right error to produce, but some error should
- // be produced
- parseExpression("f()++", [ParserErrorCode.UNEXPECTED_TOKEN]);
- }
-
- void fail_varAndType_local() {
- // This is currently reporting EXPECTED_TOKEN for a missing semicolon, but
- // this would be a better error message.
- ParserTestCase.parseStatement("var int x;", [ParserErrorCode.VAR_AND_TYPE]);
- }
-
- void fail_varAndType_parameter() {
- // This is currently reporting EXPECTED_TOKEN for a missing semicolon, but
- // this would be a better error message.
- createParser('(var int x)');
- FormalParameterList list = parser.parseFormalParameterList();
- expectNotNullIfNoErrors(list);
- listener.assertErrorsWithCodes([ParserErrorCode.VAR_AND_TYPE]);
- }
-
void test_abstractClassMember_constructor() {
createParser('abstract C.c();');
ClassMember member = parser.parseClassMember('C');
@@ -1041,42 +947,6 @@
listener.assertErrorsWithCodes([ParserErrorCode.EMPTY_ENUM_BODY]);
}
- void test_enableAsync_false_1() {
- parseAsync = false;
- createParser('foo() async {}');
- FunctionDeclarationStatement statement =
- parser.parseFunctionDeclarationStatement();
- expectNotNullIfNoErrors(statement);
- listener.assertErrorsWithCodes([ParserErrorCode.ASYNC_NOT_SUPPORTED]);
- FunctionExpression expr = statement.functionDeclaration.functionExpression;
- expect(expr.body.isAsynchronous, isTrue);
- expect(expr.body.isGenerator, isFalse);
- }
-
- void test_enableAsync_false_2() {
- parseAsync = false;
- createParser('foo() async => 0;');
- FunctionDeclarationStatement statement =
- parser.parseFunctionDeclarationStatement();
- expectNotNullIfNoErrors(statement);
- listener.assertErrorsWithCodes([ParserErrorCode.ASYNC_NOT_SUPPORTED]);
- FunctionExpression expr = statement.functionDeclaration.functionExpression;
- expect(expr.body.isAsynchronous, isTrue);
- expect(expr.body.isGenerator, isFalse);
- }
-
- void test_enableAsync_false_3() {
- parseAsync = false;
- createParser('foo() sync* {}');
- FunctionDeclarationStatement statement =
- parser.parseFunctionDeclarationStatement();
- expectNotNullIfNoErrors(statement);
- listener.assertErrorsWithCodes([ParserErrorCode.ASYNC_NOT_SUPPORTED]);
- FunctionExpression expr = statement.functionDeclaration.functionExpression;
- expect(expr.body.isAsynchronous, isFalse);
- expect(expr.body.isGenerator, isTrue);
- }
-
void test_enumInClass() {
ParserTestCase.parseCompilationUnit(
r'''
@@ -1183,6 +1053,22 @@
[new AnalysisError(null, 2, 1, ParserErrorCode.MISSING_IDENTIFIER)]);
}
+ @failingTest
+ void test_expectedListOrMapLiteral() {
+ // It isn't clear that this test can ever pass. The parser is currently
+ // create a synthetic list literal in this case, but isSynthetic() isn't
+ // overridden for ListLiteral. The problem is that the synthetic list
+ // literals that are being created are not always zero length (because they
+ // could have type parameters), which violates the contract of
+ // isSynthetic().
+ createParser('1');
+ TypedLiteral literal = parser.parseListOrMapLiteral(null);
+ expectNotNullIfNoErrors(literal);
+ listener
+ .assertErrorsWithCodes([ParserErrorCode.EXPECTED_LIST_OR_MAP_LITERAL]);
+ expect(literal.isSynthetic, isTrue);
+ }
+
void test_expectedStringLiteral() {
createParser('1');
StringLiteral literal = parser.parseStringLiteral();
@@ -1532,7 +1418,7 @@
void test_illegalAssignmentToNonAssignable_superAssigned() {
// TODO(brianwilkerson) When the test
- // fail_illegalAssignmentToNonAssignable_superAssigned starts to pass,
+ // test_illegalAssignmentToNonAssignable_superAssigned_failing starts to pass,
// remove this test (there should only be one error generated, but we're
// keeping this test until that time so that we can catch other forms of
// regressions).
@@ -1542,6 +1428,14 @@
]);
}
+ @failingTest
+ void test_illegalAssignmentToNonAssignable_superAssigned_failing() {
+ // TODO(brianwilkerson) When this test starts to pass, remove the test
+ // test_illegalAssignmentToNonAssignable_superAssigned.
+ parseExpression(
+ "super = x;", [ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE]);
+ }
+
void test_implementsBeforeExtends() {
ParserTestCase.parseCompilationUnit("class A implements B extends C {}",
[ParserErrorCode.IMPLEMENTS_BEFORE_EXTENDS]);
@@ -1574,12 +1468,46 @@
}
void test_invalidCodePoint() {
- createParser("'\\uD900'");
+ createParser("'\\u{110000}'");
StringLiteral literal = parser.parseStringLiteral();
expectNotNullIfNoErrors(literal);
listener.assertErrorsWithCodes([ParserErrorCode.INVALID_CODE_POINT]);
}
+ @failingTest
+ void test_invalidCommentReference__new_nonIdentifier() {
+ // This test fails because the method parseCommentReference returns null.
+ createParser('');
+ CommentReference reference = parser.parseCommentReference('new 42', 0);
+ expectNotNullIfNoErrors(reference);
+ listener.assertErrorsWithCodes([ParserErrorCode.INVALID_COMMENT_REFERENCE]);
+ }
+
+ @failingTest
+ void test_invalidCommentReference__new_tooMuch() {
+ createParser('');
+ CommentReference reference = parser.parseCommentReference('new a.b.c.d', 0);
+ expectNotNullIfNoErrors(reference);
+ listener.assertErrorsWithCodes([ParserErrorCode.INVALID_COMMENT_REFERENCE]);
+ }
+
+ @failingTest
+ void test_invalidCommentReference__nonNew_nonIdentifier() {
+ // This test fails because the method parseCommentReference returns null.
+ createParser('');
+ CommentReference reference = parser.parseCommentReference('42', 0);
+ expectNotNullIfNoErrors(reference);
+ listener.assertErrorsWithCodes([ParserErrorCode.INVALID_COMMENT_REFERENCE]);
+ }
+
+ @failingTest
+ void test_invalidCommentReference__nonNew_tooMuch() {
+ createParser('');
+ CommentReference reference = parser.parseCommentReference('a.b.c.d', 0);
+ expectNotNullIfNoErrors(reference);
+ listener.assertErrorsWithCodes([ParserErrorCode.INVALID_COMMENT_REFERENCE]);
+ }
+
void test_invalidHexEscape_invalidDigit() {
createParser("'\\x0 a'");
StringLiteral literal = parser.parseStringLiteral();
@@ -1860,6 +1788,18 @@
"class A class B {}", [ParserErrorCode.MISSING_CLASS_BODY]);
}
+ @failingTest
+ void test_missingClosingParenthesis() {
+ // It is possible that it is not possible to generate this error (that it's
+ // being reported in code that cannot actually be reached), but that hasn't
+ // been proven yet.
+ createParser('(int a, int b ;');
+ FormalParameterList list = parser.parseFormalParameterList();
+ expectNotNullIfNoErrors(list);
+ listener
+ .assertErrorsWithCodes([ParserErrorCode.MISSING_CLOSING_PARENTHESIS]);
+ }
+
void test_missingConstFinalVarOrType_static() {
ParserTestCase.parseCompilationUnit("class A { static f; }",
[ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE]);
@@ -1913,6 +1853,24 @@
listener.assertErrorsWithCodes([ParserErrorCode.MISSING_FUNCTION_BODY]);
}
+ @failingTest
+ void test_missingFunctionParameters_local_nonVoid_block() {
+ // The parser does not recognize this as a function declaration, so it tries
+ // to parse it as an expression statement. It isn't clear what the best
+ // error message is in this case.
+ ParserTestCase.parseStatement(
+ "int f { return x;}", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
+ }
+
+ @failingTest
+ void test_missingFunctionParameters_local_nonVoid_expression() {
+ // The parser does not recognize this as a function declaration, so it tries
+ // to parse it as an expression statement. It isn't clear what the best
+ // error message is in this case.
+ ParserTestCase.parseStatement(
+ "int f => x;", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
+ }
+
void test_missingFunctionParameters_local_void_block() {
ParserTestCase.parseStatement(
"void f { return x;}", [ParserErrorCode.MISSING_FUNCTION_PARAMETERS]);
@@ -2191,6 +2149,15 @@
[ParserErrorCode.MULTIPLE_WITH_CLAUSES]);
}
+ @failingTest
+ void test_namedFunctionExpression() {
+ createParser('f() {}');
+ Expression expression = parser.parsePrimaryExpression();
+ expectNotNullIfNoErrors(expression);
+ listener.assertErrorsWithCodes([ParserErrorCode.NAMED_FUNCTION_EXPRESSION]);
+ expect(expression, new isInstanceOf<FunctionExpression>());
+ }
+
void test_namedParameterOutsideGroup() {
createParser('(a, b : 0)');
FormalParameterList list = parser.parseFormalParameterList();
@@ -2243,6 +2210,39 @@
.assertErrorsWithCodes([ParserErrorCode.NON_USER_DEFINABLE_OPERATOR]);
}
+ void test_nullableTypeInExtends() {
+ enableNnbd = true;
+ createParser('extends B?');
+ ExtendsClause clause = parser.parseExtendsClause();
+ expectNotNullIfNoErrors(clause);
+ listener.assertErrorsWithCodes([ParserErrorCode.NULLABLE_TYPE_IN_EXTENDS]);
+ }
+
+ void test_nullableTypeInImplements() {
+ enableNnbd = true;
+ createParser('implements I?');
+ ImplementsClause clause = parser.parseImplementsClause();
+ expectNotNullIfNoErrors(clause);
+ listener
+ .assertErrorsWithCodes([ParserErrorCode.NULLABLE_TYPE_IN_IMPLEMENTS]);
+ }
+
+ void test_nullableTypeInWith() {
+ enableNnbd = true;
+ createParser('with M?');
+ WithClause clause = parser.parseWithClause();
+ expectNotNullIfNoErrors(clause);
+ listener.assertErrorsWithCodes([ParserErrorCode.NULLABLE_TYPE_IN_WITH]);
+ }
+
+ void test_nullableTypeParameter() {
+ enableNnbd = true;
+ createParser('T?');
+ TypeParameter parameter = parser.parseTypeParameter();
+ expectNotNullIfNoErrors(parameter);
+ listener.assertErrorsWithCodes([ParserErrorCode.NULLABLE_TYPE_PARAMETER]);
+ }
+
void test_optionalAfterNormalParameters_named() {
ParserTestCase.parseCompilationUnit(
"f({a}, b) {}", [ParserErrorCode.NORMAL_BEFORE_OPTIONAL_PARAMETERS]);
@@ -2534,6 +2534,13 @@
"String s = (null));", [ParserErrorCode.UNEXPECTED_TOKEN]);
}
+ @failingTest
+ void test_unexpectedToken_invalidPostfixExpression() {
+ // Note: this might not be the right error to produce, but some error should
+ // be produced
+ parseExpression("f()++", [ParserErrorCode.UNEXPECTED_TOKEN]);
+ }
+
void test_unexpectedToken_returnInExpressionFuntionBody() {
ParserTestCase.parseCompilationUnit(
"f() => return null;", [ParserErrorCode.UNEXPECTED_TOKEN]);
@@ -2641,6 +2648,23 @@
"class C { var int x; }", [ParserErrorCode.VAR_AND_TYPE]);
}
+ @failingTest
+ void test_varAndType_local() {
+ // This is currently reporting EXPECTED_TOKEN for a missing semicolon, but
+ // this would be a better error message.
+ ParserTestCase.parseStatement("var int x;", [ParserErrorCode.VAR_AND_TYPE]);
+ }
+
+ @failingTest
+ void test_varAndType_parameter() {
+ // This is currently reporting EXPECTED_TOKEN for a missing semicolon, but
+ // this would be a better error message.
+ createParser('(var int x)');
+ FormalParameterList list = parser.parseFormalParameterList();
+ expectNotNullIfNoErrors(list);
+ listener.assertErrorsWithCodes([ParserErrorCode.VAR_AND_TYPE]);
+ }
+
void test_varAndType_topLevelVariable() {
ParserTestCase
.parseCompilationUnit("var int x;", [ParserErrorCode.VAR_AND_TYPE]);
@@ -2888,7 +2912,6 @@
//
parser = new Parser(source, listener);
parser.enableAssertInitializer = enableAssertInitializer;
- parser.parseAsync = parseAsync;
parser.parseGenericMethods = enableGenericMethods;
parser.parseGenericMethodComments = enableGenericMethodComments;
parser.parseFunctionBodies = parseFunctionBodies;
@@ -3025,18 +3048,6 @@
*/
@reflectiveTest
class RecoveryParserTest extends ParserTestCase {
- void fail_incomplete_returnType() {
- ParserTestCase.parseCompilationUnit(r'''
-Map<Symbol, convertStringToSymbolMap(Map<String, dynamic> map) {
- if (map == null) return null;
- Map<Symbol, dynamic> result = new Map<Symbol, dynamic>();
- map.forEach((name, value) {
- result[new Symbol(name)] = value;
- });
- return result;
-}''');
- }
-
void test_additiveExpression_missing_LHS() {
BinaryExpression expression =
parseExpression("+ y", [ParserErrorCode.MISSING_IDENTIFIER]);
@@ -3577,6 +3588,19 @@
[ParserErrorCode.MISSING_ASSIGNMENT_IN_INITIALIZER]);
}
+ @failingTest
+ void test_incomplete_returnType() {
+ ParserTestCase.parseCompilationUnit(r'''
+Map<Symbol, convertStringToSymbolMap(Map<String, dynamic> map) {
+ if (map == null) return null;
+ Map<Symbol, dynamic> result = new Map<Symbol, dynamic>();
+ map.forEach((name, value) {
+ result[new Symbol(name)] = value;
+ });
+ return result;
+}''');
+ }
+
void test_incomplete_topLevelFunction() {
ParserTestCase.parseCompilationUnit(
"foo();", [ParserErrorCode.MISSING_FUNCTION_BODY]);
@@ -4228,56 +4252,6 @@
*/
@reflectiveTest
class SimpleParserTest extends ParserTestCase {
- void fail_parseAwaitExpression_inSync() {
- // This test requires better error recovery than we currently have. In
- // particular, we need to be able to distinguish between an await expression
- // in the wrong context, and the use of 'await' as an identifier.
- createParser('m() { return await x + await y; }');
- MethodDeclaration method = parser.parseClassMember('C');
- expectNotNullIfNoErrors(method);
- listener.assertNoErrors();
- FunctionBody body = method.body;
- EngineTestCase.assertInstanceOf(
- (obj) => obj is BlockFunctionBody, BlockFunctionBody, body);
- Statement statement = (body as BlockFunctionBody).block.statements[0];
- EngineTestCase.assertInstanceOf(
- (obj) => obj is ReturnStatement, ReturnStatement, statement);
- Expression expression = (statement as ReturnStatement).expression;
- EngineTestCase.assertInstanceOf(
- (obj) => obj is BinaryExpression, BinaryExpression, expression);
- EngineTestCase.assertInstanceOf((obj) => obj is AwaitExpression,
- AwaitExpression, (expression as BinaryExpression).leftOperand);
- EngineTestCase.assertInstanceOf((obj) => obj is AwaitExpression,
- AwaitExpression, (expression as BinaryExpression).rightOperand);
- }
-
- void fail_parseCommentReference_this() {
- // This fails because we are returning null from the method and asserting
- // that the return value is not null.
- createParser('');
- CommentReference reference = parser.parseCommentReference('this', 5);
- expectNotNullIfNoErrors(reference);
- listener.assertNoErrors();
- SimpleIdentifier identifier = EngineTestCase.assertInstanceOf(
- (obj) => obj is SimpleIdentifier,
- SimpleIdentifier,
- reference.identifier);
- expect(identifier.token, isNotNull);
- expect(identifier.name, "a");
- expect(identifier.offset, 5);
- }
-
- void fail_parseStatement_functionDeclaration_noReturnType_typeParameters() {
- enableGenericMethods = true;
- createParser('f<E>(a, b) {};');
- Statement statement = parser.parseStatement2();
- expectNotNullIfNoErrors(statement);
- listener.assertNoErrors();
- expect(statement, new isInstanceOf<FunctionDeclarationStatement>());
- FunctionDeclarationStatement declaration = statement;
- expect(declaration.functionDeclaration, isNotNull);
- }
-
void test_computeStringValue_emptyInterpolationPrefix() {
expect(_computeStringValue("'''", true, false), "");
}
@@ -5152,6 +5126,30 @@
statement);
}
+ @failingTest
+ void test_parseAwaitExpression_inSync() {
+ // This test requires better error recovery than we currently have. In
+ // particular, we need to be able to distinguish between an await expression
+ // in the wrong context, and the use of 'await' as an identifier.
+ createParser('m() { return await x + await y; }');
+ MethodDeclaration method = parser.parseClassMember('C');
+ expectNotNullIfNoErrors(method);
+ listener.assertNoErrors();
+ FunctionBody body = method.body;
+ EngineTestCase.assertInstanceOf(
+ (obj) => obj is BlockFunctionBody, BlockFunctionBody, body);
+ Statement statement = (body as BlockFunctionBody).block.statements[0];
+ EngineTestCase.assertInstanceOf(
+ (obj) => obj is ReturnStatement, ReturnStatement, statement);
+ Expression expression = (statement as ReturnStatement).expression;
+ EngineTestCase.assertInstanceOf(
+ (obj) => obj is BinaryExpression, BinaryExpression, expression);
+ EngineTestCase.assertInstanceOf((obj) => obj is AwaitExpression,
+ AwaitExpression, (expression as BinaryExpression).leftOperand);
+ EngineTestCase.assertInstanceOf((obj) => obj is AwaitExpression,
+ AwaitExpression, (expression as BinaryExpression).rightOperand);
+ }
+
void test_parseBitwiseAndExpression_normal() {
createParser('x & y');
Expression expression = parser.parseBitwiseAndExpression();
@@ -6822,6 +6820,23 @@
expect(nextToken.type, TokenType.EOF);
}
+ @failingTest
+ void test_parseCommentReference_this() {
+ // This fails because we are returning null from the method and asserting
+ // that the return value is not null.
+ createParser('');
+ CommentReference reference = parser.parseCommentReference('this', 5);
+ expectNotNullIfNoErrors(reference);
+ listener.assertNoErrors();
+ SimpleIdentifier identifier = EngineTestCase.assertInstanceOf(
+ (obj) => obj is SimpleIdentifier,
+ SimpleIdentifier,
+ reference.identifier);
+ expect(identifier.token, isNotNull);
+ expect(identifier.name, "a");
+ expect(identifier.offset, 5);
+ }
+
void test_parseCommentReferences_multiLine() {
DocumentationCommentToken token = new DocumentationCommentToken(
TokenType.MULTI_LINE_COMMENT, "/** xxx [a] yyy [bb] zzz */", 3);
@@ -10115,6 +10130,27 @@
expect(expression.argumentList, isNotNull);
}
+ void test_parseInstanceCreationExpression_type_typeParameters_nullable() {
+ enableNnbd = true;
+ Token token = TokenFactory.tokenFromKeyword(Keyword.NEW);
+ createParser('A<B?>()');
+ InstanceCreationExpression expression =
+ parser.parseInstanceCreationExpression(token);
+ expectNotNullIfNoErrors(expression);
+ listener.assertNoErrors();
+ expect(expression.keyword, token);
+ ConstructorName name = expression.constructorName;
+ expect(name, isNotNull);
+ TypeName type = name.type;
+ expect(type, isNotNull);
+ expect(name.period, isNull);
+ expect(name.name, isNull);
+ expect(expression.argumentList, isNotNull);
+ NodeList<TypeName> arguments = type.typeArguments.arguments;
+ expect(arguments, hasLength(1));
+ expect(arguments[0].question, isNotNull);
+ }
+
void test_parseLibraryDirective() {
createParser('library l;');
LibraryDirective directive =
@@ -11562,6 +11598,19 @@
expect(asExpression.type, isNotNull);
}
+ void test_parseRelationalExpression_as_nullable() {
+ enableNnbd = true;
+ createParser('x as Y?)');
+ Expression expression = parser.parseRelationalExpression();
+ expectNotNullIfNoErrors(expression);
+ listener.assertNoErrors();
+ expect(expression, new isInstanceOf<AsExpression>());
+ AsExpression asExpression = expression;
+ expect(asExpression.expression, isNotNull);
+ expect(asExpression.asOperator, isNotNull);
+ expect(asExpression.type, isNotNull);
+ }
+
void test_parseRelationalExpression_is() {
createParser('x is y');
Expression expression = parser.parseRelationalExpression();
@@ -11575,6 +11624,20 @@
expect(isExpression.type, isNotNull);
}
+ void test_parseRelationalExpression_is_nullable() {
+ enableNnbd = true;
+ createParser('x is y?)');
+ Expression expression = parser.parseRelationalExpression();
+ expectNotNullIfNoErrors(expression);
+ listener.assertNoErrors();
+ expect(expression, new isInstanceOf<IsExpression>());
+ IsExpression isExpression = expression;
+ expect(isExpression.expression, isNotNull);
+ expect(isExpression.isOperator, isNotNull);
+ expect(isExpression.notOperator, isNull);
+ expect(isExpression.type, isNotNull);
+ }
+
void test_parseRelationalExpression_isNot() {
createParser('x is! y');
Expression expression = parser.parseRelationalExpression();
@@ -11787,6 +11850,18 @@
isNotNull);
}
+ @failingTest
+ void test_parseStatement_functionDeclaration_noReturnType_typeParameters() {
+ enableGenericMethods = true;
+ createParser('f<E>(a, b) {};');
+ Statement statement = parser.parseStatement2();
+ expectNotNullIfNoErrors(statement);
+ listener.assertNoErrors();
+ expect(statement, new isInstanceOf<FunctionDeclarationStatement>());
+ FunctionDeclarationStatement declaration = statement;
+ expect(declaration.functionDeclaration, isNotNull);
+ }
+
void test_parseStatement_functionDeclaration_returnType() {
// TODO(brianwilkerson) Implement more tests for this method.
createParser('int f(a, b) {};');
@@ -12693,6 +12768,20 @@
expect(parameter.name, isNotNull);
}
+ void test_parseTypeParameter_bounded_nullable() {
+ enableNnbd = true;
+ createParser('A extends B?');
+ TypeParameter parameter = parser.parseTypeParameter();
+ expectNotNullIfNoErrors(parameter);
+ listener.assertNoErrors();
+ expect(parameter.bound, isNotNull);
+ expect(parameter.extendsKeyword, isNotNull);
+ expect(parameter.name, isNotNull);
+ TypeName bound = parameter.bound;
+ expect(bound, isNotNull);
+ expect(bound.question, isNotNull);
+ }
+
void test_parseTypeParameter_simple() {
createParser('A');
TypeParameter parameter = parser.parseTypeParameter();
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index 6c089fa..1abacd6 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -12,7 +12,6 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/src/context/context.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/error/codes.dart';
@@ -37,7 +36,6 @@
initializeTestEnvironment();
defineReflectiveTests(AnalysisDeltaTest);
defineReflectiveTests(ChangeSetTest);
- defineReflectiveTests(DisableAsyncTestCase);
defineReflectiveTests(EnclosedScopeTest);
defineReflectiveTests(ErrorResolverTest);
defineReflectiveTests(LibraryImportScopeTest);
@@ -143,51 +141,6 @@
}
@reflectiveTest
-class DisableAsyncTestCase extends ResolverTestCase {
- @override
- void setUp() {
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- options.enableAsync = false;
- resetWithOptions(options);
- }
-
- void test_resolve() {
- Source source = addSource(r'''
-class C {
- foo() {
- bar();
- }
- bar() {
- //
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, []);
- }
-
- void test_resolve_async() {
- Source source = addSource(r'''
-class C {
- Future foo() async {
- await bar();
- return null;
- }
- Future bar() {
- return new Future.delayed(new Duration(milliseconds: 10));
- }
-}''');
- computeLibrarySourceErrors(source);
- assertErrors(source, [
- StaticWarningCode.UNDEFINED_CLASS,
- StaticWarningCode.UNDEFINED_CLASS,
- StaticWarningCode.UNDEFINED_CLASS,
- StaticWarningCode.UNDEFINED_CLASS,
- ParserErrorCode.ASYNC_NOT_SUPPORTED
- ]);
- }
-}
-
-@reflectiveTest
class EnclosedScopeTest extends ResolverTestCase {
void test_define_duplicate() {
Scope rootScope = new _RootScope();
@@ -2551,79 +2504,6 @@
expect(provider.typeType, same(typeType));
}
- void test_creation_no_async() {
- //
- // Create a mock library element with the types expected to be in dart:core.
- // We cannot use either ElementFactory or TestTypeProvider (which uses
- // ElementFactory) because we side-effect the elements in ways that would
- // break other tests.
- //
- InterfaceType objectType = _classElement("Object", null).type;
- InterfaceType boolType = _classElement("bool", objectType).type;
- InterfaceType numType = _classElement("num", objectType).type;
- InterfaceType doubleType = _classElement("double", numType).type;
- InterfaceType functionType = _classElement("Function", objectType).type;
- InterfaceType intType = _classElement("int", numType).type;
- InterfaceType iterableType =
- _classElement("Iterable", objectType, ["T"]).type;
- InterfaceType listType = _classElement("List", objectType, ["E"]).type;
- InterfaceType mapType = _classElement("Map", objectType, ["K", "V"]).type;
- InterfaceType stackTraceType = _classElement("StackTrace", objectType).type;
- InterfaceType stringType = _classElement("String", objectType).type;
- InterfaceType symbolType = _classElement("Symbol", objectType).type;
- InterfaceType typeType = _classElement("Type", objectType).type;
- CompilationUnitElementImpl coreUnit =
- new CompilationUnitElementImpl("core.dart");
- coreUnit.types = <ClassElement>[
- boolType.element,
- doubleType.element,
- functionType.element,
- intType.element,
- iterableType.element,
- listType.element,
- mapType.element,
- objectType.element,
- stackTraceType.element,
- stringType.element,
- symbolType.element,
- typeType.element
- ];
- AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
- LibraryElementImpl coreLibrary = new LibraryElementImpl.forNode(
- context, AstFactory.libraryIdentifier2(["dart.core"]));
- coreLibrary.definingCompilationUnit = coreUnit;
-
- Source asyncSource = new NonExistingSource(
- 'async.dart', Uri.parse('dart:async'), UriKind.DART_URI);
- LibraryElementImpl mockAsyncLib = (context as AnalysisContextImpl)
- .createMockAsyncLib(coreLibrary, asyncSource);
- expect(mockAsyncLib.source, same(asyncSource));
- expect(mockAsyncLib.definingCompilationUnit.source, same(asyncSource));
- expect(mockAsyncLib.publicNamespace, isNotNull);
-
- //
- // Create a type provider and ensure that it can return the expected types.
- //
- TypeProviderImpl provider = new TypeProviderImpl(coreLibrary, mockAsyncLib);
- expect(provider.boolType, same(boolType));
- expect(provider.bottomType, isNotNull);
- expect(provider.doubleType, same(doubleType));
- expect(provider.dynamicType, isNotNull);
- expect(provider.functionType, same(functionType));
- InterfaceType mockFutureType = mockAsyncLib.getType('Future').type;
- expect(provider.futureType, same(mockFutureType));
- expect(provider.intType, same(intType));
- expect(provider.listType, same(listType));
- expect(provider.mapType, same(mapType));
- expect(provider.objectType, same(objectType));
- expect(provider.stackTraceType, same(stackTraceType));
- expect(provider.stringType, same(stringType));
- expect(provider.symbolType, same(symbolType));
- InterfaceType mockStreamType = mockAsyncLib.getType('Stream').type;
- expect(provider.streamType, same(mockStreamType));
- expect(provider.typeType, same(typeType));
- }
-
ClassElement _classElement(String typeName, InterfaceType superclassType,
[List<String> parameterNames]) {
ClassElementImpl element =
diff --git a/pkg/analyzer/test/instrumentation/instrumentation_test.dart b/pkg/analyzer/test/instrumentation/instrumentation_test.dart
index 8386ee7..e6cafc0 100644
--- a/pkg/analyzer/test/instrumentation/instrumentation_test.dart
+++ b/pkg/analyzer/test/instrumentation/instrumentation_test.dart
@@ -165,6 +165,9 @@
StringBuffer priorityChannel = new StringBuffer();
@override
+ String get sessionId => '';
+
+ @override
void log(String message) {
normalChannel.writeln(message);
}
diff --git a/pkg/analyzer/test/src/context/builder_test.dart b/pkg/analyzer/test/src/context/builder_test.dart
index 3ba56ac..6de0ec6 100644
--- a/pkg/analyzer/test/src/context/builder_test.dart
+++ b/pkg/analyzer/test/src/context/builder_test.dart
@@ -135,7 +135,6 @@
AnalysisOptionsImpl defaultOptions = new AnalysisOptionsImpl();
defaultOptions.dart2jsHint = !defaultOptions.dart2jsHint;
defaultOptions.enableAssertMessage = !defaultOptions.enableAssertMessage;
- defaultOptions.enableAsync = !defaultOptions.enableAsync;
defaultOptions.enableGenericMethods = !defaultOptions.enableGenericMethods;
defaultOptions.enableStrictCallChecks =
!defaultOptions.enableStrictCallChecks;
@@ -498,7 +497,7 @@
defaultOptions.enableGenericMethods = true;
builder.defaultOptions = defaultOptions;
AnalysisOptionsImpl expected = new AnalysisOptionsImpl();
- expected.enableAsync = true;
+ expected.enableSuperMixins = true;
expected.enableGenericMethods = true;
String path = '/some/directory/path';
String filePath = '$path/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}';
@@ -506,7 +505,8 @@
filePath,
'''
analyzer:
- enableAsync : true
+ language:
+ enableSuperMixins : true
''');
AnalysisEngine engine = AnalysisEngine.instance;
@@ -515,7 +515,9 @@
try {
_TestOptionsProcessor processor = new _TestOptionsProcessor();
processor.expectedOptions = <String, Object>{
- 'analyzer': {'enableAsync': true}
+ 'analyzer': {
+ 'language': {'enableSuperMixins': true}
+ }
};
(plugin.optionsProcessorExtensionPoint as ExtensionPointImpl)
.add(processor);
@@ -566,14 +568,15 @@
void test_getAnalysisOptions_noDefault_overrides() {
AnalysisOptionsImpl expected = new AnalysisOptionsImpl();
- expected.enableAsync = true;
+ expected.enableSuperMixins = true;
String path = '/some/directory/path';
String filePath = '$path/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}';
resourceProvider.newFile(
filePath,
'''
analyzer:
- enableAsync : true
+ language:
+ enableSuperMixins : true
''');
AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
@@ -643,7 +646,6 @@
expect(actual.cacheSize, expected.cacheSize);
expect(actual.dart2jsHint, expected.dart2jsHint);
expect(actual.enableAssertMessage, expected.enableAssertMessage);
- expect(actual.enableAsync, expected.enableAsync);
expect(actual.enableStrictCallChecks, expected.enableStrictCallChecks);
expect(actual.enableGenericMethods, expected.enableGenericMethods);
expect(actual.enableSuperMixins, expected.enableSuperMixins);
diff --git a/pkg/analyzer/test/src/context/cache_test.dart b/pkg/analyzer/test/src/context/cache_test.dart
index 914a674b..d6af6ce 100644
--- a/pkg/analyzer/test/src/context/cache_test.dart
+++ b/pkg/analyzer/test/src/context/cache_test.dart
@@ -58,8 +58,8 @@
test_flush() {
AnalysisTarget target = new TestSource();
- ResultDescriptor resultA = new ResultDescriptor('A', null);
- ResultDescriptor resultB = new ResultDescriptor('B', null);
+ ResultDescriptor<String> resultA = new ResultDescriptor<String>('A', null);
+ ResultDescriptor<String> resultB = new ResultDescriptor<String>('B', null);
CacheEntry entry = new CacheEntry(target);
cache.put(entry);
// put values
@@ -124,7 +124,8 @@
}
void test_getState_hasEntry_valid() {
- ResultDescriptor result = new ResultDescriptor('result', -1);
+ ResultDescriptor<String> result =
+ new ResultDescriptor<String>('result', null);
AnalysisTarget target = new TestSource();
CacheEntry entry = new CacheEntry(target);
cache.put(entry);
@@ -139,7 +140,7 @@
}
void test_getValue_hasEntry_valid() {
- ResultDescriptor result = new ResultDescriptor('result', -1);
+ ResultDescriptor<int> result = new ResultDescriptor<int>('result', -1);
AnalysisTarget target = new TestSource();
CacheEntry entry = new CacheEntry(target);
cache.put(entry);
@@ -182,9 +183,9 @@
cache.put(entry1);
cache.put(entry2);
cache.put(entry3);
- ResultDescriptor result1 = new ResultDescriptor('result1', -1);
- ResultDescriptor result2 = new ResultDescriptor('result2', -2);
- ResultDescriptor result3 = new ResultDescriptor('result3', -3);
+ ResultDescriptor<int> result1 = new ResultDescriptor<int>('result1', -1);
+ ResultDescriptor<int> result2 = new ResultDescriptor<int>('result2', -2);
+ ResultDescriptor<int> result3 = new ResultDescriptor<int>('result3', -3);
// set results, all of them are VALID
entry1.setValue(result1, 111, TargetedResult.EMPTY_LIST);
entry2.setValue(result2, 222, [new TargetedResult(target1, result1)]);
@@ -207,8 +208,8 @@
AnalysisTarget target = new TestSource('/a.dart');
CacheEntry entry = new CacheEntry(target);
cache.put(entry);
- ResultDescriptor result1 = new ResultDescriptor('result1', -1);
- ResultDescriptor result2 = new ResultDescriptor('result2', -2);
+ ResultDescriptor<int> result1 = new ResultDescriptor<int>('result1', -1);
+ ResultDescriptor<int> result2 = new ResultDescriptor<int>('result2', -2);
// set results, all of them are VALID
entry.setValue(result1, 111, TargetedResult.EMPTY_LIST);
entry.setValue(result2, 222, [new TargetedResult(target, result1)]);
@@ -258,8 +259,10 @@
@reflectiveTest
class CacheEntryTest extends AbstractCacheTest {
test_dispose() {
- ResultDescriptor descriptor1 = new ResultDescriptor('result1', -1);
- ResultDescriptor descriptor2 = new ResultDescriptor('result2', -2);
+ ResultDescriptor<int> descriptor1 =
+ new ResultDescriptor<int>('result1', -1);
+ ResultDescriptor<int> descriptor2 =
+ new ResultDescriptor<int>('result2', -2);
AnalysisTarget target1 = new TestSource('1.dart');
AnalysisTarget target2 = new TestSource('2.dart');
TargetedResult result1 = new TargetedResult(target1, descriptor1);
@@ -300,7 +303,7 @@
test_fixExceptionState_noError_exception() {
AnalysisTarget target = new TestSource();
- ResultDescriptor result = new ResultDescriptor('test', null);
+ ResultDescriptor<int> result = new ResultDescriptor<int>('test', null);
CacheEntry entry = new CacheEntry(target);
cache.put(entry);
// set one result to ERROR
@@ -324,8 +327,8 @@
test_flush() {
AnalysisTarget target = new TestSource();
- ResultDescriptor resultA = new ResultDescriptor('A', null);
- ResultDescriptor resultB = new ResultDescriptor('B', null);
+ ResultDescriptor<String> resultA = new ResultDescriptor<String>('A', null);
+ ResultDescriptor<String> resultB = new ResultDescriptor<String>('B', null);
CacheEntry entry = new CacheEntry(target);
cache.put(entry);
// put values
@@ -359,13 +362,17 @@
}
test_getValue_flushResults() {
- ResultCachingPolicy cachingPolicy = new SimpleResultCachingPolicy(2, 2);
- ResultDescriptor descriptor1 =
- new ResultDescriptor('result1', null, cachingPolicy: cachingPolicy);
- ResultDescriptor descriptor2 =
- new ResultDescriptor('result2', null, cachingPolicy: cachingPolicy);
- ResultDescriptor descriptor3 =
- new ResultDescriptor('result3', null, cachingPolicy: cachingPolicy);
+ ResultCachingPolicy<int> cachingPolicy =
+ new SimpleResultCachingPolicy<int>(2, 2);
+ ResultDescriptor<int> descriptor1 = new ResultDescriptor<int>(
+ 'result1', null,
+ cachingPolicy: cachingPolicy);
+ ResultDescriptor<int> descriptor2 = new ResultDescriptor<int>(
+ 'result2', null,
+ cachingPolicy: cachingPolicy);
+ ResultDescriptor<int> descriptor3 = new ResultDescriptor<int>(
+ 'result3', null,
+ cachingPolicy: cachingPolicy);
AnalysisTarget target = new TestSource();
CacheEntry entry = new CacheEntry(target);
cache.put(entry);
@@ -406,7 +413,8 @@
test_invalidateAllInformation() {
AnalysisTarget target = new TestSource();
- ResultDescriptor result = new ResultDescriptor('test', null);
+ ResultDescriptor<String> result =
+ new ResultDescriptor<String>('test', null);
CacheEntry entry = new CacheEntry(target);
cache.put(entry);
entry.setValue(result, 'value', TargetedResult.EMPTY_LIST);
@@ -417,9 +425,9 @@
test_setErrorState() {
AnalysisTarget target = new TestSource();
- ResultDescriptor result1 = new ResultDescriptor('res1', 1);
- ResultDescriptor result2 = new ResultDescriptor('res2', 2);
- ResultDescriptor result3 = new ResultDescriptor('res3', 3);
+ ResultDescriptor<int> result1 = new ResultDescriptor<int>('res1', 1);
+ ResultDescriptor<int> result2 = new ResultDescriptor<int>('res2', 2);
+ ResultDescriptor<int> result3 = new ResultDescriptor<int>('res3', 3);
// prepare some good state
CacheEntry entry = new CacheEntry(target);
cache.put(entry);
@@ -446,10 +454,10 @@
CacheEntry entry2 = new CacheEntry(target2);
cache.put(entry1);
cache.put(entry2);
- ResultDescriptor result1 = new ResultDescriptor('result1', -1);
- ResultDescriptor result2 = new ResultDescriptor('result2', -2);
- ResultDescriptor result3 = new ResultDescriptor('result3', -3);
- ResultDescriptor result4 = new ResultDescriptor('result4', -4);
+ ResultDescriptor<int> result1 = new ResultDescriptor<int>('result1', -1);
+ ResultDescriptor<int> result2 = new ResultDescriptor<int>('result2', -2);
+ ResultDescriptor<int> result3 = new ResultDescriptor<int>('result3', -3);
+ ResultDescriptor<int> result4 = new ResultDescriptor<int>('result4', -4);
// set results, all of them are VALID
entry1.setValue(result1, 111, TargetedResult.EMPTY_LIST);
entry2.setValue(result2, 222, [new TargetedResult(target1, result1)]);
@@ -508,7 +516,7 @@
test_setState_error() {
AnalysisTarget target = new TestSource();
- ResultDescriptor result = new ResultDescriptor('test', null);
+ ResultDescriptor<int> result = new ResultDescriptor<int>('test', null);
CacheEntry entry = new CacheEntry(target);
cache.put(entry);
entry.setValue(result, 42, TargetedResult.EMPTY_LIST);
@@ -523,7 +531,7 @@
test_setState_flushed() {
AnalysisTarget target = new TestSource();
- ResultDescriptor result = new ResultDescriptor('test', 1);
+ ResultDescriptor<int> result = new ResultDescriptor<int>('test', 1);
CacheEntry entry = new CacheEntry(target);
cache.put(entry);
// set VALID
@@ -538,7 +546,7 @@
test_setState_inProcess() {
AnalysisTarget target = new TestSource();
- ResultDescriptor result = new ResultDescriptor('test', 1);
+ ResultDescriptor<int> result = new ResultDescriptor<int>('test', 1);
CacheEntry entry = new CacheEntry(target);
cache.put(entry);
// set VALID
@@ -553,7 +561,7 @@
test_setState_invalid() {
AnalysisTarget target = new TestSource();
- ResultDescriptor result = new ResultDescriptor('test', 1);
+ ResultDescriptor<int> result = new ResultDescriptor<int>('test', 1);
CacheEntry entry = new CacheEntry(target);
cache.put(entry);
// set VALID
@@ -581,7 +589,7 @@
CacheEntry entry2 = new CacheEntry(target2);
cache.put(entry1);
cache.put(entry2);
- ResultDescriptor result = new ResultDescriptor('result', -1);
+ ResultDescriptor<int> result = new ResultDescriptor<int>('result', -1);
// Set each result as VALID with a dependency on on the other.
entry1.setValue(result, 100, [new TargetedResult(target2, result)]);
entry2.setValue(result, 200, [new TargetedResult(target1, result)]);
@@ -611,10 +619,10 @@
AnalysisTarget target = new TestSource();
CacheEntry entry = new CacheEntry(target);
cache.put(entry);
- ResultDescriptor result1 = new ResultDescriptor('result1', -1);
- ResultDescriptor result2 = new ResultDescriptor('result2', -2);
- ResultDescriptor result3 = new ResultDescriptor('result3', -3);
- ResultDescriptor result4 = new ResultDescriptor('result4', -4);
+ ResultDescriptor<int> result1 = new ResultDescriptor<int>('result1', -1);
+ ResultDescriptor<int> result2 = new ResultDescriptor<int>('result2', -2);
+ ResultDescriptor<int> result3 = new ResultDescriptor<int>('result3', -3);
+ ResultDescriptor<int> result4 = new ResultDescriptor<int>('result4', -4);
// set results, all of them are VALID
entry.setValue(result1, 111, TargetedResult.EMPTY_LIST);
entry.setValue(result2, 222, [new TargetedResult(target, result1)]);
@@ -647,7 +655,7 @@
CacheEntry entry = new CacheEntry(target);
entry.explicitlyAdded = true;
cache.put(entry);
- ResultDescriptor result = new ResultDescriptor('result1', -1);
+ ResultDescriptor<int> result = new ResultDescriptor<int>('result1', -1);
// set results, all of them are VALID
entry.setValue(result, 111, TargetedResult.EMPTY_LIST);
expect(entry.getState(result), CacheState.VALID);
@@ -664,9 +672,9 @@
CacheEntry entry2 = new CacheEntry(target2);
cache.put(entry1);
cache.put(entry2);
- ResultDescriptor result1 = new ResultDescriptor('result1', -1);
- ResultDescriptor result2 = new ResultDescriptor('result2', -2);
- ResultDescriptor result3 = new ResultDescriptor('result3', -3);
+ ResultDescriptor<int> result1 = new ResultDescriptor<int>('result1', -1);
+ ResultDescriptor<int> result2 = new ResultDescriptor<int>('result2', -2);
+ ResultDescriptor<int> result3 = new ResultDescriptor<int>('result3', -3);
// set results, all of them are VALID
entry1.setValue(result1, 111, TargetedResult.EMPTY_LIST);
entry2.setValue(result2, 222, [new TargetedResult(target1, result1)]);
@@ -687,9 +695,9 @@
Source target = new TestSource('/test.dart');
CacheEntry entry = new CacheEntry(target);
cache.put(entry);
- ResultDescriptor result1 = new ResultDescriptor('result1', -1);
- ResultDescriptor result2 = new ResultDescriptor('result2', -2);
- ResultDescriptor result3 = new ResultDescriptor('result3', -3);
+ ResultDescriptor<int> result1 = new ResultDescriptor<int>('result1', -1);
+ ResultDescriptor<int> result2 = new ResultDescriptor<int>('result2', -2);
+ ResultDescriptor<int> result3 = new ResultDescriptor<int>('result3', -3);
// set results, all of them are VALID
entry.setValue(result1, 111, TargetedResult.EMPTY_LIST);
entry.setValue(result2, 222, [new TargetedResult(target, result1)]);
@@ -734,7 +742,8 @@
test_setValue() {
AnalysisTarget target = new TestSource();
- ResultDescriptor result = new ResultDescriptor('test', null);
+ ResultDescriptor<String> result =
+ new ResultDescriptor<String>('test', null);
String value = 'value';
CacheEntry entry = new CacheEntry(target);
cache.put(entry);
@@ -744,13 +753,17 @@
}
test_setValue_flushResults() {
- ResultCachingPolicy cachingPolicy = new SimpleResultCachingPolicy(2, 2);
- ResultDescriptor descriptor1 =
- new ResultDescriptor('result1', null, cachingPolicy: cachingPolicy);
- ResultDescriptor descriptor2 =
- new ResultDescriptor('result2', null, cachingPolicy: cachingPolicy);
- ResultDescriptor descriptor3 =
- new ResultDescriptor('result3', null, cachingPolicy: cachingPolicy);
+ ResultCachingPolicy<int> cachingPolicy =
+ new SimpleResultCachingPolicy<int>(2, 2);
+ ResultDescriptor<int> descriptor1 = new ResultDescriptor<int>(
+ 'result1', null,
+ cachingPolicy: cachingPolicy);
+ ResultDescriptor<int> descriptor2 = new ResultDescriptor<int>(
+ 'result2', null,
+ cachingPolicy: cachingPolicy);
+ ResultDescriptor<int> descriptor3 = new ResultDescriptor<int>(
+ 'result3', null,
+ cachingPolicy: cachingPolicy);
AnalysisTarget target = new TestSource();
CacheEntry entry = new CacheEntry(target);
cache.put(entry);
@@ -772,12 +785,13 @@
}
test_setValue_flushResults_keepForPrioritySources() {
- ResultCachingPolicy cachingPolicy = new SimpleResultCachingPolicy(2, 2);
- ResultDescriptor newResult(String name) =>
- new ResultDescriptor(name, null, cachingPolicy: cachingPolicy);
- ResultDescriptor descriptor1 = newResult('result1');
- ResultDescriptor descriptor2 = newResult('result2');
- ResultDescriptor descriptor3 = newResult('result3');
+ ResultCachingPolicy<int> cachingPolicy =
+ new SimpleResultCachingPolicy<int>(2, 2);
+ ResultDescriptor<int> newResult(String name) =>
+ new ResultDescriptor<int>(name, null, cachingPolicy: cachingPolicy);
+ ResultDescriptor<int> descriptor1 = newResult('result1');
+ ResultDescriptor<int> descriptor2 = newResult('result2');
+ ResultDescriptor<int> descriptor3 = newResult('result3');
TestSource source1 = new TestSource('/a.dart');
TestSource source2 = new TestSource('/b.dart');
TestSource source3 = new TestSource('/c.dart');
@@ -812,8 +826,8 @@
AnalysisTarget target = new TestSource();
CacheEntry entry = new CacheEntry(target);
cache.put(entry);
- ResultDescriptor result1 = new ResultDescriptor('result1', -1);
- ResultDescriptor result2 = new ResultDescriptor('result2', -2);
+ ResultDescriptor<int> result1 = new ResultDescriptor<int>('result1', -1);
+ ResultDescriptor<int> result2 = new ResultDescriptor<int>('result2', -2);
// set results, all of them are VALID
entry.setValue(result1, 111, TargetedResult.EMPTY_LIST);
entry.setValue(result2, 222, [new TargetedResult(target, result1)]);
@@ -836,8 +850,8 @@
CacheEntry entry2 = new CacheEntry(target2);
cache.put(entry1);
cache.put(entry2);
- ResultDescriptor result1 = new ResultDescriptor('result1', -1);
- ResultDescriptor result2 = new ResultDescriptor('result2', -2);
+ ResultDescriptor<int> result1 = new ResultDescriptor<int>('result1', -1);
+ ResultDescriptor<int> result2 = new ResultDescriptor<int>('result2', -2);
// set results, all of them are VALID
entry2.setValue(result2, 222, [new TargetedResult(target1, result1)]);
entry1.setValue(result1, 111, TargetedResult.EMPTY_LIST);
@@ -855,9 +869,9 @@
AnalysisTarget target = new TestSource();
CacheEntry entry = new CacheEntry(target);
cache.put(entry);
- ResultDescriptor result1 = new ResultDescriptor('result1', -1);
- ResultDescriptor result2 = new ResultDescriptor('result2', -2);
- ResultDescriptor result3 = new ResultDescriptor('result3', -3);
+ ResultDescriptor<int> result1 = new ResultDescriptor<int>('result1', -1);
+ ResultDescriptor<int> result2 = new ResultDescriptor<int>('result2', -2);
+ ResultDescriptor<int> result3 = new ResultDescriptor<int>('result3', -3);
// set results, all of them are VALID
entry.setValue(result1, 111, TargetedResult.EMPTY_LIST);
entry.setValue(result2, 222, [new TargetedResult(target, result1)]);
@@ -890,7 +904,7 @@
test_toString_nonEmpty() {
AnalysisTarget target = new TestSource();
- ResultDescriptor result = new ResultDescriptor('test', null);
+ ResultDescriptor<int> result = new ResultDescriptor<int>('test', null);
CacheEntry entry = new CacheEntry(target);
cache.put(entry);
entry.setValue(result, 42, TargetedResult.EMPTY_LIST);
@@ -1246,8 +1260,10 @@
when(context.analysisCache).thenReturn(cache);
// configure
// prepare entries
- ResultDescriptor descriptor1 = new ResultDescriptor('result1', -1);
- ResultDescriptor descriptor2 = new ResultDescriptor('result2', -2);
+ ResultDescriptor<int> descriptor1 =
+ new ResultDescriptor<int>('result1', -1);
+ ResultDescriptor<int> descriptor2 =
+ new ResultDescriptor<int>('result2', -2);
AnalysisTarget target1 = new TestSource('1.dart');
AnalysisTarget target2 = new TestSource('2.dart');
TargetedResult result1 = new TargetedResult(target1, descriptor1);
diff --git a/pkg/analyzer/test/src/context/mock_sdk.dart b/pkg/analyzer/test/src/context/mock_sdk.dart
index 91b4e5e..b864e53 100644
--- a/pkg/analyzer/test/src/context/mock_sdk.dart
+++ b/pkg/analyzer/test/src/context/mock_sdk.dart
@@ -221,6 +221,7 @@
class List<E> implements Iterable<E> {
List();
void add(E value) {}
+ void addAll(Iterable<E> iterable) {}
E operator [](int index) => null;
void operator []=(int index, E value) {}
Iterator<E> get iterator => null;
diff --git a/pkg/analyzer/test/src/dart/element/element_test.dart b/pkg/analyzer/test/src/dart/element/element_test.dart
index 97a687a..a1f72b8 100644
--- a/pkg/analyzer/test/src/dart/element/element_test.dart
+++ b/pkg/analyzer/test/src/dart/element/element_test.dart
@@ -2755,15 +2755,17 @@
expect(typeA.getMethod(methodName), same(methodM));
}
- void test_getMethod_parameterized() {
+ void test_getMethod_parameterized_doesNotUseTypeParameter() {
//
- // class A<E> { E m(E p) {} }
+ // class A<E> { void m() {} }
+ // class B {}
//
ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
+ InterfaceType typeB = ElementFactory.classElement2("B").type;
DartType typeE = classA.type.typeArguments[0];
String methodName = "m";
MethodElementImpl methodM =
- ElementFactory.methodElement(methodName, typeE, [typeE]);
+ ElementFactory.methodElement(methodName, typeB, []);
classA.methods = <MethodElement>[methodM];
methodM.type = new FunctionTypeImpl(methodM);
//
@@ -2775,10 +2777,8 @@
MethodElement method = typeAI.getMethod(methodName);
expect(method, isNotNull);
FunctionType methodType = method.type;
- expect(methodType.returnType, same(typeI));
- List<DartType> parameterTypes = methodType.normalParameterTypes;
- expect(parameterTypes, hasLength(1));
- expect(parameterTypes[0], same(typeI));
+ expect(methodType.typeParameters, [same(typeE.element)]);
+ expect(methodType.typeArguments, [same(typeI)]);
}
void test_getMethod_parameterized_flushCached_whenVersionChanges() {
@@ -2806,6 +2806,34 @@
expect(typeAI.methods.single, isNot(same(method)));
}
+ void test_getMethod_parameterized_usesTypeParameter() {
+ //
+ // class A<E> { E m(E p) {} }
+ //
+ ClassElementImpl classA = ElementFactory.classElement2("A", ["E"]);
+ DartType typeE = classA.type.typeArguments[0];
+ String methodName = "m";
+ MethodElementImpl methodM =
+ ElementFactory.methodElement(methodName, typeE, [typeE]);
+ classA.methods = <MethodElement>[methodM];
+ methodM.type = new FunctionTypeImpl(methodM);
+ //
+ // A<I>
+ //
+ InterfaceType typeI = ElementFactory.classElement2("I").type;
+ InterfaceTypeImpl typeAI = new InterfaceTypeImpl(classA);
+ typeAI.typeArguments = <DartType>[typeI];
+ MethodElement method = typeAI.getMethod(methodName);
+ expect(method, isNotNull);
+ FunctionType methodType = method.type;
+ expect(methodType.typeParameters, [same(typeE.element)]);
+ expect(methodType.typeArguments, [same(typeI)]);
+ expect(methodType.returnType, same(typeI));
+ List<DartType> parameterTypes = methodType.normalParameterTypes;
+ expect(parameterTypes, hasLength(1));
+ expect(parameterTypes[0], same(typeI));
+ }
+
void test_getMethod_unimplemented() {
//
// class A {}
diff --git a/pkg/analyzer/test/src/summary/pub_summary_test.dart b/pkg/analyzer/test/src/summary/pub_summary_test.dart
index 4ecf074..62804a3 100644
--- a/pkg/analyzer/test/src/summary/pub_summary_test.dart
+++ b/pkg/analyzer/test/src/summary/pub_summary_test.dart
@@ -174,6 +174,14 @@
}
}
+ test_getLinkedBundles_cached_declaredVariables_export() async {
+ await _testImpl_getLinkedBundles_cached_declaredVariables('export');
+ }
+
+ test_getLinkedBundles_cached_declaredVariables_import() async {
+ await _testImpl_getLinkedBundles_cached_declaredVariables('import');
+ }
+
test_getLinkedBundles_cached_differentSdk() async {
String pathA = '$CACHE/aaa';
resourceProvider.newFile(
@@ -1258,9 +1266,10 @@
}
void _createManager(
- {int majorVersion: PackageBundleAssembler.currentMajorVersion}) {
+ {bool allowLinking: true,
+ int majorVersion: PackageBundleAssembler.currentMajorVersion}) {
manager = new PubSummaryManager(resourceProvider, '_.temp',
- majorVersion: majorVersion);
+ allowLinking: allowLinking, majorVersion: majorVersion);
}
LinkedPubPackage _getLinkedPackage(
@@ -1269,6 +1278,87 @@
.singleWhere((linkedPackage) => linkedPackage.package.name == name);
}
+ _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(
+ '$pathA/user.dart',
+ '''
+$importOrExport 'foo.dart'
+ if (dart.library.io) 'foo_io.dart'
+ if (dart.library.html) 'foo_html.dart';
+''');
+ // Configure packages resolution.
+ Folder libFolderA = resourceProvider.newFolder(pathA);
+ context.sourceFactory = new SourceFactory(<UriResolver>[
+ sdkResolver,
+ resourceResolver,
+ new PackageMapUriResolver(resourceProvider, {
+ 'aaa': [libFolderA],
+ })
+ ]);
+
+ 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 the linked bundle and cache it in a file.
+ {
+ // Ensure unlinked bundles.
+ manager.getUnlinkedBundles(context);
+ await manager.onUnlinkedComplete;
+
+ // Now we should be able to get the linked bundle.
+ List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
+ expect(linkedPackages, hasLength(1));
+ }
+
+ // 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<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
+ expect(linkedPackages, hasLength(1));
+ _assertDependencyInUser(linkedPackages.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<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
+ expect(linkedPackages, isEmpty);
+ }
+
+ // Session 4.
+ // Enable new linking, and configure to use 'foo_html.dart'.
+ {
+ context.declaredVariables.define('dart.library.html', 'true');
+ _createManager();
+ List<LinkedPubPackage> linkedPackages = manager.getLinkedBundles(context);
+ expect(linkedPackages, hasLength(1));
+ _assertDependencyInUser(linkedPackages.single.linked, 'foo_html.dart');
+ }
+ }
+
static PackageBundle _getBundleByPackageName(
Map<PubPackage, PackageBundle> bundles, String name) {
PubPackage package =
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
index 99d8ba9..126abe5 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
@@ -692,18 +692,6 @@
@override
@failingTest
- test_const_invokeConstructor_named_unresolved() {
- super.test_const_invokeConstructor_named_unresolved();
- }
-
- @override
- @failingTest
- test_const_invokeConstructor_named_unresolved3() {
- super.test_const_invokeConstructor_named_unresolved3();
- }
-
- @override
- @failingTest
test_instantiateToBounds_boundRefersToLaterTypeArgument() {
// TODO(paulberry): this is failing due to dartbug.com/27072.
super.test_instantiateToBounds_boundRefersToLaterTypeArgument();
@@ -732,12 +720,6 @@
test_syntheticFunctionType_withArguments() {
super.test_syntheticFunctionType_withArguments();
}
-
- @override
- @failingTest
- test_unused_type_parameter() {
- super.test_unused_type_parameter();
- }
}
/**
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index bb75baf..aeebef5 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -522,7 +522,9 @@
expect(o.atSign.lexeme, r.atSign.lexeme, reason: desc);
Identifier rName = r.name;
Identifier oName = o.name;
- if (oName is PrefixedIdentifier && o.constructorName != null) {
+ if (oName is PrefixedIdentifier &&
+ o.constructorName != null &&
+ o.element != null) {
// E.g. `@prefix.cls.ctor`. This gets resynthesized as `@cls.ctor`,
// with `cls.ctor` represented as a PrefixedIdentifier.
expect(rName, new isInstanceOf<PrefixedIdentifier>(), reason: desc);
@@ -541,7 +543,9 @@
compareConstAstLists(
r.arguments?.arguments, o.arguments?.arguments, desc);
Element expectedElement = o.element;
- if (oName is PrefixedIdentifier && o.constructorName != null) {
+ 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.
@@ -639,10 +643,14 @@
void compareElementAnnotations(ElementAnnotationImpl resynthesized,
ElementAnnotationImpl original, String desc) {
- expect(resynthesized.element, isNotNull, reason: desc);
- expect(resynthesized.element.kind, original.element.kind, reason: desc);
- expect(resynthesized.element.location, original.element.location,
- reason: desc);
+ if (original.element == null) {
+ expect(resynthesized.element, isNull);
+ } else {
+ expect(resynthesized.element, isNotNull, reason: desc);
+ expect(resynthesized.element.kind, original.element.kind, reason: desc);
+ expect(resynthesized.element.location, original.element.location,
+ reason: desc);
+ }
expect(resynthesized.compilationUnit, isNotNull, reason: desc);
expect(resynthesized.compilationUnit.location,
original.compilationUnit.location,
@@ -976,8 +984,8 @@
expect(resynthesized.name, original.name, reason: desc);
}
- void compareTypeParameterElements(TypeParameterElementImpl resynthesized,
- TypeParameterElementImpl original, String desc) {
+ void compareTypeParameterElements(TypeParameterElement resynthesized,
+ TypeParameterElement original, String desc) {
compareElements(resynthesized, original, desc);
compareTypes(resynthesized.type, original.type, desc);
compareTypes(resynthesized.bound, original.bound, '$desc bound');
@@ -4456,6 +4464,51 @@
checkLibrary('f() {} g() {}');
}
+ test_unresolved_annotation_namedConstructorCall_noClass() {
+ checkLibrary('@foo.bar() class C {}');
+ }
+
+ test_unresolved_annotation_namedConstructorCall_noConstructor() {
+ checkLibrary('@String.foo() class C {}');
+ }
+
+ test_unresolved_annotation_prefixedIdentifier_badPrefix() {
+ checkLibrary('@foo.bar class C {}');
+ }
+
+ test_unresolved_annotation_prefixedIdentifier_noDeclaration() {
+ checkLibrary('import "dart:async" as foo; @foo.bar class C {}');
+ }
+
+ test_unresolved_annotation_prefixedNamedConstructorCall_badPrefix() {
+ checkLibrary('@foo.bar.baz() class C {}');
+ }
+
+ test_unresolved_annotation_prefixedNamedConstructorCall_noClass() {
+ 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 {}');
+ }
+
+ test_unresolved_annotation_prefixedUnnamedConstructorCall_badPrefix() {
+ checkLibrary('@foo.bar() class C {}');
+ }
+
+ test_unresolved_annotation_prefixedUnnamedConstructorCall_noClass() {
+ checkLibrary('import "dart:async" as foo; @foo.bar() class C {}');
+ }
+
+ test_unresolved_annotation_simpleIdentifier() {
+ checkLibrary('@foo class C {}');
+ }
+
+ test_unresolved_annotation_unnamedConstructorCall_noClass() {
+ checkLibrary('@foo() class C {}');
+ }
+
test_unresolved_export() {
allowMissingFiles = true;
checkLibrary("export 'foo.dart';", allowErrors: true);
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 5146687..95e0ff8 100644
--- a/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart
+++ b/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart
@@ -129,10 +129,4 @@
test_syntheticFunctionType_inGenericFunction() {
super.test_syntheticFunctionType_inGenericFunction();
}
-
- @override
- @failingTest
- test_unused_type_parameter() {
- super.test_unused_type_parameter();
- }
}
diff --git a/pkg/analyzer/test/src/summary/summarize_ast_test.dart b/pkg/analyzer/test/src/summary/summarize_ast_test.dart
index 439b801f..b17b6da 100644
--- a/pkg/analyzer/test/src/summary/summarize_ast_test.dart
+++ b/pkg/analyzer/test/src/summary/summarize_ast_test.dart
@@ -116,12 +116,6 @@
test_syntheticFunctionType_inGenericFunction() {
super.test_syntheticFunctionType_inGenericFunction();
}
-
- @override
- @failingTest
- test_unused_type_parameter() {
- super.test_unused_type_parameter();
- }
}
/**
diff --git a/pkg/analyzer/test/src/summary/summary_common.dart b/pkg/analyzer/test/src/summary/summary_common.dart
index 5abf015..7d90d0a 100644
--- a/pkg/analyzer/test/src/summary/summary_common.dart
+++ b/pkg/analyzer/test/src/summary/summary_common.dart
@@ -8091,8 +8091,7 @@
// The type that is inferred for C.f's parameter g is "() -> void".
// Since the associated element for that function type is B.f's parameter g,
// and B has a type parameter, the inferred type will record a type
- // parameter. However, since that type parameter is irrelevant, the summary
- // should encode it as `dynamic`.
+ // parameter.
UnlinkedClass c = serializeClassText('''
abstract class B<T> {
void f(void g());
@@ -8109,7 +8108,7 @@
EntityRef typeRef = getTypeRefForSlot(g.inferredTypeSlot);
checkLinkedTypeRef(typeRef, null, null, 'f',
expectedKind: ReferenceKind.method, numTypeArguments: 1);
- checkLinkedDynamicTypeRef(typeRef.typeArguments[0]);
+ checkParamTypeRef(typeRef.typeArguments[0], 1);
}
test_inferred_type_keeps_leading_dynamic() {
@@ -9955,10 +9954,9 @@
}
test_unused_type_parameter() {
- if (skipFullyLinkedData) {
+ if (!strongMode || skipFullyLinkedData) {
return;
}
- // Unused type parameters get converted to `dynamic`.
UnlinkedVariable variable = serializeVariableText('''
class C<T> {
void f() {}
@@ -9969,7 +9967,7 @@
EntityRef type =
getTypeRefForSlot(variable.initializer.inferredReturnTypeSlot);
expect(type.typeArguments, hasLength(1));
- checkLinkedTypeRef(type.typeArguments[0], null, null, 'dynamic');
+ checkLinkedTypeRef(type.typeArguments[0], 'dart:core', 'dart:core', 'int');
}
test_variable() {
diff --git a/pkg/analyzer/test/src/summary/test_all.dart b/pkg/analyzer/test/src/summary/test_all.dart
index f4987f4..ba099c7 100644
--- a/pkg/analyzer/test/src/summary/test_all.dart
+++ b/pkg/analyzer/test/src/summary/test_all.dart
@@ -10,7 +10,6 @@
import 'api_signature_test.dart' as api_signature_test;
import 'flat_buffers_test.dart' as flat_buffers_test;
import 'in_summary_source_test.dart' as in_summary_source_test;
-import 'index_unit_test.dart' as index_unit_test;
import 'linker_test.dart' as linker_test;
import 'name_filter_test.dart' as name_filter_test;
import 'package_bundle_reader_test.dart' as package_bundle_reader_test;
@@ -27,7 +26,6 @@
api_signature_test.main();
flat_buffers_test.main();
in_summary_source_test.main();
- index_unit_test.main();
linker_test.main();
name_filter_test.main();
package_bundle_reader_test.main();
diff --git a/pkg/analyzer/test/src/task/dart_test.dart b/pkg/analyzer/test/src/task/dart_test.dart
index f9ebf8c..403467e 100644
--- a/pkg/analyzer/test/src/task/dart_test.dart
+++ b/pkg/analyzer/test/src/task/dart_test.dart
@@ -15,7 +15,7 @@
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/constant.dart';
import 'package:analyzer/src/generated/engine.dart'
- show AnalysisOptions, AnalysisOptionsImpl, CacheState;
+ show AnalysisOptionsImpl, CacheState;
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
@@ -33,7 +33,6 @@
import '../../generated/test_support.dart';
import '../../utils.dart';
import '../context/abstract_context.dart';
-import '../context/mock_sdk.dart';
main() {
initializeTestEnvironment();
@@ -45,7 +44,6 @@
defineReflectiveTests(BuildPublicNamespaceTaskTest);
defineReflectiveTests(BuildSourceExportClosureTaskTest);
defineReflectiveTests(BuildTypeProviderTaskTest);
- defineReflectiveTests(BuildTypeProviderTaskTest_noAsync);
defineReflectiveTests(ComputeConstantDependenciesTaskTest);
defineReflectiveTests(ComputeConstantValueTaskTest);
defineReflectiveTests(ComputeInferableStaticVariableDependenciesTaskTest);
@@ -1128,29 +1126,6 @@
}
@reflectiveTest
-class BuildTypeProviderTaskTest_noAsync extends _AbstractDartTaskTest {
- DartSdk createDartSdk() => new MockSdk(dartAsync: false);
-
- void prepareAnalysisContext([AnalysisOptions options]) {
- AnalysisOptionsImpl newOptions = new AnalysisOptionsImpl();
- newOptions.enableAsync = false;
- super.prepareAnalysisContext(newOptions);
- }
-
- test_perform_noAsync() {
- expect(context, isNotNull);
- computeResult(AnalysisContextTarget.request, TYPE_PROVIDER,
- matcher: isBuildTypeProviderTask);
- // validate
- TypeProvider typeProvider = outputs[TYPE_PROVIDER];
- expect(typeProvider, isNotNull);
- expect(typeProvider.boolType, isNotNull);
- expect(typeProvider.intType, isNotNull);
- expect(typeProvider.futureType, isNotNull);
- }
-}
-
-@reflectiveTest
class ComputeConstantDependenciesTaskTest extends _AbstractDartTaskTest {
Annotation findClassAnnotation(CompilationUnit unit, String className) {
for (CompilationUnitMember member in unit.declarations) {
@@ -3196,45 +3171,6 @@
expect(outputs[UNITS], hasLength(1));
}
- test_perform_enableAsync_false() {
- AnalysisOptionsImpl options = new AnalysisOptionsImpl();
- options.enableAsync = false;
- prepareAnalysisContext(options);
- _performParseTask(r'''
-import 'dart:async';
-class B {void foo() async {}}''');
- expect(outputs, hasLength(11));
- expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(1));
- expect(outputs[EXPORTED_LIBRARIES], hasLength(0));
- _assertHasCore(outputs[IMPORTED_LIBRARIES], 2);
- expect(outputs[INCLUDED_PARTS], hasLength(0));
- expect(outputs[LIBRARY_SPECIFIC_UNITS], hasLength(1));
- expect(outputs[PARSE_ERRORS], hasLength(1));
- expect(outputs[PARSED_UNIT], isNotNull);
- expect(outputs[REFERENCED_NAMES], isNotNull);
- expect(outputs[REFERENCED_SOURCES], hasLength(3));
- expect(outputs[SOURCE_KIND], SourceKind.LIBRARY);
- expect(outputs[UNITS], hasLength(1));
- }
-
- test_perform_enableAsync_true() {
- _performParseTask(r'''
-import 'dart:async';
-class B {void foo() async {}}''');
- expect(outputs, hasLength(11));
- expect(outputs[EXPLICITLY_IMPORTED_LIBRARIES], hasLength(1));
- expect(outputs[EXPORTED_LIBRARIES], hasLength(0));
- _assertHasCore(outputs[IMPORTED_LIBRARIES], 2);
- expect(outputs[INCLUDED_PARTS], hasLength(0));
- expect(outputs[LIBRARY_SPECIFIC_UNITS], hasLength(1));
- expect(outputs[PARSE_ERRORS], hasLength(0));
- expect(outputs[PARSED_UNIT], isNotNull);
- expect(outputs[REFERENCED_NAMES], isNotNull);
- expect(outputs[REFERENCED_SOURCES], hasLength(3));
- expect(outputs[SOURCE_KIND], SourceKind.LIBRARY);
- expect(outputs[UNITS], hasLength(1));
- }
-
test_perform_flushTokenStream() {
_performParseTask(r'''
class Test {}
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 84f3f63..12388d0 100644
--- a/pkg/analyzer/test/src/task/dart_work_manager_test.dart
+++ b/pkg/analyzer/test/src/task/dart_work_manager_test.dart
@@ -357,11 +357,13 @@
when(context.aboutToComputeResult(anyObject, CONTAINING_LIBRARIES))
.thenInvoke((CacheEntry entry, ResultDescriptor result) {
if (entry.target == part1) {
- entry.setValue(result, <Source>[library1, library2], []);
+ entry.setValue(result as ResultDescriptor<List<Source>>,
+ <Source>[library1, library2], []);
return true;
}
if (entry.target == part2) {
- entry.setValue(result, <Source>[library2], []);
+ entry.setValue(
+ result as ResultDescriptor<List<Source>>, <Source>[library2], []);
return true;
}
return false;
diff --git a/pkg/analyzer/test/src/task/driver_test.dart b/pkg/analyzer/test/src/task/driver_test.dart
index 14620f7..35ff657 100644
--- a/pkg/analyzer/test/src/task/driver_test.dart
+++ b/pkg/analyzer/test/src/task/driver_test.dart
@@ -187,7 +187,8 @@
test_createWorkOrderForResult_valid() {
AnalysisTarget target = new TestSource();
- ResultDescriptor result = new ResultDescriptor('result', null);
+ ResultDescriptor<String> result =
+ new ResultDescriptor<String>('result', null);
context
.getCacheEntry(target)
.setValue(result, '', TargetedResult.EMPTY_LIST);
@@ -479,7 +480,8 @@
_createWorkOrderForTarget(
bool complete, bool priorityTarget, bool priorityResult) {
AnalysisTarget target = new TestSource();
- ResultDescriptor result = new ResultDescriptor('result', null);
+ ResultDescriptor<String> result =
+ new ResultDescriptor<String>('result', null);
TaskDescriptor descriptor = new TaskDescriptor(
'task',
(context, target) => new TestAnalysisTask(context, target),
diff --git a/pkg/analyzer/test/src/task/options_test.dart b/pkg/analyzer/test/src/task/options_test.dart
index def44fd..8e50dc0 100644
--- a/pkg/analyzer/test/src/task/options_test.dart
+++ b/pkg/analyzer/test/src/task/options_test.dart
@@ -54,23 +54,6 @@
expect(analysisOptions.strongMode, false);
}
- test_configure_enableAsync() {
- configureContext('''
-analyzer:
- language:
-''');
- expect(analysisOptions.enableAsync, true);
- }
-
- test_configure_enableAsync_false() {
- configureContext('''
-analyzer:
- language:
- enableAsync: false
-''');
- expect(analysisOptions.enableAsync, false);
- }
-
test_configure_enableGenericMethods() {
expect(analysisOptions.enableGenericMethods, false);
configureContext('''
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index ae8ba3a..ef9b1eb 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -265,12 +265,15 @@
D operator +(D d) => null;
}
+class SubA extends A {}
+class SubSubA extends SubA {}
+
foo() => new A();
test() {
int x = 0;
x += 5;
- /*error:STATIC_TYPE_ERROR*/x += /*error:INVALID_ASSIGNMENT*/3.14;
+ x += /*error:INVALID_ASSIGNMENT*/3.14;
double y = 0.0;
y += 5;
@@ -281,12 +284,12 @@
z += 3.14;
x = /*info:DOWN_CAST_IMPLICIT*/x + z;
- x += /*info:DOWN_CAST_IMPLICIT*/z;
+ /*info:DOWN_CAST_IMPLICIT_ASSIGN*/x += z;
y = y + z;
y += z;
dynamic w = 42;
- x += /*info:DYNAMIC_CAST*/w;
+ /*info:DOWN_CAST_IMPLICIT_ASSIGN*/x += /*info:DYNAMIC_CAST*/w;
y += /*info:DYNAMIC_CAST*/w;
z += /*info:DYNAMIC_CAST*/w;
@@ -302,7 +305,7 @@
a += b;
a += /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/a;
a -= b;
- /*error:STATIC_TYPE_ERROR*/b -= /*error:INVALID_ASSIGNMENT*/b;
+ b -= /*error:INVALID_ASSIGNMENT*/b;
a <<= b;
a >>= b;
a &= b;
@@ -310,6 +313,10 @@
a |= b;
/*info:DYNAMIC_INVOKE*/c += b;
+ SubA sa;
+ /*info:DOWN_CAST_IMPLICIT_ASSIGN*/sa += b;
+ SubSubA ssa = /*info:ASSIGNMENT_CAST,info:DOWN_CAST_IMPLICIT_ASSIGN*/sa += b;
+
var d = new D();
a[b] += d;
a[/*info:DYNAMIC_CAST*/c] += d;
@@ -373,6 +380,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_constructorInvalid() {
// Regression test for https://github.com/dart-lang/sdk/issues/26695
checkFile('''
@@ -3845,11 +3866,14 @@
A operator -(int x) => null;
A operator -() => null;
}
+class B extends A {}
+class C extends B {}
foo() => new A();
test() {
A a = new A();
+ B b = new B();
var c = foo();
dynamic d;
@@ -3871,6 +3895,17 @@
a--;
(/*info:DYNAMIC_INVOKE*/d++);
(/*info:DYNAMIC_INVOKE*/d--);
+
+ ++/*info:DOWN_CAST_IMPLICIT_ASSIGN*/b;
+ --/*info:DOWN_CAST_IMPLICIT_ASSIGN*/b;
+ /*info:DOWN_CAST_IMPLICIT_ASSIGN*/b++;
+ /*info:DOWN_CAST_IMPLICIT_ASSIGN*/b--;
+
+ takesC(C c) => null;
+ takesC(/*info:DOWN_CAST_IMPLICIT*/++/*info:DOWN_CAST_IMPLICIT_ASSIGN*/b);
+ takesC(/*info:DOWN_CAST_IMPLICIT*/--/*info:DOWN_CAST_IMPLICIT_ASSIGN*/b);
+ takesC(/*info:DOWN_CAST_IMPLICIT,info:DOWN_CAST_IMPLICIT_ASSIGN*/b++);
+ takesC(/*info:DOWN_CAST_IMPLICIT,info:DOWN_CAST_IMPLICIT_ASSIGN*/b--);
}''');
}
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 e9ccb34..4928bd5 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -700,6 +700,17 @@
expect(unit.topLevelVariables[0].type.toString(), 'C<int>');
}
+ void test_constructors_inferFromArguments_factory_callsConstructor() {
+ checkFile(r'''
+class A<T> {
+ A<T> f = /*info:INFERRED_TYPE_ALLOCATION*/new A();
+ A();
+ factory A.factory() => /*info:INFERRED_TYPE_ALLOCATION*/new A();
+ A<T> m() => /*info:INFERRED_TYPE_ALLOCATION*/new A();
+}
+ ''');
+ }
+
void test_constructors_inferFromArguments_named() {
var unit = checkFile('''
class C<T> {
@@ -899,8 +910,8 @@
import 'dart:async';
Future test() async {
dynamic d;
- List<int> l0 = await /*info:INFERRED_TYPE_LITERAL*/[/*info:DYNAMIC_CAST*/d];
- List<int> l1 = await /*info:INFERRED_TYPE_ALLOCATION*/new Future.value(/*info:INFERRED_TYPE_LITERAL*/[/*info:DYNAMIC_CAST*/d]);
+ List<int> l0 = await /*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*info:DYNAMIC_CAST*/d];
+ List<int> l1 = await /*info:INFERRED_TYPE_ALLOCATION*/new Future.value(/*info:INFERRED_TYPE_LITERAL,error:COULD_NOT_INFER*/[/*info:DYNAMIC_CAST*/d]);
}
''');
}
@@ -1880,19 +1891,15 @@
checkFile(r'''
void main() {
List<int> o;
- var x = o.fold(0, /*info:INFERRED_TYPE_CLOSURE*/(int x, y) => x + y);
int y = o.fold(0, /*info:INFERRED_TYPE_CLOSURE*/(x, y) => x + y);
- var z = o.fold(0, /*info:INFERRED_TYPE_CLOSURE,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/(x, y) => /*info:DYNAMIC_INVOKE*/x + y);
- y = z;
- y = x;
+ var z = o.fold(0, /*info:INFERRED_TYPE_CLOSURE*/(x, y) => /*info:DYNAMIC_INVOKE*/x + y);
+ y = /*info:DYNAMIC_CAST*/z;
}
void functionExpressionInvocation() {
List<int> o;
- var x = (o.fold)(0, /*info:INFERRED_TYPE_CLOSURE*/(int x, y) => x + y);
int y = (o.fold)(0, /*info:INFERRED_TYPE_CLOSURE*/(x, y) => x + y);
- var z = (o.fold)(0, /*info:INFERRED_TYPE_CLOSURE,error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/(x, y) => /*info:DYNAMIC_INVOKE*/x + y);
- y = z;
- y = x;
+ var z = (o.fold)(0, /*info:INFERRED_TYPE_CLOSURE*/(x, y) => /*info:DYNAMIC_INVOKE*/x + y);
+ y = /*info:DYNAMIC_CAST*/z;
}
''');
}
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 8db9b24..d130a54 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
@@ -111,7 +111,7 @@
void main() {
int i = 1;
i += 2;
- /*error:STATIC_TYPE_ERROR*/i += null;
+ /*error:INVALID_ASSIGNMENT*/i += null;
print(i);
}
''');
diff --git a/pkg/analyzer/test/test_all.dart b/pkg/analyzer/test/test_all.dart
index 7e45412..1d598fb 100644
--- a/pkg/analyzer/test/test_all.dart
+++ b/pkg/analyzer/test/test_all.dart
@@ -8,7 +8,6 @@
import 'cancelable_future_test.dart' as cancelable_future_test;
import 'context/test_all.dart' as context;
-import 'enum_test.dart' as enum_test;
import 'file_system/test_all.dart' as file_system;
import 'generated/test_all.dart' as generated;
import 'instrumentation/test_all.dart' as instrumentation;
@@ -23,7 +22,6 @@
group('analysis engine', () {
cancelable_future_test.main();
context.main();
- enum_test.main();
file_system.main();
generated.main();
instrumentation.main();
diff --git a/pkg/analyzer/tool/task_dependency_graph/generate.dart b/pkg/analyzer/tool/task_dependency_graph/generate.dart
index 068790f..9761e90 100644
--- a/pkg/analyzer/tool/task_dependency_graph/generate.dart
+++ b/pkg/analyzer/tool/task_dependency_graph/generate.dart
@@ -156,9 +156,11 @@
context = AnalysisEngine.instance.createAnalysisContext();
ContextBuilder builder = new ContextBuilder(resourceProvider, null, null);
if (Platform.packageRoot != null) {
- builder.defaultPackagesDirectoryPath = Uri.parse(Platform.packageRoot).toFilePath();
+ builder.defaultPackagesDirectoryPath =
+ Uri.parse(Platform.packageRoot).toFilePath();
} else if (Platform.packageConfig != null) {
- builder.defaultPackageFilePath = Platform.packageConfig;
+ builder.defaultPackageFilePath =
+ Uri.parse(Platform.packageConfig).toFilePath();
} else {
// Let the context builder use the default algorithm for package
// resolution.
diff --git a/pkg/analyzer_cli/lib/src/analyzer_impl.dart b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
index 9f75bf9..14b61b8 100644
--- a/pkg/analyzer_cli/lib/src/analyzer_impl.dart
+++ b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
@@ -8,10 +8,11 @@
import 'dart:io';
import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/error/error.dart';
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/source/error_processor.dart';
+import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/java_io.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
diff --git a/pkg/analyzer_cli/lib/src/build_mode.dart b/pkg/analyzer_cli/lib/src/build_mode.dart
index 700e797..a8e9757 100644
--- a/pkg/analyzer_cli/lib/src/build_mode.dart
+++ b/pkg/analyzer_cli/lib/src/build_mode.dart
@@ -8,10 +8,10 @@
import 'dart:io' as io;
import 'package:analyzer/dart/ast/ast.dart' show CompilationUnit;
+import 'package:analyzer/error/error.dart';
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/sdk.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/generated/source_io.dart';
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart
index 185290b..ec779a7 100644
--- a/pkg/analyzer_cli/lib/src/driver.dart
+++ b/pkg/analyzer_cli/lib/src/driver.dart
@@ -8,6 +8,7 @@
import 'dart:convert';
import 'dart:io' as io;
+import 'package:analyzer/error/error.dart';
import 'package:analyzer/file_system/file_system.dart' as file_system;
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
@@ -22,7 +23,6 @@
import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/generated/constant.dart';
import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/interner.dart';
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/sdk.dart';
diff --git a/pkg/analyzer_cli/lib/src/error_formatter.dart b/pkg/analyzer_cli/lib/src/error_formatter.dart
index e0c9a8e..cac83b3 100644
--- a/pkg/analyzer_cli/lib/src/error_formatter.dart
+++ b/pkg/analyzer_cli/lib/src/error_formatter.dart
@@ -4,8 +4,8 @@
library analyzer_cli.src.error_formatter;
+import 'package:analyzer/error/error.dart';
import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer_cli/src/options.dart';
@@ -171,6 +171,7 @@
}
out.writeln();
}
+
void formatErrors(List<AnalysisErrorInfo> errorInfos) {
stats.unfilteredCount += errorInfos.length;
diff --git a/pkg/analyzer_cli/test/data/super_mixin_example.dart b/pkg/analyzer_cli/test/data/super_mixin_example.dart
index ea90486..8983592 100644
--- a/pkg/analyzer_cli/test/data/super_mixin_example.dart
+++ b/pkg/analyzer_cli/test/data/super_mixin_example.dart
@@ -8,7 +8,7 @@
}
abstract class B {
- void foo();
+ void foo() {}
}
abstract class C extends B {
diff --git a/pkg/analyzer_cli/test/driver_test.dart b/pkg/analyzer_cli/test/driver_test.dart
index 58b5c1a..cacbc28 100644
--- a/pkg/analyzer_cli/test/driver_test.dart
+++ b/pkg/analyzer_cli/test/driver_test.dart
@@ -6,13 +6,15 @@
import 'dart:io';
+import 'package:analyzer/error/error.dart';
import 'package:analyzer/plugin/options.dart';
import 'package:analyzer/source/analysis_options_provider.dart';
import 'package:analyzer/source/error_processor.dart';
+import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/error.dart';
import 'package:analyzer/src/generated/source.dart';
import 'package:analyzer/src/services/lint.dart';
+import 'package:analyzer/src/task/options.dart';
import 'package:analyzer_cli/src/driver.dart';
import 'package:analyzer_cli/src/options.dart';
import 'package:path/path.dart' as path;
@@ -204,6 +206,7 @@
});
});
}
+
createTests('old', AnalysisEngine.ANALYSIS_OPTIONS_FILE);
createTests('new', AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
});
@@ -303,6 +306,7 @@
});
});
}
+
createTests('old', AnalysisEngine.ANALYSIS_OPTIONS_FILE);
createTests('new', AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
});
@@ -351,6 +355,7 @@
});
});
}
+
createTests('old', AnalysisEngine.ANALYSIS_OPTIONS_FILE);
createTests('new', AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
@@ -459,6 +464,7 @@
return new File(path.join(sdkDir, 'lib', '_internal', 'spec.sum'))
.existsSync();
}
+
// Usually the sdk directory is the parent of the parent of the "dart"
// executable.
Directory executableParent = new File(Platform.executable).parent;
diff --git a/pkg/compiler/lib/src/closure.dart b/pkg/compiler/lib/src/closure.dart
index 7b71e69..f44b2d2 100644
--- a/pkg/compiler/lib/src/closure.dart
+++ b/pkg/compiler/lib/src/closure.dart
@@ -19,7 +19,7 @@
import 'resolution/tree_elements.dart' show TreeElements;
import 'tokens/token.dart' show Token;
import 'tree/tree.dart';
-import 'universe/universe.dart' show Universe;
+import 'universe/universe.dart' show CodegenUniverse;
import 'util/util.dart';
class ClosureTask extends CompilerTask {
@@ -517,14 +517,6 @@
scope.forEachCapturedVariable(f);
});
}
-
- void removeMyselfFrom(Universe universe) {
- freeVariableMap.values.forEach((e) {
- universe.closurizedMembers.remove(e);
- universe.fieldSetters.remove(e);
- universe.fieldGetters.remove(e);
- });
- }
}
class ClosureTranslator extends Visitor {
@@ -1054,8 +1046,7 @@
ClosureClassElement globalizedElement =
new ClosureClassElement(node, closureName, compiler, element);
// Extend [globalizedElement] as an instantiated class in the closed world.
- compiler.world
- .registerClass(globalizedElement, isDirectlyInstantiated: true);
+ compiler.inferenceWorld.registerClosureClass(globalizedElement);
FunctionElement callElement = new SynthesizedCallMethodElementX(
Identifiers.call, element, globalizedElement, node, elements);
backend.maybeMarkClosureAsNeededForReflection(
diff --git a/pkg/compiler/lib/src/common/backend_api.dart b/pkg/compiler/lib/src/common/backend_api.dart
index 7906b04..258a38f 100644
--- a/pkg/compiler/lib/src/common/backend_api.dart
+++ b/pkg/compiler/lib/src/common/backend_api.dart
@@ -30,7 +30,8 @@
import '../serialization/serialization.dart'
show DeserializerPlugin, SerializerPlugin;
import '../tree/tree.dart' show Node;
-import '../universe/world_impact.dart' show ImpactStrategy, WorldImpact;
+import '../universe/world_impact.dart'
+ show ImpactStrategy, WorldImpact, WorldImpactBuilder;
import 'codegen.dart' show CodegenWorkItem;
import 'registry.dart' show Registry;
import 'tasks.dart' show CompilerTask;
@@ -116,7 +117,8 @@
bool enableDeferredLoadingIfSupported(Spannable node, Registry registry);
/// Called during codegen when [constant] has been used.
- void registerCompileTimeConstant(ConstantValue constant, Registry registry) {}
+ void computeImpactForCompileTimeConstant(ConstantValue constant,
+ WorldImpactBuilder impactBuilder, bool isForResolution) {}
/// Called to notify to the backend that a class is being instantiated.
// TODO(johnniwinther): Remove this. It's only called once for each [cls] and
@@ -153,9 +155,7 @@
/// Called to instruct the backend to register that a closure exists for a
/// function on an instantiated generic class.
void registerClosureWithFreeTypeVariables(
- Element closure, Enqueuer enqueuer, Registry registry) {
- enqueuer.universe.closuresWithFreeTypeVariables.add(closure);
- }
+ Element closure, Enqueuer enqueuer, Registry registry) {}
/// Call this to register that a member has been closurized.
void registerBoundClosure(Enqueuer enqueuer) {}
diff --git a/pkg/compiler/lib/src/common/codegen.dart b/pkg/compiler/lib/src/common/codegen.dart
index 84eb422..5214585 100644
--- a/pkg/compiler/lib/src/common/codegen.dart
+++ b/pkg/compiler/lib/src/common/codegen.dart
@@ -19,17 +19,14 @@
import '../enqueue.dart' show Enqueuer;
import '../universe/use.dart' show DynamicUse, StaticUse, TypeUse;
import '../universe/world_impact.dart'
- show WorldImpact, WorldImpactBuilder, WorldImpactVisitor;
+ show WorldImpact, WorldImpactBuilderImpl, WorldImpactVisitor;
import '../util/util.dart' show Pair, Setlet;
-import 'registry.dart' show Registry, EagerRegistry;
+import 'registry.dart' show Registry;
import 'work.dart' show WorkItem;
class CodegenImpact extends WorldImpact {
const CodegenImpact();
- // TODO(johnniwinther): Remove this.
- Registry get registry => null;
-
Iterable<ConstantValue> get compileTimeConstants => const <ConstantValue>[];
Iterable<Pair<DartType, DartType>> get typeVariableBoundsSubtypeChecks {
@@ -49,10 +46,7 @@
Iterable<Element> get asyncMarkers => const <FunctionElement>[];
}
-class _CodegenImpact extends WorldImpactBuilder implements CodegenImpact {
- // TODO(johnniwinther): Remove this.
- final Registry registry;
-
+class _CodegenImpact extends WorldImpactBuilderImpl implements CodegenImpact {
Setlet<ConstantValue> _compileTimeConstants;
Setlet<Pair<DartType, DartType>> _typeVariableBoundsSubtypeChecks;
Setlet<String> _constSymbols;
@@ -61,7 +55,7 @@
Setlet<ClassElement> _typeConstants;
Setlet<FunctionElement> _asyncMarkers;
- _CodegenImpact(this.registry);
+ _CodegenImpact();
void apply(WorldImpactVisitor visitor) {
staticUses.forEach(visitor.visitStaticUse);
@@ -160,8 +154,7 @@
CodegenRegistry(Compiler compiler, AstElement currentElement)
: this.compiler = compiler,
this.currentElement = currentElement,
- this.worldImpact = new _CodegenImpact(new EagerRegistry(
- 'EagerRegistry for $currentElement', compiler.enqueuer.codegen));
+ this.worldImpact = new _CodegenImpact();
bool get isForResolution => false;
diff --git a/pkg/compiler/lib/src/common/registry.dart b/pkg/compiler/lib/src/common/registry.dart
index 96ee845..08d6081 100644
--- a/pkg/compiler/lib/src/common/registry.dart
+++ b/pkg/compiler/lib/src/common/registry.dart
@@ -4,48 +4,10 @@
library dart2js.common.registry;
-import '../dart_types.dart' show InterfaceType;
import '../elements/elements.dart' show Element;
-import '../enqueue.dart' show Enqueuer;
-import '../universe/use.dart' show DynamicUse, StaticUse;
-
-/// Interface for registration of element dependencies.
-abstract class Registry {
- // TODO(johnniwinther): Remove this.
- void registerDependency(Element element) {}
-
- bool get isForResolution;
-
- void registerDynamicUse(DynamicUse staticUse);
-
- void registerStaticUse(StaticUse staticUse);
-
- void registerInstantiation(InterfaceType type);
-}
// TODO(johnniwinther): Remove this.
-class EagerRegistry extends Registry {
- final String name;
- final Enqueuer world;
-
- EagerRegistry(this.name, this.world);
-
- bool get isForResolution => world.isResolutionQueue;
-
- @override
- void registerDynamicUse(DynamicUse dynamicUse) {
- world.registerDynamicUse(dynamicUse);
- }
-
- @override
- void registerInstantiation(InterfaceType type) {
- world.registerInstantiatedType(type);
- }
-
- @override
- void registerStaticUse(StaticUse staticUse) {
- world.registerStaticUse(staticUse);
- }
-
- String toString() => name;
+/// Interface for registration of element dependencies.
+abstract class Registry {
+ void registerDependency(Element element) {}
}
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index c7d00d8..5667a4e 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -13,7 +13,7 @@
import 'common/codegen.dart' show CodegenWorkItem;
import 'common/names.dart' show Selectors;
import 'common/names.dart' show Identifiers, Uris;
-import 'common/registry.dart' show EagerRegistry, Registry;
+import 'common/registry.dart' show Registry;
import 'common/resolution.dart'
show
ParsingContext,
@@ -73,11 +73,11 @@
import 'types/types.dart' show GlobalTypeInferenceTask;
import 'types/masks.dart' show CommonMasks;
import 'universe/selector.dart' show Selector;
-import 'universe/universe.dart' show Universe;
+import 'universe/universe.dart' show ResolutionUniverse, CodegenUniverse;
import 'universe/use.dart' show StaticUse;
import 'universe/world_impact.dart' show ImpactStrategy, WorldImpact;
import 'util/util.dart' show Link, Setlet;
-import 'world.dart' show World;
+import 'world.dart' show ClosedWorld, ClosedWorldRefiner, OpenWorld, WorldImpl;
typedef Backend MakeBackendFuncion(Compiler compiler);
@@ -88,7 +88,7 @@
Measurer get measurer;
final IdGenerator idGenerator = new IdGenerator();
- World world;
+ WorldImpl _world;
Types types;
_CompilerCoreTypes _coreTypes;
CompilerDiagnosticReporter _reporter;
@@ -225,7 +225,7 @@
this.userOutputProvider = outputProvider == null
? const NullCompilerOutput()
: outputProvider {
- world = new World(this);
+ _world = new WorldImpl(this);
if (makeReporter != null) {
_reporter = makeReporter(this, options);
} else {
@@ -244,7 +244,7 @@
// TODO(johnniwinther): Separate the dependency tracking from the enqueuing
// for global dependencies.
- globalDependencies = new GlobalDependencyRegistry(this);
+ globalDependencies = new GlobalDependencyRegistry();
if (makeBackend != null) {
backend = makeBackend(this);
@@ -302,6 +302,20 @@
tasks.addAll(backend.tasks);
}
+ /// The world currently being computed by resolution. This forms a basis for
+ /// the [inferenceWorld] and later the [closedWorld].
+ OpenWorld get openWorld => _world;
+
+ /// The closed world after resolution but currently refined by inference.
+ ClosedWorldRefiner get inferenceWorld => _world;
+
+ /// The closed world after resolution and inference.
+ ClosedWorld get closedWorld {
+ assert(invariant(CURRENT_ELEMENT_SPANNABLE, _world.isClosed,
+ message: "Closed world not computed yet."));
+ return _world;
+ }
+
/// Creates the scanner task.
///
/// Override this to mock the scanner for testing.
@@ -314,11 +328,13 @@
/// Override this to mock the resolver for testing.
ResolverTask createResolverTask() {
return new ResolverTask(
- resolution, backend.constantCompilerTask, world, measurer);
+ resolution, backend.constantCompilerTask, openWorld, measurer);
}
- Universe get resolverWorld => enqueuer.resolution.universe;
- Universe get codegenWorld => enqueuer.codegen.universe;
+ // TODO(johnniwinther): Rename these appropriately when unification of worlds/
+ // universes is complete.
+ ResolutionUniverse get resolverWorld => enqueuer.resolution.universe;
+ CodegenUniverse get codegenWorld => enqueuer.codegen.universe;
bool get analyzeAll => options.analyzeAll || compileAll;
@@ -709,7 +725,7 @@
assert(mainFunction != null);
phase = PHASE_DONE_RESOLVING;
- world.populate();
+ openWorld.closeWorld();
// Compute whole-program-knowledge that the backend needs. (This might
// require the information computed in [world.populate].)
backend.onResolutionComplete();
@@ -1982,7 +1998,7 @@
@override
void registerClass(ClassElement cls) {
- compiler.world.registerClass(cls);
+ compiler.openWorld.registerClass(cls);
}
@override
@@ -2180,16 +2196,10 @@
}
}
-class GlobalDependencyRegistry extends EagerRegistry {
- final Compiler compiler;
+class GlobalDependencyRegistry extends Registry {
Setlet<Element> _otherDependencies;
- GlobalDependencyRegistry(this.compiler) : super('GlobalDependencies', null);
-
- // TODO(johnniwinther): Rename world/universe/enqueuer through out the
- // compiler.
- @override
- Enqueuer get world => compiler.enqueuer.codegen;
+ GlobalDependencyRegistry();
void registerDependency(Element element) {
if (element == null) return;
@@ -2202,6 +2212,8 @@
Iterable<Element> get otherDependencies {
return _otherDependencies != null ? _otherDependencies : const <Element>[];
}
+
+ String get name => 'GlobalDependencies';
}
class _ScriptLoader implements ScriptLoader {
diff --git a/pkg/compiler/lib/src/dump_info.dart b/pkg/compiler/lib/src/dump_info.dart
index 2afb849..de65277 100644
--- a/pkg/compiler/lib/src/dump_info.dart
+++ b/pkg/compiler/lib/src/dump_info.dart
@@ -265,12 +265,13 @@
// TODO(sigmund): why all these checks?
if (element.isInstanceMember &&
!element.isAbstract &&
- compiler.world.allFunctions.contains(element)) {
+ compiler.closedWorld.allFunctions.contains(element)) {
returnType = '${element.type.returnType}';
}
String inferredReturnType =
'${compiler.globalInference.results.returnTypeOf(element)}';
- String sideEffects = '${compiler.world.getSideEffectsOfElement(element)}';
+ String sideEffects =
+ '${compiler.closedWorld.getSideEffectsOfElement(element)}';
int inlinedCount = compiler.dumpInfoTask.inlineCount[element];
if (inlinedCount == null) inlinedCount = 0;
@@ -438,7 +439,7 @@
element,
impact,
new WorldImpactVisitorImpl(visitDynamicUse: (dynamicUse) {
- selections.addAll(compiler.world.allFunctions
+ selections.addAll(compiler.closedWorld.allFunctions
.filter(dynamicUse.selector, dynamicUse.mask)
.map((e) => new Selection(e, dynamicUse.mask)));
}, visitStaticUse: (staticUse) {
diff --git a/pkg/compiler/lib/src/elements/elements.dart b/pkg/compiler/lib/src/elements/elements.dart
index 814e1fb..29e2396 100644
--- a/pkg/compiler/lib/src/elements/elements.dart
+++ b/pkg/compiler/lib/src/elements/elements.dart
@@ -801,9 +801,9 @@
ClassElement cls = constructor.enclosingClass;
return cls.library == compiler.commonElements.typedDataLibrary &&
compiler.backend.isNative(cls) &&
- compiler.world
+ compiler.closedWorld
.isSubtypeOf(cls, compiler.commonElements.typedDataClass) &&
- compiler.world.isSubtypeOf(cls, compiler.coreClasses.listClass) &&
+ compiler.closedWorld.isSubtypeOf(cls, compiler.coreClasses.listClass) &&
constructor.name == '';
}
@@ -1378,6 +1378,9 @@
/// is `C.c`.
ConstructorElement get definingConstructor;
+ /// Returns `true` if this constructor is an implicit default constructor.
+ bool get isDefaultConstructor;
+
/// The constant constructor defining the binding of fields if `const`,
/// `null` otherwise.
ConstantConstructor get constantConstructor;
diff --git a/pkg/compiler/lib/src/elements/modelx.dart b/pkg/compiler/lib/src/elements/modelx.dart
index 4eb76bb..691e6d7 100644
--- a/pkg/compiler/lib/src/elements/modelx.dart
+++ b/pkg/compiler/lib/src/elements/modelx.dart
@@ -224,6 +224,8 @@
bool get isCyclicRedirection => false;
+ bool get isDefaultConstructor => false;
+
bool get isMalformed => true;
PrefixElement get redirectionDeferredPrefix => null;
@@ -2237,6 +2239,8 @@
// generative constructors.
bool get isCyclicRedirection => effectiveTarget.isRedirectingFactory;
+ bool get isDefaultConstructor => false;
+
/// These fields are set by the post process queue when checking for cycles.
ConstructorElement effectiveTargetInternal;
DartType _effectiveTargetType;
diff --git a/pkg/compiler/lib/src/enqueue.dart b/pkg/compiler/lib/src/enqueue.dart
index 24c8771..c29912a 100644
--- a/pkg/compiler/lib/src/enqueue.dart
+++ b/pkg/compiler/lib/src/enqueue.dart
@@ -131,7 +131,8 @@
new Map<String, Set<Element>>();
final Set<ClassElement> _processedClasses = new Set<ClassElement>();
Set<ClassElement> recentClasses = new Setlet<ClassElement>();
- final Universe universe = new Universe(const TypeMaskStrategy());
+ final ResolutionUniverseImpl _universe =
+ new ResolutionUniverseImpl(const TypeMaskStrategy());
static final TRACE_MIRROR_ENQUEUING =
const bool.fromEnvironment("TRACE_MIRROR_ENQUEUING");
@@ -155,6 +156,8 @@
// TODO(johnniwinther): Move this to [ResolutionEnqueuer].
Resolution get resolution => compiler.resolution;
+ ResolutionUniverse get universe => _universe;
+
bool get queueIsEmpty => queue.isEmpty;
QueueFilter get filter => compiler.enqueuerFilter;
@@ -191,7 +194,7 @@
ClassElement cls = type.element;
cls.ensureResolved(resolution);
bool isNative = compiler.backend.isNative(cls);
- universe.registerTypeInstantiation(type,
+ _universe.registerTypeInstantiation(type,
isNative: isNative,
byMirrors: mirrorUsage, onImplemented: (ClassElement cls) {
compiler.backend
@@ -227,13 +230,13 @@
// Note: this assumes that there are no non-native fields on native
// classes, which may not be the case when a native class is subclassed.
if (compiler.backend.isNative(cls)) {
- compiler.world.registerUsedElement(member);
- if (universe.hasInvokedGetter(member, compiler.world) ||
- universe.hasInvocation(member, compiler.world)) {
+ compiler.openWorld.registerUsedElement(member);
+ if (_universe.hasInvokedGetter(member, compiler.openWorld) ||
+ _universe.hasInvocation(member, compiler.openWorld)) {
addToWorkList(member);
return;
}
- if (universe.hasInvokedSetter(member, compiler.world)) {
+ if (_universe.hasInvokedSetter(member, compiler.openWorld)) {
addToWorkList(member);
return;
}
@@ -257,7 +260,7 @@
}
// If there is a property access with the same name as a method we
// need to emit the method.
- if (universe.hasInvokedGetter(function, compiler.world)) {
+ if (_universe.hasInvokedGetter(function, compiler.openWorld)) {
registerClosurizedMember(function);
addToWorkList(function);
return;
@@ -267,27 +270,27 @@
instanceFunctionsByName
.putIfAbsent(memberName, () => new Set<Element>())
.add(member);
- if (universe.hasInvocation(function, compiler.world)) {
+ if (_universe.hasInvocation(function, compiler.openWorld)) {
addToWorkList(function);
return;
}
} else if (member.isGetter) {
FunctionElement getter = member;
getter.computeType(resolution);
- if (universe.hasInvokedGetter(getter, compiler.world)) {
+ if (_universe.hasInvokedGetter(getter, compiler.openWorld)) {
addToWorkList(getter);
return;
}
// We don't know what selectors the returned closure accepts. If
// the set contains any selector we have to assume that it matches.
- if (universe.hasInvocation(getter, compiler.world)) {
+ if (_universe.hasInvocation(getter, compiler.openWorld)) {
addToWorkList(getter);
return;
}
} else if (member.isSetter) {
FunctionElement setter = member;
setter.computeType(resolution);
- if (universe.hasInvokedSetter(setter, compiler.world)) {
+ if (_universe.hasInvokedSetter(setter, compiler.openWorld)) {
addToWorkList(setter);
return;
}
@@ -334,7 +337,7 @@
void registerDynamicUse(DynamicUse dynamicUse) {
task.measure(() {
- if (universe.registerDynamicUse(dynamicUse)) {
+ if (_universe.registerDynamicUse(dynamicUse)) {
handleUnseenSelector(dynamicUse);
}
});
@@ -537,7 +540,7 @@
Selector selector = dynamicUse.selector;
String methodName = selector.name;
processInstanceMembers(methodName, (Element member) {
- if (dynamicUse.appliesUnnamed(member, compiler.world)) {
+ if (dynamicUse.appliesUnnamed(member, compiler.openWorld)) {
if (member.isFunction && selector.isGetter) {
registerClosurizedMember(member);
}
@@ -548,7 +551,7 @@
});
if (selector.isGetter) {
processInstanceFunctions(methodName, (Element member) {
- if (dynamicUse.appliesUnnamed(member, compiler.world)) {
+ if (dynamicUse.appliesUnnamed(member, compiler.openWorld)) {
registerClosurizedMember(member);
return true;
}
@@ -570,7 +573,7 @@
Element element = staticUse.element;
assert(invariant(element, element.isDeclaration,
message: "Element ${element} is not the declaration."));
- universe.registerStaticUse(staticUse);
+ _universe.registerStaticUse(staticUse);
compiler.backend.registerStaticUse(element, this);
bool addElement = true;
switch (staticUse.kind) {
@@ -619,7 +622,7 @@
}
void _registerIsCheck(DartType type) {
- type = universe.registerIsCheck(type, compiler);
+ type = _universe.registerIsCheck(type, compiler);
// 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.
@@ -629,7 +632,7 @@
void registerCallMethodWithFreeTypeVariables(Element element) {
compiler.backend.registerCallMethodWithFreeTypeVariables(
element, this, compiler.globalDependencies);
- universe.callMethodsWithFreeTypeVariables.add(element);
+ _universe.callMethodsWithFreeTypeVariables.add(element);
}
void registerClosurizedMember(TypedElement element) {
@@ -637,9 +640,10 @@
if (element.computeType(resolution).containsTypeVariables) {
compiler.backend.registerClosureWithFreeTypeVariables(
element, this, compiler.globalDependencies);
+ _universe.closuresWithFreeTypeVariables.add(element);
}
compiler.backend.registerBoundClosure(this);
- universe.closurizedMembers.add(element);
+ _universe.closurizedMembers.add(element);
}
void forEach(void f(WorkItem work)) {
@@ -722,7 +726,7 @@
element, "Resolution work list is closed. Trying to add $element.");
}
- compiler.world.registerUsedElement(element);
+ compiler.openWorld.registerUsedElement(element);
ResolutionWorkItem workItem = compiler.resolution.createWorkItem(element);
queue.add(workItem);
@@ -809,7 +813,7 @@
}
void forgetElement(Element element) {
- universe.forgetElement(element, compiler);
+ _universe.forgetElement(element, compiler);
_processedClasses.remove(element);
instanceMembersByName[element.name]?.remove(element);
instanceFunctionsByName[element.name]?.remove(element);
diff --git a/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart b/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
index 2e554e5..bff02bd 100644
--- a/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
+++ b/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
@@ -21,7 +21,7 @@
import '../universe/call_structure.dart' show CallStructure;
import '../universe/selector.dart' show Selector;
import '../util/util.dart';
-import '../world.dart' show ClassWorld;
+import '../world.dart' show ClosedWorld;
/**
* The interface [InferrerVisitor] will use when working on types.
@@ -950,8 +950,8 @@
T get thisType {
if (_thisType != null) return _thisType;
ClassElement cls = outermostElement.enclosingClass;
- ClassWorld classWorld = compiler.world;
- if (classWorld.isUsedAsMixin(cls)) {
+ ClosedWorld closedWorld = compiler.closedWorld;
+ if (closedWorld.isUsedAsMixin(cls)) {
return _thisType = types.nonNullSubtype(cls);
} else {
return _thisType = types.nonNullSubclass(cls);
diff --git a/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart b/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
index 0a6c628..effe4fb 100644
--- a/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
+++ b/pkg/compiler/lib/src/inferrer/simple_types_inferrer.dart
@@ -22,7 +22,7 @@
import '../universe/selector.dart' show Selector;
import '../universe/side_effects.dart' show SideEffects;
import '../util/util.dart' show Link, Setlet;
-import '../world.dart' show ClassWorld;
+import '../world.dart' show ClosedWorld;
import 'inferrer_visitor.dart';
/**
@@ -33,14 +33,14 @@
abstract class InferrerEngine<T, V extends TypeSystem>
implements MinimalInferrerEngine<T> {
final Compiler compiler;
- final ClassWorld classWorld;
+ final ClosedWorld closedWorld;
final V types;
final Map<ast.Node, T> concreteTypes = new Map<ast.Node, T>();
final Set<Element> generativeConstructorsExposingThis = new Set<Element>();
InferrerEngine(Compiler compiler, this.types)
: this.compiler = compiler,
- this.classWorld = compiler.world;
+ this.closedWorld = compiler.closedWorld;
CoreClasses get coreClasses => compiler.coreClasses;
@@ -174,7 +174,7 @@
void forEachElementMatching(
Selector selector, TypeMask mask, bool f(Element element)) {
Iterable<Element> elements =
- compiler.world.allFunctions.filter(selector, mask);
+ compiler.closedWorld.allFunctions.filter(selector, mask);
for (Element e in elements) {
if (!f(e.implementation)) return;
}
@@ -210,7 +210,8 @@
sideEffects.setAllSideEffects();
sideEffects.setDependsOnSomething();
} else {
- sideEffects.add(compiler.world.getSideEffectsOfElement(callee));
+ sideEffects
+ .add(compiler.inferenceWorld.getCurrentlyKnownSideEffects(callee));
}
}
@@ -480,9 +481,9 @@
});
}
if (analyzedElement.isGenerativeConstructor && cls.isAbstract) {
- if (compiler.world.isDirectlyInstantiated(cls)) {
+ if (compiler.closedWorld.isDirectlyInstantiated(cls)) {
returnType = types.nonNullExact(cls);
- } else if (compiler.world.isIndirectlyInstantiated(cls)) {
+ } else if (compiler.closedWorld.isIndirectlyInstantiated(cls)) {
returnType = types.nonNullSubclass(cls);
} else {
// TODO(johnniwinther): Avoid analyzing [analyzedElement] in this
@@ -531,7 +532,7 @@
}
}
- compiler.world.registerSideEffects(analyzedElement, sideEffects);
+ compiler.inferenceWorld.registerSideEffects(analyzedElement, sideEffects);
assert(breaksFor.isEmpty);
assert(continuesFor.isEmpty);
return returnType;
@@ -645,7 +646,7 @@
bool isInClassOrSubclass(Element element) {
ClassElement cls = outermostElement.enclosingClass.declaration;
ClassElement enclosing = element.enclosingClass.declaration;
- return compiler.world.isSubclassOf(enclosing, cls);
+ return compiler.closedWorld.isSubclassOf(enclosing, cls);
}
void checkIfExposesThis(Selector selector, TypeMask mask) {
@@ -1070,7 +1071,7 @@
(node.asSendSet() != null) &&
(node.asSendSet().receiver != null) &&
node.asSendSet().receiver.isThis()) {
- Iterable<Element> targets = compiler.world.allFunctions.filter(
+ Iterable<Element> targets = compiler.closedWorld.allFunctions.filter(
setterSelector, types.newTypedSelector(thisType, setterMask));
// We just recognized a field initialization of the form:
// `this.foo = 42`. If there is only one target, we can update
@@ -1297,7 +1298,7 @@
} else if (element != null &&
element.isField &&
Elements.isStaticOrTopLevelField(element) &&
- compiler.world.fieldNeverChanges(element)) {
+ compiler.closedWorld.fieldNeverChanges(element)) {
FieldElement fieldElement = element;
ConstantValue value =
compiler.backend.constants.getConstantValue(fieldElement.constant);
@@ -1351,8 +1352,9 @@
// In erroneous code the number of arguments in the selector might not
// match the function element.
// TODO(polux): return nonNullEmpty and check it doesn't break anything
- if (!selector.applies(target, compiler.world) ||
- (mask != null && !mask.canHit(target, selector, compiler.world))) {
+ if (!selector.applies(target, compiler.backend) ||
+ (mask != null &&
+ !mask.canHit(target, selector, compiler.closedWorld))) {
return types.dynamicType;
}
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
index 42c6913..67f2aa0 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
@@ -25,7 +25,7 @@
import '../universe/selector.dart' show Selector;
import '../universe/side_effects.dart' show SideEffects;
import '../util/util.dart' show Setlet;
-import '../world.dart' show ClassWorld;
+import '../world.dart' show ClosedWorld;
import 'closure_tracer.dart';
import 'debug.dart' as debug;
import 'inferrer_visitor.dart' show ArgumentsTypes, TypeSystem;
@@ -37,7 +37,7 @@
class TypeInformationSystem extends TypeSystem<TypeInformation> {
final Compiler compiler;
- final ClassWorld classWorld;
+ final ClosedWorld closedWorld;
final CommonMasks commonMasks;
/// [ElementTypeInformation]s for elements.
@@ -74,7 +74,7 @@
TypeInformationSystem(Compiler compiler, this.commonMasks)
: this.compiler = compiler,
- this.classWorld = compiler.world {
+ this.closedWorld = compiler.closedWorld {
nonNullEmptyType = getConcreteTypeFor(const TypeMask.nonNullEmpty());
}
@@ -242,7 +242,7 @@
return dynamicType;
}
return getConcreteTypeFor(
- firstType.type.union(secondType.type, classWorld));
+ firstType.type.union(secondType.type, closedWorld));
}
bool selectorNeedsUpdate(TypeInformation info, TypeMask mask) {
@@ -253,7 +253,7 @@
TypeInformation receiver, bool isConditional) {
if (receiver.type.isExact) return receiver;
TypeMask otherType =
- compiler.world.allFunctions.receiverType(selector, mask);
+ compiler.closedWorld.allFunctions.receiverType(selector, mask);
// Conditional sends (a?.b) can still narrow the possible types of `a`,
// however, we still need to consider that `a` may be null.
if (isConditional) {
@@ -263,10 +263,10 @@
}
// If this is refining to nullable subtype of `Object` just return
// the receiver. We know the narrowing is useless.
- if (otherType.isNullable && otherType.containsAll(classWorld)) {
+ if (otherType.isNullable && otherType.containsAll(closedWorld)) {
return receiver;
}
- assert(TypeMask.assertIsNormalized(otherType, classWorld));
+ assert(TypeMask.assertIsNormalized(otherType, closedWorld));
TypeInformation newType = new NarrowTypeInformation(receiver, otherType);
allocatedTypes.add(newType);
return newType;
@@ -276,7 +276,10 @@
{bool isNullable: true}) {
if (annotation.treatAsDynamic) return type;
if (annotation.isVoid) return nullType;
- if (annotation.element == classWorld.objectClass && isNullable) return type;
+ if (annotation.element == closedWorld.coreClasses.objectClass &&
+ isNullable) {
+ return type;
+ }
TypeMask otherType;
if (annotation.isTypedef || annotation.isFunctionType) {
otherType = functionType.type;
@@ -285,15 +288,15 @@
return type;
} else {
assert(annotation.isInterfaceType);
- otherType = annotation.element == classWorld.objectClass
+ otherType = annotation.element == closedWorld.coreClasses.objectClass
? dynamicType.type.nonNullable()
- : new TypeMask.nonNullSubtype(annotation.element, classWorld);
+ : new TypeMask.nonNullSubtype(annotation.element, closedWorld);
}
if (isNullable) otherType = otherType.nullable();
if (type.type.isExact) {
return type;
} else {
- assert(TypeMask.assertIsNormalized(otherType, classWorld));
+ assert(TypeMask.assertIsNormalized(otherType, closedWorld));
TypeInformation newType = new NarrowTypeInformation(type, otherType);
allocatedTypes.add(newType);
return newType;
@@ -339,17 +342,17 @@
TypeInformation nonNullSubtype(ClassElement type) {
return getConcreteTypeFor(
- new TypeMask.nonNullSubtype(type.declaration, classWorld));
+ new TypeMask.nonNullSubtype(type.declaration, closedWorld));
}
TypeInformation nonNullSubclass(ClassElement type) {
return getConcreteTypeFor(
- new TypeMask.nonNullSubclass(type.declaration, classWorld));
+ new TypeMask.nonNullSubclass(type.declaration, closedWorld));
}
TypeInformation nonNullExact(ClassElement type) {
return getConcreteTypeFor(
- new TypeMask.nonNullExact(type.declaration, classWorld));
+ new TypeMask.nonNullExact(type.declaration, closedWorld));
}
TypeInformation nonNullEmpty() {
@@ -365,8 +368,8 @@
[TypeInformation elementType, int length]) {
ClassElement typedDataClass = compiler.commonElements.typedDataClass;
bool isTypedArray = typedDataClass != null &&
- classWorld.isInstantiated(typedDataClass) &&
- type.type.satisfies(typedDataClass, classWorld);
+ closedWorld.isInstantiated(typedDataClass) &&
+ type.type.satisfies(typedDataClass, closedWorld);
bool isConst = (type.type == commonMasks.constListType);
bool isFixed =
(type.type == commonMasks.fixedListType) || isConst || isTypedArray;
@@ -402,9 +405,9 @@
TypeMask keyType, valueType;
if (isFixed) {
keyType = keyTypes.fold(nonNullEmptyType.type,
- (type, info) => type.union(info.type, classWorld));
+ (type, info) => type.union(info.type, closedWorld));
valueType = valueTypes.fold(nonNullEmptyType.type,
- (type, info) => type.union(info.type, classWorld));
+ (type, info) => type.union(info.type, closedWorld));
} else {
keyType = valueType = dynamicType.type;
}
@@ -507,15 +510,15 @@
// work the result will be `dynamic`.
// TODO(sigmund): change to `mask == dynamicType` so we can continue to
// track the non-nullable bit.
- if (mask.containsAll(classWorld)) return dynamicType;
+ if (mask.containsAll(closedWorld)) return dynamicType;
list.add(mask);
}
TypeMask newType = null;
for (TypeMask mask in list) {
- newType = newType == null ? mask : newType.union(mask, classWorld);
+ newType = newType == null ? mask : newType.union(mask, closedWorld);
// Likewise - stop early if we already reach dynamic.
- if (newType.containsAll(classWorld)) return dynamicType;
+ if (newType.containsAll(closedWorld)) return dynamicType;
}
return newType ?? const TypeMask.nonNullEmpty();
@@ -701,7 +704,7 @@
tracer.run();
if (!tracer.continueAnalyzing) {
elements.forEach((FunctionElement e) {
- compiler.world.registerMightBePassedToApply(e);
+ compiler.inferenceWorld.registerMightBePassedToApply(e);
if (debug.VERBOSE) print("traced closure $e as ${true} (bail)");
e.functionSignature.forEachParameter((parameter) {
types
@@ -721,12 +724,12 @@
workQueue.add(info);
});
if (tracer.tracedType.mightBePassedToFunctionApply) {
- compiler.world.registerMightBePassedToApply(e);
+ compiler.inferenceWorld.registerMightBePassedToApply(e);
}
- ;
if (debug.VERBOSE) {
print("traced closure $e as "
- "${compiler.world.getMightBePassedToApply(e)}");
+ "${compiler.inferenceWorld
+ .getCurrentlyKnownMightBePassedToApply(e)}");
}
});
}
@@ -864,7 +867,7 @@
// the old type around to ensure that we get a complete view
// of the type graph and do not drop any flow edges.
TypeMask refinedType = computeTypeMask(compiler, value);
- assert(TypeMask.assertIsNormalized(refinedType, classWorld));
+ assert(TypeMask.assertIsNormalized(refinedType, closedWorld));
type = new NarrowTypeInformation(type, refinedType);
types.allocatedTypes.add(type);
}
@@ -912,13 +915,14 @@
allocatedCalls.forEach((info) {
if (!info.inLoop) return;
if (info is StaticCallSiteTypeInformation) {
- compiler.world.addFunctionCalledInLoop(info.calledElement);
- } else if (info.mask != null && !info.mask.containsAll(compiler.world)) {
+ compiler.inferenceWorld.addFunctionCalledInLoop(info.calledElement);
+ } else if (info.mask != null &&
+ !info.mask.containsAll(compiler.closedWorld)) {
// For instance methods, we only register a selector called in a
// loop if it is a typed selector, to avoid marking too many
// methods as being called from within a loop. This cuts down
// on the code bloat.
- info.targets.forEach(compiler.world.addFunctionCalledInLoop);
+ info.targets.forEach(compiler.inferenceWorld.addFunctionCalledInLoop);
}
});
}
@@ -1185,7 +1189,7 @@
arguments, sideEffects, inLoop);
}
- compiler.world.allFunctions.filter(selector, mask).forEach((callee) {
+ compiler.closedWorld.allFunctions.filter(selector, mask).forEach((callee) {
updateSideEffects(sideEffects, selector, callee);
});
@@ -1413,11 +1417,11 @@
TypeMask result = const TypeMask.nonNullEmpty();
Iterable<Element> elements =
- compiler.world.allFunctions.filter(selector, mask);
+ compiler.closedWorld.allFunctions.filter(selector, mask);
for (Element element in elements) {
TypeMask type =
inferrer.typeOfElementWithSelector(element, selector).type;
- result = result.union(type, compiler.world);
+ result = result.union(type, compiler.closedWorld);
}
return result;
}
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
index feaed3e..98e12be 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
@@ -639,7 +639,8 @@
giveUp(inferrer);
return safeType(inferrer);
}
- if (inferrer.compiler.world.getMightBePassedToApply(declaration)) {
+ if (inferrer.compiler.inferenceWorld
+ .getCurrentlyKnownMightBePassedToApply(declaration)) {
giveUp(inferrer);
return safeType(inferrer);
}
@@ -816,7 +817,8 @@
void addToGraph(TypeGraphInferrerEngine inferrer) {
assert(receiver != null);
TypeMask typeMask = computeTypedSelector(inferrer);
- targets = inferrer.compiler.world.allFunctions.filter(selector, typeMask);
+ targets =
+ inferrer.compiler.closedWorld.allFunctions.filter(selector, typeMask);
receiver.addUser(this);
if (arguments != null) {
arguments.forEach((info) => info.addUser(this));
@@ -865,7 +867,7 @@
*/
TypeInformation handleIntrisifiedSelector(
Selector selector, TypeMask mask, TypeGraphInferrerEngine inferrer) {
- ClassWorld classWorld = inferrer.classWorld;
+ ClassWorld classWorld = inferrer.closedWorld;
if (!classWorld.backend.intImplementation.isResolved) return null;
if (mask == null) return null;
if (!mask.containsOnlyInt(classWorld)) {
@@ -968,16 +970,16 @@
Compiler compiler = inferrer.compiler;
TypeMask maskToUse =
- compiler.world.extendMaskIfReachesAll(selector, typeMask);
+ compiler.closedWorld.extendMaskIfReachesAll(selector, typeMask);
bool canReachAll = compiler.enabledInvokeOn && (maskToUse != typeMask);
// If this call could potentially reach all methods that satisfy
// the untyped selector (through noSuchMethod's `Invocation`
// and a call to `delegate`), we iterate over all these methods to
// update their parameter types.
- targets = compiler.world.allFunctions.filter(selector, maskToUse);
+ targets = compiler.closedWorld.allFunctions.filter(selector, maskToUse);
Iterable<Element> typedTargets = canReachAll
- ? compiler.world.allFunctions.filter(selector, typeMask)
+ ? compiler.closedWorld.allFunctions.filter(selector, typeMask)
: targets;
// Update the call graph if the targets could have changed.
@@ -1073,7 +1075,8 @@
if (!abandonInferencing) {
inferrer.updateSelectorInTree(caller, call, selector, mask);
Iterable<Element> oldTargets = targets;
- targets = inferrer.compiler.world.allFunctions.filter(selector, mask);
+ targets =
+ inferrer.compiler.closedWorld.allFunctions.filter(selector, mask);
for (Element element in targets) {
if (!oldTargets.contains(element)) {
MemberTypeInformation callee =
@@ -1274,10 +1277,10 @@
TypeMask computeType(TypeGraphInferrerEngine inferrer) {
TypeMask input = assignments.first.type;
TypeMask intersection =
- input.intersection(typeAnnotation, inferrer.classWorld);
+ input.intersection(typeAnnotation, inferrer.closedWorld);
if (debug.ANOMALY_WARN) {
- if (!input.containsMask(intersection, inferrer.classWorld) ||
- !typeAnnotation.containsMask(intersection, inferrer.classWorld)) {
+ if (!input.containsMask(intersection, inferrer.closedWorld) ||
+ !typeAnnotation.containsMask(intersection, inferrer.closedWorld)) {
print("ANOMALY WARNING: narrowed $input to $intersection via "
"$typeAnnotation");
}
@@ -1513,7 +1516,7 @@
for (var key in typeInfoMap.keys) {
TypeInformation value = typeInfoMap[key];
if (!mask.typeMap.containsKey(key) &&
- !value.type.containsAll(inferrer.classWorld) &&
+ !value.type.containsAll(inferrer.closedWorld) &&
!value.type.isNullable) {
return toTypeMask(inferrer);
}
@@ -1734,9 +1737,10 @@
otherType = compiler.commonMasks.nullType;
} else {
assert(annotation.isInterfaceType);
- otherType = new TypeMask.nonNullSubtype(annotation.element, compiler.world);
+ otherType =
+ new TypeMask.nonNullSubtype(annotation.element, compiler.closedWorld);
}
if (isNullable) otherType = otherType.nullable();
if (type == null) return otherType;
- return type.intersection(otherType, compiler.world);
+ return type.intersection(otherType, compiler.closedWorld);
}
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index f688ff7..acc0edc1 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -14,7 +14,7 @@
show Backend, ImpactTransformer, ForeignResolver, NativeRegistry;
import '../common/codegen.dart' show CodegenImpact, CodegenWorkItem;
import '../common/names.dart' show Identifiers, Selectors, Uris;
-import '../common/registry.dart' show EagerRegistry, Registry;
+import '../common/registry.dart' show Registry;
import '../common/resolution.dart' show Frontend, Resolution, ResolutionImpact;
import '../common/tasks.dart' show CompilerTask;
import '../compiler.dart' show Compiler;
@@ -54,9 +54,11 @@
ImpactUseCase,
TransformedWorldImpact,
WorldImpact,
- WorldImpactVisitor;
+ WorldImpactBuilder,
+ WorldImpactVisitor,
+ StagedWorldImpactBuilder;
import '../util/util.dart';
-import '../world.dart' show ClassWorld;
+import '../world.dart' show ClosedWorld;
import 'backend_helpers.dart';
import 'backend_impact.dart';
import 'backend_serialization.dart' show JavaScriptBackendSerialization;
@@ -345,8 +347,8 @@
TypeMask _indexablePrimitiveTypeCache;
TypeMask get indexablePrimitiveType {
if (_indexablePrimitiveTypeCache == null) {
- _indexablePrimitiveTypeCache =
- new TypeMask.nonNullSubtype(helpers.jsIndexableClass, compiler.world);
+ _indexablePrimitiveTypeCache = new TypeMask.nonNullSubtype(
+ helpers.jsIndexableClass, compiler.closedWorld);
}
return _indexablePrimitiveTypeCache;
}
@@ -354,8 +356,8 @@
TypeMask _readableArrayTypeCache;
TypeMask get readableArrayType {
if (_readableArrayTypeCache == null) {
- _readableArrayTypeCache =
- new TypeMask.nonNullSubclass(helpers.jsArrayClass, compiler.world);
+ _readableArrayTypeCache = new TypeMask.nonNullSubclass(
+ helpers.jsArrayClass, compiler.closedWorld);
}
return _readableArrayTypeCache;
}
@@ -364,7 +366,7 @@
TypeMask get mutableArrayType {
if (_mutableArrayTypeCache == null) {
_mutableArrayTypeCache = new TypeMask.nonNullSubclass(
- helpers.jsMutableArrayClass, compiler.world);
+ helpers.jsMutableArrayClass, compiler.closedWorld);
}
return _mutableArrayTypeCache;
}
@@ -372,8 +374,8 @@
TypeMask _fixedArrayTypeCache;
TypeMask get fixedArrayType {
if (_fixedArrayTypeCache == null) {
- _fixedArrayTypeCache =
- new TypeMask.nonNullExact(helpers.jsFixedArrayClass, compiler.world);
+ _fixedArrayTypeCache = new TypeMask.nonNullExact(
+ helpers.jsFixedArrayClass, compiler.closedWorld);
}
return _fixedArrayTypeCache;
}
@@ -382,7 +384,7 @@
TypeMask get extendableArrayType {
if (_extendableArrayTypeCache == null) {
_extendableArrayTypeCache = new TypeMask.nonNullExact(
- helpers.jsExtendableArrayClass, compiler.world);
+ helpers.jsExtendableArrayClass, compiler.closedWorld);
}
return _extendableArrayTypeCache;
}
@@ -391,7 +393,7 @@
TypeMask get unmodifiableArrayType {
if (_unmodifiableArrayTypeCache == null) {
_unmodifiableArrayTypeCache = new TypeMask.nonNullExact(
- helpers.jsUnmodifiableArrayClass, compiler.world);
+ helpers.jsUnmodifiableArrayClass, compiler.closedWorld);
}
return _fixedArrayTypeCache;
}
@@ -579,6 +581,12 @@
JavaScriptBackendSerialization serialization;
+ StagedWorldImpactBuilder constantImpactsForResolution =
+ new StagedWorldImpactBuilder();
+
+ StagedWorldImpactBuilder constantImpactsForCodegen =
+ new StagedWorldImpactBuilder();
+
final NativeData nativeData = new NativeData();
final BackendHelpers helpers;
@@ -917,8 +925,9 @@
if (elements == null) return false;
if (elements.isEmpty) return false;
return elements.any((element) {
- return selector.applies(element, compiler.world) &&
- (mask == null || mask.canHit(element, selector, compiler.world));
+ return selector.applies(element, this) &&
+ (mask == null ||
+ mask.canHit(element, selector, compiler.closedWorld));
});
}
@@ -974,11 +983,11 @@
}
Set<ClassElement> nativeSubclassesOfMixin(ClassElement mixin) {
- ClassWorld classWorld = compiler.world;
- Iterable<MixinApplicationElement> uses = classWorld.mixinUsesOf(mixin);
+ ClosedWorld closedWorld = compiler.closedWorld;
+ Iterable<MixinApplicationElement> uses = closedWorld.mixinUsesOf(mixin);
Set<ClassElement> result = null;
for (MixinApplicationElement use in uses) {
- classWorld.forEachStrictSubclassOf(use, (ClassElement subclass) {
+ closedWorld.forEachStrictSubclassOf(use, (ClassElement subclass) {
if (isNativeOrExtendsNative(subclass)) {
if (result == null) result = new Set<ClassElement>();
result.add(subclass);
@@ -1068,17 +1077,20 @@
}
}
- void registerCompileTimeConstant(ConstantValue constant, Registry registry) {
- registerCompileTimeConstantInternal(constant, registry);
+ void computeImpactForCompileTimeConstant(ConstantValue constant,
+ WorldImpactBuilder impactBuilder, bool isForResolution) {
+ computeImpactForCompileTimeConstantInternal(
+ constant, impactBuilder, isForResolution);
- if (!registry.isForResolution && lookupMapAnalysis.isLookupMap(constant)) {
+ if (!isForResolution && lookupMapAnalysis.isLookupMap(constant)) {
// Note: internally, this registration will temporarily remove the
// constant dependencies and add them later on-demand.
lookupMapAnalysis.registerLookupMapReference(constant);
}
for (ConstantValue dependency in constant.getDependencies()) {
- registerCompileTimeConstant(dependency, registry);
+ computeImpactForCompileTimeConstant(
+ dependency, impactBuilder, isForResolution);
}
}
@@ -1086,32 +1098,43 @@
constants.addCompileTimeConstantForEmission(constant);
}
- void registerCompileTimeConstantInternal(
- ConstantValue constant, Registry registry) {
+ void computeImpactForCompileTimeConstantInternal(ConstantValue constant,
+ WorldImpactBuilder impactBuilder, bool isForResolution) {
DartType type = constant.getType(compiler.coreTypes);
- registerInstantiatedConstantType(type, registry);
+ computeImpactForInstantiatedConstantType(type, impactBuilder);
if (constant.isFunction) {
FunctionConstantValue function = constant;
- registry.registerStaticUse(new StaticUse.staticTearOff(function.element));
+ impactBuilder
+ .registerStaticUse(new StaticUse.staticTearOff(function.element));
} else if (constant.isInterceptor) {
// An interceptor constant references the class's prototype chain.
InterceptorConstantValue interceptor = constant;
- registerInstantiatedConstantType(interceptor.dispatchedType, registry);
+ computeImpactForInstantiatedConstantType(
+ interceptor.dispatchedType, impactBuilder);
} else if (constant.isType) {
- enqueueInResolution(helpers.createRuntimeType, registry);
- registry.registerInstantiation(typeImplementation.rawType);
+ if (isForResolution) {
+ impactBuilder.registerStaticUse(new StaticUse.staticInvoke(
+ // TODO(johnniwinther): Find the right [CallStructure].
+ helpers.createRuntimeType,
+ null));
+ registerBackendUse(helpers.createRuntimeType);
+ }
+ impactBuilder.registerTypeUse(
+ new TypeUse.instantiation(typeImplementation.rawType));
}
lookupMapAnalysis.registerConstantKey(constant);
}
- void registerInstantiatedConstantType(DartType type, Registry registry) {
+ void computeImpactForInstantiatedConstantType(
+ DartType type, WorldImpactBuilder impactBuilder) {
DartType instantiatedType =
type.isFunctionType ? coreTypes.functionType : type;
if (type is InterfaceType) {
- registry.registerInstantiation(instantiatedType);
+ impactBuilder
+ .registerTypeUse(new TypeUse.instantiation(instantiatedType));
if (classNeedsRtiField(type.element)) {
- registry.registerStaticUse(new StaticUse.staticInvoke(
+ impactBuilder.registerStaticUse(new StaticUse.staticInvoke(
// TODO(johnniwinther): Find the right [CallStructure].
helpers.setRuntimeTypeInfo,
null));
@@ -1120,7 +1143,7 @@
// If we use a type literal in a constant, the compile time
// constant emitter will generate a call to the createRuntimeType
// helper so we register a use of that.
- registry.registerStaticUse(new StaticUse.staticInvoke(
+ impactBuilder.registerStaticUse(new StaticUse.staticInvoke(
// TODO(johnniwinther): Find the right [CallStructure].
helpers.createRuntimeType,
null));
@@ -1289,23 +1312,11 @@
void registerInstantiatedType(
InterfaceType type, Enqueuer enqueuer, Registry registry,
{bool mirrorUsage: false}) {
- lookupMapAnalysis.registerInstantiatedType(type, registry);
+ lookupMapAnalysis.registerInstantiatedType(type);
super.registerInstantiatedType(type, enqueuer, registry,
mirrorUsage: mirrorUsage);
}
- void registerUseInterceptor(Enqueuer enqueuer) {
- assert(!enqueuer.isResolutionQueue);
- if (!enqueuer.nativeEnqueuer.hasInstantiatedNativeClasses()) return;
- Registry registry = compiler.globalDependencies;
- enqueue(enqueuer, helpers.getNativeInterceptorMethod, registry);
- enqueueClass(enqueuer, helpers.jsJavaScriptObjectClass, registry);
- enqueueClass(enqueuer, helpers.jsPlainJavaScriptObjectClass, registry);
- enqueueClass(enqueuer, helpers.jsJavaScriptFunctionClass, registry);
- needToInitializeIsolateAffinityTag = true;
- needToInitializeDispatchProperty = true;
- }
-
void enqueueHelpers(ResolutionEnqueuer world, Registry registry) {
assert(helpers.interceptorsLibrary != null);
// TODO(ngeoffray): Not enqueuing those two classes currently make
@@ -1361,7 +1372,6 @@
if (enqueuer.isResolutionQueue || methodNeedsRti(closure)) {
registerComputeSignature(enqueuer, registry);
}
- super.registerClosureWithFreeTypeVariables(closure, enqueuer, registry);
}
void registerBoundClosure(Enqueuer enqueuer) {
@@ -1605,7 +1615,8 @@
if (constant != null) {
ConstantValue initialValue = constants.getConstantValue(constant);
if (initialValue != null) {
- registerCompileTimeConstant(initialValue, work.registry);
+ computeImpactForCompileTimeConstant(
+ initialValue, work.registry.worldImpact, false);
addCompileTimeConstantForEmission(initialValue);
// We don't need to generate code for static or top-level
// variables. For instance variables, we may need to generate
@@ -1883,7 +1894,7 @@
if (!type.isRaw) return false;
ClassElement classElement = type.element;
if (isInterceptorClass(classElement)) return false;
- return compiler.world.hasOnlySubclasses(classElement);
+ return compiler.closedWorld.hasOnlySubclasses(classElement);
}
bool isNullImplementation(ClassElement cls) {
@@ -2176,8 +2187,9 @@
}
});
// 4) all overriding members of subclasses/subtypes (should be resolved)
- if (compiler.world.hasAnyStrictSubtype(cls)) {
- compiler.world.forEachStrictSubtypeOf(cls, (ClassElement subcls) {
+ if (compiler.closedWorld.hasAnyStrictSubtype(cls)) {
+ compiler.closedWorld.forEachStrictSubtypeOf(cls,
+ (ClassElement subcls) {
subcls.forEachClassMember((Member member) {
if (memberNames.contains(member.name)) {
// TODO(20993): find out why this assertion fails.
@@ -2256,8 +2268,8 @@
reflectableMembers.add(helpers.boundClosureClass);
}
// Add typedefs.
- reflectableMembers
- .addAll(compiler.world.allTypedefs.where(referencedFromMirrorSystem));
+ reflectableMembers.addAll(
+ compiler.closedWorld.allTypedefs.where(referencedFromMirrorSystem));
// Register all symbols of reflectable elements
for (Element element in reflectableMembers) {
symbolsUsed.add(element.name);
@@ -2300,25 +2312,26 @@
// check for the interface [JavaScriptIndexingBehavior].
ClassElement typedDataClass = compiler.commonElements.typedDataClass;
return typedDataClass != null &&
- compiler.world.isInstantiated(typedDataClass) &&
- mask.satisfies(typedDataClass, compiler.world) &&
- mask.satisfies(helpers.jsIndexingBehaviorInterface, compiler.world);
+ compiler.closedWorld.isInstantiated(typedDataClass) &&
+ mask.satisfies(typedDataClass, compiler.closedWorld) &&
+ mask.satisfies(
+ helpers.jsIndexingBehaviorInterface, compiler.closedWorld);
}
bool couldBeTypedArray(TypeMask mask) {
bool intersects(TypeMask type1, TypeMask type2) =>
- !type1.intersection(type2, compiler.world).isEmpty;
+ !type1.intersection(type2, compiler.closedWorld).isEmpty;
// TODO(herhut): Maybe cache the TypeMask for typedDataClass and
// jsIndexingBehaviourInterface.
ClassElement typedDataClass = compiler.commonElements.typedDataClass;
return typedDataClass != null &&
- compiler.world.isInstantiated(typedDataClass) &&
+ compiler.closedWorld.isInstantiated(typedDataClass) &&
intersects(
- mask, new TypeMask.subtype(typedDataClass, compiler.world)) &&
+ mask, new TypeMask.subtype(typedDataClass, compiler.closedWorld)) &&
intersects(
mask,
new TypeMask.subtype(
- helpers.jsIndexingBehaviorInterface, compiler.world));
+ helpers.jsIndexingBehaviorInterface, compiler.closedWorld));
}
/// Returns all static fields that are referenced through [targetsUsed].
@@ -2350,15 +2363,15 @@
/// Called when [enqueuer] is empty, but before it is closed.
bool onQueueEmpty(Enqueuer enqueuer, Iterable<ClassElement> recentClasses) {
- if (!compiler.options.resolveOnly) {
- // TODO(johnniwinther): The custom element analysis eagerly enqueues
- // elements on the codegen queue. Change to compute the data needed
- // instead.
+ // Add elements used synthetically, that is, through features rather than
+ // syntax, for instance custom elements.
+ //
+ // 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);
- // Add elements referenced only via custom elements. Return early if any
- // elements are added to avoid counting the elements as due to mirrors.
- customElementsAnalysis.onQueueEmpty(enqueuer);
- }
if (!enqueuer.queueIsEmpty) return false;
noSuchMethodRegistry.onQueueEmpty();
@@ -2402,6 +2415,9 @@
compiler.libraryLoader.libraries.forEach(retainMetadataOf);
+ StagedWorldImpactBuilder impactBuilder = enqueuer.isResolutionQueue
+ ? constantImpactsForResolution
+ : constantImpactsForResolution;
if (enqueuer.isResolutionQueue && !enqueuer.queueIsClosed) {
/// Register the constant value of [metadata] as live in resolution.
void registerMetadataConstant(MetadataAnnotation metadata) {
@@ -2410,8 +2426,8 @@
Dependency dependency =
new Dependency(constant, metadata.annotatedElement);
metadataConstants.add(dependency);
- registerCompileTimeConstant(dependency.constant,
- new EagerRegistry('EagerRegistry for ${dependency}', enqueuer));
+ computeImpactForCompileTimeConstant(
+ dependency.constant, impactBuilder, enqueuer.isResolutionQueue);
}
// TODO(johnniwinther): We should have access to all recently processed
@@ -2420,11 +2436,12 @@
registerMetadataConstant);
} else {
for (Dependency dependency in metadataConstants) {
- registerCompileTimeConstant(dependency.constant,
- new EagerRegistry('EagerRegistry for ${dependency}', enqueuer));
+ computeImpactForCompileTimeConstant(
+ dependency.constant, impactBuilder, enqueuer.isResolutionQueue);
}
metadataConstants.clear();
}
+ enqueuer.applyImpact(null, impactBuilder.flush());
}
return true;
}
@@ -2524,14 +2541,14 @@
reporter.reportHintMessage(
element, MessageKind.GENERIC, {'text': "Cannot throw"});
}
- compiler.world.registerCannotThrow(element);
+ compiler.inferenceWorld.registerCannotThrow(element);
} else if (cls == helpers.noSideEffectsClass) {
hasNoSideEffects = true;
if (VERBOSE_OPTIMIZER_HINTS) {
reporter.reportHintMessage(
element, MessageKind.GENERIC, {'text': "Has no side effects"});
}
- compiler.world.registerSideEffectsFree(element);
+ compiler.inferenceWorld.registerSideEffectsFree(element);
}
}
if (hasForceInline && hasNoInline) {
@@ -2821,6 +2838,7 @@
registerBackendImpact(transformed, impacts.fallThroughError);
break;
case Feature.FIELD_WITHOUT_INITIALIZER:
+ case Feature.LOCAL_WITHOUT_INITIALIZER:
transformed.registerTypeUse(
new TypeUse.instantiation(backend.coreTypes.nullType));
registerBackendImpact(transformed, impacts.nullLiteral);
@@ -2890,7 +2908,7 @@
case TypeUseKind.TYPE_LITERAL:
backend.customElementsAnalysis.registerTypeLiteral(type);
if (type.isTypedef) {
- backend.compiler.world.allTypedefs.add(type.element);
+ backend.compiler.openWorld.registerTypedef(type.element);
}
if (type.isTypeVariable && type is! MethodTypeVariableType) {
// GENERIC_METHODS: The `is!` test above filters away method type
@@ -2996,6 +3014,10 @@
// TODO(johnniwinther): Store the correct use in impacts.
new StaticUse.foreignUse(staticUse));
}
+ for (Selector selector in backendImpact.dynamicUses) {
+ assert(selector != null);
+ worldImpact.registerDynamicUse(new DynamicUse(selector, null));
+ }
for (InterfaceType instantiatedType in backendImpact.instantiatedTypes) {
backend.registerBackendUse(instantiatedType.element);
worldImpact.registerTypeUse(new TypeUse.instantiation(instantiatedType));
@@ -3008,6 +3030,16 @@
for (BackendImpact otherImpact in backendImpact.otherImpacts) {
registerBackendImpact(worldImpact, otherImpact);
}
+ for (BackendFeature feature in backendImpact.features) {
+ switch (feature) {
+ case BackendFeature.needToInitializeDispatchProperty:
+ backend.needToInitializeDispatchProperty = true;
+ break;
+ case BackendFeature.needToInitializeIsolateAffinityTag:
+ backend.needToInitializeIsolateAffinityTag = true;
+ break;
+ }
+ }
}
/// Register [type] as required for the runtime type information system.
@@ -3099,14 +3131,12 @@
@override
WorldImpact transformCodegenImpact(CodegenImpact impact) {
TransformedWorldImpact transformed = new TransformedWorldImpact(impact);
- EagerRegistry registry = impact.registry;
- Enqueuer world = registry.world;
for (TypeUse typeUse in impact.typeUses) {
DartType type = typeUse.type;
switch (typeUse.kind) {
case TypeUseKind.INSTANTIATION:
- backend.lookupMapAnalysis.registerInstantiatedType(type, registry);
+ backend.lookupMapAnalysis.registerInstantiatedType(type);
break;
case TypeUseKind.IS_CHECK:
onIsCheckForCodegen(type, transformed);
@@ -3116,7 +3146,7 @@
}
for (ConstantValue constant in impact.compileTimeConstants) {
- backend.registerCompileTimeConstant(constant, registry);
+ backend.computeImpactForCompileTimeConstant(constant, transformed, false);
backend.addCompileTimeConstantForEmission(constant);
}
@@ -3143,7 +3173,9 @@
}
if (impact.usesInterceptor) {
- backend.registerUseInterceptor(world);
+ if (backend.codegenEnqueuer.nativeEnqueuer.hasInstantiatedNativeClasses) {
+ registerBackendImpact(transformed, impacts.interceptorUse);
+ }
}
for (ClassElement element in impact.typeConstants) {
@@ -3201,7 +3233,9 @@
impact.apply(visitor);
} else {
impact.apply(visitor);
- resolution.uncacheWorldImpact(element);
+ if (element != null) {
+ resolution.uncacheWorldImpact(element);
+ }
}
} else if (impactUse == DeferredLoadTask.IMPACT_USE) {
impact.apply(visitor);
diff --git a/pkg/compiler/lib/src/js_backend/backend_impact.dart b/pkg/compiler/lib/src/js_backend/backend_impact.dart
index 7fb1e9c..e933ae5 100644
--- a/pkg/compiler/lib/src/js_backend/backend_impact.dart
+++ b/pkg/compiler/lib/src/js_backend/backend_impact.dart
@@ -4,26 +4,43 @@
library dart2js.js_helpers.impact;
+import '../common/names.dart';
import '../compiler.dart' show Compiler;
import '../core_types.dart' show CommonElements;
import '../dart_types.dart' show InterfaceType;
import '../elements/elements.dart' show ClassElement, Element;
+import '../universe/selector.dart';
+import '../util/enumset.dart';
import 'backend_helpers.dart';
import 'constant_system_javascript.dart';
import 'js_backend.dart';
+/// Backend specific features required by a backend impact.
+enum BackendFeature {
+ needToInitializeIsolateAffinityTag,
+ needToInitializeDispatchProperty,
+}
+
/// A set of JavaScript backend dependencies.
class BackendImpact {
final List<Element> staticUses;
+ final List<Selector> dynamicUses;
final List<InterfaceType> instantiatedTypes;
final List<ClassElement> instantiatedClasses;
final List<BackendImpact> otherImpacts;
+ final EnumSet<BackendFeature> _features;
- BackendImpact(
+ const BackendImpact(
{this.staticUses: const <Element>[],
+ this.dynamicUses: const <Selector>[],
this.instantiatedTypes: const <InterfaceType>[],
this.instantiatedClasses: const <ClassElement>[],
- this.otherImpacts: const <BackendImpact>[]});
+ this.otherImpacts: const <BackendImpact>[],
+ EnumSet<BackendFeature> features: const EnumSet<BackendFeature>.fixed(0)})
+ : this._features = features;
+
+ Iterable<BackendFeature> get features =>
+ _features.iterable(BackendFeature.values);
}
/// The JavaScript backend dependencies for various features.
@@ -359,6 +376,7 @@
BackendImpact get stringInterpolation {
if (_stringInterpolation == null) {
_stringInterpolation = new BackendImpact(
+ dynamicUses: [Selectors.toString_],
staticUses: [helpers.stringInterpolationHelper],
otherImpacts: [_needsString('Strings are created.')]);
}
@@ -593,4 +611,25 @@
}
return _closure;
}
+
+ BackendImpact _interceptorUse;
+
+ BackendImpact get interceptorUse {
+ if (_interceptorUse == null) {
+ _interceptorUse = new BackendImpact(
+ staticUses: [
+ helpers.getNativeInterceptorMethod
+ ],
+ instantiatedClasses: [
+ helpers.jsJavaScriptObjectClass,
+ helpers.jsPlainJavaScriptObjectClass,
+ helpers.jsJavaScriptFunctionClass
+ ],
+ features: new EnumSet<BackendFeature>.fromValues([
+ BackendFeature.needToInitializeDispatchProperty,
+ BackendFeature.needToInitializeIsolateAffinityTag
+ ], fixed: true));
+ }
+ return _interceptorUse;
+ }
}
diff --git a/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart b/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart
index 2ab684e..0473fe6 100644
--- a/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart
@@ -274,14 +274,5 @@
void visitNode(Node node) {
node.visitChildren(this);
constants.nodeConstantMap.remove(node);
-
- // TODO(ahe): This doesn't belong here. Rename this class and generalize.
- var closureClassMap = constants
- .compiler.closureToClassMapper.closureMappingCache
- .remove(node);
- if (closureClassMap != null) {
- closureClassMap
- .removeMyselfFrom(constants.compiler.enqueuer.codegen.universe);
- }
}
}
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 11ff3c9..807bcb9 100644
--- a/pkg/compiler/lib/src/js_backend/custom_elements_analysis.dart
+++ b/pkg/compiler/lib/src/js_backend/custom_elements_analysis.dart
@@ -8,6 +8,8 @@
import '../elements/elements.dart';
import '../enqueue.dart' show Enqueuer;
import '../universe/use.dart' show StaticUse;
+import '../universe/world_impact.dart'
+ show WorldImpact, StagedWorldImpactBuilder;
import 'backend.dart';
/**
@@ -130,6 +132,8 @@
final JavaScriptBackend backend;
Compiler get compiler => backend.compiler;
+ final StagedWorldImpactBuilder impactBuilder = new StagedWorldImpactBuilder();
+
// Classes that are candidates for needing constructors. Classes are moved to
// [activeClasses] when we know they need constructors.
final instantiatedClasses = new Set<ClassElement>();
@@ -171,13 +175,14 @@
// Force the generaton of the type constant that is the key to an entry
// in the generated table.
ConstantValue constant = makeTypeConstant(classElement);
- backend.registerCompileTimeConstant(
- constant, compiler.globalDependencies);
+ backend.computeImpactForCompileTimeConstant(
+ constant, impactBuilder, false);
backend.addCompileTimeConstantForEmission(constant);
}
}
activeClasses.addAll(newActiveClasses);
instantiatedClasses.removeAll(newActiveClasses);
+ enqueuer.applyImpact(null, 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 29bec96..8ceca0b 100644
--- a/pkg/compiler/lib/src/js_backend/enqueuer.dart
+++ b/pkg/compiler/lib/src/js_backend/enqueuer.dart
@@ -54,7 +54,8 @@
new Map<String, Set<Element>>();
final Set<ClassElement> _processedClasses = new Set<ClassElement>();
Set<ClassElement> recentClasses = new Setlet<ClassElement>();
- final Universe universe = new Universe(const TypeMaskStrategy());
+ final CodegenUniverseImpl _universe =
+ new CodegenUniverseImpl(const TypeMaskStrategy());
static final TRACE_MIRROR_ENQUEUING =
const bool.fromEnvironment("TRACE_MIRROR_ENQUEUING");
@@ -77,6 +78,8 @@
impactVisitor = new _EnqueuerImpactVisitor(this);
}
+ CodegenUniverse get universe => _universe;
+
Backend get backend => _compiler.backend;
CompilerOptions get options => _compiler.options;
@@ -85,7 +88,7 @@
Registry get mirrorDependencies => _compiler.mirrorDependencies;
- ClassWorld get _world => _compiler.world;
+ ClassWorld get _world => _compiler.closedWorld;
bool get queueIsEmpty => queue.isEmpty;
@@ -141,7 +144,7 @@
task.measure(() {
ClassElement cls = type.element;
bool isNative = backend.isNative(cls);
- universe.registerTypeInstantiation(type,
+ _universe.registerTypeInstantiation(type,
isNative: isNative,
byMirrors: mirrorUsage, onImplemented: (ClassElement cls) {
backend.registerImplementedClass(cls, this, globalDependencies);
@@ -176,13 +179,11 @@
// Note: this assumes that there are no non-native fields on native
// classes, which may not be the case when a native class is subclassed.
if (backend.isNative(cls)) {
- _compiler.world.registerUsedElement(member);
- if (universe.hasInvokedGetter(member, _world) ||
- universe.hasInvocation(member, _world)) {
+ if (_universe.hasInvokedGetter(member, _world) ||
+ _universe.hasInvocation(member, _world)) {
addToWorkList(member);
return;
- }
- if (universe.hasInvokedSetter(member, _world)) {
+ } else if (universe.hasInvokedSetter(member, _world)) {
addToWorkList(member);
return;
}
@@ -205,7 +206,7 @@
}
// If there is a property access with the same name as a method we
// need to emit the method.
- if (universe.hasInvokedGetter(function, _world)) {
+ if (_universe.hasInvokedGetter(function, _world)) {
registerClosurizedMember(function);
addToWorkList(function);
return;
@@ -215,25 +216,25 @@
instanceFunctionsByName
.putIfAbsent(memberName, () => new Set<Element>())
.add(member);
- if (universe.hasInvocation(function, _world)) {
+ if (_universe.hasInvocation(function, _world)) {
addToWorkList(function);
return;
}
} else if (member.isGetter) {
FunctionElement getter = member;
- if (universe.hasInvokedGetter(getter, _world)) {
+ if (_universe.hasInvokedGetter(getter, _world)) {
addToWorkList(getter);
return;
}
// We don't know what selectors the returned closure accepts. If
// the set contains any selector we have to assume that it matches.
- if (universe.hasInvocation(getter, _world)) {
+ if (_universe.hasInvocation(getter, _world)) {
addToWorkList(getter);
return;
}
} else if (member.isSetter) {
FunctionElement setter = member;
- if (universe.hasInvokedSetter(setter, _world)) {
+ if (_universe.hasInvokedSetter(setter, _world)) {
addToWorkList(setter);
return;
}
@@ -282,7 +283,7 @@
void registerDynamicUse(DynamicUse dynamicUse) {
task.measure(() {
- if (universe.registerDynamicUse(dynamicUse)) {
+ if (_universe.registerDynamicUse(dynamicUse)) {
handleUnseenSelector(dynamicUse);
}
});
@@ -511,7 +512,7 @@
Element element = staticUse.element;
assert(invariant(element, element.isDeclaration,
message: "Element ${element} is not the declaration."));
- universe.registerStaticUse(staticUse);
+ _universe.registerStaticUse(staticUse);
backend.registerStaticUse(element, this);
bool addElement = true;
switch (staticUse.kind) {
@@ -560,7 +561,7 @@
}
void _registerIsCheck(DartType type) {
- type = universe.registerIsCheck(type, _compiler);
+ type = _universe.registerIsCheck(type, _compiler);
// 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.
@@ -570,7 +571,6 @@
void registerCallMethodWithFreeTypeVariables(Element element) {
backend.registerCallMethodWithFreeTypeVariables(
element, this, globalDependencies);
- universe.callMethodsWithFreeTypeVariables.add(element);
}
void registerClosurizedMember(TypedElement element) {
@@ -580,7 +580,6 @@
element, this, globalDependencies);
}
backend.registerBoundClosure(this);
- universe.closurizedMembers.add(element);
}
void forEach(void f(WorkItem work)) {
@@ -613,7 +612,7 @@
String toString() => 'Enqueuer($name)';
void _forgetElement(Element element) {
- universe.forgetElement(element, _compiler);
+ _universe.forgetElement(element, _compiler);
_processedClasses.remove(element);
instanceMembersByName[element.name]?.remove(element);
instanceFunctionsByName[element.name]?.remove(element);
diff --git a/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart b/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart
index 7ac77d5..b5e3c71 100644
--- a/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart
+++ b/pkg/compiler/lib/src/js_backend/field_naming_mixin.dart
@@ -24,8 +24,8 @@
names = new _FieldNamingScope.forBox(element.box, fieldRegistry);
} else {
ClassElement cls = element.enclosingClass;
- names =
- new _FieldNamingScope.forClass(cls, compiler.world, fieldRegistry);
+ names = new _FieldNamingScope.forClass(
+ cls, compiler.closedWorld, fieldRegistry);
}
if (names.containsField(element)) {
@@ -118,7 +118,7 @@
}
factory _FieldNamingScope.forClass(
- ClassElement cls, ClassWorld world, _FieldNamingRegistry registry) {
+ ClassElement cls, ClosedWorld world, _FieldNamingRegistry registry) {
_FieldNamingScope result = registry.scopes[cls];
if (result != null) return result;
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 74b10ab..380d196 100644
--- a/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart
+++ b/pkg/compiler/lib/src/js_backend/js_interop_analysis.dart
@@ -116,7 +116,7 @@
// Skip classes that are completely unreachable. This should only happen
// when all of jsinterop types are unreachable from main.
- if (!backend.compiler.world.isImplemented(classElement)) return;
+ if (!backend.compiler.resolverWorld.isImplemented(classElement)) return;
if (!classElement.implementsInterface(helpers.jsJavaScriptObjectClass)) {
backend.reporter.reportErrorMessage(classElement,
diff --git a/pkg/compiler/lib/src/js_backend/kernel_task.dart b/pkg/compiler/lib/src/js_backend/kernel_task.dart
index 0c59fa4..ea32143 100644
--- a/pkg/compiler/lib/src/js_backend/kernel_task.dart
+++ b/pkg/compiler/lib/src/js_backend/kernel_task.dart
@@ -4,6 +4,7 @@
import '../compiler.dart';
import '../kernel/kernel.dart';
+import 'package:kernel/ast.dart' as ir;
import 'backend.dart';
@@ -18,10 +19,14 @@
: this._compiler = backend.compiler,
this.kernel = new Kernel(backend.compiler);
+ ir.Program program;
+
/// Builds the kernel IR for the main function.
///
/// May enqueue more elements to the resolution queue.
void buildKernelIr() {
- kernel.libraryDependencies(_compiler.options.entryPoint);
+ program =
+ new ir.Program(kernel.libraryDependencies(_compiler.options.entryPoint))
+ ..mainMethod = kernel.functionToIr(_compiler.mainFunction);
}
}
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 2db7b35..2045c6c 100644
--- a/pkg/compiler/lib/src/js_backend/lookup_map_analysis.dart
+++ b/pkg/compiler/lib/src/js_backend/lookup_map_analysis.dart
@@ -22,6 +22,9 @@
import '../dart_types.dart' show InterfaceType;
import '../elements/elements.dart'
show ClassElement, FieldElement, LibraryElement, VariableElement;
+import '../enqueue.dart';
+import '../universe/world_impact.dart'
+ show WorldImpact, StagedWorldImpactBuilder;
import 'js_backend.dart' show JavaScriptBackend;
/// An analysis and optimization to remove unused entries from a `LookupMap`.
@@ -118,11 +121,18 @@
/// entry with that key.
final _pending = <ConstantValue, List<_LookupMapInfo>>{};
+ final StagedWorldImpactBuilder impactBuilder = new StagedWorldImpactBuilder();
+
/// Whether the backend is currently processing the codegen queue.
bool _inCodegen = false;
LookupMapAnalysis(this.backend, this.reporter);
+ void onQueueEmpty(Enqueuer enqueuer) {
+ if (enqueuer.isResolutionQueue) return;
+ enqueuer.applyImpact(null, impactBuilder.flush());
+ }
+
/// Whether this analysis and optimization is enabled.
bool get _isEnabled {
// `lookupMap==off` kept here to make it easy to test disabling this feature
@@ -248,17 +258,17 @@
}
/// Callback from the enqueuer, invoked when [type] is instantiated.
- void registerInstantiatedType(InterfaceType type, Registry registry) {
+ void registerInstantiatedType(InterfaceType type) {
if (!_isEnabled || !_inCodegen) return;
// TODO(sigmund): only add if .runtimeType is ever used
_addClassUse(type.element);
// TODO(sigmund): only do this when type-argument expressions are used?
- _addGenerics(type, registry);
+ _addGenerics(type);
}
/// Records generic type arguments in [type], in case they are retrieved and
/// returned using a type-argument expression.
- void _addGenerics(InterfaceType type, Registry registry) {
+ void _addGenerics(InterfaceType type) {
if (!type.isGeneric) return;
for (var arg in type.typeArguments) {
if (arg is InterfaceType) {
@@ -266,9 +276,9 @@
// Note: this call was needed to generate correct code for
// type_lookup_map/generic_type_test
// TODO(sigmund): can we get rid of this?
- backend.registerInstantiatedConstantType(
- backend.typeImplementation.rawType, registry);
- _addGenerics(arg, registry);
+ backend.computeImpactForInstantiatedConstantType(
+ backend.typeImplementation.rawType, impactBuilder);
+ _addGenerics(arg);
}
}
}
@@ -407,8 +417,8 @@
assert(!usedEntries.containsKey(key));
ConstantValue constant = unusedEntries.remove(key);
usedEntries[key] = constant;
- analysis.backend.registerCompileTimeConstant(
- constant, analysis.backend.compiler.globalDependencies);
+ analysis.backend.computeImpactForCompileTimeConstant(
+ constant, analysis.impactBuilder, false);
}
/// Restores [original] to contain all of the entries marked as possibly used.
diff --git a/pkg/compiler/lib/src/js_backend/namer.dart b/pkg/compiler/lib/src/js_backend/namer.dart
index 0d43e7b..8043861 100644
--- a/pkg/compiler/lib/src/js_backend/namer.dart
+++ b/pkg/compiler/lib/src/js_backend/namer.dart
@@ -24,7 +24,7 @@
import '../universe/selector.dart' show Selector, SelectorKind;
import '../util/characters.dart';
import '../util/util.dart';
-import '../world.dart' show ClassWorld;
+import '../world.dart' show ClosedWorld;
import 'backend.dart';
import 'backend_helpers.dart';
import 'constant_system_javascript.dart';
@@ -853,8 +853,8 @@
// mangle the field names of classes extending native classes.
// Methods on such classes are stored on the interceptor, not the instance,
// so only fields have the potential to clash with a native property name.
- ClassWorld classWorld = compiler.world;
- if (classWorld.isUsedAsMixin(enclosingClass) ||
+ ClosedWorld closedWorld = compiler.closedWorld;
+ if (closedWorld.isUsedAsMixin(enclosingClass) ||
_isShadowingSuperField(element) ||
_isUserClassExtendingNative(enclosingClass)) {
String proposeName() => '${enclosingClass.name}_${element.name}';
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types.dart b/pkg/compiler/lib/src/js_backend/runtime_types.dart
index 21e3e76..f465f76 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types.dart
@@ -227,7 +227,7 @@
classesNeedingRti.add(cls);
// TODO(ngeoffray): This should use subclasses, not subtypes.
- compiler.world.forEachStrictSubtypeOf(cls, (ClassElement sub) {
+ compiler.closedWorld.forEachStrictSubtypeOf(cls, (ClassElement sub) {
potentiallyAddForRti(sub);
});
@@ -364,7 +364,7 @@
computeChecks(allInstantiatedArguments, checkedArguments);
}
- Set<DartType> computeInstantiatedTypesAndClosures(Universe universe) {
+ Set<DartType> computeInstantiatedTypesAndClosures(CodegenUniverse 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 ada9d16..d7c3281 100644
--- a/pkg/compiler/lib/src/js_backend/type_variable_handler.dart
+++ b/pkg/compiler/lib/src/js_backend/type_variable_handler.dart
@@ -15,6 +15,7 @@
show CodeEmitterTask, MetadataCollector, Placeholder;
import '../universe/call_structure.dart' show CallStructure;
import '../universe/use.dart' show StaticUse;
+import '../universe/world_impact.dart';
import '../util/util.dart';
import 'backend.dart';
@@ -44,6 +45,10 @@
Map<TypeVariableElement, jsAst.Expression> _typeVariableConstants =
new Map<TypeVariableElement, jsAst.Expression>();
+ /// Impact builder used for the codegen world computation.
+ // TODO(johnniwinther): Add impact builder for resolution.
+ final StagedWorldImpactBuilder impactBuilder = new StagedWorldImpactBuilder();
+
TypeVariableHandler(this._compiler);
ClassElement get _typeVariableClass => _backend.helpers.typeVariableClass;
@@ -52,6 +57,12 @@
JavaScriptBackend get _backend => _compiler.backend;
DiagnosticReporter get reporter => _compiler.reporter;
+ void onQueueEmpty(Enqueuer enqueuer) {
+ if (enqueuer.isResolutionQueue) return;
+
+ enqueuer.applyImpact(null, impactBuilder.flush());
+ }
+
void registerClassWithTypeVariables(
ClassElement cls, Enqueuer enqueuer, Registry registry) {
if (enqueuer.isResolutionQueue) {
@@ -108,9 +119,8 @@
_backend.constants.evaluate(constant);
ConstantValue value = _backend.constants.getConstantValue(constant);
- _backend.registerCompileTimeConstant(value, _compiler.globalDependencies);
+ _backend.computeImpactForCompileTimeConstant(value, impactBuilder, false);
_backend.addCompileTimeConstantForEmission(value);
- _backend.constants.addCompileTimeConstantForEmission(value);
constants
.add(_reifyTypeVariableConstant(value, currentTypeVariable.element));
}
diff --git a/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
index d07c36f..1e0b6a3 100644
--- a/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
@@ -92,8 +92,8 @@
Set<Selector> generatedSelectors = new Set<Selector>();
for (Selector selector in selectors.keys) {
if (generatedSelectors.contains(selector)) continue;
- if (!selector.appliesUnnamed(member, compiler.world)) continue;
- if (selectors[selector].applies(member, selector, compiler.world)) {
+ if (!selector.appliesUnnamed(member, backend)) continue;
+ if (selectors[selector].applies(member, selector, compiler.closedWorld)) {
generatedSelectors.add(selector);
jsAst.Name invocationName = namer.invocationName(selector);
@@ -134,7 +134,7 @@
String ignore, Map<Selector, SelectorConstraints> selectors) {
for (Selector selector in selectors.keys) {
SelectorConstraints maskSet = selectors[selector];
- if (maskSet.needsNoSuchMethodHandling(selector, compiler.world)) {
+ if (maskSet.needsNoSuchMethodHandling(selector, compiler.closedWorld)) {
jsAst.Name jsName = namer.invocationMirrorInternalName(selector);
jsNames[jsName] = selector;
}
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/nsm_emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/nsm_emitter.dart
index a21e42a..f0a6e0f 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/nsm_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/nsm_emitter.dart
@@ -55,7 +55,7 @@
generator.generateStubForNoSuchMethod(jsName, selector);
addProperty(method.name, method.code);
if (reflectionName != null) {
- bool accessible = compiler.world.allFunctions
+ bool accessible = compiler.closedWorld.allFunctions
.filter(selector, null)
.any((Element e) => backend.isAccessibleByReflection(e));
addProperty(
diff --git a/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart
index 1ccb101..265c946 100644
--- a/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/interceptor_stub_generator.dart
@@ -57,7 +57,7 @@
bool hasString = false;
bool hasNative = false;
bool anyNativeClasses =
- compiler.enqueuer.codegen.nativeEnqueuer.hasInstantiatedNativeClasses();
+ compiler.enqueuer.codegen.nativeEnqueuer.hasInstantiatedNativeClasses;
for (ClassElement cls in classes) {
if (cls == helpers.jsArrayClass ||
@@ -248,7 +248,7 @@
bool containsJsIndexable =
helpers.jsIndexingBehaviorInterface.isResolved &&
classes.any((cls) {
- return compiler.world
+ return compiler.closedWorld
.isSubtypeOf(cls, helpers.jsIndexingBehaviorInterface);
});
// The index set operator requires a check on its set value in
diff --git a/pkg/compiler/lib/src/js_emitter/native_emitter.dart b/pkg/compiler/lib/src/js_emitter/native_emitter.dart
index 137f407..2e5f457 100644
--- a/pkg/compiler/lib/src/js_emitter/native_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/native_emitter.dart
@@ -191,8 +191,7 @@
// Add properties containing the information needed to construct maps used
// by getNativeInterceptor and custom elements.
- if (compiler.enqueuer.codegen.nativeEnqueuer
- .hasInstantiatedNativeClasses()) {
+ if (compiler.enqueuer.codegen.nativeEnqueuer.hasInstantiatedNativeClasses) {
fillNativeInfo(jsInterceptorClass);
for (Class cls in classes) {
if (!cls.isNative || neededClasses.contains(cls)) {
diff --git a/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
index fa01ef9..621d781 100644
--- a/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
@@ -248,7 +248,9 @@
new Selector.call(member.memberName, selector.callStructure);
renamedCallSelectors.add(renamedSelector);
- if (!renamedSelector.appliesUnnamed(member, compiler.world)) continue;
+ if (!renamedSelector.appliesUnnamed(member, compiler.backend)) {
+ continue;
+ }
if (untypedSelectors.add(renamedSelector)) {
ParameterStubMethod stub =
@@ -264,8 +266,9 @@
// call-selectors (and they are in the renamedCallSelectors set.
for (Selector selector in selectors.keys) {
if (renamedCallSelectors.contains(selector)) continue;
- if (!selector.appliesUnnamed(member, compiler.world)) continue;
- if (!selectors[selector].applies(member, selector, compiler.world)) {
+ if (!selector.appliesUnnamed(member, backend)) continue;
+ if (!selectors[selector]
+ .applies(member, selector, compiler.closedWorld)) {
continue;
}
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart b/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
index 8314f15..6e43f98 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/collector.dart
@@ -170,7 +170,7 @@
void computeNeededDeclarations() {
// Compute needed typedefs.
typedefsNeededForReflection = Elements.sortedByPosition(compiler
- .world.allTypedefs
+ .closedWorld.allTypedefs
.where(backend.isAccessibleByReflection)
.toList());
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart b/pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart
index 935fa5f..1f6956d 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/field_visitor.dart
@@ -140,7 +140,7 @@
if (fieldAccessNeverThrows(field)) return false;
if (backend.shouldRetainGetter(field)) return true;
return field.isClassMember &&
- compiler.codegenWorld.hasInvokedGetter(field, compiler.world);
+ compiler.codegenWorld.hasInvokedGetter(field, compiler.closedWorld);
}
bool fieldNeedsSetter(VariableElement field) {
@@ -149,7 +149,7 @@
if (field.isFinal || field.isConst) return false;
if (backend.shouldRetainSetter(field)) return true;
return field.isClassMember &&
- compiler.codegenWorld.hasInvokedSetter(field, compiler.world);
+ compiler.codegenWorld.hasInvokedSetter(field, compiler.closedWorld);
}
static bool fieldAccessNeverThrows(VariableElement field) {
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 a3dc79f..b977ffe 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,7 @@
import '../../js_backend/js_backend.dart'
show Namer, JavaScriptBackend, JavaScriptConstantCompiler, StringBackedName;
import '../../universe/selector.dart' show Selector;
-import '../../universe/universe.dart' show Universe, SelectorConstraints;
+import '../../universe/universe.dart' show CodegenUniverse, SelectorConstraints;
import '../js_emitter.dart'
show
ClassStubGenerator,
@@ -79,7 +79,7 @@
JavaScriptBackend get backend => _compiler.backend;
BackendHelpers get helpers => backend.helpers;
- Universe get universe => _compiler.codegenWorld;
+ CodegenUniverse get universe => _compiler.codegenWorld;
/// Mapping from [ClassElement] to constructed [Class]. We need this to
/// update the superclass in the [Class].
@@ -169,7 +169,7 @@
List<Holder> holders = _registry.holders.toList(growable: false);
bool needsNativeSupport = _compiler.enqueuer.codegen.nativeEnqueuer
- .hasInstantiatedNativeClasses();
+ .hasInstantiatedNativeClasses;
assert(!needsNativeSupport || nativeClasses.isNotEmpty);
@@ -675,7 +675,7 @@
bool _methodCanBeApplied(FunctionElement method) {
return _compiler.enabledFunctionApply &&
- _compiler.world.getMightBePassedToApply(method);
+ _compiler.closedWorld.getMightBePassedToApply(method);
}
// TODO(herhut): Refactor incremental compilation and remove method.
@@ -735,8 +735,9 @@
isClosureCallMethod = true;
} else {
// Careful with operators.
- canTearOff = universe.hasInvokedGetter(element, _compiler.world) ||
- (canBeReflected && !element.isOperator);
+ canTearOff =
+ universe.hasInvokedGetter(element, _compiler.closedWorld) ||
+ (canBeReflected && !element.isOperator);
assert(canTearOff ||
!universe.methodsNeedingSuperGetter.contains(element));
tearOffName = namer.getterForElement(element);
diff --git a/pkg/compiler/lib/src/js_emitter/type_test_registry.dart b/pkg/compiler/lib/src/js_emitter/type_test_registry.dart
index 0a6e271..c1ff342 100644
--- a/pkg/compiler/lib/src/js_emitter/type_test_registry.dart
+++ b/pkg/compiler/lib/src/js_emitter/type_test_registry.dart
@@ -106,7 +106,7 @@
} else if (function.isInstanceMember) {
if (!function.enclosingClass.isClosure) {
return compiler.codegenWorld
- .hasInvokedGetter(function, compiler.world);
+ .hasInvokedGetter(function, compiler.closedWorld);
}
}
return false;
diff --git a/pkg/compiler/lib/src/kernel/kernel.dart b/pkg/compiler/lib/src/kernel/kernel.dart
index fa53c0e..2fe3c70 100644
--- a/pkg/compiler/lib/src/kernel/kernel.dart
+++ b/pkg/compiler/lib/src/kernel/kernel.dart
@@ -24,6 +24,7 @@
FunctionElement,
ImportElement,
LibraryElement,
+ LocalFunctionElement,
MixinApplicationElement,
TypeVariableElement;
import '../elements/modelx.dart' show ErroneousFieldElementX;
@@ -50,6 +51,9 @@
final Map<FunctionElement, ir.Member> functions =
<FunctionElement, ir.Member>{};
+ final Map<LocalFunctionElement, ir.Node> localFunctions =
+ <LocalFunctionElement, ir.Node>{};
+
final Map<FieldElement, ir.Field> fields = <FieldElement, ir.Field>{};
final Map<TypeVariableElement, ir.TypeParameter> typeParameters =
@@ -206,7 +210,8 @@
}
});
classNode.typeParameters.addAll(typeVariablesToIr(cls.typeVariables));
- for (ir.InterfaceType interface in typesToIr(cls.interfaces.toList())) {
+ for (ir.InterfaceType interface
+ in typesToIr(cls.interfaces.reverse().toList())) {
classNode.implementedTypes.add(interface);
}
});
@@ -378,6 +383,7 @@
procedure.kind = irFunction.kind;
}
endFactoryScope(function);
+ member.transformerFlags = visitor.transformerFlags;
assert(() {
visitor.locals.forEach(checkMember);
return true;
@@ -437,9 +443,7 @@
isConst: field.isConst);
addWork(field, () {
setParent(fieldNode, field);
- if (!field.isMalformed &&
- !field.isInstanceMember &&
- field.initializer != null) {
+ if (!field.isMalformed && field.initializer != null) {
KernelVisitor visitor =
new KernelVisitor(field, field.treeElements, this);
fieldNode.initializer = visitor.buildInitializer()
diff --git a/pkg/compiler/lib/src/kernel/kernel_debug.dart b/pkg/compiler/lib/src/kernel/kernel_debug.dart
index 7258161..725e2d1 100644
--- a/pkg/compiler/lib/src/kernel/kernel_debug.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_debug.dart
@@ -36,6 +36,32 @@
openAndCloseNode(node, '${node.runtimeType}', {'value': '${node.value}'});
}
+ @override
+ void visitVariableGet(VariableGet node) {
+ openAndCloseNode(
+ node, '${node.runtimeType}', {'variable': '${node.variable}'});
+ }
+
+ @override
+ void visitVariableDeclaration(VariableDeclaration node) {
+ openNode(node, '${node.runtimeType}', {
+ 'name': '${node.name}',
+ 'isFinal': '${node.isFinal}',
+ 'isConst': '${node.isConst}'
+ });
+ node.visitChildren(this);
+ closeNode();
+ }
+
+ @override
+ void visitInterfaceType(InterfaceType node) {
+ openNode(node, '${node.runtimeType}', {
+ 'name': '${node.classNode.name}',
+ });
+ node.visitChildren(this);
+ closeNode();
+ }
+
/// Pretty-prints given node tree into string.
static String prettyPrint(Node node) {
var p = new DebugPrinter();
diff --git a/pkg/compiler/lib/src/kernel/kernel_visitor.dart b/pkg/compiler/lib/src/kernel/kernel_visitor.dart
index 26f3b3a..37ab7d2 100644
--- a/pkg/compiler/lib/src/kernel/kernel_visitor.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_visitor.dart
@@ -19,7 +19,9 @@
makeBinary,
makeLet,
makeOrReuseVariable;
+import 'package:kernel/transformations/flags.dart';
+import '../common.dart';
import '../constants/expressions.dart'
show
BoolFromEnvironmentConstantExpression,
@@ -182,6 +184,7 @@
TreeElements elements;
AstElement currentElement;
final Kernel kernel;
+ int transformerFlags = 0;
final Map<JumpTarget, ir.LabeledStatement> continueTargets =
<JumpTarget, ir.LabeledStatement>{};
@@ -774,8 +777,8 @@
JumpTarget jumpTarget = elements.getTargetDefinition(node);
ir.Statement body =
buildContinueTarget(buildStatementInBlock(node.body), node, jumpTarget);
- ir.ForStatement forStatement =
- new ir.ForStatement(variables, condition, updates, body);
+ ir.ForStatement forStatement = associateNode(
+ new ir.ForStatement(variables, condition, updates, body), node);
ir.Statement result = buildBreakTarget(forStatement, node, jumpTarget);
if (initializer != null) {
result = new ir.Block(
@@ -1090,7 +1093,9 @@
ir.Statement body =
buildContinueTarget(buildStatementInBlock(node.body), node, jumpTarget);
return buildBreakTarget(
- new ir.WhileStatement(condition, body), node, jumpTarget);
+ associateNode(new ir.WhileStatement(condition, body), node),
+ node,
+ jumpTarget);
}
@override
@@ -1142,8 +1147,13 @@
ir.Expression buildConstructorInvoke(NewExpression node, {bool isConst}) {
ConstructorElement constructor = elements[node.send];
- ConstructorTarget target =
- kernel.computeEffectiveTarget(constructor, elements.getType(node));
+ ConstructorTarget target;
+ if (isConst) {
+ target =
+ kernel.computeEffectiveTarget(constructor, elements.getType(node));
+ } else {
+ target = new ConstructorTarget(constructor, elements.getType(node));
+ }
NodeList arguments = node.send.argumentsNode;
if (kernel.isSyntheticError(target.element)) {
return new ir.MethodInvocation(new ir.InvalidExpression(),
@@ -1203,7 +1213,10 @@
ir.FunctionExpression visitClosureDeclaration(FunctionExpression node,
LocalFunctionElement closure, NodeList parameters, Node body, _) {
return withCurrentElement(closure, () {
- return new ir.FunctionExpression(buildFunctionNode(closure, body));
+ ir.FunctionExpression function =
+ new ir.FunctionExpression(buildFunctionNode(closure, body));
+ kernel.localFunctions[closure] = function;
+ return function;
});
}
@@ -1383,22 +1396,6 @@
.buildAssignment(visitForValue(rhs), voidContext: isVoidContext);
}
- void addFieldsWithInitializers(
- ConstructorElement constructor, List<ir.Initializer> initializers) {
- constructor.enclosingClass.forEachInstanceField((_, FieldElement element) {
- // Convert the element into the corresponding IR field before asking
- // if the initializer exists. This is necessary to ensure that the
- // element has been analyzed before looking at its initializer.
- ir.Field field = kernel.fieldToIr(element);
- if (element.initializer != null) {
- KernelVisitor visitor =
- new KernelVisitor(element, element.treeElements, kernel);
- ir.Expression value = visitor.buildInitializer();
- initializers.add(new ir.FieldInitializer(field, value));
- }
- });
- }
-
IrFunction buildGenerativeConstructor(
ConstructorElement constructor, NodeList parameters, Node body) {
List<ir.Initializer> constructorInitializers = <ir.Initializer>[];
@@ -1424,13 +1421,11 @@
if (kernel.isSyntheticError(constructor.definingConstructor)) {
constructorInitializers.add(new ir.InvalidInitializer());
} else {
- addFieldsWithInitializers(constructor, constructorInitializers);
constructorInitializers.add(new ir.SuperInitializer(
kernel.functionToIr(constructor.definingConstructor),
new ir.Arguments(arguments, named: named, types: null)));
}
} else {
- addFieldsWithInitializers(constructor, constructorInitializers);
if (parameters != null) {
// TODO(ahe): the following is a (modified) copy of
// [SemanticDeclarationResolvedMixin.visitParameters].
@@ -1689,8 +1684,12 @@
LocalFunctionElement localFunction, NodeList parameters, Node body, _) {
return withCurrentElement(localFunction, () {
ir.VariableDeclaration local = getLocal(localFunction)..isFinal = true;
- return new ir.FunctionDeclaration(
+ ir.FunctionDeclaration function = new ir.FunctionDeclaration(
local, buildFunctionNode(localFunction, body));
+ // Closures can escape their context and we must therefore store them
+ // globally to include them in the world computation.
+ kernel.localFunctions[localFunction] = function;
+ return function;
});
}
@@ -1955,11 +1954,13 @@
ir.VariableDeclaration getLocal(LocalElement local) {
return locals.putIfAbsent(local, () {
+ // Currently, initializing formals are not final.
+ bool isFinal = local.isFinal && !local.isInitializingFormal;
return associateElement(
new ir.VariableDeclaration(local.name,
initializer: null,
type: typeToIrHack(local.type),
- isFinal: local.isFinal,
+ isFinal: isFinal,
isConst: local.isConst),
local);
});
@@ -1993,7 +1994,11 @@
initializer.parent = variable;
}
});
- returnType = typeToIrHack(signature.type.returnType);
+ if (function.isGenerativeConstructor) {
+ returnType = const ir.VoidType();
+ } else {
+ returnType = typeToIrHack(signature.type.returnType);
+ }
if (function.isFactoryConstructor) {
InterfaceType type = function.enclosingClass.thisType;
if (type.isGeneric) {
@@ -2029,8 +2034,20 @@
break;
}
}
- ir.Statement body =
- (bodyNode == null) ? null : buildStatementInBlock(bodyNode);
+ ir.Statement body;
+ if (function.isExternal) {
+ // [body] must be `null`.
+ } else if (function.isConstructor) {
+ // TODO(johnniwinther): Clean this up pending kernel issue #28.
+ ConstructorElement constructor = function;
+ if (constructor.isDefaultConstructor) {
+ body = new ir.EmptyStatement();
+ } else if (bodyNode != null && bodyNode.asEmptyStatement() == null) {
+ body = buildStatementInBlock(bodyNode);
+ }
+ } else if (bodyNode != null) {
+ body = buildStatementInBlock(bodyNode);
+ }
return associateElement(
new ir.FunctionNode(body,
asyncMarker: asyncMarker,
@@ -2179,6 +2196,7 @@
@override
ir.SuperMethodInvocation visitSuperBinary(Send node, FunctionElement function,
BinaryOperator operator, Node argument, _) {
+ transformerFlags |= TransformerFlag.superCalls;
return new ir.SuperMethodInvocation(
kernel.irName(operator.selectorName, currentElement),
new ir.Arguments(<ir.Expression>[visitForValue(argument)]),
@@ -2219,6 +2237,7 @@
ir.SuperMethodInvocation buildSuperEquals(
FunctionElement function, Node argument) {
+ transformerFlags |= TransformerFlag.superCalls;
return new ir.SuperMethodInvocation(
kernel.irName(function.name, function),
new ir.Arguments(<ir.Expression>[visitForValue(argument)],
@@ -2298,6 +2317,7 @@
}
Accessor buildSuperPropertyAccessor(Element getter, [Element setter]) {
+ transformerFlags |= TransformerFlag.superCalls;
if (setter == null &&
getter.isField &&
!getter.isFinal &&
@@ -2398,6 +2418,7 @@
ir.SuperMethodInvocation buildSuperMethodInvoke(
MethodElement method, NodeList arguments) {
+ transformerFlags |= TransformerFlag.superCalls;
return new ir.SuperMethodInvocation(kernel.irName(method.name, method),
buildArguments(arguments), kernel.functionToIr(method));
}
@@ -2457,6 +2478,7 @@
@override
ir.SuperMethodInvocation visitSuperUnary(
Send node, UnaryOperator operator, FunctionElement function, _) {
+ transformerFlags |= TransformerFlag.superCalls;
return new ir.SuperMethodInvocation(kernel.irName(function.name, function),
new ir.Arguments.empty(), kernel.functionToIr(function));
}
diff --git a/pkg/compiler/lib/src/native/enqueue.dart b/pkg/compiler/lib/src/native/enqueue.dart
index 166e6cf..1ab06fe 100644
--- a/pkg/compiler/lib/src/native/enqueue.dart
+++ b/pkg/compiler/lib/src/native/enqueue.dart
@@ -47,7 +47,7 @@
void handleMethodAnnotations(Element method) {}
/// Returns whether native classes are being used.
- bool hasInstantiatedNativeClasses() => false;
+ bool get hasInstantiatedNativeClasses => false;
/// Emits a summary information using the [log] function.
void logSummary(log(message)) {}
@@ -73,7 +73,7 @@
final Set<LibraryElement> processedLibraries;
- bool hasInstantiatedNativeClasses() => !registeredClasses.isEmpty;
+ bool get hasInstantiatedNativeClasses => !registeredClasses.isEmpty;
final Set<ClassElement> nativeClassesAndSubclasses = new Set<ClassElement>();
diff --git a/pkg/compiler/lib/src/resolution/members.dart b/pkg/compiler/lib/src/resolution/members.dart
index 39bd77d..390b161 100644
--- a/pkg/compiler/lib/src/resolution/members.dart
+++ b/pkg/compiler/lib/src/resolution/members.dart
@@ -4157,9 +4157,7 @@
ResolutionResult visitStringInterpolation(StringInterpolation node) {
// TODO(johnniwinther): This should be a consequence of the registration
// of [registerStringInterpolation].
- registry.registerTypeUse(new TypeUse.instantiation(coreTypes.stringType));
registry.registerFeature(Feature.STRING_INTERPOLATION);
- registerImplicitInvocation(Selectors.toString_);
bool isValidAsConstant = true;
List<ConstantExpression> parts = <ConstantExpression>[];
@@ -4244,10 +4242,6 @@
return const NoneResult();
}
- registerImplicitInvocation(Selector selector) {
- registry.registerDynamicUse(new DynamicUse(selector, null));
- }
-
ResolutionResult visitAsyncForIn(AsyncForIn node) {
if (!resolution.target.supportsAsyncAwait) {
reporter.reportErrorMessage(
diff --git a/pkg/compiler/lib/src/resolution/registry.dart b/pkg/compiler/lib/src/resolution/registry.dart
index d6aa72c..da2c129 100644
--- a/pkg/compiler/lib/src/resolution/registry.dart
+++ b/pkg/compiler/lib/src/resolution/registry.dart
@@ -18,16 +18,15 @@
import '../universe/feature.dart';
import '../universe/selector.dart' show Selector;
import '../universe/use.dart' show DynamicUse, StaticUse, TypeUse;
-import '../universe/world_impact.dart' show WorldImpact, WorldImpactBuilder;
+import '../universe/world_impact.dart' show WorldImpact, WorldImpactBuilderImpl;
import '../util/enumset.dart' show EnumSet;
import '../util/util.dart' show Setlet;
import 'members.dart' show ResolverVisitor;
import 'send_structure.dart';
import 'tree_elements.dart' show TreeElementMapping;
-class ResolutionWorldImpactBuilder extends ResolutionImpact
- with WorldImpactBuilder
- implements NativeRegistry {
+class ResolutionWorldImpactBuilder extends WorldImpactBuilderImpl
+ implements NativeRegistry, ResolutionImpact {
final String name;
EnumSet<Feature> _features;
Setlet<MapLiteralUse> _mapLiterals;
diff --git a/pkg/compiler/lib/src/resolution/resolution.dart b/pkg/compiler/lib/src/resolution/resolution.dart
index 37c0933..13f248c 100644
--- a/pkg/compiler/lib/src/resolution/resolution.dart
+++ b/pkg/compiler/lib/src/resolution/resolution.dart
@@ -64,7 +64,7 @@
class ResolverTask extends CompilerTask {
final ConstantCompiler constantCompiler;
final Resolution resolution;
- final World world;
+ final OpenWorld world;
ResolverTask(
this.resolution, this.constantCompiler, this.world, Measurer measurer)
@@ -1017,7 +1017,7 @@
WorldImpact resolveTypedef(TypedefElementX element) {
if (element.isResolved) return const ResolutionImpact();
- world.allTypedefs.add(element);
+ world.registerTypedef(element);
return _resolveTypeDeclaration(element, () {
ResolutionRegistry registry = new ResolutionRegistry(
resolution.target, _ensureTreeElements(element));
diff --git a/pkg/compiler/lib/src/resolution/variables.dart b/pkg/compiler/lib/src/resolution/variables.dart
index 77a8f4e..fa7dd75 100644
--- a/pkg/compiler/lib/src/resolution/variables.dart
+++ b/pkg/compiler/lib/src/resolution/variables.dart
@@ -9,6 +9,7 @@
import '../elements/modelx.dart' show LocalVariableElementX, VariableList;
import '../tree/tree.dart';
import '../universe/use.dart' show TypeUse;
+import '../universe/feature.dart';
import '../util/util.dart' show Link;
import 'members.dart' show ResolverVisitor;
import 'registry.dart' show ResolutionRegistry;
@@ -42,9 +43,7 @@
Identifier visitIdentifier(Identifier node) {
// The variable is initialized to null.
- // TODO(johnniwinther): Register a feature instead.
- registry.registerTypeUse(
- new TypeUse.instantiation(resolution.coreTypes.nullType));
+ registry.registerFeature(Feature.LOCAL_WITHOUT_INITIALIZER);
if (definitions.modifiers.isConst) {
if (resolver.inLoopVariable) {
reporter.reportErrorMessage(node, MessageKind.CONST_LOOP_VARIABLE);
diff --git a/pkg/compiler/lib/src/serialization/equivalence.dart b/pkg/compiler/lib/src/serialization/equivalence.dart
index 4456623..9db38fd 100644
--- a/pkg/compiler/lib/src/serialization/equivalence.dart
+++ b/pkg/compiler/lib/src/serialization/equivalence.dart
@@ -516,14 +516,18 @@
bool visitLocalFunctionElement(
LocalFunctionElement element1, LocalFunctionElement element2) {
// TODO(johnniwinther): Define an equivalence on locals.
- return checkMembers(element1.memberContext, element2.memberContext);
+ return strategy.test(
+ element1, element2, 'name', element1.name, element2.name) &&
+ checkMembers(element1.memberContext, element2.memberContext);
}
@override
bool visitLocalVariableElement(
LocalVariableElement element1, LocalVariableElement element2) {
// TODO(johnniwinther): Define an equivalence on locals.
- return checkMembers(element1.memberContext, element2.memberContext);
+ return strategy.test(
+ element1, element2, 'name', element1.name, element2.name) &&
+ checkMembers(element1.memberContext, element2.memberContext);
}
bool visitAbstractFieldElement(
diff --git a/pkg/compiler/lib/src/serialization/modelz.dart b/pkg/compiler/lib/src/serialization/modelz.dart
index a6ba195..a628cbf 100644
--- a/pkg/compiler/lib/src/serialization/modelz.dart
+++ b/pkg/compiler/lib/src/serialization/modelz.dart
@@ -1242,6 +1242,9 @@
@override
bool get isExternal => _decoder.getBool(Key.IS_EXTERNAL);
+ @override
+ bool get isDefaultConstructor => false;
+
ConstantConstructor get constantConstructor {
if (isConst && _constantConstructor == null) {
ObjectDecoder data =
@@ -1320,6 +1323,9 @@
bool get isSynthesized => true;
@override
+ bool get isDefaultConstructor => true;
+
+ @override
ConstructorElement get definingConstructor {
return enclosingClass.superclass.lookupConstructor('');
}
@@ -1440,6 +1446,9 @@
bool get isClassMember => true;
@override
+ bool get isDefaultConstructor => false;
+
+ @override
ConstantConstructor get constantConstructor => null;
@override
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
index 2456e81..5cca521 100644
--- a/pkg/compiler/lib/src/ssa/builder.dart
+++ b/pkg/compiler/lib/src/ssa/builder.dart
@@ -37,10 +37,12 @@
import '../universe/side_effects.dart' show SideEffects;
import '../universe/use.dart' show DynamicUse, StaticUse, TypeUse;
import '../util/util.dart';
-import '../world.dart' show ClassWorld;
+import '../world.dart' show ClosedWorld;
import 'graph_builder.dart';
+import 'jump_handler.dart';
import 'locals_handler.dart';
+import 'loop_handler.dart';
import 'nodes.dart';
import 'optimize.dart';
import 'ssa_branch_builder.dart';
@@ -125,226 +127,6 @@
}
}
-// Represents a single break/continue instruction.
-class JumpHandlerEntry {
- final HJump jumpInstruction;
- final LocalsHandler locals;
- bool isBreak() => jumpInstruction is HBreak;
- bool isContinue() => jumpInstruction is HContinue;
- JumpHandlerEntry(this.jumpInstruction, this.locals);
-}
-
-abstract class JumpHandler {
- factory JumpHandler(SsaBuilder builder, JumpTarget target) {
- return new TargetJumpHandler(builder, target);
- }
- void generateBreak([LabelDefinition label]);
- void generateContinue([LabelDefinition label]);
- void forEachBreak(void action(HBreak instruction, LocalsHandler locals));
- void forEachContinue(
- void action(HContinue instruction, LocalsHandler locals));
- bool hasAnyContinue();
- bool hasAnyBreak();
- void close();
- final JumpTarget target;
- List<LabelDefinition> labels();
-}
-
-// Insert break handler used to avoid null checks when a target isn't
-// used as the target of a break, and therefore doesn't need a break
-// handler associated with it.
-class NullJumpHandler implements JumpHandler {
- final DiagnosticReporter reporter;
-
- NullJumpHandler(this.reporter);
-
- void generateBreak([LabelDefinition label]) {
- reporter.internalError(CURRENT_ELEMENT_SPANNABLE,
- 'NullJumpHandler.generateBreak should not be called.');
- }
-
- void generateContinue([LabelDefinition label]) {
- reporter.internalError(CURRENT_ELEMENT_SPANNABLE,
- 'NullJumpHandler.generateContinue should not be called.');
- }
-
- void forEachBreak(Function ignored) {}
- void forEachContinue(Function ignored) {}
- void close() {}
- bool hasAnyContinue() => false;
- bool hasAnyBreak() => false;
-
- List<LabelDefinition> labels() => const <LabelDefinition>[];
- JumpTarget get target => null;
-}
-
-// Records breaks until a target block is available.
-// Breaks are always forward jumps.
-// Continues in loops are implemented as breaks of the body.
-// Continues in switches is currently not handled.
-class TargetJumpHandler implements JumpHandler {
- final SsaBuilder builder;
- final JumpTarget target;
- final List<JumpHandlerEntry> jumps;
-
- TargetJumpHandler(SsaBuilder builder, this.target)
- : this.builder = builder,
- jumps = <JumpHandlerEntry>[] {
- assert(builder.jumpTargets[target] == null);
- builder.jumpTargets[target] = this;
- }
-
- void generateBreak([LabelDefinition label]) {
- HInstruction breakInstruction;
- if (label == null) {
- breakInstruction = new HBreak(target);
- } else {
- breakInstruction = new HBreak.toLabel(label);
- }
- LocalsHandler locals = new LocalsHandler.from(builder.localsHandler);
- builder.close(breakInstruction);
- jumps.add(new JumpHandlerEntry(breakInstruction, locals));
- }
-
- void generateContinue([LabelDefinition label]) {
- HInstruction continueInstruction;
- if (label == null) {
- continueInstruction = new HContinue(target);
- } else {
- continueInstruction = new HContinue.toLabel(label);
- // Switch case continue statements must be handled by the
- // [SwitchCaseJumpHandler].
- assert(label.target.statement is! ast.SwitchCase);
- }
- LocalsHandler locals = new LocalsHandler.from(builder.localsHandler);
- builder.close(continueInstruction);
- jumps.add(new JumpHandlerEntry(continueInstruction, locals));
- }
-
- void forEachBreak(Function action) {
- for (JumpHandlerEntry entry in jumps) {
- if (entry.isBreak()) action(entry.jumpInstruction, entry.locals);
- }
- }
-
- void forEachContinue(Function action) {
- for (JumpHandlerEntry entry in jumps) {
- if (entry.isContinue()) action(entry.jumpInstruction, entry.locals);
- }
- }
-
- bool hasAnyContinue() {
- for (JumpHandlerEntry entry in jumps) {
- if (entry.isContinue()) return true;
- }
- return false;
- }
-
- bool hasAnyBreak() {
- for (JumpHandlerEntry entry in jumps) {
- if (entry.isBreak()) return true;
- }
- return false;
- }
-
- void close() {
- // The mapping from TargetElement to JumpHandler is no longer needed.
- builder.jumpTargets.remove(target);
- }
-
- List<LabelDefinition> labels() {
- List<LabelDefinition> result = null;
- for (LabelDefinition element in target.labels) {
- if (result == null) result = <LabelDefinition>[];
- result.add(element);
- }
- return (result == null) ? const <LabelDefinition>[] : result;
- }
-}
-
-/// Special [JumpHandler] implementation used to handle continue statements
-/// targeting switch cases.
-class SwitchCaseJumpHandler extends TargetJumpHandler {
- /// Map from switch case targets to indices used to encode the flow of the
- /// switch case loop.
- final Map<JumpTarget, int> targetIndexMap = new Map<JumpTarget, int>();
-
- SwitchCaseJumpHandler(
- SsaBuilder builder, JumpTarget target, ast.SwitchStatement node)
- : super(builder, target) {
- // The switch case indices must match those computed in
- // [SsaFromAstMixin.buildSwitchCaseConstants].
- // Switch indices are 1-based so we can bypass the synthetic loop when no
- // cases match simply by branching on the index (which defaults to null).
- int switchIndex = 1;
- for (ast.SwitchCase switchCase in node.cases) {
- for (ast.Node labelOrCase in switchCase.labelsAndCases) {
- ast.Node label = labelOrCase.asLabel();
- if (label != null) {
- LabelDefinition labelElement =
- builder.elements.getLabelDefinition(label);
- if (labelElement != null && labelElement.isContinueTarget) {
- JumpTarget continueTarget = labelElement.target;
- targetIndexMap[continueTarget] = switchIndex;
- assert(builder.jumpTargets[continueTarget] == null);
- builder.jumpTargets[continueTarget] = this;
- }
- }
- }
- switchIndex++;
- }
- }
-
- void generateBreak([LabelDefinition label]) {
- if (label == null) {
- // Creates a special break instruction for the synthetic loop generated
- // for a switch statement with continue statements. See
- // [SsaFromAstMixin.buildComplexSwitchStatement] for detail.
-
- HInstruction breakInstruction =
- new HBreak(target, breakSwitchContinueLoop: true);
- LocalsHandler locals = new LocalsHandler.from(builder.localsHandler);
- builder.close(breakInstruction);
- jumps.add(new JumpHandlerEntry(breakInstruction, locals));
- } else {
- super.generateBreak(label);
- }
- }
-
- bool isContinueToSwitchCase(LabelDefinition label) {
- return label != null && targetIndexMap.containsKey(label.target);
- }
-
- void generateContinue([LabelDefinition label]) {
- if (isContinueToSwitchCase(label)) {
- // Creates the special instructions 'label = i; continue l;' used in
- // switch statements with continue statements. See
- // [SsaFromAstMixin.buildComplexSwitchStatement] for detail.
-
- assert(label != null);
- HInstruction value = builder.graph
- .addConstantInt(targetIndexMap[label.target], builder.compiler);
- builder.localsHandler.updateLocal(target, value);
-
- assert(label.target.labels.contains(label));
- HInstruction continueInstruction = new HContinue(target);
- LocalsHandler locals = new LocalsHandler.from(builder.localsHandler);
- builder.close(continueInstruction);
- jumps.add(new JumpHandlerEntry(continueInstruction, locals));
- } else {
- super.generateContinue(label);
- }
- }
-
- void close() {
- // The mapping from TargetElement to JumpHandler is no longer needed.
- for (JumpTarget target in targetIndexMap.keys) {
- builder.jumpTargets.remove(target);
- }
- super.close();
- }
-}
-
/**
* This class builds SSA nodes for functions represented in AST.
*/
@@ -376,7 +158,6 @@
// used only for codegen, but currently we want to experiment using it for
// code-analysis too.
final CodegenRegistry registry;
- final Compiler compiler;
final GlobalTypeInferenceResults inferenceResults;
final JavaScriptBackend backend;
final ConstantSystem constantSystem;
@@ -397,13 +178,6 @@
bool inExpressionOfThrow = false;
/**
- * The loop nesting is consulted when inlining a function invocation in
- * [tryInlineMethod]. The inlining heuristics take this information into
- * account.
- */
- int loopNesting = 0;
-
- /**
* This stack contains declaration elements of the functions being built
* or inlined by this builder.
*/
@@ -411,8 +185,6 @@
HInstruction rethrowableException;
- Map<JumpTarget, JumpHandler> jumpTargets = <JumpTarget, JumpHandler>{};
-
/// Returns `true` if the current element is an `async` function.
bool get isBuildingAsyncFunction {
Element element = sourceElement;
@@ -420,6 +192,9 @@
element.asyncMarker == AsyncMarker.ASYNC);
}
+ /// Handles the building of loops.
+ LoopHandler<ast.Node> loopHandler;
+
// TODO(sigmund): make most args optional
SsaBuilder(
this.target,
@@ -428,13 +203,13 @@
JavaScriptBackend backend,
this.nativeEmitter,
SourceInformationStrategy sourceInformationFactory)
- : this.compiler = backend.compiler,
- this.infoReporter = backend.compiler.dumpInfoTask,
+ : this.infoReporter = backend.compiler.dumpInfoTask,
this.backend = backend,
this.constantSystem = backend.constantSystem,
this.rti = backend.rti,
this.inferenceResults = backend.compiler.globalInference.results {
assert(target.isImplementation);
+ compiler = backend.compiler;
graph.element = target;
sourceElementStack.add(target);
sourceInformationBuilder =
@@ -442,6 +217,7 @@
graph.sourceInformation =
sourceInformationBuilder.buildVariableDeclaration();
localsHandler = new LocalsHandler(this, target, null, compiler);
+ loopHandler = new SsaLoopHandler(this);
}
BackendHelpers get helpers => backend.helpers;
@@ -556,7 +332,7 @@
*/
List<HInstruction> completeDynamicSendArgumentsList(Selector selector,
FunctionElement function, List<HInstruction> providedArguments) {
- assert(selector.applies(function, compiler.world));
+ assert(selector.applies(function, backend));
FunctionSignature signature = function.functionSignature;
List<HInstruction> compiledArguments = new List<HInstruction>(
signature.parameterCount + 1); // Plus one for receiver.
@@ -632,7 +408,7 @@
FunctionElement function = element;
ResolvedAst functionResolvedAst = function.resolvedAst;
- bool insideLoop = loopNesting > 0 || graph.calledInLoop;
+ bool insideLoop = loopDepth > 0 || graph.calledInLoop;
// Bail out early if the inlining decision is in the cache and we can't
// inline (no need to check the hard constraints).
@@ -650,8 +426,9 @@
element.isGenerativeConstructorBody,
message: "Missing selector for inlining of $element."));
if (selector != null) {
- if (!selector.applies(function, compiler.world)) return false;
- if (mask != null && !mask.canHit(function, selector, compiler.world)) {
+ if (!selector.applies(function, backend)) return false;
+ if (mask != null &&
+ !mask.canHit(function, selector, compiler.closedWorld)) {
return false;
}
}
@@ -896,7 +673,7 @@
*/
HGraph buildMethod(FunctionElement functionElement) {
assert(invariant(functionElement, functionElement.isImplementation));
- graph.calledInLoop = compiler.world.isCalledInLoop(functionElement);
+ graph.calledInLoop = compiler.closedWorld.isCalledInLoop(functionElement);
ast.FunctionExpression function = resolvedAst.node;
assert(function != null);
assert(elements.getFunctionDefinition(function) != null);
@@ -1484,8 +1261,8 @@
}, includeSuperAndInjectedMembers: true);
InterfaceType type = classElement.thisType;
- TypeMask ssaType =
- new TypeMask.nonNullExact(classElement.declaration, compiler.world);
+ TypeMask ssaType = new TypeMask.nonNullExact(
+ classElement.declaration, compiler.closedWorld);
List<DartType> instantiatedTypes;
addInlinedInstantiation(type);
if (!currentInlinedInstantiations.isEmpty) {
@@ -1600,7 +1377,7 @@
HInvokeConstructorBody invoke = new HInvokeConstructorBody(
body.declaration, bodyCallInputs, backend.nonNullType);
invoke.sideEffects =
- compiler.world.getSideEffectsOfElement(constructor);
+ compiler.closedWorld.getSideEffectsOfElement(constructor);
add(invoke);
}
}
@@ -1742,7 +1519,8 @@
type = type.unaliased;
assert(assertTypeInContext(type, original));
if (type.isInterfaceType && !type.treatAsRaw) {
- TypeMask subtype = new TypeMask.subtype(type.element, compiler.world);
+ TypeMask subtype =
+ new TypeMask.subtype(type.element, compiler.closedWorld);
HInstruction representations = buildTypeArgumentRepresentations(type);
add(representations);
return new HTypeConversion.withTypeRepresentation(
@@ -1783,7 +1561,7 @@
if (type.isObject) return original;
// The type element is either a class or the void element.
Element element = type.element;
- TypeMask mask = new TypeMask.subtype(element, compiler.world);
+ TypeMask mask = new TypeMask.subtype(element, compiler.closedWorld);
return new HTypeKnown.pinned(mask, original);
}
@@ -1951,275 +1729,6 @@
}
}
- /**
- * Creates a new loop-header block. The previous [current] block
- * is closed with an [HGoto] and replaced by the newly created block.
- * Also notifies the locals handler that we're entering a loop.
- */
- JumpHandler beginLoopHeader(ast.Node node) {
- assert(!isAborted());
- HBasicBlock previousBlock = close(new HGoto());
-
- JumpHandler jumpHandler = createJumpHandler(node, isLoopJump: true);
- HBasicBlock loopEntry =
- graph.addNewLoopHeaderBlock(jumpHandler.target, jumpHandler.labels());
- previousBlock.addSuccessor(loopEntry);
- open(loopEntry);
-
- localsHandler.beginLoopHeader(loopEntry);
- return jumpHandler;
- }
-
- /**
- * Ends the loop:
- * - creates a new block and adds it as successor to the [branchExitBlock] and
- * any blocks that end in break.
- * - opens the new block (setting as [current]).
- * - notifies the locals handler that we're exiting a loop.
- * [savedLocals] are the locals from the end of the loop condition.
- * [branchExitBlock] is the exit (branching) block of the condition. Generally
- * this is not the top of the loop, since this would lead to critical edges.
- * It is null for degenerate do-while loops that have
- * no back edge because they abort (throw/return/break in the body and have
- * no continues).
- */
- void endLoop(HBasicBlock loopEntry, HBasicBlock branchExitBlock,
- JumpHandler jumpHandler, LocalsHandler savedLocals) {
- HBasicBlock loopExitBlock = addNewBlock();
-
- List<LocalsHandler> breakHandlers = <LocalsHandler>[];
- // Collect data for the successors and the phis at each break.
- jumpHandler.forEachBreak((HBreak breakInstruction, LocalsHandler locals) {
- breakInstruction.block.addSuccessor(loopExitBlock);
- breakHandlers.add(locals);
- });
-
- // The exit block is a successor of the loop condition if it is reached.
- // We don't add the successor in the case of a while/for loop that aborts
- // because the caller of endLoop will be wiring up a special empty else
- // block instead.
- if (branchExitBlock != null) {
- branchExitBlock.addSuccessor(loopExitBlock);
- }
- // Update the phis at the loop entry with the current values of locals.
- localsHandler.endLoop(loopEntry);
-
- // Start generating code for the exit block.
- open(loopExitBlock);
-
- // Create a new localsHandler for the loopExitBlock with the correct phis.
- if (!breakHandlers.isEmpty) {
- if (branchExitBlock != null) {
- // Add the values of the locals at the end of the condition block to
- // the phis. These are the values that flow to the exit if the
- // condition fails.
- breakHandlers.add(savedLocals);
- }
- localsHandler = savedLocals.mergeMultiple(breakHandlers, loopExitBlock);
- } else {
- localsHandler = savedLocals;
- }
- }
-
- HSubGraphBlockInformation wrapStatementGraph(SubGraph statements) {
- if (statements == null) return null;
- return new HSubGraphBlockInformation(statements);
- }
-
- HSubExpressionBlockInformation wrapExpressionGraph(SubExpression expression) {
- if (expression == null) return null;
- return new HSubExpressionBlockInformation(expression);
- }
-
- // For while loops, initializer and update are null.
- // The condition function must return a boolean result.
- // None of the functions must leave anything on the stack.
- void handleLoop(ast.Node loop, void initialize(), HInstruction condition(),
- void update(), void body()) {
- // Generate:
- // <initializer>
- // loop-entry:
- // if (!<condition>) goto loop-exit;
- // <body>
- // <updates>
- // goto loop-entry;
- // loop-exit:
-
- localsHandler.startLoop(loop);
-
- // The initializer.
- SubExpression initializerGraph = null;
- HBasicBlock startBlock;
- if (initialize != null) {
- HBasicBlock initializerBlock = openNewBlock();
- startBlock = initializerBlock;
- initialize();
- assert(!isAborted());
- initializerGraph = new SubExpression(initializerBlock, current);
- }
-
- loopNesting++;
- JumpHandler jumpHandler = beginLoopHeader(loop);
- HLoopInformation loopInfo = current.loopInformation;
- HBasicBlock conditionBlock = current;
- if (startBlock == null) startBlock = conditionBlock;
-
- HInstruction conditionInstruction = condition();
- HBasicBlock conditionEndBlock =
- close(new HLoopBranch(conditionInstruction));
- SubExpression conditionExpression =
- new SubExpression(conditionBlock, conditionEndBlock);
-
- // Save the values of the local variables at the end of the condition
- // block. These are the values that will flow to the loop exit if the
- // condition fails.
- LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
-
- // The body.
- HBasicBlock beginBodyBlock = addNewBlock();
- conditionEndBlock.addSuccessor(beginBodyBlock);
- open(beginBodyBlock);
-
- localsHandler.enterLoopBody(loop);
- body();
-
- SubGraph bodyGraph = new SubGraph(beginBodyBlock, lastOpenedBlock);
- HBasicBlock bodyBlock = current;
- if (current != null) close(new HGoto());
-
- SubExpression updateGraph;
-
- bool loopIsDegenerate = !jumpHandler.hasAnyContinue() && bodyBlock == null;
- if (!loopIsDegenerate) {
- // Update.
- // We create an update block, even when we are in a while loop. There the
- // update block is the jump-target for continue statements. We could avoid
- // the creation if there is no continue, but for now we always create it.
- HBasicBlock updateBlock = addNewBlock();
-
- List<LocalsHandler> continueHandlers = <LocalsHandler>[];
- jumpHandler
- .forEachContinue((HContinue instruction, LocalsHandler locals) {
- instruction.block.addSuccessor(updateBlock);
- continueHandlers.add(locals);
- });
-
- if (bodyBlock != null) {
- continueHandlers.add(localsHandler);
- bodyBlock.addSuccessor(updateBlock);
- }
-
- open(updateBlock);
- localsHandler =
- continueHandlers[0].mergeMultiple(continueHandlers, updateBlock);
-
- List<LabelDefinition> labels = jumpHandler.labels();
- JumpTarget target = elements.getTargetDefinition(loop);
- if (!labels.isEmpty) {
- beginBodyBlock.setBlockFlow(
- new HLabeledBlockInformation(
- new HSubGraphBlockInformation(bodyGraph), jumpHandler.labels(),
- isContinue: true),
- updateBlock);
- } else if (target != null && target.isContinueTarget) {
- beginBodyBlock.setBlockFlow(
- new HLabeledBlockInformation.implicit(
- new HSubGraphBlockInformation(bodyGraph), target,
- isContinue: true),
- updateBlock);
- }
-
- localsHandler.enterLoopUpdates(loop);
-
- update();
-
- HBasicBlock updateEndBlock = close(new HGoto());
- // The back-edge completing the cycle.
- updateEndBlock.addSuccessor(conditionBlock);
- updateGraph = new SubExpression(updateBlock, updateEndBlock);
-
- // Avoid a critical edge from the condition to the loop-exit body.
- HBasicBlock conditionExitBlock = addNewBlock();
- open(conditionExitBlock);
- close(new HGoto());
- conditionEndBlock.addSuccessor(conditionExitBlock);
-
- endLoop(conditionBlock, conditionExitBlock, jumpHandler, savedLocals);
-
- conditionBlock.postProcessLoopHeader();
- HLoopBlockInformation info = new HLoopBlockInformation(
- _loopKind(loop),
- wrapExpressionGraph(initializerGraph),
- wrapExpressionGraph(conditionExpression),
- wrapStatementGraph(bodyGraph),
- wrapExpressionGraph(updateGraph),
- conditionBlock.loopInformation.target,
- conditionBlock.loopInformation.labels,
- sourceInformationBuilder.buildLoop(loop));
-
- startBlock.setBlockFlow(info, current);
- loopInfo.loopBlockInformation = info;
- } else {
- // The body of the for/while loop always aborts, so there is no back edge.
- // We turn the code into:
- // if (condition) {
- // body;
- // } else {
- // // We always create an empty else block to avoid critical edges.
- // }
- //
- // If there is any break in the body, we attach a synthetic
- // label to the if.
- HBasicBlock elseBlock = addNewBlock();
- open(elseBlock);
- close(new HGoto());
- // Pass the elseBlock as the branchBlock, because that's the block we go
- // to just before leaving the 'loop'.
- endLoop(conditionBlock, elseBlock, jumpHandler, savedLocals);
-
- SubGraph elseGraph = new SubGraph(elseBlock, elseBlock);
- // Remove the loop information attached to the header.
- conditionBlock.loopInformation = null;
-
- // Remove the [HLoopBranch] instruction and replace it with
- // [HIf].
- HInstruction condition = conditionEndBlock.last.inputs[0];
- conditionEndBlock.addAtExit(new HIf(condition));
- conditionEndBlock.addSuccessor(elseBlock);
- conditionEndBlock.remove(conditionEndBlock.last);
- HIfBlockInformation info = new HIfBlockInformation(
- wrapExpressionGraph(conditionExpression),
- wrapStatementGraph(bodyGraph),
- wrapStatementGraph(elseGraph));
-
- conditionEndBlock.setBlockFlow(info, current);
- HIf ifBlock = conditionEndBlock.last;
- ifBlock.blockInformation = conditionEndBlock.blockFlow;
-
- // If the body has any break, attach a synthesized label to the
- // if block.
- if (jumpHandler.hasAnyBreak()) {
- JumpTarget target = elements.getTargetDefinition(loop);
- LabelDefinition label = target.addLabel(null, 'loop');
- label.setBreakTarget();
- SubGraph labelGraph = new SubGraph(conditionBlock, current);
- HLabeledBlockInformation labelInfo = new HLabeledBlockInformation(
- new HSubGraphBlockInformation(labelGraph),
- <LabelDefinition>[label]);
-
- conditionBlock.setBlockFlow(labelInfo, current);
-
- jumpHandler.forEachBreak((HBreak breakInstruction, _) {
- HBasicBlock block = breakInstruction.block;
- block.addAtExit(new HBreak.toLabel(label));
- block.remove(breakInstruction);
- });
- }
- }
- jumpHandler.close();
- loopNesting--;
- }
-
visitFor(ast.For node) {
assert(isReachable);
assert(node.body != null);
@@ -2254,7 +1763,8 @@
visit(node.body);
}
- handleLoop(node, buildInitializer, buildCondition, buildUpdate, buildBody);
+ loopHandler.handleLoop(
+ node, buildInitializer, buildCondition, buildUpdate, buildBody);
}
visitWhile(ast.While node) {
@@ -2264,7 +1774,7 @@
return popBoolified();
}
- handleLoop(node, () {}, buildCondition, () {}, () {
+ loopHandler.handleLoop(node, () {}, buildCondition, () {}, () {
visit(node.body);
});
}
@@ -2273,8 +1783,8 @@
assert(isReachable);
LocalsHandler savedLocals = new LocalsHandler.from(localsHandler);
localsHandler.startLoop(node);
- loopNesting++;
- JumpHandler jumpHandler = beginLoopHeader(node);
+ loopDepth++;
+ JumpHandler jumpHandler = loopHandler.beginLoopHeader(node);
HLoopInformation loopInfo = current.loopInformation;
HBasicBlock loopEntryBlock = current;
HBasicBlock bodyEntryBlock = current;
@@ -2361,7 +1871,8 @@
close(new HGoto());
conditionEndBlock.addSuccessor(conditionExitBlock);
- endLoop(loopEntryBlock, conditionExitBlock, jumpHandler, localsHandler);
+ loopHandler.endLoop(
+ loopEntryBlock, conditionExitBlock, jumpHandler, localsHandler);
loopEntryBlock.postProcessLoopHeader();
SubGraph bodyGraph = new SubGraph(loopEntryBlock, bodyExitBlock);
@@ -2384,7 +1895,7 @@
if (jumpHandler.hasAnyBreak()) {
// Null branchBlock because the body of the do-while loop always aborts,
// so we never get to the condition.
- endLoop(loopEntryBlock, null, jumpHandler, localsHandler);
+ loopHandler.endLoop(loopEntryBlock, null, jumpHandler, localsHandler);
// Since the body of the loop has a break, we attach a synthesized label
// to the body.
@@ -2403,7 +1914,7 @@
}
}
jumpHandler.close();
- loopNesting--;
+ loopDepth--;
}
visitFunctionExpression(ast.FunctionExpression node) {
@@ -2428,7 +1939,7 @@
});
TypeMask type =
- new TypeMask.nonNullExact(closureClassElement, compiler.world);
+ new TypeMask.nonNullExact(closureClassElement, compiler.closedWorld);
push(new HCreate(closureClassElement, capturedVariables, type)
..sourceInformation = sourceInformationBuilder.buildCreate(node));
@@ -2704,7 +2215,8 @@
// handler in the case of lists, because the constant handler
// does not look at elements in the list.
TypeMask type = TypeMaskFactory.inferredTypeForElement(field, compiler);
- if (!type.containsAll(compiler.world) && !instruction.isConstantNull()) {
+ if (!type.containsAll(compiler.closedWorld) &&
+ !instruction.isConstantNull()) {
// TODO(13429): The inferrer should know that an element
// cannot be null.
instruction.instructionType = type.nonNullable();
@@ -3048,7 +2560,8 @@
add(representations);
js.Name operator = backend.namer.operatorIs(element);
HInstruction isFieldName = addConstantStringFromName(operator);
- HInstruction asFieldName = compiler.world.hasAnyStrictSubtype(element)
+ HInstruction asFieldName = compiler.closedWorld
+ .hasAnyStrictSubtype(element)
? addConstantStringFromName(backend.namer.substitutionName(element))
: graph.addConstantNull(compiler);
List<HInstruction> inputs = <HInstruction>[
@@ -3072,7 +2585,7 @@
}
HInstruction buildFunctionType(FunctionType type) {
- type.accept(new TypeBuilder(compiler.world), this);
+ type.accept(new TypeBuilder(compiler.closedWorld), this);
return pop();
}
@@ -3688,8 +3201,7 @@
// TODO(5347): Try to avoid the need for calling [implementation] before
// calling [makeStaticArgumentList].
Selector selector = elements.getSelector(node);
- assert(invariant(
- node, selector.applies(function.implementation, compiler.world),
+ assert(invariant(node, selector.applies(function.implementation, backend),
message: "$selector does not apply to ${function.implementation}"));
List<HInstruction> inputs = makeStaticArgumentList(
selector.callStructure, node.arguments, function.implementation);
@@ -3854,10 +3366,11 @@
}
bool needsSubstitutionForTypeVariableAccess(ClassElement cls) {
- ClassWorld classWorld = compiler.world;
- if (classWorld.isUsedAsMixin(cls)) return true;
+ ClosedWorld closedWorld = compiler.closedWorld;
+ if (closedWorld.isUsedAsMixin(cls)) return true;
- return compiler.world.anyStrictSubclassOf(cls, (ClassElement subclass) {
+ return compiler.closedWorld.anyStrictSubclassOf(cls,
+ (ClassElement subclass) {
return !rti.isTrivialSubstitution(subclass, cls);
});
}
@@ -4038,12 +3551,12 @@
originalElement, send, compiler)) {
isFixedList = true;
TypeMask inferred = _inferredTypeOfNewList(send);
- return inferred.containsAll(compiler.world)
+ return inferred.containsAll(compiler.closedWorld)
? backend.fixedArrayType
: inferred;
} else if (isGrowableListConstructorCall) {
TypeMask inferred = _inferredTypeOfNewList(send);
- return inferred.containsAll(compiler.world)
+ return inferred.containsAll(compiler.closedWorld)
? backend.extendableArrayType
: inferred;
} else if (Elements.isConstructorOfTypedArraySubclass(
@@ -4052,8 +3565,9 @@
TypeMask inferred = _inferredTypeOfNewList(send);
ClassElement cls = element.enclosingClass;
assert(backend.isNative(cls.thisType.element));
- return inferred.containsAll(compiler.world)
- ? new TypeMask.nonNullExact(cls.thisType.element, compiler.world)
+ return inferred.containsAll(compiler.closedWorld)
+ ? new TypeMask.nonNullExact(
+ cls.thisType.element, compiler.closedWorld)
: inferred;
} else if (element.isGenerativeConstructor) {
ClassElement cls = element.enclosingClass;
@@ -4062,7 +3576,7 @@
return new TypeMask.nonNullEmpty();
} else {
return new TypeMask.nonNullExact(
- cls.thisType.element, compiler.world);
+ cls.thisType.element, compiler.closedWorld);
}
} else {
return TypeMaskFactory.inferredReturnTypeForElement(
@@ -4686,10 +4200,11 @@
bool isOptimizableOperationOnIndexable(Selector selector, Element element) {
bool isLength = selector.isGetter && selector.name == "length";
if (isLength || selector.isIndex) {
- return compiler.world.isSubtypeOf(
+ return compiler.closedWorld.isSubtypeOf(
element.enclosingClass.declaration, helpers.jsIndexableClass);
} else if (selector.isIndexSet) {
- return compiler.world.isSubtypeOf(element.enclosingClass.declaration,
+ return compiler.closedWorld.isSubtypeOf(
+ element.enclosingClass.declaration,
helpers.jsMutableIndexableClass);
} else {
return false;
@@ -4712,7 +4227,7 @@
return false;
}
- Element element = compiler.world.locateSingleElement(selector, mask);
+ Element element = compiler.closedWorld.locateSingleElement(selector, mask);
if (element != null &&
!element.isField &&
!(element.isGetter && selector.isCall) &&
@@ -4859,7 +4374,7 @@
typeMask =
TypeMaskFactory.inferredReturnTypeForElement(element, compiler);
}
- bool targetCanThrow = !compiler.world.getCannotThrow(element);
+ bool targetCanThrow = !compiler.closedWorld.getCannotThrow(element);
// TODO(5346): Try to avoid the need for calling [declaration] before
var instruction;
if (backend.isJsInterop(element)) {
@@ -4874,7 +4389,8 @@
instruction.instantiatedTypes =
new List<DartType>.from(currentInlinedInstantiations);
}
- instruction.sideEffects = compiler.world.getSideEffectsOfElement(element);
+ instruction.sideEffects =
+ compiler.closedWorld.getSideEffectsOfElement(element);
}
if (location == null) {
push(instruction);
@@ -4908,7 +4424,7 @@
selector, inputs, type, sourceInformation,
isSetter: selector.isSetter || selector.isIndexSet);
instruction.sideEffects =
- compiler.world.getSideEffectsOfSelector(selector, null);
+ compiler.closedWorld.getSideEffectsOfSelector(selector, null);
return instruction;
}
@@ -4938,7 +4454,7 @@
void generateSuperSendSet() {
Selector setterSelector = elements.getSelector(node);
if (Elements.isUnresolved(element) ||
- !setterSelector.applies(element, compiler.world)) {
+ !setterSelector.applies(element, compiler.backend)) {
generateSuperNoSuchMethodSend(node, setterSelector, setterInputs);
pop();
} else {
@@ -5917,7 +5433,7 @@
HInstruction awaited = pop();
// TODO(herhut): Improve this type.
push(new HAwait(awaited,
- new TypeMask.subclass(coreClasses.objectClass, compiler.world)));
+ new TypeMask.subclass(coreClasses.objectClass, compiler.closedWorld)));
}
visitTypeAnnotation(ast.TypeAnnotation node) {
@@ -5977,7 +5493,9 @@
}
TypeMask type = _inferredTypeOfNewList(node);
- if (!type.containsAll(compiler.world)) instruction.instructionType = type;
+ if (!type.containsAll(compiler.closedWorld)) {
+ instruction.instructionType = type;
+ }
stack.add(instruction);
}
@@ -6047,7 +5565,7 @@
* a special "null handler" is returned.
*
* [isLoopJump] is [:true:] when the jump handler is for a loop. This is used
- * to distinguish the synthetized loop created for a switch statement with
+ * to distinguish the synthesized loop created for a switch statement with
* continue statements from simple switch statements.
*/
JumpHandler createJumpHandler(ast.Statement node, {bool isLoopJump}) {
@@ -6081,8 +5599,10 @@
TypeMask mask = inferenceResults.typeOfIteratorMoveNext(node, elements);
pushInvokeDynamic(node, selector, mask, [streamIterator]);
HInstruction future = pop();
- push(new HAwait(future,
- new TypeMask.subclass(coreClasses.objectClass, compiler.world)));
+ push(new HAwait(
+ future,
+ new TypeMask.subclass(
+ coreClasses.objectClass, compiler.closedWorld)));
return popBoolified();
}
@@ -6114,12 +5634,14 @@
void buildUpdate() {}
buildProtectedByFinally(() {
- handleLoop(
+ loopHandler.handleLoop(
node, buildInitializer, buildCondition, buildUpdate, buildBody);
}, () {
pushInvokeDynamic(node, Selectors.cancel, null, [streamIterator]);
- push(new HAwait(pop(),
- new TypeMask.subclass(coreClasses.objectClass, compiler.world)));
+ push(new HAwait(
+ pop(),
+ new TypeMask.subclass(
+ coreClasses.objectClass, compiler.closedWorld)));
pop();
});
}
@@ -6137,11 +5659,11 @@
TypeMask mask = inferenceResults.typeOfIterator(node, elements);
- ClassWorld classWorld = compiler.world;
+ ClosedWorld closedWorld = compiler.closedWorld;
if (mask != null &&
- mask.satisfies(helpers.jsIndexableClass, classWorld) &&
+ mask.satisfies(helpers.jsIndexableClass, closedWorld) &&
// String is indexable but not iterable.
- !mask.satisfies(helpers.jsStringClass, classWorld)) {
+ !mask.satisfies(helpers.jsStringClass, closedWorld)) {
return buildSyncForInIndexable(node, mask);
}
buildSyncForInIterator(node);
@@ -6182,7 +5704,8 @@
visit(node.body);
}
- handleLoop(node, buildInitializer, buildCondition, () {}, buildBody);
+ loopHandler.handleLoop(
+ node, buildInitializer, buildCondition, () {}, buildBody);
}
buildAssignLoopVariable(ast.ForIn node, HInstruction value) {
@@ -6301,7 +5824,8 @@
localsHandler.updateLocal(indexVariable, addInstruction);
}
- handleLoop(node, buildInitializer, buildCondition, buildUpdate, buildBody);
+ loopHandler.handleLoop(
+ node, buildInitializer, buildCondition, buildUpdate, buildBody);
}
visitLabel(ast.Label node) {
@@ -6415,12 +5939,12 @@
// The instruction type will always be a subtype of the mapLiteralClass, but
// type inference might discover a more specific type, or find nothing (in
// dart2js unit tests).
- TypeMask mapType =
- new TypeMask.nonNullSubtype(helpers.mapLiteralClass, compiler.world);
+ TypeMask mapType = new TypeMask.nonNullSubtype(
+ helpers.mapLiteralClass, compiler.closedWorld);
TypeMask returnTypeMask =
TypeMaskFactory.inferredReturnTypeForElement(constructor, compiler);
TypeMask instructionType =
- mapType.intersection(returnTypeMask, compiler.world);
+ mapType.intersection(returnTypeMask, compiler.closedWorld);
addInlinedInstantiation(expectedType);
pushInvokeStatic(node, constructor, inputs,
@@ -6645,7 +6169,7 @@
}
void buildLoop() {
- handleLoop(node, () {}, buildCondition, () {}, buildSwitch);
+ loopHandler.handleLoop(node, () {}, buildCondition, () {}, buildSwitch);
}
if (hasDefault) {
@@ -7248,7 +6772,7 @@
Selector selector = Selectors.toString_;
TypeMask type = TypeMaskFactory.inferredTypeForSelector(
selector, expression.instructionType, compiler);
- if (type.containsOnlyString(compiler.world)) {
+ if (type.containsOnlyString(compiler.closedWorld)) {
builder.pushInvokeDynamic(node, selector, expression.instructionType,
<HInstruction>[expression]);
append(builder.pop());
@@ -7458,20 +6982,20 @@
}
class TypeBuilder implements DartTypeVisitor<dynamic, SsaBuilder> {
- final ClassWorld classWorld;
+ final ClosedWorld closedWorld;
- TypeBuilder(this.classWorld);
+ TypeBuilder(this.closedWorld);
void visit(DartType type, SsaBuilder builder) => type.accept(this, builder);
void visitVoidType(VoidType type, SsaBuilder builder) {
ClassElement cls = builder.backend.helpers.VoidRuntimeType;
- builder.push(new HVoidType(type, new TypeMask.exact(cls, classWorld)));
+ builder.push(new HVoidType(type, new TypeMask.exact(cls, closedWorld)));
}
void visitTypeVariableType(TypeVariableType type, SsaBuilder builder) {
ClassElement cls = builder.backend.helpers.RuntimeType;
- TypeMask instructionType = new TypeMask.subclass(cls, classWorld);
+ TypeMask instructionType = new TypeMask.subclass(cls, closedWorld);
if (!builder.sourceElement.enclosingElement.isClosure &&
builder.sourceElement.isInstanceMember) {
HInstruction receiver = builder.localsHandler.readThis();
@@ -7508,7 +7032,7 @@
ClassElement cls = builder.backend.helpers.RuntimeFunctionType;
builder.push(
- new HFunctionType(inputs, type, new TypeMask.exact(cls, classWorld)));
+ new HFunctionType(inputs, type, new TypeMask.exact(cls, closedWorld)));
}
void visitMalformedType(MalformedType type, SsaBuilder builder) {
@@ -7532,7 +7056,7 @@
cls = builder.backend.helpers.RuntimeTypeGeneric;
}
builder.push(
- new HInterfaceType(inputs, type, new TypeMask.exact(cls, classWorld)));
+ new HInterfaceType(inputs, type, new TypeMask.exact(cls, closedWorld)));
}
void visitTypedefType(TypedefType type, SsaBuilder builder) {
@@ -7544,22 +7068,6 @@
void visitDynamicType(DynamicType type, SsaBuilder builder) {
JavaScriptBackend backend = builder.compiler.backend;
ClassElement cls = backend.helpers.DynamicRuntimeType;
- builder.push(new HDynamicType(type, new TypeMask.exact(cls, classWorld)));
+ builder.push(new HDynamicType(type, new TypeMask.exact(cls, closedWorld)));
}
}
-
-/// Determine what kind of loop [node] represents. The result is one of the
-/// kinds defined in [HLoopBlockInformation].
-int _loopKind(ast.Node node) => node.accept(const _LoopTypeVisitor());
-
-class _LoopTypeVisitor extends ast.Visitor {
- const _LoopTypeVisitor();
- int visitNode(ast.Node node) => HLoopBlockInformation.NOT_A_LOOP;
- int visitWhile(ast.While node) => HLoopBlockInformation.WHILE_LOOP;
- int visitFor(ast.For node) => HLoopBlockInformation.FOR_LOOP;
- int visitDoWhile(ast.DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP;
- int visitAsyncForIn(ast.AsyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP;
- int visitSyncForIn(ast.SyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP;
- int visitSwitchStatement(ast.SwitchStatement node) =>
- HLoopBlockInformation.SWITCH_CONTINUE_LOOP;
-}
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index 2e4511c..2d4726d 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -13,13 +13,16 @@
import '../io/source_information.dart';
import '../js_backend/backend.dart' show JavaScriptBackend;
import '../kernel/kernel.dart';
+import '../resolution/tree_elements.dart';
import '../tree/dartstring.dart';
import '../types/masks.dart';
import '../universe/selector.dart';
import 'graph_builder.dart';
import 'kernel_ast_adapter.dart';
+import 'kernel_string_builder.dart';
import 'locals_handler.dart';
+import 'loop_handler.dart';
import 'nodes.dart';
import 'ssa_branch_builder.dart';
@@ -48,21 +51,25 @@
ir.Node target;
final AstElement targetElement;
final ResolvedAst resolvedAst;
- final Compiler compiler;
final CodegenRegistry registry;
JavaScriptBackend get backend => compiler.backend;
+ TreeElements get elements => resolvedAst.elements;
+
SourceInformationBuilder sourceInformationBuilder;
KernelAstAdapter astAdapter;
+ LoopHandler<ir.Node> loopHandler;
KernelSsaBuilder(
this.targetElement,
this.resolvedAst,
- this.compiler,
+ Compiler compiler,
this.registry,
SourceInformationStrategy sourceInformationFactory,
Kernel kernel) {
+ this.compiler = compiler;
+ this.loopHandler = new KernelLoopHandler(this);
graph.element = targetElement;
// TODO(het): Should sourceInformationBuilder be in GraphBuilder?
this.sourceInformationBuilder =
@@ -199,6 +206,55 @@
}
@override
+ void visitForStatement(ir.ForStatement forStatement) {
+ assert(isReachable);
+ assert(forStatement.body != null);
+ void buildInitializer() {
+ for (ir.VariableDeclaration declaration in forStatement.variables) {
+ declaration.accept(this);
+ }
+ }
+
+ HInstruction buildCondition() {
+ if (forStatement.condition == null) {
+ return graph.addConstantBool(true, compiler);
+ }
+ forStatement.condition.accept(this);
+ return popBoolified();
+ }
+
+ void buildUpdate() {
+ for (ir.Expression expression in forStatement.updates) {
+ expression.accept(this);
+ assert(!isAborted());
+ // The result of the update instruction isn't used, and can just
+ // be dropped.
+ pop();
+ }
+ }
+
+ void buildBody() {
+ forStatement.body.accept(this);
+ }
+
+ loopHandler.handleLoop(
+ forStatement, buildInitializer, buildCondition, buildUpdate, buildBody);
+ }
+
+ @override
+ void visitWhileStatement(ir.WhileStatement whileStatement) {
+ assert(isReachable);
+ HInstruction buildCondition() {
+ whileStatement.condition.accept(this);
+ return popBoolified();
+ }
+
+ loopHandler.handleLoop(whileStatement, () {}, buildCondition, () {}, () {
+ whileStatement.body.accept(this);
+ });
+ }
+
+ @override
void visitIfStatement(ir.IfStatement ifStatement) {
SsaBranchBuilder brancher = new SsaBranchBuilder(this, compiler);
brancher.handleIf(
@@ -514,7 +570,7 @@
null,
isSetter: selector.isSetter || selector.isIndexSet);
instruction.sideEffects =
- compiler.world.getSideEffectsOfSelector(selector, null);
+ compiler.closedWorld.getSideEffectsOfSelector(selector, null);
push(instruction);
}
@@ -523,7 +579,7 @@
ir.Constructor target = invocation.target;
List<HInstruction> arguments = _visitArguments(invocation.arguments);
TypeMask typeMask = new TypeMask.nonNullExact(
- astAdapter.getElement(target.enclosingClass), compiler.world);
+ astAdapter.getElement(target.enclosingClass), compiler.closedWorld);
_pushStaticInvocation(target, arguments, typeMask);
}
@@ -565,4 +621,11 @@
not.operand.accept(this);
push(new HNot(popBoolified(), backend.boolType));
}
+
+ @override
+ void visitStringConcatenation(ir.StringConcatenation stringConcat) {
+ KernelStringBuilder stringBuilder = new KernelStringBuilder(this);
+ stringConcat.accept(stringBuilder);
+ stack.add(stringBuilder.result);
+ }
}
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index 6faf0b4..e677afd 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -22,7 +22,7 @@
import '../universe/selector.dart' show Selector;
import '../universe/use.dart' show DynamicUse, StaticUse, TypeUse;
import '../util/util.dart';
-import '../world.dart' show ClassWorld;
+import '../world.dart' show ClosedWorld;
import 'codegen_helpers.dart';
import 'nodes.dart';
import 'variable_allocator.dart';
@@ -1656,21 +1656,22 @@
// type because our optimizations might end up in a state where the
// invoke dynamic knows more than the receiver.
ClassElement enclosing = node.element.enclosingClass;
- if (compiler.world.isInstantiated(enclosing)) {
- return new TypeMask.nonNullExact(enclosing.declaration, compiler.world);
+ if (compiler.closedWorld.isInstantiated(enclosing)) {
+ return new TypeMask.nonNullExact(
+ enclosing.declaration, compiler.closedWorld);
} else {
// The element is mixed in so a non-null subtype mask is the most
// precise we have.
- assert(invariant(node, compiler.world.isUsedAsMixin(enclosing),
+ assert(invariant(node, compiler.closedWorld.isUsedAsMixin(enclosing),
message: "Element ${node.element} from $enclosing expected "
"to be mixed in."));
return new TypeMask.nonNullSubtype(
- enclosing.declaration, compiler.world);
+ enclosing.declaration, compiler.closedWorld);
}
}
// If [JSInvocationMirror._invokeOn] is enabled, and this call
// might hit a `noSuchMethod`, we register an untyped selector.
- return compiler.world.extendMaskIfReachesAll(selector, mask);
+ return compiler.closedWorld.extendMaskIfReachesAll(selector, mask);
}
void registerMethodInvoke(HInvokeDynamic node) {
@@ -2703,18 +2704,18 @@
js.Expression generateReceiverOrArgumentTypeTest(
HInstruction input, TypeMask checkedType) {
- ClassWorld classWorld = compiler.world;
+ ClosedWorld closedWorld = compiler.closedWorld;
TypeMask inputType = input.instructionType;
// Figure out if it is beneficial to turn this into a null check.
// V8 generally prefers 'typeof' checks, but for integers and
// indexable primitives we cannot compile this test into a single
// typeof check so the null check is cheaper.
- bool isIntCheck = checkedType.containsOnlyInt(classWorld);
+ bool isIntCheck = checkedType.containsOnlyInt(closedWorld);
bool turnIntoNumCheck = isIntCheck && input.isIntegerOrNull(compiler);
bool turnIntoNullCheck = !turnIntoNumCheck &&
(checkedType.nullable() == inputType) &&
(isIntCheck ||
- checkedType.satisfies(helpers.jsIndexableClass, classWorld));
+ checkedType.satisfies(helpers.jsIndexableClass, closedWorld));
if (turnIntoNullCheck) {
use(input);
@@ -2724,15 +2725,15 @@
// input is !int
checkBigInt(input, '!==', input.sourceInformation);
return pop();
- } else if (turnIntoNumCheck || checkedType.containsOnlyNum(classWorld)) {
+ } else if (turnIntoNumCheck || checkedType.containsOnlyNum(closedWorld)) {
// input is !num
checkNum(input, '!==', input.sourceInformation);
return pop();
- } else if (checkedType.containsOnlyBool(classWorld)) {
+ } else if (checkedType.containsOnlyBool(closedWorld)) {
// input is !bool
checkBool(input, '!==', input.sourceInformation);
return pop();
- } else if (checkedType.containsOnlyString(classWorld)) {
+ } else if (checkedType.containsOnlyString(closedWorld)) {
// input is !string
checkString(input, '!==', input.sourceInformation);
return pop();
@@ -2743,11 +2744,11 @@
void visitTypeConversion(HTypeConversion node) {
if (node.isArgumentTypeCheck || node.isReceiverTypeCheck) {
- ClassWorld classWorld = compiler.world;
+ ClosedWorld closedWorld = compiler.closedWorld;
// An int check if the input is not int or null, is not
// sufficient for doing an argument or receiver check.
assert(compiler.options.trustTypeAnnotations ||
- !node.checkedType.containsOnlyInt(classWorld) ||
+ !node.checkedType.containsOnlyInt(closedWorld) ||
node.checkedInput.isIntegerOrNull(compiler));
js.Expression test = generateReceiverOrArgumentTypeTest(
node.checkedInput, node.checkedType);
@@ -2857,15 +2858,15 @@
void visitTypeInfoReadVariable(HTypeInfoReadVariable node) {
TypeVariableElement element = node.variable.element;
- ClassElement context = element.enclosingClass;
int index = element.index;
- use(node.inputs[0]);
+ HInstruction object = node.object;
+ use(object);
js.Expression receiver = pop();
- if (needsSubstitutionForTypeVariableAccess(context)) {
+ if (typeVariableAccessNeedsSubstitution(element, object.instructionType)) {
js.Expression typeName =
- js.quoteName(backend.namer.runtimeTypeName(context));
+ js.quoteName(backend.namer.runtimeTypeName(element.enclosingClass));
Element helperElement = helpers.getRuntimeTypeArgument;
registry.registerStaticUse(
new StaticUse.staticInvoke(helperElement, CallStructure.THREE_ARGS));
@@ -2909,11 +2910,25 @@
}
}
- bool needsSubstitutionForTypeVariableAccess(ClassElement cls) {
- ClassWorld classWorld = compiler.world;
- if (classWorld.isUsedAsMixin(cls)) return true;
+ bool typeVariableAccessNeedsSubstitution(
+ TypeVariableElement element, TypeMask receiverMask) {
+ ClassElement cls = element.enclosingClass;
+ ClosedWorld closedWorld = compiler.closedWorld;
- return compiler.world.anyStrictSubclassOf(cls, (ClassElement subclass) {
+ // See if the receiver type narrows the set of classes to ones that can be
+ // indexed.
+ // TODO(sra): Currently the only convenient query is [singleClass]. We
+ // should iterate over all the concrete classes in [receiverMask].
+ ClassElement receiverClass = receiverMask.singleClass(closedWorld);
+ if (receiverClass != null) {
+ if (backend.rti.isTrivialSubstitution(receiverClass, cls)) {
+ return false;
+ }
+ }
+
+ if (closedWorld.isUsedAsMixin(cls)) return true;
+
+ return closedWorld.anyStrictSubclassOf(cls, (ClassElement subclass) {
return !backend.rti.isTrivialSubstitution(subclass, cls);
});
}
diff --git a/pkg/compiler/lib/src/ssa/graph_builder.dart b/pkg/compiler/lib/src/ssa/graph_builder.dart
index f7578f3..9898c6a 100644
--- a/pkg/compiler/lib/src/ssa/graph_builder.dart
+++ b/pkg/compiler/lib/src/ssa/graph_builder.dart
@@ -2,9 +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.
+import '../compiler.dart';
import '../elements/elements.dart';
+import '../resolution/tree_elements.dart';
import '../types/types.dart';
+import 'jump_handler.dart';
import 'locals_handler.dart';
import 'nodes.dart';
@@ -16,6 +19,13 @@
/// Holds the resulting SSA graph.
final HGraph graph = new HGraph();
+ // TODO(het): remove this
+ /// A reference to the compiler.
+ Compiler compiler;
+
+ /// The tree elements for the element being built into an SSA graph.
+ TreeElements get elements;
+
/// Used to track the locals while building the graph.
LocalsHandler localsHandler;
@@ -24,6 +34,15 @@
/// We build the SSA graph by simulating a stack machine.
List<HInstruction> stack = <HInstruction>[];
+ /// The count of nested loops we are currently building.
+ ///
+ /// The loop nesting is consulted when inlining a function invocation. The
+ /// inlining heuristics take this information into account.
+ int loopDepth = 0;
+
+ /// A mapping from jump targets to their handlers.
+ Map<JumpTarget, JumpHandler> jumpTargets = <JumpTarget, JumpHandler>{};
+
void push(HInstruction instruction) {
add(instruction);
stack.add(instruction);
@@ -133,4 +152,14 @@
lastAddedParameter = result;
return result;
}
+
+ HSubGraphBlockInformation wrapStatementGraph(SubGraph statements) {
+ if (statements == null) return null;
+ return new HSubGraphBlockInformation(statements);
+ }
+
+ HSubExpressionBlockInformation wrapExpressionGraph(SubExpression expression) {
+ if (expression == null) return null;
+ return new HSubExpressionBlockInformation(expression);
+ }
}
diff --git a/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart b/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
index 10202de..eafe01b 100644
--- a/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
+++ b/pkg/compiler/lib/src/ssa/interceptor_simplifier.dart
@@ -49,7 +49,7 @@
BackendHelpers get helpers => backend.helpers;
- ClassWorld get classWorld => compiler.world;
+ ClassWorld get classWorld => compiler.closedWorld;
void visitGraph(HGraph graph) {
this.graph = graph;
diff --git a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
index cf05b2e..463c31c 100644
--- a/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
+++ b/pkg/compiler/lib/src/ssa/invoke_dynamic_specializers.dart
@@ -10,7 +10,7 @@
import '../types/types.dart';
import '../universe/call_structure.dart';
import '../universe/selector.dart';
-import '../world.dart' show World;
+import '../world.dart' show ClosedWorld;
import 'nodes.dart';
import 'types.dart';
@@ -660,7 +660,7 @@
if (right.isConstantNull() || left.isPrimitiveOrNull(compiler)) {
return newBuiltinVariant(instruction, compiler);
}
- World world = compiler.world;
+ ClosedWorld world = compiler.closedWorld;
JavaScriptBackend backend = compiler.backend;
Iterable<Element> matches =
world.allFunctions.filter(instruction.selector, instructionType);
diff --git a/pkg/compiler/lib/src/ssa/jump_handler.dart b/pkg/compiler/lib/src/ssa/jump_handler.dart
new file mode 100644
index 0000000..a50d496
--- /dev/null
+++ b/pkg/compiler/lib/src/ssa/jump_handler.dart
@@ -0,0 +1,234 @@
+// 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 '../common.dart';
+import '../elements/elements.dart';
+import '../tree/tree.dart' as ast;
+
+import 'builder.dart';
+import 'graph_builder.dart';
+import 'locals_handler.dart';
+import 'nodes.dart';
+
+/// A single break/continue instruction.
+class JumpHandlerEntry {
+ final HJump jumpInstruction;
+ final LocalsHandler locals;
+ bool isBreak() => jumpInstruction is HBreak;
+ bool isContinue() => jumpInstruction is HContinue;
+ JumpHandlerEntry(this.jumpInstruction, this.locals);
+}
+
+abstract class JumpHandler {
+ factory JumpHandler(GraphBuilder builder, JumpTarget target) {
+ return new TargetJumpHandler(builder, target);
+ }
+ void generateBreak([LabelDefinition label]);
+ void generateContinue([LabelDefinition label]);
+ void forEachBreak(void action(HBreak instruction, LocalsHandler locals));
+ void forEachContinue(
+ void action(HContinue instruction, LocalsHandler locals));
+ bool hasAnyContinue();
+ bool hasAnyBreak();
+ void close();
+ final JumpTarget target;
+ List<LabelDefinition> labels();
+}
+
+/// Jump handler used to avoid null checks when a target isn't used as the
+/// target of a break, and therefore doesn't need a break handler associated
+/// with it.
+class NullJumpHandler implements JumpHandler {
+ final DiagnosticReporter reporter;
+
+ NullJumpHandler(this.reporter);
+
+ void generateBreak([LabelDefinition label]) {
+ reporter.internalError(CURRENT_ELEMENT_SPANNABLE,
+ 'NullJumpHandler.generateBreak should not be called.');
+ }
+
+ void generateContinue([LabelDefinition label]) {
+ reporter.internalError(CURRENT_ELEMENT_SPANNABLE,
+ 'NullJumpHandler.generateContinue should not be called.');
+ }
+
+ void forEachBreak(Function ignored) {}
+ void forEachContinue(Function ignored) {}
+ void close() {}
+ bool hasAnyContinue() => false;
+ bool hasAnyBreak() => false;
+
+ List<LabelDefinition> labels() => const <LabelDefinition>[];
+ JumpTarget get target => null;
+}
+
+/// Jump handler that records breaks until a target block is available.
+///
+/// Breaks are always forward jumps. Continues in loops are implemented as
+/// breaks of the body. Continues in switches is currently not handled.
+class TargetJumpHandler implements JumpHandler {
+ final GraphBuilder builder;
+ final JumpTarget target;
+ final List<JumpHandlerEntry> jumps;
+
+ TargetJumpHandler(GraphBuilder builder, this.target)
+ : this.builder = builder,
+ jumps = <JumpHandlerEntry>[] {
+ assert(builder.jumpTargets[target] == null);
+ builder.jumpTargets[target] = this;
+ }
+
+ void generateBreak([LabelDefinition label]) {
+ HInstruction breakInstruction;
+ if (label == null) {
+ breakInstruction = new HBreak(target);
+ } else {
+ breakInstruction = new HBreak.toLabel(label);
+ }
+ LocalsHandler locals = new LocalsHandler.from(builder.localsHandler);
+ builder.close(breakInstruction);
+ jumps.add(new JumpHandlerEntry(breakInstruction, locals));
+ }
+
+ void generateContinue([LabelDefinition label]) {
+ HInstruction continueInstruction;
+ if (label == null) {
+ continueInstruction = new HContinue(target);
+ } else {
+ continueInstruction = new HContinue.toLabel(label);
+ // Switch case continue statements must be handled by the
+ // [SwitchCaseJumpHandler].
+ assert(label.target.statement is! ast.SwitchCase);
+ }
+ LocalsHandler locals = new LocalsHandler.from(builder.localsHandler);
+ builder.close(continueInstruction);
+ jumps.add(new JumpHandlerEntry(continueInstruction, locals));
+ }
+
+ void forEachBreak(Function action) {
+ for (JumpHandlerEntry entry in jumps) {
+ if (entry.isBreak()) action(entry.jumpInstruction, entry.locals);
+ }
+ }
+
+ void forEachContinue(Function action) {
+ for (JumpHandlerEntry entry in jumps) {
+ if (entry.isContinue()) action(entry.jumpInstruction, entry.locals);
+ }
+ }
+
+ bool hasAnyContinue() {
+ for (JumpHandlerEntry entry in jumps) {
+ if (entry.isContinue()) return true;
+ }
+ return false;
+ }
+
+ bool hasAnyBreak() {
+ for (JumpHandlerEntry entry in jumps) {
+ if (entry.isBreak()) return true;
+ }
+ return false;
+ }
+
+ void close() {
+ // The mapping from TargetElement to JumpHandler is no longer needed.
+ builder.jumpTargets.remove(target);
+ }
+
+ List<LabelDefinition> labels() {
+ List<LabelDefinition> result = null;
+ for (LabelDefinition element in target.labels) {
+ if (result == null) result = <LabelDefinition>[];
+ result.add(element);
+ }
+ return (result == null) ? const <LabelDefinition>[] : result;
+ }
+}
+
+/// Special [JumpHandler] implementation used to handle continue statements
+/// targeting switch cases.
+class SwitchCaseJumpHandler extends TargetJumpHandler {
+ /// Map from switch case targets to indices used to encode the flow of the
+ /// switch case loop.
+ final Map<JumpTarget, int> targetIndexMap = new Map<JumpTarget, int>();
+
+ SwitchCaseJumpHandler(
+ GraphBuilder builder, JumpTarget target, ast.SwitchStatement node)
+ : super(builder, target) {
+ // The switch case indices must match those computed in
+ // [SsaFromAstMixin.buildSwitchCaseConstants].
+ // Switch indices are 1-based so we can bypass the synthetic loop when no
+ // cases match simply by branching on the index (which defaults to null).
+ int switchIndex = 1;
+ for (ast.SwitchCase switchCase in node.cases) {
+ for (ast.Node labelOrCase in switchCase.labelsAndCases) {
+ ast.Node label = labelOrCase.asLabel();
+ if (label != null) {
+ LabelDefinition labelElement =
+ builder.elements.getLabelDefinition(label);
+ if (labelElement != null && labelElement.isContinueTarget) {
+ JumpTarget continueTarget = labelElement.target;
+ targetIndexMap[continueTarget] = switchIndex;
+ assert(builder.jumpTargets[continueTarget] == null);
+ builder.jumpTargets[continueTarget] = this;
+ }
+ }
+ }
+ switchIndex++;
+ }
+ }
+
+ void generateBreak([LabelDefinition label]) {
+ if (label == null) {
+ // Creates a special break instruction for the synthetic loop generated
+ // for a switch statement with continue statements. See
+ // [SsaFromAstMixin.buildComplexSwitchStatement] for detail.
+
+ HInstruction breakInstruction =
+ new HBreak(target, breakSwitchContinueLoop: true);
+ LocalsHandler locals = new LocalsHandler.from(builder.localsHandler);
+ builder.close(breakInstruction);
+ jumps.add(new JumpHandlerEntry(breakInstruction, locals));
+ } else {
+ super.generateBreak(label);
+ }
+ }
+
+ bool isContinueToSwitchCase(LabelDefinition label) {
+ return label != null && targetIndexMap.containsKey(label.target);
+ }
+
+ void generateContinue([LabelDefinition label]) {
+ if (isContinueToSwitchCase(label)) {
+ // Creates the special instructions 'label = i; continue l;' used in
+ // switch statements with continue statements. See
+ // [SsaFromAstMixin.buildComplexSwitchStatement] for detail.
+
+ assert(label != null);
+ // TODO(het): change the graph 'addConstantXXX' to take a ConstantSystem
+ // instead of a Compiler.
+ HInstruction value = builder.graph
+ .addConstantInt(targetIndexMap[label.target], builder.compiler);
+ builder.localsHandler.updateLocal(target, value);
+
+ assert(label.target.labels.contains(label));
+ HInstruction continueInstruction = new HContinue(target);
+ LocalsHandler locals = new LocalsHandler.from(builder.localsHandler);
+ builder.close(continueInstruction);
+ jumps.add(new JumpHandlerEntry(continueInstruction, locals));
+ } else {
+ super.generateContinue(label);
+ }
+ }
+
+ void close() {
+ // The mapping from TargetElement to JumpHandler is no longer needed.
+ for (JumpTarget target in targetIndexMap.keys) {
+ builder.jumpTargets.remove(target);
+ }
+ super.close();
+ }
+}
diff --git a/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart b/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart
index 4f31bb2..7f5b6f0 100644
--- a/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart
+++ b/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart
@@ -46,11 +46,14 @@
for (LibraryElement libraryElement in kernel.libraries.keys) {
_nodeToElement[kernel.libraries[libraryElement]] = libraryElement;
}
+ for (LocalFunctionElement localFunction in kernel.localFunctions.keys) {
+ _nodeToElement[kernel.localFunctions[localFunction]] = localFunction;
+ }
_typeConverter = new DartTypeConverter(this);
}
Compiler get _compiler => _backend.compiler;
- TreeElements get _elements => _resolvedAst.elements;
+ TreeElements get elements => _resolvedAst.elements;
ConstantValue getConstantForSymbol(ir.SymbolLiteral node) {
ast.Node astNode = getNode(node);
@@ -74,7 +77,8 @@
}
bool getCanThrow(ir.Node procedure) {
- return !_compiler.world.getCannotThrow(getElement(procedure));
+ FunctionElement function = getElement(procedure);
+ return !_compiler.closedWorld.getCannotThrow(function);
}
TypeMask returnTypeOf(ir.Member node) {
@@ -83,7 +87,7 @@
}
SideEffects getSideEffects(ir.Node node) {
- return _compiler.world.getSideEffectsOfElement(getElement(node));
+ return _compiler.closedWorld.getSideEffectsOfElement(getElement(node));
}
CallStructure getCallStructure(ir.Arguments arguments) {
@@ -124,12 +128,12 @@
TypeMask typeOfInvocation(ir.MethodInvocation invocation) {
return _compiler.globalInference.results
- .typeOfSend(getNode(invocation), _elements);
+ .typeOfSend(getNode(invocation), elements);
}
TypeMask typeOfGet(ir.PropertyGet getter) {
return _compiler.globalInference.results
- .typeOfSend(getNode(getter), _elements);
+ .typeOfSend(getNode(getter), elements);
}
TypeMask inferredTypeOf(ir.Member node) {
@@ -148,7 +152,7 @@
ConstantValue getConstantFor(ir.Node node) {
ConstantValue constantValue =
- _backend.constants.getConstantValueForNode(getNode(node), _elements);
+ _backend.constants.getConstantValueForNode(getNode(node), elements);
assert(invariant(getNode(node), constantValue != null,
message: 'No constant computed for $node'));
return constantValue;
@@ -164,6 +168,9 @@
return _backend.isInterceptedSelector(selector);
}
+ JumpTarget getTargetDefinition(ir.Node node) =>
+ elements.getTargetDefinition(getNode(node));
+
ir.Procedure get mapLiteralConstructor =>
kernel.functions[_backend.helpers.mapLiteralConstructor];
@@ -184,6 +191,8 @@
DartTypeConverter(this.astAdapter);
+ DartType visitType(ir.DartType type) => type.accept(this);
+
List<DartType> visitTypes(List<ir.DartType> types) {
return new List.generate(
types.length, (int index) => types[index].accept(this));
@@ -196,7 +205,16 @@
@override
DartType visitFunctionType(ir.FunctionType node) {
- throw new UnimplementedError("Function types not currently supported");
+ return new FunctionType.synthesized(
+ visitType(node.returnType),
+ visitTypes(node.positionalParameters
+ .take(node.requiredParameterCount)
+ .toList()),
+ visitTypes(node.positionalParameters
+ .skip(node.requiredParameterCount)
+ .toList()),
+ node.namedParameters.keys.toList(),
+ visitTypes(node.namedParameters.values.toList()));
}
@override
diff --git a/pkg/compiler/lib/src/ssa/kernel_impact.dart b/pkg/compiler/lib/src/ssa/kernel_impact.dart
index 15efe23..a2f9279 100644
--- a/pkg/compiler/lib/src/ssa/kernel_impact.dart
+++ b/pkg/compiler/lib/src/ssa/kernel_impact.dart
@@ -5,6 +5,7 @@
import 'package:kernel/ast.dart' as ir;
import '../common.dart';
+import '../common/names.dart';
import '../compiler.dart';
import '../constants/expressions.dart';
import '../dart_types.dart';
@@ -71,10 +72,17 @@
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));
+ }
+
ResolutionImpact buildField(ir.Field field) {
checkType(field.type);
if (field.initializer != null) {
- field.initializer.accept(this);
+ visitNode(field.initializer);
} else {
impactBuilder.registerFeature(Feature.FIELD_WITHOUT_INITIALIZER);
}
@@ -84,10 +92,8 @@
ResolutionImpact buildProcedure(ir.Procedure procedure) {
if (procedure.kind == ir.ProcedureKind.Method ||
procedure.kind == ir.ProcedureKind.Operator) {
- checkType(procedure.function.returnType);
- procedure.function.positionalParameters.forEach((v) => checkType(v.type));
- procedure.function.namedParameters.forEach((v) => checkType(v.type));
- procedure.function.body.accept(this);
+ checkFunctionTypes(procedure.function);
+ visitNode(procedure.function.body);
} else {
compiler.reporter.internalError(
resolvedAst.element,
@@ -97,8 +103,10 @@
return impactBuilder;
}
+ void visitNode(ir.Node node) => node?.accept(this);
+
void visitNodes(Iterable<ir.Node> nodes) {
- nodes.forEach((ir.Node node) => node.accept(this));
+ nodes.forEach(visitNode);
}
@override
@@ -106,19 +114,19 @@
@override
void visitExpressionStatement(ir.ExpressionStatement exprStatement) {
- exprStatement.expression.accept(this);
+ visitNode(exprStatement.expression);
}
@override
void visitReturnStatement(ir.ReturnStatement returnStatement) {
- returnStatement.expression?.accept(this);
+ visitNode(returnStatement.expression);
}
@override
void visitIfStatement(ir.IfStatement ifStatement) {
- ifStatement.condition.accept(this);
- ifStatement.then.accept(this);
- ifStatement.otherwise?.accept(this);
+ visitNode(ifStatement.condition);
+ visitNode(ifStatement.then);
+ visitNode(ifStatement.otherwise);
}
@override
@@ -178,17 +186,13 @@
}
void visitMapEntry(ir.MapEntry entry) {
- entry.key.accept(this);
- entry.value.accept(this);
+ visitNode(entry.key);
+ visitNode(entry.value);
}
void _visitArguments(ir.Arguments arguments) {
- for (ir.Expression argument in arguments.positional) {
- argument.accept(this);
- }
- for (ir.NamedExpression argument in arguments.named) {
- argument.value.accept(this);
- }
+ arguments.positional.forEach(visitNode);
+ arguments.named.forEach(visitNode);
}
@override
@@ -237,45 +241,88 @@
@override
void visitStaticGet(ir.StaticGet node) {
- Element target = astAdapter.getElement(node.target).declaration;
- impactBuilder.registerStaticUse(new StaticUse.staticGet(target));
+ ir.Member target = node.target;
+ Element element = astAdapter.getElement(target).declaration;
+ if (target is ir.Procedure && target.kind == ir.ProcedureKind.Method) {
+ impactBuilder.registerStaticUse(new StaticUse.staticTearOff(element));
+ } else {
+ impactBuilder.registerStaticUse(new StaticUse.staticGet(element));
+ }
}
@override
void visitMethodInvocation(ir.MethodInvocation invocation) {
- invocation.receiver.accept(this);
+ var receiver = invocation.receiver;
+ if (receiver is ir.VariableGet &&
+ receiver.variable.isFinal &&
+ receiver.variable.parent is ir.FunctionDeclaration) {
+ // Invocation of a local function. No need for dynamic use.
+ } else {
+ visitNode(invocation.receiver);
+ impactBuilder.registerDynamicUse(
+ new DynamicUse(astAdapter.getSelector(invocation), null));
+ }
_visitArguments(invocation.arguments);
- impactBuilder.registerDynamicUse(
- new DynamicUse(astAdapter.getSelector(invocation), null));
}
@override
void visitPropertyGet(ir.PropertyGet node) {
- node.receiver.accept(this);
+ visitNode(node.receiver);
impactBuilder.registerDynamicUse(new DynamicUse(
new Selector.getter(astAdapter.getName(node.name)), null));
}
@override
void visitPropertySet(ir.PropertySet node) {
- node.receiver.accept(this);
- node.value.accept(this);
+ visitNode(node.receiver);
+ visitNode(node.value);
impactBuilder.registerDynamicUse(new DynamicUse(
new Selector.setter(astAdapter.getName(node.name)), null));
}
@override
- void visitNot(ir.Not not) {
- not.operand.accept(this);
- }
-
- @override
void visitAssertStatement(ir.AssertStatement node) {
impactBuilder.registerFeature(
node.message != null ? Feature.ASSERT_WITH_MESSAGE : Feature.ASSERT);
- node.visitChildren(this);
+ visitNode(node.condition);
+ visitNode(node.message);
}
@override
+ void visitStringConcatenation(ir.StringConcatenation node) {
+ impactBuilder.registerFeature(Feature.STRING_INTERPOLATION);
+ impactBuilder.registerFeature(Feature.STRING_JUXTAPOSITION);
+ visitNodes(node.expressions);
+ }
+
+ @override
+ void visitFunctionDeclaration(ir.FunctionDeclaration node) {
+ impactBuilder
+ .registerStaticUse(new StaticUse.closure(astAdapter.getElement(node)));
+ checkFunctionTypes(node.function);
+ visitNode(node.function.body);
+ }
+
+ @override
+ void visitFunctionExpression(ir.FunctionExpression node) {
+ impactBuilder
+ .registerStaticUse(new StaticUse.closure(astAdapter.getElement(node)));
+ checkFunctionTypes(node.function);
+ visitNode(node.function.body);
+ }
+
+ @override
+ void visitVariableDeclaration(ir.VariableDeclaration node) {
+ checkType(node.type);
+ if (node.initializer != null) {
+ visitNode(node.initializer);
+ } else {
+ impactBuilder.registerFeature(Feature.LOCAL_WITHOUT_INITIALIZER);
+ }
+ }
+
+ // TODO(johnniwinther): Make this throw and visit child nodes explicitly
+ // instead to ensure that we don't visit unwanted parts of the ir.
+ @override
void defaultNode(ir.Node node) => node.visitChildren(this);
}
diff --git a/pkg/compiler/lib/src/ssa/kernel_string_builder.dart b/pkg/compiler/lib/src/ssa/kernel_string_builder.dart
new file mode 100644
index 0000000..21da2e4
--- /dev/null
+++ b/pkg/compiler/lib/src/ssa/kernel_string_builder.dart
@@ -0,0 +1,75 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:kernel/ast.dart' as ir;
+
+import '../compiler.dart';
+
+import 'builder_kernel.dart';
+import 'kernel_ast_adapter.dart';
+import 'nodes.dart';
+
+/// Visits and concatenates the expressions in a string concatenation.
+class KernelStringBuilder extends ir.Visitor {
+ final KernelSsaBuilder builder;
+ Compiler get compiler => builder.compiler;
+ KernelAstAdapter get astAdapter => builder.astAdapter;
+
+ /// The string value generated so far.
+ HInstruction result = null;
+
+ KernelStringBuilder(this.builder);
+
+ @override
+ void defaultNode(ir.Node node) {
+ compiler.reporter
+ .internalError(astAdapter.getNode(node), 'Unexpected node.');
+ }
+
+ @override
+ void defaultExpression(ir.Expression node) {
+ node.accept(builder);
+ HInstruction expression = builder.pop();
+
+ // We want to use HStringify when:
+ // 1. The value is known to be a primitive type, because it might get
+ // constant-folded and codegen has some tricks with JavaScript
+ // conversions.
+ // 2. The value can be primitive, because the library stringifier has
+ // fast-path code for most primitives.
+ if (expression.canBePrimitive(compiler)) {
+ append(stringify(expression));
+ return;
+ }
+
+ // TODO(het): If toString method is guaranteed to return a string, then call
+ // it directly instead of stringify. Or, better yet, do this later in the
+ // optimization phase.
+
+ append(stringify(expression));
+ }
+
+ @override
+ void visitStringConcatenation(ir.StringConcatenation node) {
+ node.visitChildren(this);
+ }
+
+ void append(HInstruction expression) {
+ result = (result == null) ? expression : concat(result, expression);
+ }
+
+ HInstruction concat(HInstruction left, HInstruction right) {
+ HInstruction instruction =
+ new HStringConcat(left, right, builder.backend.stringType);
+ builder.add(instruction);
+ return instruction;
+ }
+
+ HInstruction stringify(HInstruction expression) {
+ HInstruction instruction =
+ new HStringify(expression, builder.backend.stringType);
+ builder.add(instruction);
+ return instruction;
+ }
+}
diff --git a/pkg/compiler/lib/src/ssa/locals_handler.dart b/pkg/compiler/lib/src/ssa/locals_handler.dart
index 581114a..2aa766c 100644
--- a/pkg/compiler/lib/src/ssa/locals_handler.dart
+++ b/pkg/compiler/lib/src/ssa/locals_handler.dart
@@ -13,7 +13,7 @@
import '../native/native.dart' as native;
import '../tree/tree.dart' as ast;
import '../types/types.dart';
-import '../world.dart' show ClassWorld;
+import '../world.dart' show ClosedWorld;
import 'builder.dart' show SyntheticLocal;
import 'graph_builder.dart';
import 'nodes.dart';
@@ -267,9 +267,9 @@
new SyntheticLocal('receiver', executableContext);
// Unlike `this`, receiver is nullable since direct calls to generative
// constructor call the constructor with `null`.
- ClassWorld classWorld = _compiler.world;
+ ClosedWorld closedWorld = _compiler.closedWorld;
HParameterValue value =
- new HParameterValue(parameter, new TypeMask.exact(cls, classWorld));
+ new HParameterValue(parameter, new TypeMask.exact(cls, closedWorld));
builder.graph.explicitReceiverParameter = value;
builder.graph.entry.addAtEntry(value);
}
@@ -625,15 +625,17 @@
if (result == null) {
ThisLocal local = closureData.thisLocal;
ClassElement cls = local.enclosingClass;
- ClassWorld classWorld = _compiler.world;
- if (classWorld.isUsedAsMixin(cls)) {
+ ClosedWorld closedWorld = _compiler.closedWorld;
+ if (closedWorld.isUsedAsMixin(cls)) {
// If the enclosing class is used as a mixin, [:this:] can be
// of the class that mixins the enclosing class. These two
// classes do not have a subclass relationship, so, for
// simplicity, we mark the type as an interface type.
- result = new TypeMask.nonNullSubtype(cls.declaration, _compiler.world);
+ result =
+ new TypeMask.nonNullSubtype(cls.declaration, _compiler.closedWorld);
} else {
- result = new TypeMask.nonNullSubclass(cls.declaration, _compiler.world);
+ result = new TypeMask.nonNullSubclass(
+ cls.declaration, _compiler.closedWorld);
}
cachedTypeOfThis = result;
}
diff --git a/pkg/compiler/lib/src/ssa/loop_handler.dart b/pkg/compiler/lib/src/ssa/loop_handler.dart
new file mode 100644
index 0000000..e897820
--- /dev/null
+++ b/pkg/compiler/lib/src/ssa/loop_handler.dart
@@ -0,0 +1,414 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:kernel/ast.dart' as ir;
+
+import '../elements/elements.dart';
+import '../io/source_information.dart';
+import '../tree/tree.dart' as ast;
+
+import 'builder.dart';
+import 'builder_kernel.dart';
+import 'graph_builder.dart';
+import 'jump_handler.dart';
+import 'kernel_ast_adapter.dart';
+import 'locals_handler.dart';
+import 'nodes.dart';
+
+/// Builds the SSA graph for loop nodes.
+abstract class LoopHandler<T> {
+ final GraphBuilder builder;
+
+ LoopHandler(this.builder);
+
+ /// Builds a graph for the given [loop] node.
+ ///
+ /// For while loops, [initialize] and [update] are null.
+ /// The [condition] function must return a boolean result.
+ /// None of the functions must leave anything on the stack.
+ void handleLoop(T loop, void initialize(), HInstruction condition(),
+ void update(), void body()) {
+ // Generate:
+ // <initializer>
+ // loop-entry:
+ // if (!<condition>) goto loop-exit;
+ // <body>
+ // <updates>
+ // goto loop-entry;
+ // loop-exit:
+
+ builder.localsHandler.startLoop(getNode(loop));
+
+ // The initializer.
+ SubExpression initializerGraph = null;
+ HBasicBlock startBlock;
+ if (initialize != null) {
+ HBasicBlock initializerBlock = builder.openNewBlock();
+ startBlock = initializerBlock;
+ initialize();
+ assert(!builder.isAborted());
+ initializerGraph = new SubExpression(initializerBlock, builder.current);
+ }
+
+ builder.loopDepth++;
+ JumpHandler jumpHandler = beginLoopHeader(loop);
+ HLoopInformation loopInfo = builder.current.loopInformation;
+ HBasicBlock conditionBlock = builder.current;
+ if (startBlock == null) startBlock = conditionBlock;
+
+ HInstruction conditionInstruction = condition();
+ HBasicBlock conditionEndBlock =
+ builder.close(new HLoopBranch(conditionInstruction));
+ SubExpression conditionExpression =
+ new SubExpression(conditionBlock, conditionEndBlock);
+
+ // Save the values of the local variables at the end of the condition
+ // block. These are the values that will flow to the loop exit if the
+ // condition fails.
+ LocalsHandler savedLocals = new LocalsHandler.from(builder.localsHandler);
+
+ // The body.
+ HBasicBlock beginBodyBlock = builder.addNewBlock();
+ conditionEndBlock.addSuccessor(beginBodyBlock);
+ builder.open(beginBodyBlock);
+
+ builder.localsHandler.enterLoopBody(getNode(loop));
+ body();
+
+ SubGraph bodyGraph = new SubGraph(beginBodyBlock, builder.lastOpenedBlock);
+ HBasicBlock bodyBlock = builder.current;
+ if (builder.current != null) builder.close(new HGoto());
+
+ SubExpression updateGraph;
+
+ bool loopIsDegenerate = !jumpHandler.hasAnyContinue() && bodyBlock == null;
+ if (!loopIsDegenerate) {
+ // Update.
+ // We create an update block, even when we are in a while loop. There the
+ // update block is the jump-target for continue statements. We could avoid
+ // the creation if there is no continue, but for now we always create it.
+ HBasicBlock updateBlock = builder.addNewBlock();
+
+ List<LocalsHandler> continueHandlers = <LocalsHandler>[];
+ jumpHandler
+ .forEachContinue((HContinue instruction, LocalsHandler locals) {
+ instruction.block.addSuccessor(updateBlock);
+ continueHandlers.add(locals);
+ });
+
+ if (bodyBlock != null) {
+ continueHandlers.add(builder.localsHandler);
+ bodyBlock.addSuccessor(updateBlock);
+ }
+
+ builder.open(updateBlock);
+ builder.localsHandler =
+ continueHandlers[0].mergeMultiple(continueHandlers, updateBlock);
+
+ List<LabelDefinition> labels = jumpHandler.labels();
+ JumpTarget target = getTargetDefinition(loop);
+ if (!labels.isEmpty) {
+ beginBodyBlock.setBlockFlow(
+ new HLabeledBlockInformation(
+ new HSubGraphBlockInformation(bodyGraph), jumpHandler.labels(),
+ isContinue: true),
+ updateBlock);
+ } else if (target != null && target.isContinueTarget) {
+ beginBodyBlock.setBlockFlow(
+ new HLabeledBlockInformation.implicit(
+ new HSubGraphBlockInformation(bodyGraph), target,
+ isContinue: true),
+ updateBlock);
+ }
+
+ builder.localsHandler.enterLoopUpdates(getNode(loop));
+
+ update();
+
+ HBasicBlock updateEndBlock = builder.close(new HGoto());
+ // The back-edge completing the cycle.
+ updateEndBlock.addSuccessor(conditionBlock);
+ updateGraph = new SubExpression(updateBlock, updateEndBlock);
+
+ // Avoid a critical edge from the condition to the loop-exit body.
+ HBasicBlock conditionExitBlock = builder.addNewBlock();
+ builder.open(conditionExitBlock);
+ builder.close(new HGoto());
+ conditionEndBlock.addSuccessor(conditionExitBlock);
+
+ endLoop(conditionBlock, conditionExitBlock, jumpHandler, savedLocals);
+
+ conditionBlock.postProcessLoopHeader();
+ HLoopBlockInformation info = new HLoopBlockInformation(
+ loopKind(loop),
+ builder.wrapExpressionGraph(initializerGraph),
+ builder.wrapExpressionGraph(conditionExpression),
+ builder.wrapStatementGraph(bodyGraph),
+ builder.wrapExpressionGraph(updateGraph),
+ conditionBlock.loopInformation.target,
+ conditionBlock.loopInformation.labels,
+ loopSourceInformation(loop));
+
+ startBlock.setBlockFlow(info, builder.current);
+ loopInfo.loopBlockInformation = info;
+ } else {
+ // The body of the for/while loop always aborts, so there is no back edge.
+ // We turn the code into:
+ // if (condition) {
+ // body;
+ // } else {
+ // // We always create an empty else block to avoid critical edges.
+ // }
+ //
+ // If there is any break in the body, we attach a synthetic
+ // label to the if.
+ HBasicBlock elseBlock = builder.addNewBlock();
+ builder.open(elseBlock);
+ builder.close(new HGoto());
+ // Pass the elseBlock as the branchBlock, because that's the block we go
+ // to just before leaving the 'loop'.
+ endLoop(conditionBlock, elseBlock, jumpHandler, savedLocals);
+
+ SubGraph elseGraph = new SubGraph(elseBlock, elseBlock);
+ // Remove the loop information attached to the header.
+ conditionBlock.loopInformation = null;
+
+ // Remove the [HLoopBranch] instruction and replace it with
+ // [HIf].
+ HInstruction condition = conditionEndBlock.last.inputs[0];
+ conditionEndBlock.addAtExit(new HIf(condition));
+ conditionEndBlock.addSuccessor(elseBlock);
+ conditionEndBlock.remove(conditionEndBlock.last);
+ HIfBlockInformation info = new HIfBlockInformation(
+ builder.wrapExpressionGraph(conditionExpression),
+ builder.wrapStatementGraph(bodyGraph),
+ builder.wrapStatementGraph(elseGraph));
+
+ conditionEndBlock.setBlockFlow(info, builder.current);
+ HIf ifBlock = conditionEndBlock.last;
+ ifBlock.blockInformation = conditionEndBlock.blockFlow;
+
+ // If the body has any break, attach a synthesized label to the
+ // if block.
+ if (jumpHandler.hasAnyBreak()) {
+ JumpTarget target = getTargetDefinition(loop);
+ LabelDefinition label = target.addLabel(null, 'loop');
+ label.setBreakTarget();
+ SubGraph labelGraph = new SubGraph(conditionBlock, builder.current);
+ HLabeledBlockInformation labelInfo = new HLabeledBlockInformation(
+ new HSubGraphBlockInformation(labelGraph),
+ <LabelDefinition>[label]);
+
+ conditionBlock.setBlockFlow(labelInfo, builder.current);
+
+ jumpHandler.forEachBreak((HBreak breakInstruction, _) {
+ HBasicBlock block = breakInstruction.block;
+ block.addAtExit(new HBreak.toLabel(label));
+ block.remove(breakInstruction);
+ });
+ }
+ }
+ jumpHandler.close();
+ builder.loopDepth--;
+ }
+
+ /// Creates a new loop-header block. The previous [current] block
+ /// is closed with an [HGoto] and replaced by the newly created block.
+ /// Also notifies the locals handler that we're entering a loop.
+ JumpHandler beginLoopHeader(T node) {
+ assert(!builder.isAborted());
+ HBasicBlock previousBlock = builder.close(new HGoto());
+
+ JumpHandler jumpHandler = createJumpHandler(node, isLoopJump: true);
+ HBasicBlock loopEntry = builder.graph
+ .addNewLoopHeaderBlock(jumpHandler.target, jumpHandler.labels());
+ previousBlock.addSuccessor(loopEntry);
+ builder.open(loopEntry);
+
+ builder.localsHandler.beginLoopHeader(loopEntry);
+ return jumpHandler;
+ }
+
+ /// Ends the loop.
+ ///
+ /// It does this by:
+ /// - creating a new block and adding it as successor to the [branchExitBlock]
+ /// and any blocks that end in break.
+ /// - opening the new block (setting as [current]).
+ /// - notifying the locals handler that we're exiting a loop.
+ ///
+ /// [savedLocals] are the locals from the end of the loop condition.
+ ///
+ /// [branchExitBlock] is the exit (branching) block of the condition.
+ /// Generally this is not the top of the loop, since this would lead to
+ /// critical edges. It is null for degenerate do-while loops that have no back
+ /// edge because they abort (throw/return/break in the body and have no
+ /// continues).
+ void endLoop(HBasicBlock loopEntry, HBasicBlock branchExitBlock,
+ JumpHandler jumpHandler, LocalsHandler savedLocals) {
+ HBasicBlock loopExitBlock = builder.addNewBlock();
+
+ List<LocalsHandler> breakHandlers = <LocalsHandler>[];
+ // Collect data for the successors and the phis at each break.
+ jumpHandler.forEachBreak((HBreak breakInstruction, LocalsHandler locals) {
+ breakInstruction.block.addSuccessor(loopExitBlock);
+ breakHandlers.add(locals);
+ });
+
+ // The exit block is a successor of the loop condition if it is reached.
+ // We don't add the successor in the case of a while/for loop that aborts
+ // because the caller of endLoop will be wiring up a special empty else
+ // block instead.
+ if (branchExitBlock != null) {
+ branchExitBlock.addSuccessor(loopExitBlock);
+ }
+ // Update the phis at the loop entry with the current values of locals.
+ builder.localsHandler.endLoop(loopEntry);
+
+ // Start generating code for the exit block.
+ builder.open(loopExitBlock);
+
+ // Create a new localsHandler for the loopExitBlock with the correct phis.
+ if (!breakHandlers.isEmpty) {
+ if (branchExitBlock != null) {
+ // Add the values of the locals at the end of the condition block to
+ // the phis. These are the values that flow to the exit if the
+ // condition fails.
+ breakHandlers.add(savedLocals);
+ }
+ builder.localsHandler =
+ savedLocals.mergeMultiple(breakHandlers, loopExitBlock);
+ } else {
+ builder.localsHandler = savedLocals;
+ }
+ }
+
+ /// Returns the jump target defined by [node].
+ JumpTarget getTargetDefinition(T node);
+
+ /// Returns the corresponding AST node for [node].
+ ast.Node getNode(T node);
+
+ /// Determine what kind of loop [node] represents.
+ ///
+ /// The result is one of the kinds defined in [HLoopBlockInformation].
+ int loopKind(T node);
+
+ /// Returns the source information for the loop [node].
+ SourceInformation loopSourceInformation(T node);
+
+ /// Creates a [JumpHandler] for a statement. The node must be a jump
+ /// target. If there are no breaks or continues targeting the statement,
+ /// a special "null handler" is returned.
+ ///
+ /// [isLoopJump] is [:true:] when the jump handler is for a loop. This is used
+ /// to distinguish the synthesized loop created for a switch statement with
+ /// continue statements from simple switch statements.
+ JumpHandler createJumpHandler(T node, {bool isLoopJump});
+}
+
+/// A loop handler for the builder that just uses AST nodes directly.
+class SsaLoopHandler extends LoopHandler<ast.Node> {
+ final SsaBuilder builder;
+
+ SsaLoopHandler(SsaBuilder builder)
+ : this.builder = builder,
+ super(builder);
+
+ @override
+ JumpTarget getTargetDefinition(ast.Node node) {
+ return builder.elements.getTargetDefinition(node);
+ }
+
+ @override
+ ast.Node getNode(ast.Node node) => node;
+
+ @override
+ int loopKind(ast.Node node) => node.accept(const _SsaLoopTypeVisitor());
+
+ @override
+ SourceInformation loopSourceInformation(ast.Node node) =>
+ builder.sourceInformationBuilder.buildLoop(node);
+
+ @override
+ JumpHandler createJumpHandler(ast.Node node, {bool isLoopJump}) =>
+ builder.createJumpHandler(node, isLoopJump: isLoopJump);
+}
+
+class _SsaLoopTypeVisitor extends ast.Visitor {
+ const _SsaLoopTypeVisitor();
+ int visitNode(ast.Node node) => HLoopBlockInformation.NOT_A_LOOP;
+ int visitWhile(ast.While node) => HLoopBlockInformation.WHILE_LOOP;
+ int visitFor(ast.For node) => HLoopBlockInformation.FOR_LOOP;
+ int visitDoWhile(ast.DoWhile node) => HLoopBlockInformation.DO_WHILE_LOOP;
+ int visitAsyncForIn(ast.AsyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP;
+ int visitSyncForIn(ast.SyncForIn node) => HLoopBlockInformation.FOR_IN_LOOP;
+ int visitSwitchStatement(ast.SwitchStatement node) =>
+ HLoopBlockInformation.SWITCH_CONTINUE_LOOP;
+}
+
+// TODO(het): Since kernel simplifies loop breaks and continues, we should
+// rewrite the loop handler from scratch to account for the simplified structure
+class KernelLoopHandler extends LoopHandler<ir.Node> {
+ final KernelSsaBuilder builder;
+
+ KernelAstAdapter get astAdapter => builder.astAdapter;
+
+ KernelLoopHandler(KernelSsaBuilder builder)
+ : this.builder = builder,
+ super(builder);
+
+ @override
+ JumpHandler createJumpHandler(ir.Node node, {bool isLoopJump}) {
+ JumpTarget element = getTargetDefinition(node);
+ if (element == null || !identical(element.statement, node)) {
+ // No breaks or continues to this node.
+ return new NullJumpHandler(builder.compiler.reporter);
+ }
+ if (isLoopJump && node is ast.SwitchStatement) {
+ // Create a special jump handler for loops created for switch statements
+ // with continue statements.
+ return new SwitchCaseJumpHandler(builder, element, getNode(node));
+ }
+ return new JumpHandler(builder, element);
+ }
+
+ @override
+ ast.Node getNode(ir.Node node) => astAdapter.getNode(node);
+
+ @override
+ JumpTarget getTargetDefinition(ir.Node node) =>
+ astAdapter.getTargetDefinition(node);
+
+ @override
+ int loopKind(ir.Node node) => node.accept(new _KernelLoopTypeVisitor());
+
+ // TODO(het): return the actual source information
+ @override
+ SourceInformation loopSourceInformation(ir.Node node) => null;
+}
+
+class _KernelLoopTypeVisitor extends ir.Visitor<int> {
+ @override
+ int defaultNode(ir.Node node) => HLoopBlockInformation.NOT_A_LOOP;
+
+ @override
+ int visitWhileStatement(ir.WhileStatement node) =>
+ HLoopBlockInformation.WHILE_LOOP;
+
+ @override
+ int visitForStatement(ir.ForStatement node) => HLoopBlockInformation.FOR_LOOP;
+
+ @override
+ int visitDoStatement(ir.DoStatement node) =>
+ HLoopBlockInformation.DO_WHILE_LOOP;
+
+ @override
+ int visitForInStatement(ir.ForInStatement node) =>
+ HLoopBlockInformation.FOR_IN_LOOP;
+
+ @override
+ int visitSwitchStatement(ir.SwitchStatement node) =>
+ HLoopBlockInformation.SWITCH_CONTINUE_LOOP;
+}
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index e3342cd..ddeaf26 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -20,7 +20,7 @@
import '../universe/selector.dart' show Selector;
import '../universe/side_effects.dart' show SideEffects;
import '../util/util.dart';
-import '../world.dart' show ClassWorld;
+import '../world.dart' show ClosedWorld;
import 'invoke_dynamic_specializers.dart';
import 'validate.dart';
@@ -926,20 +926,22 @@
/// Returns `true` if [typeMask] contains [cls].
static bool containsType(
- TypeMask typeMask, ClassElement cls, ClassWorld classWorld) {
- return classWorld.isInstantiated(cls) && typeMask.contains(cls, classWorld);
+ TypeMask typeMask, ClassElement cls, ClosedWorld closedWorld) {
+ return closedWorld.isInstantiated(cls) &&
+ typeMask.contains(cls, closedWorld);
}
/// Returns `true` if [typeMask] contains only [cls].
static bool containsOnlyType(
- TypeMask typeMask, ClassElement cls, ClassWorld classWorld) {
- return classWorld.isInstantiated(cls) && typeMask.containsOnly(cls);
+ TypeMask typeMask, ClassElement cls, ClosedWorld closedWorld) {
+ return closedWorld.isInstantiated(cls) && typeMask.containsOnly(cls);
}
/// Returns `true` if [typeMask] is an instance of [cls].
static bool isInstanceOf(
- TypeMask typeMask, ClassElement cls, ClassWorld classWorld) {
- return classWorld.isImplemented(cls) && typeMask.satisfies(cls, classWorld);
+ TypeMask typeMask, ClassElement cls, ClosedWorld closedWorld) {
+ return closedWorld.isImplemented(cls) &&
+ typeMask.satisfies(cls, closedWorld);
}
bool canBePrimitive(Compiler compiler) {
@@ -951,182 +953,183 @@
}
bool canBePrimitiveNumber(Compiler compiler) {
- ClassWorld classWorld = compiler.world;
+ ClosedWorld closedWorld = compiler.closedWorld;
JavaScriptBackend backend = compiler.backend;
BackendHelpers helpers = backend.helpers;
// TODO(sra): It should be possible to test only jsDoubleClass and
// jsUInt31Class, since all others are superclasses of these two.
- return containsType(instructionType, helpers.jsNumberClass, classWorld) ||
- containsType(instructionType, helpers.jsIntClass, classWorld) ||
- containsType(instructionType, helpers.jsPositiveIntClass, classWorld) ||
- containsType(instructionType, helpers.jsUInt32Class, classWorld) ||
- containsType(instructionType, helpers.jsUInt31Class, classWorld) ||
- containsType(instructionType, helpers.jsDoubleClass, classWorld);
+ return containsType(instructionType, helpers.jsNumberClass, closedWorld) ||
+ containsType(instructionType, helpers.jsIntClass, closedWorld) ||
+ containsType(
+ instructionType, helpers.jsPositiveIntClass, closedWorld) ||
+ containsType(instructionType, helpers.jsUInt32Class, closedWorld) ||
+ containsType(instructionType, helpers.jsUInt31Class, closedWorld) ||
+ containsType(instructionType, helpers.jsDoubleClass, closedWorld);
}
bool canBePrimitiveBoolean(Compiler compiler) {
- ClassWorld classWorld = compiler.world;
+ ClosedWorld closedWorld = compiler.closedWorld;
JavaScriptBackend backend = compiler.backend;
BackendHelpers helpers = backend.helpers;
- return containsType(instructionType, helpers.jsBoolClass, classWorld);
+ return containsType(instructionType, helpers.jsBoolClass, closedWorld);
}
bool canBePrimitiveArray(Compiler compiler) {
- ClassWorld classWorld = compiler.world;
+ ClosedWorld closedWorld = compiler.closedWorld;
JavaScriptBackend backend = compiler.backend;
BackendHelpers helpers = backend.helpers;
- return containsType(instructionType, helpers.jsArrayClass, classWorld) ||
- containsType(instructionType, helpers.jsFixedArrayClass, classWorld) ||
+ return containsType(instructionType, helpers.jsArrayClass, closedWorld) ||
+ containsType(instructionType, helpers.jsFixedArrayClass, closedWorld) ||
containsType(
- instructionType, helpers.jsExtendableArrayClass, classWorld) ||
+ instructionType, helpers.jsExtendableArrayClass, closedWorld) ||
containsType(
- instructionType, helpers.jsUnmodifiableArrayClass, classWorld);
+ instructionType, helpers.jsUnmodifiableArrayClass, closedWorld);
}
bool isIndexablePrimitive(Compiler compiler) {
- ClassWorld classWorld = compiler.world;
+ ClosedWorld closedWorld = compiler.closedWorld;
JavaScriptBackend backend = compiler.backend;
BackendHelpers helpers = backend.helpers;
- return instructionType.containsOnlyString(classWorld) ||
- isInstanceOf(instructionType, helpers.jsIndexableClass, classWorld);
+ return instructionType.containsOnlyString(closedWorld) ||
+ isInstanceOf(instructionType, helpers.jsIndexableClass, closedWorld);
}
bool isFixedArray(Compiler compiler) {
- ClassWorld classWorld = compiler.world;
+ ClosedWorld closedWorld = compiler.closedWorld;
JavaScriptBackend backend = compiler.backend;
BackendHelpers helpers = backend.helpers;
// TODO(sra): Recognize the union of these types as well.
return containsOnlyType(
- instructionType, helpers.jsFixedArrayClass, classWorld) ||
+ instructionType, helpers.jsFixedArrayClass, closedWorld) ||
containsOnlyType(
- instructionType, helpers.jsUnmodifiableArrayClass, classWorld);
+ instructionType, helpers.jsUnmodifiableArrayClass, closedWorld);
}
bool isExtendableArray(Compiler compiler) {
- ClassWorld classWorld = compiler.world;
+ ClosedWorld closedWorld = compiler.closedWorld;
JavaScriptBackend backend = compiler.backend;
BackendHelpers helpers = backend.helpers;
return containsOnlyType(
- instructionType, helpers.jsExtendableArrayClass, classWorld);
+ instructionType, helpers.jsExtendableArrayClass, closedWorld);
}
bool isMutableArray(Compiler compiler) {
- ClassWorld classWorld = compiler.world;
+ ClosedWorld closedWorld = compiler.closedWorld;
JavaScriptBackend backend = compiler.backend;
BackendHelpers helpers = backend.helpers;
return isInstanceOf(
- instructionType, helpers.jsMutableArrayClass, classWorld);
+ instructionType, helpers.jsMutableArrayClass, closedWorld);
}
bool isReadableArray(Compiler compiler) {
- ClassWorld classWorld = compiler.world;
+ ClosedWorld closedWorld = compiler.closedWorld;
JavaScriptBackend backend = compiler.backend;
BackendHelpers helpers = backend.helpers;
- return isInstanceOf(instructionType, helpers.jsArrayClass, classWorld);
+ return isInstanceOf(instructionType, helpers.jsArrayClass, closedWorld);
}
bool isMutableIndexable(Compiler compiler) {
- ClassWorld classWorld = compiler.world;
+ ClosedWorld closedWorld = compiler.closedWorld;
JavaScriptBackend backend = compiler.backend;
BackendHelpers helpers = backend.helpers;
return isInstanceOf(
- instructionType, helpers.jsMutableIndexableClass, classWorld);
+ instructionType, helpers.jsMutableIndexableClass, closedWorld);
}
bool isArray(Compiler compiler) => isReadableArray(compiler);
bool canBePrimitiveString(Compiler compiler) {
- ClassWorld classWorld = compiler.world;
+ ClosedWorld closedWorld = compiler.closedWorld;
JavaScriptBackend backend = compiler.backend;
BackendHelpers helpers = backend.helpers;
- return containsType(instructionType, helpers.jsStringClass, classWorld);
+ return containsType(instructionType, helpers.jsStringClass, closedWorld);
}
bool isInteger(Compiler compiler) {
- ClassWorld classWorld = compiler.world;
- return instructionType.containsOnlyInt(classWorld) &&
+ ClosedWorld closedWorld = compiler.closedWorld;
+ return instructionType.containsOnlyInt(closedWorld) &&
!instructionType.isNullable;
}
bool isUInt32(Compiler compiler) {
- ClassWorld classWorld = compiler.world;
+ ClosedWorld closedWorld = compiler.closedWorld;
JavaScriptBackend backend = compiler.backend;
BackendHelpers helpers = backend.helpers;
return !instructionType.isNullable &&
- isInstanceOf(instructionType, helpers.jsUInt32Class, classWorld);
+ isInstanceOf(instructionType, helpers.jsUInt32Class, closedWorld);
}
bool isUInt31(Compiler compiler) {
- ClassWorld classWorld = compiler.world;
+ ClosedWorld closedWorld = compiler.closedWorld;
JavaScriptBackend backend = compiler.backend;
BackendHelpers helpers = backend.helpers;
return !instructionType.isNullable &&
- isInstanceOf(instructionType, helpers.jsUInt31Class, classWorld);
+ isInstanceOf(instructionType, helpers.jsUInt31Class, closedWorld);
}
bool isPositiveInteger(Compiler compiler) {
- ClassWorld classWorld = compiler.world;
+ ClosedWorld closedWorld = compiler.closedWorld;
JavaScriptBackend backend = compiler.backend;
BackendHelpers helpers = backend.helpers;
return !instructionType.isNullable &&
- isInstanceOf(instructionType, helpers.jsPositiveIntClass, classWorld);
+ isInstanceOf(instructionType, helpers.jsPositiveIntClass, closedWorld);
}
bool isPositiveIntegerOrNull(Compiler compiler) {
- ClassWorld classWorld = compiler.world;
+ ClosedWorld closedWorld = compiler.closedWorld;
JavaScriptBackend backend = compiler.backend;
BackendHelpers helpers = backend.helpers;
return isInstanceOf(
- instructionType, helpers.jsPositiveIntClass, classWorld);
+ instructionType, helpers.jsPositiveIntClass, closedWorld);
}
bool isIntegerOrNull(Compiler compiler) {
- ClassWorld classWorld = compiler.world;
- return instructionType.containsOnlyInt(classWorld);
+ ClosedWorld closedWorld = compiler.closedWorld;
+ return instructionType.containsOnlyInt(closedWorld);
}
bool isNumber(Compiler compiler) {
- ClassWorld classWorld = compiler.world;
- return instructionType.containsOnlyNum(classWorld) &&
+ ClosedWorld closedWorld = compiler.closedWorld;
+ return instructionType.containsOnlyNum(closedWorld) &&
!instructionType.isNullable;
}
bool isNumberOrNull(Compiler compiler) {
- ClassWorld classWorld = compiler.world;
- return instructionType.containsOnlyNum(classWorld);
+ ClosedWorld closedWorld = compiler.closedWorld;
+ return instructionType.containsOnlyNum(closedWorld);
}
bool isDouble(Compiler compiler) {
- ClassWorld classWorld = compiler.world;
- return instructionType.containsOnlyDouble(classWorld) &&
+ ClosedWorld closedWorld = compiler.closedWorld;
+ return instructionType.containsOnlyDouble(closedWorld) &&
!instructionType.isNullable;
}
bool isDoubleOrNull(Compiler compiler) {
- ClassWorld classWorld = compiler.world;
- return instructionType.containsOnlyDouble(classWorld);
+ ClosedWorld closedWorld = compiler.closedWorld;
+ return instructionType.containsOnlyDouble(closedWorld);
}
bool isBoolean(Compiler compiler) {
- ClassWorld classWorld = compiler.world;
- return instructionType.containsOnlyBool(classWorld) &&
+ ClosedWorld closedWorld = compiler.closedWorld;
+ return instructionType.containsOnlyBool(closedWorld) &&
!instructionType.isNullable;
}
bool isBooleanOrNull(Compiler compiler) {
- ClassWorld classWorld = compiler.world;
- return instructionType.containsOnlyBool(classWorld);
+ ClosedWorld closedWorld = compiler.closedWorld;
+ return instructionType.containsOnlyBool(closedWorld);
}
bool isString(Compiler compiler) {
- ClassWorld classWorld = compiler.world;
- return instructionType.containsOnlyString(classWorld) &&
+ ClosedWorld closedWorld = compiler.closedWorld;
+ return instructionType.containsOnlyString(closedWorld) &&
!instructionType.isNullable;
}
bool isStringOrNull(Compiler compiler) {
- ClassWorld classWorld = compiler.world;
- return instructionType.containsOnlyString(classWorld);
+ ClosedWorld closedWorld = compiler.closedWorld;
+ return instructionType.containsOnlyString(closedWorld);
}
bool isPrimitive(Compiler compiler) {
@@ -1378,7 +1381,7 @@
throw 'creating compound check to $type (this = ${this})';
} else {
TypeMask subtype =
- new TypeMask.subtype(element.declaration, compiler.world);
+ new TypeMask.subtype(element.declaration, compiler.closedWorld);
return new HTypeConversion(type, kind, subtype, this);
}
}
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index 3ac8e27..627e7195 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem;
+import '../common/names.dart' show Selectors;
import '../common/tasks.dart' show CompilerTask;
import '../compiler.dart' show Compiler;
import '../constants/constant_system.dart';
@@ -19,7 +20,7 @@
import '../universe/selector.dart' show Selector;
import '../universe/side_effects.dart' show SideEffects;
import '../util/util.dart';
-import '../world.dart' show ClassWorld, World;
+import '../world.dart' show ClosedWorld;
import 'interceptor_simplifier.dart';
import 'nodes.dart';
import 'types.dart';
@@ -126,7 +127,7 @@
/// of identifying gvn-able lengths and mis-identifies some unions of fixed
/// length indexables (see TODO) as not fixed length.
bool isFixedLength(mask, Compiler compiler) {
- ClassWorld classWorld = compiler.world;
+ ClosedWorld closedWorld = compiler.closedWorld;
JavaScriptBackend backend = compiler.backend;
if (mask.isContainer && mask.length != null) {
// A container on which we have inferred the length.
@@ -135,7 +136,7 @@
// TODO(sra): Recognize any combination of fixed length indexables.
if (mask.containsOnly(backend.helpers.jsFixedArrayClass) ||
mask.containsOnly(backend.helpers.jsUnmodifiableArrayClass) ||
- mask.containsOnlyString(classWorld) ||
+ mask.containsOnlyString(closedWorld) ||
backend.isTypedArray(mask)) {
return true;
}
@@ -191,7 +192,7 @@
// If we can replace [instruction] with [replacement], then
// [replacement]'s type can be narrowed.
TypeMask newType = replacement.instructionType
- .intersection(instruction.instructionType, compiler.world);
+ .intersection(instruction.instructionType, compiler.closedWorld);
replacement.instructionType = newType;
}
@@ -284,7 +285,7 @@
// All values that cannot be 'true' are boolified to false.
TypeMask mask = input.instructionType;
- if (!mask.contains(helpers.jsBoolClass, compiler.world)) {
+ if (!mask.contains(helpers.jsBoolClass, compiler.closedWorld)) {
return graph.addConstantBool(false, compiler);
}
return node;
@@ -334,14 +335,14 @@
Element element = helpers.jsIndexableLength;
bool isFixed = isFixedLength(actualReceiver.instructionType, compiler);
TypeMask actualType = node.instructionType;
- ClassWorld classWorld = compiler.world;
+ ClosedWorld closedWorld = compiler.closedWorld;
TypeMask resultType = backend.positiveIntType;
// If we already have computed a more specific type, keep that type.
if (HInstruction.isInstanceOf(
- actualType, helpers.jsUInt31Class, classWorld)) {
+ actualType, helpers.jsUInt31Class, closedWorld)) {
resultType = backend.uint31Type;
} else if (HInstruction.isInstanceOf(
- actualType, helpers.jsUInt32Class, classWorld)) {
+ actualType, helpers.jsUInt32Class, closedWorld)) {
resultType = backend.uint32Type;
}
HFieldGet result = new HFieldGet(element, actualReceiver, resultType,
@@ -374,10 +375,10 @@
TypeMask mask = node.mask;
HInstruction input = node.inputs[1];
- World world = compiler.world;
+ ClosedWorld world = compiler.closedWorld;
bool applies(Element element) {
- return selector.applies(element, world) &&
+ return selector.applies(element, backend) &&
(mask == null || mask.canHit(element, selector, world));
}
@@ -426,7 +427,7 @@
return result;
}
} else if (selector.isGetter) {
- if (selector.applies(helpers.jsIndexableLength, world)) {
+ if (selector.applies(helpers.jsIndexableLength, backend)) {
HInstruction optimized = tryOptimizeLengthInterceptedGetter(node);
if (optimized != null) return optimized;
}
@@ -444,7 +445,7 @@
TypeMask receiverType = node.getDartReceiver(compiler).instructionType;
Element element =
- compiler.world.locateSingleElement(node.selector, receiverType);
+ compiler.closedWorld.locateSingleElement(node.selector, receiverType);
// TODO(ngeoffray): Also fold if it's a getter or variable.
if (element != null &&
element.isFunction
@@ -643,7 +644,7 @@
// Intersection of int and double return conflicting, so
// we don't optimize on numbers to preserve the runtime semantics.
if (!(left.isNumberOrNull(compiler) && right.isNumberOrNull(compiler))) {
- if (leftType.isDisjoint(rightType, compiler.world)) {
+ if (leftType.isDisjoint(rightType, compiler.closedWorld)) {
return makeFalse();
}
}
@@ -734,7 +735,7 @@
return graph.addConstantBool(true, compiler);
}
- ClassWorld classWorld = compiler.world;
+ ClosedWorld closedWorld = compiler.closedWorld;
HInstruction expression = node.expression;
if (expression.isInteger(compiler)) {
if (element == coreClasses.intClass ||
@@ -778,13 +779,13 @@
// raw type.
} else if (!RuntimeTypes.hasTypeArguments(type)) {
TypeMask expressionMask = expression.instructionType;
- assert(TypeMask.assertIsNormalized(expressionMask, classWorld));
+ assert(TypeMask.assertIsNormalized(expressionMask, closedWorld));
TypeMask typeMask = (element == coreClasses.nullClass)
- ? new TypeMask.subtype(element, classWorld)
- : new TypeMask.nonNullSubtype(element, classWorld);
- if (expressionMask.union(typeMask, classWorld) == typeMask) {
+ ? new TypeMask.subtype(element, closedWorld)
+ : new TypeMask.nonNullSubtype(element, closedWorld);
+ if (expressionMask.union(typeMask, closedWorld) == typeMask) {
return graph.addConstantBool(true, compiler);
- } else if (expressionMask.isDisjoint(typeMask, compiler.world)) {
+ } else if (expressionMask.isDisjoint(typeMask, compiler.closedWorld)) {
return graph.addConstantBool(false, compiler);
}
}
@@ -815,11 +816,11 @@
}
HInstruction removeIfCheckAlwaysSucceeds(HCheck node, TypeMask checkedType) {
- ClassWorld classWorld = compiler.world;
- if (checkedType.containsAll(classWorld)) return node;
+ ClosedWorld closedWorld = compiler.closedWorld;
+ if (checkedType.containsAll(closedWorld)) return node;
HInstruction input = node.checkedInput;
TypeMask inputType = input.instructionType;
- return inputType.isInMask(checkedType, classWorld) ? input : node;
+ return inputType.isInMask(checkedType, closedWorld) ? input : node;
}
HInstruction removeCheck(HCheck node) => node.checkedInput;
@@ -827,7 +828,7 @@
VariableElement findConcreteFieldForDynamicAccess(
HInstruction receiver, Selector selector) {
TypeMask receiverType = receiver.instructionType;
- return compiler.world.locateSingleField(selector, receiverType);
+ return compiler.closedWorld.locateSingleField(selector, receiverType);
}
HInstruction visitFieldGet(HFieldGet node) {
@@ -905,7 +906,7 @@
}
HInstruction directFieldGet(HInstruction receiver, Element field) {
- bool isAssignable = !compiler.world.fieldNeverChanges(field);
+ bool isAssignable = !compiler.closedWorld.fieldNeverChanges(field);
TypeMask type;
if (backend.isNative(field.enclosingClass)) {
@@ -1013,22 +1014,51 @@
HInstruction visitStringify(HStringify node) {
HInstruction input = node.inputs[0];
if (input.isString(compiler)) return input;
- if (input.isConstant()) {
+
+ HInstruction tryConstant() {
+ if (!input.isConstant()) return null;
HConstant constant = input;
- if (!constant.constant.isPrimitive) return node;
+ if (!constant.constant.isPrimitive) return null;
if (constant.constant.isInt) {
// Only constant-fold int.toString() when Dart and JS results the same.
// TODO(18103): We should be able to remove this work-around when issue
// 18103 is resolved by providing the correct string.
IntConstantValue intConstant = constant.constant;
// Very conservative range.
- if (!intConstant.isUInt32()) return node;
+ if (!intConstant.isUInt32()) return null;
}
PrimitiveConstantValue primitive = constant.constant;
return graph.addConstant(
constantSystem.createString(primitive.toDartString()), compiler);
}
- return node;
+
+ HInstruction tryToString() {
+ // If the `toString` method is guaranteed to return a string we can call
+ // it directly. Keep the stringifier for primitives (since they have fast
+ // path code in the stringifier) and for classes requiring interceptors
+ // (since SsaInstructionSimplifier runs after SsaSimplifyInterceptors).
+ if (input.canBePrimitive(compiler)) return null;
+ if (input.canBeNull()) return null;
+ Selector selector = Selectors.toString_;
+ TypeMask toStringType = TypeMaskFactory.inferredTypeForSelector(
+ selector, input.instructionType, compiler);
+ ClosedWorld closedWorld = compiler.closedWorld;
+ if (!toStringType.containsOnlyString(closedWorld)) return null;
+ // All intercepted classes extend `Interceptor`, so if the receiver can't
+ // be a class extending `Interceptor` then it can be called directly.
+ if (new TypeMask.nonNullSubclass(helpers.jsInterceptorClass, closedWorld)
+ .isDisjoint(input.instructionType, closedWorld)) {
+ HInstruction result = new HInvokeDynamicMethod(
+ selector,
+ input.instructionType, // receiver mask.
+ <HInstruction>[input, input], // [interceptor, receiver].
+ toStringType)..sourceInformation = node.sourceInformation;
+ return result;
+ }
+ return null;
+ }
+
+ return tryConstant() ?? tryToString() ?? node;
}
HInstruction visitOneShotInterceptor(HOneShotInterceptor node) {
@@ -1036,10 +1066,10 @@
}
bool needsSubstitutionForTypeVariableAccess(ClassElement cls) {
- ClassWorld classWorld = compiler.world;
- if (classWorld.isUsedAsMixin(cls)) return true;
+ ClosedWorld closedWorld = compiler.closedWorld;
+ if (closedWorld.isUsedAsMixin(cls)) return true;
- return classWorld.anyStrictSubclassOf(cls, (ClassElement subclass) {
+ return closedWorld.anyStrictSubclassOf(cls, (ClassElement subclass) {
return !backend.rti.isTrivialSubstitution(subclass, cls);
});
}
@@ -2056,7 +2086,7 @@
if (ifUsers.isEmpty && notIfUsers.isEmpty) return;
TypeMask convertedType =
- new TypeMask.nonNullSubtype(element, compiler.world);
+ new TypeMask.nonNullSubtype(element, compiler.closedWorld);
HInstruction input = instruction.expression;
for (HIf ifUser in ifUsers) {
@@ -2243,9 +2273,9 @@
// Assume the argument escapes. All we do with our initial allocation is
// have it escape or store it into an object that escapes.
return false;
- // TODO(sra): Handle more functions. `setRuntimeTypeInfo` does not
- // actually kill it's input, but we don't make use of that elsewhere so
- // there is not point in checking here.
+ // TODO(sra): Handle library functions that we know do not modify or
+ // leak the inputs. For example `setRuntimeTypeInfo` is used to mark
+ // list literals with type information.
}
if (use is HPhi) {
// The initial allocation (it's only alias) gets merged out of the model
@@ -2291,6 +2321,8 @@
void visitLiteralList(HLiteralList instruction) {
memorySet.registerAllocation(instruction);
memorySet.killAffectedBy(instruction);
+ // TODO(sra): Set initial keyed values.
+ // TODO(sra): Set initial length.
}
void visitIndex(HIndex instruction) {
@@ -2310,10 +2342,31 @@
memorySet.registerKeyedValueUpdate(
receiver, instruction.index, instruction.value);
}
+
+ // Pure operations that do not escape their inputs.
+ void visitBinaryArithmetic(HBinaryArithmetic instruction) {}
+ void visitConstant(HConstant instruction) {}
+ void visitIf(HIf instruction) {}
+ void visitInterceptor(HInterceptor instruction) {}
+ void visitIs(HIs instruction) {}
+ void visitIsViaInterceptor(HIsViaInterceptor instruction) {}
+ void visitNot(HNot instruction) {}
+ void visitParameterValue(HParameterValue instruction) {}
+ void visitRelational(HRelational instruction) {}
+ void visitStringConcat(HStringConcat instruction) {}
+ void visitTypeKnown(HTypeKnown instruction) {}
+ void visitTypeInfoReadRaw(HTypeInfoReadRaw instruction) {}
+ void visitTypeInfoReadVariable(HTypeInfoReadVariable instruction) {}
+ void visitTypeInfoExpression(HTypeInfoExpression instruction) {}
}
/**
* Holds values of memory places.
+ *
+ * Generally, values that name a place (a receiver) have type refinements and
+ * other checks removed to ensure that checks and type refinements do not
+ * confuse aliasing. Values stored into a memory place keep the type
+ * refinements to help further optimizations.
*/
class MemorySet {
final Compiler compiler;
@@ -2357,11 +2410,11 @@
// Typed arrays of different types might have a shared buffer.
if (couldBeTypedArray(first) && couldBeTypedArray(second)) return true;
return !first.instructionType
- .isDisjoint(second.instructionType, compiler.world);
+ .isDisjoint(second.instructionType, compiler.closedWorld);
}
bool isFinal(Element element) {
- return compiler.world.fieldNeverChanges(element);
+ return compiler.closedWorld.fieldNeverChanges(element);
}
bool isConcrete(HInstruction instruction) {
@@ -2379,25 +2432,28 @@
* Returns whether [receiver] escapes the current function.
*/
bool escapes(HInstruction receiver) {
+ assert(receiver == null || receiver == receiver.nonCheck());
return !nonEscapingReceivers.contains(receiver);
}
void registerAllocation(HInstruction instruction) {
+ assert(instruction == instruction.nonCheck());
nonEscapingReceivers.add(instruction);
}
/**
- * Sets `receiver.element` to contain [value]. Kills all potential
- * places that may be affected by this update.
+ * Sets `receiver.element` to contain [value]. Kills all potential places that
+ * may be affected by this update.
*/
void registerFieldValueUpdate(
Element element, HInstruction receiver, HInstruction value) {
+ assert(receiver == null || receiver == receiver.nonCheck());
if (backend.isNative(element)) {
return; // TODO(14955): Remove this restriction?
}
// [value] is being set in some place in memory, we remove it from
// the non-escaping set.
- nonEscapingReceivers.remove(value);
+ nonEscapingReceivers.remove(value.nonCheck());
Map<HInstruction, HInstruction> map =
fieldValues.putIfAbsent(element, () => <HInstruction, HInstruction>{});
map.forEach((key, value) {
@@ -2411,6 +2467,7 @@
*/
void registerFieldValue(
Element element, HInstruction receiver, HInstruction value) {
+ assert(receiver == null || receiver == receiver.nonCheck());
if (backend.isNative(element)) {
return; // TODO(14955): Remove this restriction?
}
@@ -2420,27 +2477,26 @@
}
/**
- * Returns the value stored in `receiver.element`. Returns null if
- * we don't know.
+ * Returns the value stored in `receiver.element`. Returns `null` if we don't
+ * know.
*/
HInstruction lookupFieldValue(Element element, HInstruction receiver) {
+ assert(receiver == null || receiver == receiver.nonCheck());
Map<HInstruction, HInstruction> map = fieldValues[element];
return (map == null) ? null : map[receiver];
}
/**
- * Kill all places that may be affected by this [instruction]. Also
- * update the set of non-escaping objects in case [instruction] has
- * non-escaping objects in its inputs.
+ * Kill all places that may be affected by this [instruction]. Also update the
+ * set of non-escaping objects in case [instruction] has non-escaping objects
+ * in its inputs.
*/
void killAffectedBy(HInstruction instruction) {
- // Even if [instruction] does not have side effects, it may use
- // non-escaping objects and store them in a new object, which
- // make these objects escaping.
- // TODO(ngeoffray): We need a new side effect flag to know whether
- // an instruction allocates an object.
+ // Even if [instruction] does not have side effects, it may use non-escaping
+ // objects and store them in a new object, which make these objects
+ // escaping.
instruction.inputs.forEach((input) {
- nonEscapingReceivers.remove(input);
+ nonEscapingReceivers.remove(input.nonCheck());
});
if (instruction.sideEffects.changesInstanceProperty() ||
@@ -2491,7 +2547,7 @@
*/
void registerKeyedValueUpdate(
HInstruction receiver, HInstruction index, HInstruction value) {
- nonEscapingReceivers.remove(value);
+ nonEscapingReceivers.remove(value.nonCheck());
keyedValues.forEach((key, values) {
if (mayAlias(receiver, key)) {
// Typed arrays that are views of the same buffer may have different
@@ -2522,8 +2578,8 @@
HBasicBlock block, int predecessorIndex) {
if (first == null || second == null) return null;
if (first == second) return first;
- TypeMask phiType =
- second.instructionType.union(first.instructionType, compiler.world);
+ TypeMask phiType = second.instructionType
+ .union(first.instructionType, compiler.closedWorld);
if (first is HPhi && first.block == block) {
HPhi phi = first;
phi.addInput(second);
diff --git a/pkg/compiler/lib/src/ssa/ssa_tracer.dart b/pkg/compiler/lib/src/ssa/ssa_tracer.dart
index d47e3ad..1768db1 100644
--- a/pkg/compiler/lib/src/ssa/ssa_tracer.dart
+++ b/pkg/compiler/lib/src/ssa/ssa_tracer.dart
@@ -145,7 +145,7 @@
prefix = 'd';
} else if (instruction.isNumber(compiler)) {
prefix = 'n';
- } else if (instruction.instructionType.containsAll(compiler.world)) {
+ } else if (instruction.instructionType.containsAll(compiler.closedWorld)) {
prefix = 'v';
} else {
prefix = 'U';
diff --git a/pkg/compiler/lib/src/ssa/types.dart b/pkg/compiler/lib/src/ssa/types.dart
index f43ca7e..edffc3a 100644
--- a/pkg/compiler/lib/src/ssa/types.dart
+++ b/pkg/compiler/lib/src/ssa/types.dart
@@ -34,7 +34,7 @@
var typesReturned = nativeBehavior.typesReturned;
if (typesReturned.isEmpty) return compiler.commonMasks.dynamicType;
- ClassWorld world = compiler.world;
+ ClassWorld world = compiler.closedWorld;
CommonMasks commonMasks = compiler.commonMasks;
CoreClasses coreClasses = compiler.coreClasses;
@@ -53,7 +53,7 @@
TypeMask result = typesReturned
.map(fromNativeType)
- .reduce((t1, t2) => t1.union(t2, compiler.world));
+ .reduce((t1, t2) => t1.union(t2, compiler.closedWorld));
assert(!result.isEmpty);
return result;
}
diff --git a/pkg/compiler/lib/src/ssa/types_propagation.dart b/pkg/compiler/lib/src/ssa/types_propagation.dart
index 298d928..e9b4c98 100644
--- a/pkg/compiler/lib/src/ssa/types_propagation.dart
+++ b/pkg/compiler/lib/src/ssa/types_propagation.dart
@@ -24,7 +24,7 @@
SsaTypePropagator(Compiler compiler)
: this.compiler = compiler,
- this.classWorld = compiler.world;
+ this.classWorld = compiler.closedWorld;
TypeMask computeType(HInstruction instruction) {
return instruction.accept(this);
@@ -268,7 +268,7 @@
HTypeConversion.RECEIVER_TYPE_CHECK);
return true;
} else if (instruction.element == null) {
- Iterable<Element> targets = compiler.world.allFunctions
+ Iterable<Element> targets = compiler.closedWorld.allFunctions
.filter(instruction.selector, instruction.mask);
if (targets.length == 1) {
Element target = targets.first;
@@ -371,7 +371,7 @@
if (!instruction.selector.isClosureCall) {
TypeMask newType;
TypeMask computeNewType() {
- newType = compiler.world.allFunctions
+ newType = compiler.closedWorld.allFunctions
.receiverType(instruction.selector, instruction.mask);
newType = newType.intersection(receiverType, classWorld);
return newType;
diff --git a/pkg/compiler/lib/src/string_validator.dart b/pkg/compiler/lib/src/string_validator.dart
index 60c3c78..b81661a 100644
--- a/pkg/compiler/lib/src/string_validator.dart
+++ b/pkg/compiler/lib/src/string_validator.dart
@@ -111,13 +111,10 @@
Token token, int startOffset, String string, StringQuoting quoting) {
// We need to check for invalid x and u escapes, for line
// terminators in non-multiline strings, and for invalid Unicode
- // scalar values (either directly or as u-escape values). We also check
- // for unpaired UTF-16 surrogates.
+ // code points (either directly or as u-escape values).
int length = 0;
int index = startOffset;
bool containsEscape = false;
- bool previousWasLeadSurrogate = false;
- bool invalidUtf16 = false;
var stringIter = string.codeUnits.iterator;
for (HasNextIterator<int> iter = new HasNextIterator(stringIter);
iter.hasNext;
@@ -199,26 +196,14 @@
code = value;
}
}
- if (code >= 0x10000) length++;
- // This handles both unescaped characters and the value of unicode
- // escapes.
- if (previousWasLeadSurrogate) {
- if (!isUtf16TrailSurrogate(code)) {
- invalidUtf16 = true;
- break;
+ if (code >= 0x10000) {
+ length++;
+ if (code > 0x10FFFF) {
+ stringParseError("Invalid code point", token, index);
+ return null;
}
- previousWasLeadSurrogate = false;
- } else if (isUtf16LeadSurrogate(code)) {
- previousWasLeadSurrogate = true;
- } else if (!isUnicodeScalarValue(code)) {
- invalidUtf16 = true;
- break;
}
}
- if (previousWasLeadSurrogate || invalidUtf16) {
- stringParseError("Invalid Utf16 surrogate", token, index);
- return null;
- }
// String literal successfully validated.
if (quoting.raw || !containsEscape) {
// A string without escapes could just as well have been raw.
diff --git a/pkg/compiler/lib/src/types/constants.dart b/pkg/compiler/lib/src/types/constants.dart
index b4689ce..8c3f6b7 100644
--- a/pkg/compiler/lib/src/types/constants.dart
+++ b/pkg/compiler/lib/src/types/constants.dart
@@ -24,7 +24,8 @@
if (compiler.backend.isInterceptorClass(constant.type.element)) {
return compiler.commonMasks.nonNullType;
}
- return new TypeMask.nonNullExact(constant.type.element, compiler.world);
+ return new TypeMask.nonNullExact(
+ constant.type.element, compiler.closedWorld);
}
@override
diff --git a/pkg/compiler/lib/src/types/flat_type_mask.dart b/pkg/compiler/lib/src/types/flat_type_mask.dart
index 380c2fb..1055af2 100644
--- a/pkg/compiler/lib/src/types/flat_type_mask.dart
+++ b/pkg/compiler/lib/src/types/flat_type_mask.dart
@@ -48,7 +48,8 @@
* 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, World world) {
+ factory FlatTypeMask.normalized(
+ ClassElement base, int flags, ClosedWorld world) {
if ((flags >> 1) == EMPTY || ((flags >> 1) == EXACT)) {
return new FlatTypeMask.internal(base, flags);
}
@@ -97,7 +98,7 @@
return isNullable ? new FlatTypeMask.internal(base, flags & ~1) : this;
}
- bool contains(ClassElement type, ClassWorld classWorld) {
+ bool contains(ClassElement type, ClosedWorld closedWorld) {
assert(type.isDeclaration);
if (isEmptyOrNull) {
return false;
@@ -106,42 +107,43 @@
} else if (isExact) {
return false;
} else if (isSubclass) {
- return classWorld.isSubclassOf(type, base);
+ return closedWorld.isSubclassOf(type, base);
} else {
assert(isSubtype);
- return classWorld.isSubtypeOf(type, base);
+ return closedWorld.isSubtypeOf(type, base);
}
}
- bool isSingleImplementationOf(ClassElement cls, ClassWorld classWorld) {
+ bool isSingleImplementationOf(ClassElement 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
// implements [base] and [base] is not instantiated. We however do
// not track correctly the list of truly instantiated classes.
- Backend backend = classWorld.backend;
- if (containsOnlyString(classWorld)) {
- return cls == classWorld.stringClass ||
+ Backend backend = closedWorld.backend;
+ if (containsOnlyString(closedWorld)) {
+ return cls == closedWorld.coreClasses.stringClass ||
cls == backend.stringImplementation;
}
- if (containsOnlyBool(classWorld)) {
- return cls == classWorld.boolClass || cls == backend.boolImplementation;
+ if (containsOnlyBool(closedWorld)) {
+ return cls == closedWorld.coreClasses.boolClass ||
+ cls == backend.boolImplementation;
}
- if (containsOnlyInt(classWorld)) {
- return cls == classWorld.intClass ||
+ if (containsOnlyInt(closedWorld)) {
+ return cls == closedWorld.coreClasses.intClass ||
cls == backend.intImplementation ||
cls == backend.positiveIntImplementation ||
cls == backend.uint32Implementation ||
cls == backend.uint31Implementation;
}
- if (containsOnlyDouble(classWorld)) {
- return cls == classWorld.doubleClass ||
+ if (containsOnlyDouble(closedWorld)) {
+ return cls == closedWorld.coreClasses.doubleClass ||
cls == backend.doubleImplementation;
}
return false;
}
- bool isInMask(TypeMask other, ClassWorld classWorld) {
+ bool isInMask(TypeMask other, ClosedWorld closedWorld) {
if (isEmptyOrNull) return isNullable ? other.isNullable : true;
// The empty type contains no classes.
if (other.isEmptyOrNull) return false;
@@ -149,7 +151,7 @@
if (isNullable && !other.isNullable) return false;
other = TypeMask.nonForwardingMask(other);
// If other is union, delegate to UnionTypeMask.containsMask.
- if (other is! FlatTypeMask) return other.containsMask(this, classWorld);
+ 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;
@@ -157,7 +159,7 @@
// TODO(herhut): Get rid of isSingleImplementationOf.
if (flatOther.isExact) {
return (isExact && base == otherBase) ||
- isSingleImplementationOf(otherBase, classWorld);
+ isSingleImplementationOf(otherBase, closedWorld);
}
// If other is subclass, this has to be subclass, as well. Unless
// flatOther.base covers all subtypes of this. Currently, we only
@@ -165,49 +167,50 @@
// TODO(herhut): Add check whether flatOther.base is superclass of
// all subclasses of this.base.
if (flatOther.isSubclass) {
- if (isSubtype) return (otherBase == classWorld.objectClass);
- return classWorld.isSubclassOf(base, otherBase);
+ if (isSubtype) return (otherBase == closedWorld.coreClasses.objectClass);
+ return closedWorld.isSubclassOf(base, otherBase);
}
assert(flatOther.isSubtype);
// Check whether this TypeMask satisfies otherBase's interface.
- return satisfies(otherBase, classWorld);
+ return satisfies(otherBase, closedWorld);
}
- bool containsMask(TypeMask other, ClassWorld classWorld) {
- return other.isInMask(this, classWorld);
+ bool containsMask(TypeMask other, ClosedWorld closedWorld) {
+ return other.isInMask(this, closedWorld);
}
- bool containsOnlyInt(ClassWorld classWorld) {
- Backend backend = classWorld.backend;
- return base == classWorld.intClass ||
+ bool containsOnlyInt(ClosedWorld closedWorld) {
+ Backend backend = closedWorld.backend;
+ return base == closedWorld.coreClasses.intClass ||
base == backend.intImplementation ||
base == backend.positiveIntImplementation ||
base == backend.uint31Implementation ||
base == backend.uint32Implementation;
}
- bool containsOnlyDouble(ClassWorld classWorld) {
- Backend backend = classWorld.backend;
- return base == classWorld.doubleClass ||
+ bool containsOnlyDouble(ClosedWorld closedWorld) {
+ Backend backend = closedWorld.backend;
+ return base == closedWorld.coreClasses.doubleClass ||
base == backend.doubleImplementation;
}
- bool containsOnlyNum(ClassWorld classWorld) {
- Backend backend = classWorld.backend;
- return containsOnlyInt(classWorld) ||
- containsOnlyDouble(classWorld) ||
- base == classWorld.numClass ||
+ bool containsOnlyNum(ClosedWorld closedWorld) {
+ Backend backend = closedWorld.backend;
+ return containsOnlyInt(closedWorld) ||
+ containsOnlyDouble(closedWorld) ||
+ base == closedWorld.coreClasses.numClass ||
base == backend.numImplementation;
}
- bool containsOnlyBool(ClassWorld classWorld) {
- Backend backend = classWorld.backend;
- return base == classWorld.boolClass || base == backend.boolImplementation;
+ bool containsOnlyBool(ClosedWorld closedWorld) {
+ Backend backend = closedWorld.backend;
+ return base == closedWorld.coreClasses.boolClass ||
+ base == backend.boolImplementation;
}
- bool containsOnlyString(ClassWorld classWorld) {
- Backend backend = classWorld.backend;
- return base == classWorld.stringClass ||
+ bool containsOnlyString(ClosedWorld closedWorld) {
+ Backend backend = closedWorld.backend;
+ return base == closedWorld.coreClasses.stringClass ||
base == backend.stringImplementation;
}
@@ -216,10 +219,10 @@
return base == cls;
}
- bool satisfies(ClassElement cls, ClassWorld classWorld) {
+ bool satisfies(ClassElement cls, ClosedWorld closedWorld) {
assert(cls.isDeclaration);
if (isEmptyOrNull) return false;
- if (classWorld.isSubtypeOf(base, cls)) return true;
+ if (closedWorld.isSubtypeOf(base, cls)) return true;
return false;
}
@@ -227,13 +230,13 @@
* Returns the [ClassElement] if this type represents a single class,
* otherwise returns `null`. This method is conservative.
*/
- ClassElement singleClass(ClassWorld classWorld) {
+ ClassElement singleClass(ClosedWorld closedWorld) {
if (isEmptyOrNull) return null;
if (isNullable) return null; // It is Null and some other class.
if (isExact) {
return base;
} else if (isSubclass) {
- return classWorld.hasAnyStrictSubclass(base) ? null : base;
+ return closedWorld.hasAnyStrictSubclass(base) ? null : base;
} else {
assert(isSubtype);
return null;
@@ -243,40 +246,40 @@
/**
* Returns whether or not this type mask contains all types.
*/
- bool containsAll(ClassWorld classWorld) {
+ bool containsAll(ClosedWorld closedWorld) {
if (isEmptyOrNull || isExact) return false;
- return identical(base, classWorld.objectClass);
+ return identical(base, closedWorld.coreClasses.objectClass);
}
- TypeMask union(TypeMask other, ClassWorld classWorld) {
+ TypeMask union(TypeMask other, ClosedWorld closedWorld) {
assert(other != null);
- assert(TypeMask.assertIsNormalized(this, classWorld));
- assert(TypeMask.assertIsNormalized(other, classWorld));
- if (other is! FlatTypeMask) return other.union(this, classWorld);
+ assert(TypeMask.assertIsNormalized(this, closedWorld));
+ assert(TypeMask.assertIsNormalized(other, closedWorld));
+ if (other is! FlatTypeMask) return other.union(this, closedWorld);
FlatTypeMask flatOther = other;
if (isEmptyOrNull) {
return isNullable ? flatOther.nullable() : flatOther;
} else if (flatOther.isEmptyOrNull) {
return flatOther.isNullable ? nullable() : this;
} else if (base == flatOther.base) {
- return unionSame(flatOther, classWorld);
- } else if (classWorld.isSubclassOf(flatOther.base, base)) {
- return unionStrictSubclass(flatOther, classWorld);
- } else if (classWorld.isSubclassOf(base, flatOther.base)) {
- return flatOther.unionStrictSubclass(this, classWorld);
- } else if (classWorld.isSubtypeOf(flatOther.base, base)) {
- return unionStrictSubtype(flatOther, classWorld);
- } else if (classWorld.isSubtypeOf(base, flatOther.base)) {
- return flatOther.unionStrictSubtype(this, classWorld);
+ return unionSame(flatOther, closedWorld);
+ } else if (closedWorld.isSubclassOf(flatOther.base, base)) {
+ return unionStrictSubclass(flatOther, closedWorld);
+ } else if (closedWorld.isSubclassOf(base, flatOther.base)) {
+ return flatOther.unionStrictSubclass(this, closedWorld);
+ } else if (closedWorld.isSubtypeOf(flatOther.base, base)) {
+ return unionStrictSubtype(flatOther, closedWorld);
+ } else if (closedWorld.isSubtypeOf(base, flatOther.base)) {
+ return flatOther.unionStrictSubtype(this, closedWorld);
} else {
return new UnionTypeMask._internal(<FlatTypeMask>[this, flatOther]);
}
}
- TypeMask unionSame(FlatTypeMask other, ClassWorld classWorld) {
+ TypeMask unionSame(FlatTypeMask other, ClosedWorld closedWorld) {
assert(base == other.base);
- assert(TypeMask.assertIsNormalized(this, classWorld));
- assert(TypeMask.assertIsNormalized(other, classWorld));
+ assert(TypeMask.assertIsNormalized(this, closedWorld));
+ assert(TypeMask.assertIsNormalized(other, closedWorld));
// The two masks share the base type, so we must chose the least
// constraining kind (the highest) of the two. If either one of
// the masks are nullable the result should be nullable too.
@@ -289,17 +292,18 @@
} else if (other.flags == combined) {
return other;
} else {
- return new FlatTypeMask.normalized(base, combined, classWorld);
+ return new FlatTypeMask.normalized(base, combined, closedWorld);
}
}
- TypeMask unionStrictSubclass(FlatTypeMask other, ClassWorld classWorld) {
+ TypeMask unionStrictSubclass(FlatTypeMask other, ClosedWorld closedWorld) {
assert(base != other.base);
- assert(classWorld.isSubclassOf(other.base, base));
- assert(TypeMask.assertIsNormalized(this, classWorld));
- assert(TypeMask.assertIsNormalized(other, classWorld));
+ assert(closedWorld.isSubclassOf(other.base, base));
+ assert(TypeMask.assertIsNormalized(this, closedWorld));
+ assert(TypeMask.assertIsNormalized(other, closedWorld));
int combined;
- if ((isExact && other.isExact) || base == classWorld.objectClass) {
+ if ((isExact && other.isExact) ||
+ base == closedWorld.coreClasses.objectClass) {
// Since the other mask is a subclass of this mask, we need the
// resulting union to be a subclass too. If either one of the
// masks are nullable the result should be nullable too.
@@ -315,16 +319,16 @@
// If we weaken the constraint on this type, we have to make sure that
// the result is normalized.
return (flags != combined)
- ? new FlatTypeMask.normalized(base, combined, classWorld)
+ ? new FlatTypeMask.normalized(base, combined, closedWorld)
: this;
}
- TypeMask unionStrictSubtype(FlatTypeMask other, ClassWorld classWorld) {
+ TypeMask unionStrictSubtype(FlatTypeMask other, ClosedWorld closedWorld) {
assert(base != other.base);
- assert(!classWorld.isSubclassOf(other.base, base));
- assert(classWorld.isSubtypeOf(other.base, base));
- assert(TypeMask.assertIsNormalized(this, classWorld));
- assert(TypeMask.assertIsNormalized(other, classWorld));
+ assert(!closedWorld.isSubclassOf(other.base, base));
+ assert(closedWorld.isSubtypeOf(other.base, base));
+ assert(TypeMask.assertIsNormalized(this, closedWorld));
+ assert(TypeMask.assertIsNormalized(other, closedWorld));
// Since the other mask is a subtype of this mask, we need the
// resulting union to be a subtype too. If either one of the masks
// are nullable the result should be nullable too.
@@ -332,37 +336,37 @@
// We know there is at least one subtype, [other.base], so no need
// to normalize.
return (flags != combined)
- ? new FlatTypeMask.normalized(base, combined, classWorld)
+ ? new FlatTypeMask.normalized(base, combined, closedWorld)
: this;
}
- TypeMask intersection(TypeMask other, ClassWorld classWorld) {
+ TypeMask intersection(TypeMask other, ClosedWorld closedWorld) {
assert(other != null);
- if (other is! FlatTypeMask) return other.intersection(this, classWorld);
- assert(TypeMask.assertIsNormalized(this, classWorld));
- assert(TypeMask.assertIsNormalized(other, classWorld));
+ if (other is! FlatTypeMask) return other.intersection(this, closedWorld);
+ assert(TypeMask.assertIsNormalized(this, closedWorld));
+ assert(TypeMask.assertIsNormalized(other, closedWorld));
FlatTypeMask flatOther = other;
if (isEmptyOrNull) {
return flatOther.isNullable ? this : nonNullable();
} else if (flatOther.isEmptyOrNull) {
return isNullable ? flatOther : other.nonNullable();
} else if (base == flatOther.base) {
- return intersectionSame(flatOther, classWorld);
- } else if (classWorld.isSubclassOf(flatOther.base, base)) {
- return intersectionStrictSubclass(flatOther, classWorld);
- } else if (classWorld.isSubclassOf(base, flatOther.base)) {
- return flatOther.intersectionStrictSubclass(this, classWorld);
- } else if (classWorld.isSubtypeOf(flatOther.base, base)) {
- return intersectionStrictSubtype(flatOther, classWorld);
- } else if (classWorld.isSubtypeOf(base, flatOther.base)) {
- return flatOther.intersectionStrictSubtype(this, classWorld);
+ return intersectionSame(flatOther, closedWorld);
+ } else if (closedWorld.isSubclassOf(flatOther.base, base)) {
+ return intersectionStrictSubclass(flatOther, closedWorld);
+ } else if (closedWorld.isSubclassOf(base, flatOther.base)) {
+ return flatOther.intersectionStrictSubclass(this, closedWorld);
+ } else if (closedWorld.isSubtypeOf(flatOther.base, base)) {
+ return intersectionStrictSubtype(flatOther, closedWorld);
+ } else if (closedWorld.isSubtypeOf(base, flatOther.base)) {
+ return flatOther.intersectionStrictSubtype(this, closedWorld);
} else {
- return intersectionDisjoint(flatOther, classWorld);
+ return intersectionDisjoint(flatOther, closedWorld);
}
}
- bool isDisjoint(TypeMask other, ClassWorld classWorld) {
- if (other is! FlatTypeMask) return other.isDisjoint(this, classWorld);
+ bool isDisjoint(TypeMask other, ClosedWorld closedWorld) {
+ if (other is! FlatTypeMask) return other.isDisjoint(this, closedWorld);
FlatTypeMask flatOther = other;
if (isNullable && flatOther.isNullable) return false;
@@ -370,39 +374,39 @@
if (base == flatOther.base) return false;
if (isExact && flatOther.isExact) return true;
- if (isExact) return !flatOther.contains(base, classWorld);
- if (flatOther.isExact) return !contains(flatOther.base, classWorld);
+ if (isExact) return !flatOther.contains(base, closedWorld);
+ if (flatOther.isExact) return !contains(flatOther.base, closedWorld);
// Normalization guarantees that isExact === !isSubclass && !isSubtype.
// Both are subclass or subtype masks, so if there is a subclass
// relationship, they are not disjoint.
- if (classWorld.isSubclassOf(flatOther.base, base)) return false;
- if (classWorld.isSubclassOf(base, flatOther.base)) return false;
+ if (closedWorld.isSubclassOf(flatOther.base, base)) return false;
+ if (closedWorld.isSubclassOf(base, flatOther.base)) return false;
// Two different base classes have no common subclass unless one is a
// subclass of the other (checked above).
if (isSubclass && flatOther.isSubclass) return true;
- return _isDisjointHelper(this, flatOther, classWorld);
+ return _isDisjointHelper(this, flatOther, closedWorld);
}
static bool _isDisjointHelper(
- FlatTypeMask a, FlatTypeMask b, ClassWorld classWorld) {
+ FlatTypeMask a, FlatTypeMask b, ClosedWorld closedWorld) {
if (!a.isSubclass && b.isSubclass) {
- return _isDisjointHelper(b, a, classWorld);
+ return _isDisjointHelper(b, a, closedWorld);
}
assert(a.isSubclass || a.isSubtype);
assert(b.isSubtype);
var elements = a.isSubclass
- ? classWorld.strictSubclassesOf(a.base)
- : classWorld.strictSubtypesOf(a.base);
+ ? closedWorld.strictSubclassesOf(a.base)
+ : closedWorld.strictSubtypesOf(a.base);
for (var element in elements) {
- if (classWorld.isSubtypeOf(element, b.base)) return false;
+ if (closedWorld.isSubtypeOf(element, b.base)) return false;
}
return true;
}
- TypeMask intersectionSame(FlatTypeMask other, ClassWorld classWorld) {
+ TypeMask intersectionSame(FlatTypeMask other, ClosedWorld closedWorld) {
assert(base == other.base);
// The two masks share the base type, so we must chose the most
// constraining kind (the lowest) of the two. Only if both masks
@@ -416,14 +420,14 @@
} else if (other.flags == combined) {
return other;
} else {
- return new FlatTypeMask.normalized(base, combined, classWorld);
+ return new FlatTypeMask.normalized(base, combined, closedWorld);
}
}
TypeMask intersectionStrictSubclass(
- FlatTypeMask other, ClassWorld classWorld) {
+ FlatTypeMask other, ClosedWorld closedWorld) {
assert(base != other.base);
- assert(classWorld.isSubclassOf(other.base, base));
+ assert(closedWorld.isSubclassOf(other.base, base));
// If this mask isn't at least a subclass mask, then the
// intersection with the other mask is empty.
if (isExact) return intersectionEmpty(other);
@@ -436,15 +440,15 @@
if (other.flags == combined) {
return other;
} else {
- return new FlatTypeMask.normalized(other.base, combined, classWorld);
+ return new FlatTypeMask.normalized(other.base, combined, closedWorld);
}
}
TypeMask intersectionStrictSubtype(
- FlatTypeMask other, ClassWorld classWorld) {
+ FlatTypeMask other, ClosedWorld closedWorld) {
assert(base != other.base);
- assert(classWorld.isSubtypeOf(other.base, base));
- if (!isSubtype) return intersectionHelper(other, classWorld);
+ assert(closedWorld.isSubtypeOf(other.base, base));
+ if (!isSubtype) return intersectionHelper(other, closedWorld);
// Only the other mask puts constraints on the intersection mask,
// so base the combined flags on the other mask. Only if both
// masks are nullable, will the result be nullable too.
@@ -454,21 +458,21 @@
if (other.flags == combined) {
return other;
} else {
- return new FlatTypeMask.normalized(other.base, combined, classWorld);
+ return new FlatTypeMask.normalized(other.base, combined, closedWorld);
}
}
- TypeMask intersectionDisjoint(FlatTypeMask other, ClassWorld classWorld) {
+ TypeMask intersectionDisjoint(FlatTypeMask other, ClosedWorld closedWorld) {
assert(base != other.base);
- assert(!classWorld.isSubtypeOf(base, other.base));
- assert(!classWorld.isSubtypeOf(other.base, base));
- return intersectionHelper(other, classWorld);
+ assert(!closedWorld.isSubtypeOf(base, other.base));
+ assert(!closedWorld.isSubtypeOf(other.base, base));
+ return intersectionHelper(other, closedWorld);
}
- TypeMask intersectionHelper(FlatTypeMask other, ClassWorld classWorld) {
+ TypeMask intersectionHelper(FlatTypeMask other, ClosedWorld closedWorld) {
assert(base != other.base);
- assert(!classWorld.isSubclassOf(base, other.base));
- assert(!classWorld.isSubclassOf(other.base, base));
+ assert(!closedWorld.isSubclassOf(base, other.base));
+ assert(!closedWorld.isSubclassOf(other.base, base));
// If one of the masks are exact or if both of them are subclass
// masks, then the intersection is empty.
if (isExact || other.isExact) return intersectionEmpty(other);
@@ -476,7 +480,7 @@
assert(isSubtype || other.isSubtype);
int kind = (isSubclass || other.isSubclass) ? SUBCLASS : SUBTYPE;
// Compute the set of classes that are contained in both type masks.
- Set<ClassElement> common = commonContainedClasses(this, other, classWorld);
+ Set<ClassElement> common = commonContainedClasses(this, other, closedWorld);
if (common == null || common.isEmpty) return intersectionEmpty(other);
// Narrow down the candidates by only looking at common classes
// that do not have a superclass or supertype that will be a
@@ -501,9 +505,9 @@
// 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) {
- return new FlatTypeMask.normalized(cls, combined, classWorld);
+ return new FlatTypeMask.normalized(cls, combined, closedWorld);
});
- return UnionTypeMask.unionOf(masks, classWorld);
+ return UnionTypeMask.unionOf(masks, closedWorld);
}
TypeMask intersectionEmpty(FlatTypeMask other) {
@@ -538,8 +542,8 @@
* invoked on this type mask. [selector] is used to ensure library
* privacy is taken into account.
*/
- bool canHit(Element element, Selector selector, ClassWorld classWorld) {
- Backend backend = classWorld.backend;
+ bool canHit(Element element, Selector selector, ClosedWorld closedWorld) {
+ Backend backend = closedWorld.backend;
assert(element.name == selector.name);
if (isEmpty) return false;
if (isNull) {
@@ -561,25 +565,25 @@
} else if (isExact) {
return hasElementIn(self, selector, element);
} else if (isSubclass) {
- assert(classWorld.isClosed);
+ assert(closedWorld.isClosed);
return hasElementIn(self, selector, element) ||
other.isSubclassOf(self) ||
- classWorld.hasAnySubclassThatMixes(self, other);
+ closedWorld.hasAnySubclassThatMixes(self, other);
} else {
assert(isSubtype);
- assert(classWorld.isClosed);
+ assert(closedWorld.isClosed);
bool result = hasElementIn(self, selector, element) ||
other.implementsInterface(self) ||
- classWorld.hasAnySubclassThatImplements(other, base) ||
- classWorld.hasAnySubclassOfMixinUseThatImplements(other, base);
+ closedWorld.hasAnySubclassThatImplements(other, base) ||
+ closedWorld.hasAnySubclassOfMixinUseThatImplements(other, base);
if (result) return true;
// If the class is used as a mixin, we have to check if the element
// can be hit from any of the mixin applications.
- Iterable<ClassElement> mixinUses = classWorld.mixinUsesOf(self);
+ Iterable<ClassElement> mixinUses = closedWorld.mixinUsesOf(self);
return mixinUses.any((mixinApplication) =>
hasElementIn(mixinApplication, selector, element) ||
other.isSubclassOf(mixinApplication) ||
- classWorld.hasAnySubclassThatMixes(mixinApplication, other));
+ closedWorld.hasAnySubclassThatMixes(mixinApplication, other));
}
}
@@ -588,7 +592,7 @@
* will hit a method at runtime, and not go through [noSuchMethod].
*/
static bool hasConcreteMatch(
- ClassElement cls, Selector selector, ClassWorld world) {
+ ClassElement cls, Selector selector, ClosedWorld world) {
assert(invariant(cls, world.isInstantiated(cls),
message: '$cls has not been instantiated.'));
Element element = findMatchIn(cls, selector);
@@ -598,10 +602,10 @@
ClassElement enclosingClass = element.enclosingClass;
return hasConcreteMatch(enclosingClass.superclass, selector, world);
}
- return selector.appliesUntyped(element, world);
+ return selector.appliesUntyped(element, world.backend);
}
- bool needsNoSuchMethodHandling(Selector selector, ClassWorld classWorld) {
+ 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;
@@ -654,14 +658,14 @@
bool needsNoSuchMethod(ClassElement cls) {
// We can skip uninstantiated subclasses.
// TODO(johnniwinther): Put filtering into the (Class)World.
- if (!classWorld.isInstantiated(cls)) {
+ 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, classWorld);
+ return !cls.isAbstract && !hasConcreteMatch(cls, selector, closedWorld);
}
bool baseNeedsNoSuchMethod = needsNoSuchMethod(base);
@@ -671,10 +675,10 @@
Iterable<ClassElement> subclassesToCheck;
if (isSubtype) {
- subclassesToCheck = classWorld.strictSubtypesOf(base);
+ subclassesToCheck = closedWorld.strictSubtypesOf(base);
} else {
assert(isSubclass);
- subclassesToCheck = classWorld.strictSubclassesOf(base);
+ subclassesToCheck = closedWorld.strictSubclassesOf(base);
}
return subclassesToCheck != null &&
@@ -684,7 +688,7 @@
Element locateSingleElement(Selector selector, Compiler compiler) {
if (isEmptyOrNull) return null;
Iterable<Element> targets =
- compiler.world.allFunctions.filter(selector, this);
+ compiler.closedWorld.allFunctions.filter(selector, this);
if (targets.length != 1) return null;
Element result = targets.first;
ClassElement enclosing = result.enclosingClass;
@@ -692,17 +696,17 @@
// all classes in the receiver type [this]. It could be found only in a
// subclass or in an inheritance-wise unrelated class in case of subtype
// selectors.
- ClassWorld classWorld = compiler.world;
+ ClosedWorld closedWorld = compiler.closedWorld;
if (isSubtype) {
- // if (classWorld.isUsedAsMixin(enclosing)) {
- if (classWorld.everySubtypeIsSubclassOfOrMixinUseOf(base, enclosing)) {
+ // if (closedWorld.isUsedAsMixin(enclosing)) {
+ if (closedWorld.everySubtypeIsSubclassOfOrMixinUseOf(base, enclosing)) {
return result;
}
//}
return null;
} else {
if (base.isSubclassOf(enclosing)) return result;
- if (classWorld.isSubclassOfMixinUseOf(base, enclosing)) return result;
+ if (closedWorld.isSubclassOfMixinUseOf(base, enclosing)) return result;
}
return null;
}
@@ -730,24 +734,24 @@
}
static Set<ClassElement> commonContainedClasses(
- FlatTypeMask x, FlatTypeMask y, ClassWorld classWorld) {
- Iterable<ClassElement> xSubset = containedSubset(x, classWorld);
+ FlatTypeMask x, FlatTypeMask y, ClosedWorld closedWorld) {
+ Iterable<ClassElement> xSubset = containedSubset(x, closedWorld);
if (xSubset == null) return null;
- Iterable<ClassElement> ySubset = containedSubset(y, classWorld);
+ Iterable<ClassElement> ySubset = containedSubset(y, closedWorld);
if (ySubset == null) return null;
return xSubset.toSet().intersection(ySubset.toSet());
}
static Iterable<ClassElement> containedSubset(
- FlatTypeMask x, ClassWorld classWorld) {
+ FlatTypeMask x, ClosedWorld closedWorld) {
ClassElement element = x.base;
if (x.isExact) {
return null;
} else if (x.isSubclass) {
- return classWorld.strictSubclassesOf(element);
+ return closedWorld.strictSubclassesOf(element);
} else {
assert(x.isSubtype);
- return classWorld.strictSubtypesOf(element);
+ return closedWorld.strictSubtypesOf(element);
}
}
}
diff --git a/pkg/compiler/lib/src/types/map_type_mask.dart b/pkg/compiler/lib/src/types/map_type_mask.dart
index 4645cd7..57f3c46 100644
--- a/pkg/compiler/lib/src/types/map_type_mask.dart
+++ b/pkg/compiler/lib/src/types/map_type_mask.dart
@@ -77,7 +77,10 @@
return new MapTypeMask(
newForwardTo, null, null, newKeyType, newValueType);
} else if (other.isDictionary) {
- assert(other.keyType == classWorld.compiler.commonMasks.stringType);
+ // TODO(johnniwinther): Find another way to check this invariant that
+ // doesn't need the compiler.
+ assert(
+ other.keyType == classWorld.backend.compiler.commonMasks.stringType);
TypeMask newKeyType = keyType.union(other.keyType, classWorld);
TypeMask newValueType =
other.typeMap.values.fold(keyType, (p, n) => p.union(n, classWorld));
diff --git a/pkg/compiler/lib/src/types/masks.dart b/pkg/compiler/lib/src/types/masks.dart
index ee12b65..b498b80 100644
--- a/pkg/compiler/lib/src/types/masks.dart
+++ b/pkg/compiler/lib/src/types/masks.dart
@@ -18,7 +18,7 @@
UniverseSelectorConstraints,
SelectorConstraintsStrategy;
import '../util/util.dart';
-import '../world.dart' show ClassWorld, World;
+import '../world.dart' show ClassWorld, ClosedWorld;
import 'abstract_value_domain.dart' show AbstractValue;
part 'container_type_mask.dart';
@@ -31,14 +31,13 @@
part 'value_type_mask.dart';
class CommonMasks {
- final ClassWorld classWorld;
// TODO(sigmund): once we split out the backend common elements, depend
// directly on those instead.
final Compiler compiler;
- CommonMasks(Compiler compiler)
- : this.classWorld = compiler.world,
- compiler = compiler;
+ CommonMasks(this.compiler);
+
+ ClassWorld get classWorld => compiler.closedWorld;
TypeMask _dynamicType;
TypeMask _nonNullType;
@@ -64,10 +63,10 @@
TypeMask _asyncStarStreamType;
TypeMask get dynamicType => _dynamicType ??=
- new TypeMask.subclass(classWorld.objectClass, classWorld);
+ new TypeMask.subclass(classWorld.coreClasses.objectClass, classWorld);
- TypeMask get nonNullType => _nonNullType ??=
- new TypeMask.nonNullSubclass(classWorld.objectClass, classWorld);
+ TypeMask get nonNullType => _nonNullType ??= new TypeMask.nonNullSubclass(
+ classWorld.coreClasses.objectClass, classWorld);
TypeMask get intType => _intType ??= new TypeMask.nonNullSubclass(
compiler.backend.intImplementation, classWorld);
diff --git a/pkg/compiler/lib/src/types/type_mask.dart b/pkg/compiler/lib/src/types/type_mask.dart
index d14bd95..cd92ed9 100644
--- a/pkg/compiler/lib/src/types/type_mask.dart
+++ b/pkg/compiler/lib/src/types/type_mask.dart
@@ -12,7 +12,7 @@
Set<TypeMask> _masks;
@override
- bool applies(Element element, Selector selector, ClassWorld world) {
+ bool applies(Element element, Selector selector, ClosedWorld world) {
if (isAll) return true;
if (_masks == null) return false;
for (TypeMask mask in _masks) {
@@ -22,9 +22,10 @@
}
@override
- bool needsNoSuchMethodHandling(Selector selector, ClassWorld world) {
+ bool needsNoSuchMethodHandling(Selector selector, ClosedWorld world) {
if (isAll) {
- TypeMask mask = new TypeMask.subclass(world.objectClass, world);
+ TypeMask mask =
+ new TypeMask.subclass(world.coreClasses.objectClass, world);
return mask.needsNoSuchMethodHandling(selector, world);
}
for (TypeMask mask in _masks) {
@@ -76,102 +77,102 @@
*/
abstract class TypeMask implements ReceiverConstraint, AbstractValue {
factory TypeMask(
- ClassElement base, int kind, bool isNullable, ClassWorld classWorld) {
+ ClassElement base, int kind, bool isNullable, ClosedWorld closedWorld) {
return new FlatTypeMask.normalized(
- base, (kind << 1) | (isNullable ? 1 : 0), classWorld);
+ base, (kind << 1) | (isNullable ? 1 : 0), closedWorld);
}
const factory TypeMask.empty() = FlatTypeMask.empty;
- factory TypeMask.exact(ClassElement base, ClassWorld classWorld) {
- assert(invariant(base, classWorld.isInstantiated(base),
+ factory TypeMask.exact(ClassElement base, ClosedWorld closedWorld) {
+ assert(invariant(base, closedWorld.isInstantiated(base),
message: () => "Cannot create exact type mask for uninstantiated "
- "class $base.\n${classWorld.dump(base)}"));
+ "class $base.\n${closedWorld.dump(base)}"));
return new FlatTypeMask.exact(base);
}
- factory TypeMask.exactOrEmpty(ClassElement base, ClassWorld classWorld) {
- if (classWorld.isInstantiated(base)) return new FlatTypeMask.exact(base);
+ factory TypeMask.exactOrEmpty(ClassElement base, ClosedWorld closedWorld) {
+ if (closedWorld.isInstantiated(base)) return new FlatTypeMask.exact(base);
return const TypeMask.empty();
}
- factory TypeMask.subclass(ClassElement base, ClassWorld classWorld) {
- assert(invariant(base, classWorld.isInstantiated(base),
+ factory TypeMask.subclass(ClassElement base, ClosedWorld closedWorld) {
+ assert(invariant(base, closedWorld.isInstantiated(base),
message: () => "Cannot create subclass type mask for uninstantiated "
- "class $base.\n${classWorld.dump(base)}"));
- ClassElement topmost = classWorld.getLubOfInstantiatedSubclasses(base);
+ "class $base.\n${closedWorld.dump(base)}"));
+ ClassElement topmost = closedWorld.getLubOfInstantiatedSubclasses(base);
if (topmost == null) {
return new TypeMask.empty();
- } else if (classWorld.hasAnyStrictSubclass(topmost)) {
+ } else if (closedWorld.hasAnyStrictSubclass(topmost)) {
return new FlatTypeMask.subclass(topmost);
} else {
- return new TypeMask.exact(topmost, classWorld);
+ return new TypeMask.exact(topmost, closedWorld);
}
}
- factory TypeMask.subtype(ClassElement base, ClassWorld classWorld) {
- ClassElement topmost = classWorld.getLubOfInstantiatedSubtypes(base);
+ factory TypeMask.subtype(ClassElement base, ClosedWorld closedWorld) {
+ ClassElement topmost = closedWorld.getLubOfInstantiatedSubtypes(base);
if (topmost == null) {
return new TypeMask.empty();
}
- if (classWorld.hasOnlySubclasses(topmost)) {
- return new TypeMask.subclass(topmost, classWorld);
+ if (closedWorld.hasOnlySubclasses(topmost)) {
+ return new TypeMask.subclass(topmost, closedWorld);
}
- if (classWorld.hasAnyStrictSubtype(topmost)) {
+ if (closedWorld.hasAnyStrictSubtype(topmost)) {
return new FlatTypeMask.subtype(topmost);
} else {
- return new TypeMask.exact(topmost, classWorld);
+ return new TypeMask.exact(topmost, closedWorld);
}
}
const factory TypeMask.nonNullEmpty() = FlatTypeMask.nonNullEmpty;
- factory TypeMask.nonNullExact(ClassElement base, ClassWorld classWorld) {
- assert(invariant(base, classWorld.isInstantiated(base),
+ factory TypeMask.nonNullExact(ClassElement base, ClosedWorld closedWorld) {
+ assert(invariant(base, closedWorld.isInstantiated(base),
message: () => "Cannot create exact type mask for uninstantiated "
- "class $base.\n${classWorld.dump(base)}"));
+ "class $base.\n${closedWorld.dump(base)}"));
return new FlatTypeMask.nonNullExact(base);
}
factory TypeMask.nonNullExactOrEmpty(
- ClassElement base, ClassWorld classWorld) {
- if (classWorld.isInstantiated(base)) {
+ ClassElement base, ClosedWorld closedWorld) {
+ if (closedWorld.isInstantiated(base)) {
return new FlatTypeMask.nonNullExact(base);
}
return const TypeMask.nonNullEmpty();
}
- factory TypeMask.nonNullSubclass(ClassElement base, ClassWorld classWorld) {
- assert(invariant(base, classWorld.isInstantiated(base),
+ factory TypeMask.nonNullSubclass(ClassElement base, ClosedWorld closedWorld) {
+ assert(invariant(base, closedWorld.isInstantiated(base),
message: () => "Cannot create subclass type mask for uninstantiated "
- "class $base.\n${classWorld.dump(base)}"));
- ClassElement topmost = classWorld.getLubOfInstantiatedSubclasses(base);
+ "class $base.\n${closedWorld.dump(base)}"));
+ ClassElement topmost = closedWorld.getLubOfInstantiatedSubclasses(base);
if (topmost == null) {
return new TypeMask.nonNullEmpty();
- } else if (classWorld.hasAnyStrictSubclass(topmost)) {
+ } else if (closedWorld.hasAnyStrictSubclass(topmost)) {
return new FlatTypeMask.nonNullSubclass(topmost);
} else {
- return new TypeMask.nonNullExact(topmost, classWorld);
+ return new TypeMask.nonNullExact(topmost, closedWorld);
}
}
- factory TypeMask.nonNullSubtype(ClassElement base, ClassWorld classWorld) {
- ClassElement topmost = classWorld.getLubOfInstantiatedSubtypes(base);
+ factory TypeMask.nonNullSubtype(ClassElement base, ClosedWorld closedWorld) {
+ ClassElement topmost = closedWorld.getLubOfInstantiatedSubtypes(base);
if (topmost == null) {
return new TypeMask.nonNullEmpty();
}
- if (classWorld.hasOnlySubclasses(topmost)) {
- return new TypeMask.nonNullSubclass(topmost, classWorld);
+ if (closedWorld.hasOnlySubclasses(topmost)) {
+ return new TypeMask.nonNullSubclass(topmost, closedWorld);
}
- if (classWorld.hasAnyStrictSubtype(topmost)) {
+ if (closedWorld.hasAnyStrictSubtype(topmost)) {
return new FlatTypeMask.nonNullSubtype(topmost);
} else {
- return new TypeMask.nonNullExact(topmost, classWorld);
+ return new TypeMask.nonNullExact(topmost, closedWorld);
}
}
- factory TypeMask.unionOf(Iterable<TypeMask> masks, ClassWorld classWorld) {
- return UnionTypeMask.unionOf(masks, classWorld);
+ factory TypeMask.unionOf(Iterable<TypeMask> masks, ClosedWorld closedWorld) {
+ return UnionTypeMask.unionOf(masks, closedWorld);
}
/**
@@ -192,39 +193,39 @@
* subclasses exist. We also normalize exact to empty if the corresponding
* baseclass was never instantiated.
*/
- static bool assertIsNormalized(TypeMask mask, ClassWorld classWorld) {
- String reason = getNotNormalizedReason(mask, classWorld);
+ static bool assertIsNormalized(TypeMask mask, ClosedWorld closedWorld) {
+ String reason = getNotNormalizedReason(mask, closedWorld);
return invariant(NO_LOCATION_SPANNABLE, reason == null,
message: () => '$mask is not normalized: $reason');
}
- static String getNotNormalizedReason(TypeMask mask, ClassWorld classWorld) {
+ static String getNotNormalizedReason(TypeMask mask, ClosedWorld closedWorld) {
mask = nonForwardingMask(mask);
if (mask is FlatTypeMask) {
if (mask.isEmptyOrNull) return null;
if (mask.isExact) {
- if (!classWorld.isInstantiated(mask.base)) {
+ if (!closedWorld.isInstantiated(mask.base)) {
return 'Exact ${mask.base} is not instantiated.';
}
return null;
}
if (mask.isSubclass) {
- if (!classWorld.hasAnyStrictSubclass(mask.base)) {
+ if (!closedWorld.hasAnyStrictSubclass(mask.base)) {
return 'Subclass ${mask.base} does not have any subclasses.';
}
return null;
}
assert(mask.isSubtype);
- if (!classWorld.hasAnyStrictSubtype(mask.base)) {
+ if (!closedWorld.hasAnyStrictSubtype(mask.base)) {
return 'Subtype ${mask.base} does not have any subclasses.';
}
- if (classWorld.hasOnlySubclasses(mask.base)) {
+ if (closedWorld.hasOnlySubclasses(mask.base)) {
return 'Subtype ${mask.base} only has subclasses.';
}
return null;
} else if (mask is UnionTypeMask) {
for (TypeMask submask in mask.disjointMasks) {
- String submaskReason = getNotNormalizedReason(submask, classWorld);
+ String submaskReason = getNotNormalizedReason(submask, closedWorld);
if (submaskReason != null) {
return 'Submask $submask in $mask: $submaskReason.';
}
@@ -281,11 +282,11 @@
/// Returns `true` if this mask holds encodes an exact value within a type.
bool get isValue;
- bool containsOnlyInt(ClassWorld classWorld);
- bool containsOnlyDouble(ClassWorld classWorld);
- bool containsOnlyNum(ClassWorld classWorld);
- bool containsOnlyBool(ClassWorld classWorld);
- bool containsOnlyString(ClassWorld classWorld);
+ bool containsOnlyInt(ClosedWorld closedWorld);
+ bool containsOnlyDouble(ClosedWorld closedWorld);
+ bool containsOnlyNum(ClosedWorld closedWorld);
+ bool containsOnlyBool(ClosedWorld closedWorld);
+ bool containsOnlyString(ClosedWorld closedWorld);
bool containsOnly(ClassElement element);
/**
@@ -302,7 +303,7 @@
* Enable [UnionTypeMask.PERFORM_EXTRA_CONTAINS_CHECK] to be notified of
* false negatives.
*/
- bool isInMask(TypeMask other, ClassWorld classWorld);
+ bool isInMask(TypeMask other, ClosedWorld closedWorld);
/**
* If this returns `true`, [other] is guaranteed to be a subtype of this mask,
@@ -310,48 +311,48 @@
* Enable [UnionTypeMask.PERFORM_EXTRA_CONTAINS_CHECK] to be notified of
* false negatives.
*/
- bool containsMask(TypeMask other, ClassWorld classWorld);
+ bool containsMask(TypeMask other, ClosedWorld closedWorld);
/**
* Returns whether this type mask is an instance of [cls].
*/
- bool satisfies(ClassElement cls, ClassWorld classWorld);
+ bool satisfies(ClassElement cls, ClosedWorld closedWorld);
/**
* Returns whether or not this type mask contains the given type.
*/
- bool contains(ClassElement type, ClassWorld classWorld);
+ bool contains(ClassElement type, ClosedWorld closedWorld);
/**
* Returns whether or not this type mask contains all types.
*/
- bool containsAll(ClassWorld classWorld);
+ bool containsAll(ClosedWorld closedWorld);
/**
* Returns the [ClassElement] if this type represents a single class,
* otherwise returns `null`. This method is conservative.
*/
- ClassElement singleClass(ClassWorld classWorld);
+ ClassElement singleClass(ClosedWorld closedWorld);
/**
* Returns a type mask representing the union of [this] and [other].
*/
- TypeMask union(TypeMask other, ClassWorld classWorld);
+ TypeMask union(TypeMask other, ClosedWorld closedWorld);
/// Returns whether the intersection of this and [other] is empty.
- bool isDisjoint(TypeMask other, ClassWorld classWorld);
+ bool isDisjoint(TypeMask other, ClosedWorld closedWorld);
/**
* Returns a type mask representing the intersection of [this] and [other].
*/
- TypeMask intersection(TypeMask other, ClassWorld classWorld);
+ TypeMask intersection(TypeMask other, ClosedWorld closedWorld);
/**
* 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.
*/
- bool canHit(Element element, Selector selector, ClassWorld classWorld);
+ bool canHit(Element element, Selector selector, ClosedWorld closedWorld);
/**
* Returns the [element] that is known to always be hit at runtime
diff --git a/pkg/compiler/lib/src/types/union_type_mask.dart b/pkg/compiler/lib/src/types/union_type_mask.dart
index 32e4e2a..8e4aa39 100644
--- a/pkg/compiler/lib/src/types/union_type_mask.dart
+++ b/pkg/compiler/lib/src/types/union_type_mask.dart
@@ -19,30 +19,30 @@
assert(disjointMasks.every((TypeMask mask) => !mask.isUnion));
}
- static TypeMask unionOf(Iterable<TypeMask> masks, ClassWorld classWorld) {
+ static TypeMask unionOf(Iterable<TypeMask> masks, ClosedWorld closedWorld) {
assert(
- masks.every((mask) => TypeMask.assertIsNormalized(mask, classWorld)));
+ masks.every((mask) => TypeMask.assertIsNormalized(mask, closedWorld)));
List<FlatTypeMask> disjoint = <FlatTypeMask>[];
- unionOfHelper(masks, disjoint, classWorld);
+ unionOfHelper(masks, disjoint, closedWorld);
if (disjoint.isEmpty) return new TypeMask.nonNullEmpty();
if (disjoint.length > MAX_UNION_LENGTH) {
- return flatten(disjoint, classWorld);
+ return flatten(disjoint, closedWorld);
}
if (disjoint.length == 1) return disjoint[0];
UnionTypeMask union = new UnionTypeMask._internal(disjoint);
- assert(TypeMask.assertIsNormalized(union, classWorld));
+ assert(TypeMask.assertIsNormalized(union, closedWorld));
return union;
}
static void unionOfHelper(Iterable<TypeMask> masks,
- List<FlatTypeMask> disjoint, ClassWorld classWorld) {
+ List<FlatTypeMask> disjoint, ClosedWorld closedWorld) {
// TODO(johnniwinther): Impose an order on the mask to ensure subclass masks
// are preferred to subtype masks.
for (TypeMask mask in masks) {
mask = TypeMask.nonForwardingMask(mask);
if (mask.isUnion) {
UnionTypeMask union = mask;
- unionOfHelper(union.disjointMasks, disjoint, classWorld);
+ unionOfHelper(union.disjointMasks, disjoint, closedWorld);
} else if (mask.isEmpty) {
continue;
} else {
@@ -55,7 +55,7 @@
for (int i = 0; i < disjoint.length; i++) {
FlatTypeMask current = disjoint[i];
if (current == null) continue;
- TypeMask newMask = flatMask.union(current, classWorld);
+ TypeMask newMask = flatMask.union(current, closedWorld);
// If we have found a disjoint union, continue iterating.
if (newMask.isUnion) continue;
covered = true;
@@ -87,7 +87,7 @@
}
}
- static TypeMask flatten(List<FlatTypeMask> masks, ClassWorld classWorld) {
+ static TypeMask flatten(List<FlatTypeMask> masks, ClosedWorld closedWorld) {
assert(masks.length > 1);
// If either type mask is a subtype type mask, we cannot use a
// subclass type mask to represent their union.
@@ -96,7 +96,7 @@
List<ClassElement> masksBases = masks.map((mask) => mask.base).toList();
Iterable<ClassElement> candidates =
- classWorld.commonSupertypesOf(masksBases);
+ closedWorld.commonSupertypesOf(masksBases);
// Compute the best candidate and its kind.
ClassElement bestElement;
@@ -105,8 +105,8 @@
for (ClassElement candidate in candidates) {
bool isInstantiatedStrictSubclass(cls) =>
cls != candidate &&
- classWorld.isDirectlyInstantiated(cls) &&
- classWorld.isSubclassOf(cls, candidate);
+ closedWorld.isDirectlyInstantiated(cls) &&
+ closedWorld.isSubclassOf(cls, candidate);
int size;
int kind;
@@ -119,11 +119,11 @@
// TODO(sigmund, johnniwinther): computing length here (and below) is
// expensive. If we can't prevent `flatten` from being called a lot, it
// might be worth caching results.
- size = classWorld.strictSubclassCount(candidate);
- assert(size <= classWorld.strictSubtypeCount(candidate));
+ size = closedWorld.strictSubclassCount(candidate);
+ assert(size <= closedWorld.strictSubtypeCount(candidate));
} else {
kind = FlatTypeMask.SUBTYPE;
- size = classWorld.strictSubtypeCount(candidate);
+ size = closedWorld.strictSubtypeCount(candidate);
}
// Update the best candidate if the new one is better.
if (bestElement == null || size < bestSize) {
@@ -132,10 +132,10 @@
bestKind = kind;
}
}
- return new TypeMask(bestElement, bestKind, isNullable, classWorld);
+ return new TypeMask(bestElement, bestKind, isNullable, closedWorld);
}
- TypeMask union(var other, ClassWorld classWorld) {
+ TypeMask union(var other, ClosedWorld closedWorld) {
other = TypeMask.nonForwardingMask(other);
if (!other.isUnion && disjointMasks.contains(other)) return this;
@@ -146,10 +146,10 @@
assert(other is UnionTypeMask);
newList.addAll(other.disjointMasks);
}
- return new TypeMask.unionOf(newList, classWorld);
+ return new TypeMask.unionOf(newList, closedWorld);
}
- TypeMask intersection(var other, ClassWorld classWorld) {
+ TypeMask intersection(var other, ClosedWorld closedWorld) {
other = TypeMask.nonForwardingMask(other);
if (!other.isUnion && disjointMasks.contains(other)) return other;
if (other.isUnion && this == other) return this;
@@ -161,19 +161,19 @@
intersections.add(current);
} else {
for (FlatTypeMask flatOther in other.disjointMasks) {
- intersections.add(current.intersection(flatOther, classWorld));
+ intersections.add(current.intersection(flatOther, closedWorld));
}
}
} else {
- intersections.add(current.intersection(other, classWorld));
+ intersections.add(current.intersection(other, closedWorld));
}
}
- return new TypeMask.unionOf(intersections, classWorld);
+ return new TypeMask.unionOf(intersections, closedWorld);
}
- bool isDisjoint(TypeMask other, ClassWorld classWorld) {
+ bool isDisjoint(TypeMask other, ClosedWorld closedWorld) {
for (var current in disjointMasks) {
- if (!current.isDisjoint(other, classWorld)) return false;
+ if (!current.isDisjoint(other, closedWorld)) return false;
}
return true;
}
@@ -212,34 +212,36 @@
* - the cheap test matching against individual members of [disjointMasks]
* must have failed.
*/
- bool slowContainsCheck(TypeMask other, ClassWorld classWorld) {
+ bool slowContainsCheck(TypeMask other, ClosedWorld closedWorld) {
// Unions should never make it here.
assert(!other.isUnion);
// Ensure the cheap test fails.
- assert(!disjointMasks.any((mask) => mask.containsMask(other, classWorld)));
+ assert(!disjointMasks.any((mask) => mask.containsMask(other, closedWorld)));
// If we cover object, we should never get here.
- assert(!contains(classWorld.objectClass, classWorld));
+ assert(!contains(closedWorld.coreClasses.objectClass, closedWorld));
// Likewise, nullness should be covered.
assert(isNullable || !other.isNullable);
// The fast test is precise for exact types.
if (other.isExact) return false;
// We cannot contain object.
- if (other.contains(classWorld.objectClass, classWorld)) return false;
+ if (other.contains(closedWorld.coreClasses.objectClass, closedWorld)) {
+ return false;
+ }
FlatTypeMask flat = TypeMask.nonForwardingMask(other);
// Check we cover the base class.
- if (!contains(flat.base, classWorld)) return false;
+ if (!contains(flat.base, closedWorld)) return false;
// Check for other members.
Iterable<ClassElement> members;
if (flat.isSubclass) {
- members = classWorld.strictSubclassesOf(flat.base);
+ members = closedWorld.strictSubclassesOf(flat.base);
} else {
assert(flat.isSubtype);
- members = classWorld.strictSubtypesOf(flat.base);
+ members = closedWorld.strictSubtypesOf(flat.base);
}
- return members.every((ClassElement cls) => this.contains(cls, classWorld));
+ return members.every((ClassElement cls) => this.contains(cls, closedWorld));
}
- bool isInMask(TypeMask other, ClassWorld classWorld) {
+ bool isInMask(TypeMask other, ClosedWorld closedWorld) {
other = TypeMask.nonForwardingMask(other);
if (isNullable && !other.isNullable) return false;
if (other.isUnion) {
@@ -250,7 +252,7 @@
// context, so we can safely ignore it here.
FlatTypeMask maskDisregardNull = mask.nonNullable();
return masks.any((FlatTypeMask other) {
- return other.containsMask(maskDisregardNull, classWorld);
+ return other.containsMask(maskDisregardNull, closedWorld);
});
}
@@ -258,77 +260,77 @@
bool contained = containedInAnyOf(disjointMask, union.disjointMasks);
if (PERFORM_EXTRA_CONTAINS_CHECK &&
!contained &&
- union.slowContainsCheck(disjointMask, classWorld)) {
+ union.slowContainsCheck(disjointMask, closedWorld)) {
throw "TypeMask based containment check failed for $this and $other.";
}
return contained;
});
}
- return disjointMasks.every((mask) => mask.isInMask(other, classWorld));
+ return disjointMasks.every((mask) => mask.isInMask(other, closedWorld));
}
- bool containsMask(TypeMask other, ClassWorld classWorld) {
+ bool containsMask(TypeMask other, ClosedWorld closedWorld) {
other = TypeMask.nonForwardingMask(other);
if (other.isNullable && !isNullable) return false;
- if (other.isUnion) return other.isInMask(this, classWorld);
+ if (other.isUnion) return other.isInMask(this, closedWorld);
other = other.nonNullable(); // nullable is not canonicalized, so drop it.
bool contained =
- disjointMasks.any((mask) => mask.containsMask(other, classWorld));
+ disjointMasks.any((mask) => mask.containsMask(other, closedWorld));
if (PERFORM_EXTRA_CONTAINS_CHECK &&
!contained &&
- slowContainsCheck(other, classWorld)) {
+ slowContainsCheck(other, closedWorld)) {
throw "TypeMask based containment check failed for $this and $other.";
}
return contained;
}
- bool containsOnlyInt(ClassWorld classWorld) {
- return disjointMasks.every((mask) => mask.containsOnlyInt(classWorld));
+ bool containsOnlyInt(ClosedWorld closedWorld) {
+ return disjointMasks.every((mask) => mask.containsOnlyInt(closedWorld));
}
- bool containsOnlyDouble(ClassWorld classWorld) {
- return disjointMasks.every((mask) => mask.containsOnlyDouble(classWorld));
+ bool containsOnlyDouble(ClosedWorld closedWorld) {
+ return disjointMasks.every((mask) => mask.containsOnlyDouble(closedWorld));
}
- bool containsOnlyNum(ClassWorld classWorld) {
+ bool containsOnlyNum(ClosedWorld closedWorld) {
return disjointMasks.every((mask) {
- return mask.containsOnlyNum(classWorld);
+ return mask.containsOnlyNum(closedWorld);
});
}
- bool containsOnlyBool(ClassWorld classWorld) {
- return disjointMasks.every((mask) => mask.containsOnlyBool(classWorld));
+ bool containsOnlyBool(ClosedWorld closedWorld) {
+ return disjointMasks.every((mask) => mask.containsOnlyBool(closedWorld));
}
- bool containsOnlyString(ClassWorld classWorld) {
- return disjointMasks.every((mask) => mask.containsOnlyString(classWorld));
+ bool containsOnlyString(ClosedWorld closedWorld) {
+ return disjointMasks.every((mask) => mask.containsOnlyString(closedWorld));
}
bool containsOnly(ClassElement element) {
return disjointMasks.every((mask) => mask.containsOnly(element));
}
- bool satisfies(ClassElement cls, ClassWorld classWorld) {
- return disjointMasks.every((mask) => mask.satisfies(cls, classWorld));
+ bool satisfies(ClassElement cls, ClosedWorld closedWorld) {
+ return disjointMasks.every((mask) => mask.satisfies(cls, closedWorld));
}
- bool contains(ClassElement type, ClassWorld classWorld) {
- return disjointMasks.any((e) => e.contains(type, classWorld));
+ bool contains(ClassElement type, ClosedWorld closedWorld) {
+ return disjointMasks.any((e) => e.contains(type, closedWorld));
}
- bool containsAll(ClassWorld classWorld) {
- return disjointMasks.any((mask) => mask.containsAll(classWorld));
+ bool containsAll(ClosedWorld closedWorld) {
+ return disjointMasks.any((mask) => mask.containsAll(closedWorld));
}
- ClassElement singleClass(ClassWorld classWorld) => null;
+ ClassElement singleClass(ClosedWorld closedWorld) => null;
- bool needsNoSuchMethodHandling(Selector selector, ClassWorld classWorld) {
+ bool needsNoSuchMethodHandling(Selector selector, ClosedWorld closedWorld) {
return disjointMasks
- .any((e) => e.needsNoSuchMethodHandling(selector, classWorld));
+ .any((e) => e.needsNoSuchMethodHandling(selector, closedWorld));
}
- bool canHit(Element element, Selector selector, ClassWorld classWorld) {
- return disjointMasks.any((e) => e.canHit(element, selector, classWorld));
+ bool canHit(Element element, Selector selector, ClosedWorld closedWorld) {
+ return disjointMasks.any((e) => e.canHit(element, selector, closedWorld));
}
Element locateSingleElement(Selector selector, Compiler compiler) {
diff --git a/pkg/compiler/lib/src/universe/feature.dart b/pkg/compiler/lib/src/universe/feature.dart
index a7fd61f..580da8b 100644
--- a/pkg/compiler/lib/src/universe/feature.dart
+++ b/pkg/compiler/lib/src/universe/feature.dart
@@ -43,6 +43,9 @@
/// A field without an initializer.
FIELD_WITHOUT_INITIALIZER,
+ /// A local variable without an initializer.
+ LOCAL_WITHOUT_INITIALIZER,
+
/// A field whose initialization is not a constant.
LAZY_FIELD,
diff --git a/pkg/compiler/lib/src/universe/function_set.dart b/pkg/compiler/lib/src/universe/function_set.dart
index afa0951..c34ae91 100644
--- a/pkg/compiler/lib/src/universe/function_set.dart
+++ b/pkg/compiler/lib/src/universe/function_set.dart
@@ -9,7 +9,7 @@
import '../elements/elements.dart';
import '../types/types.dart';
import '../util/util.dart' show Hashing, Setlet;
-import '../world.dart' show ClassWorld;
+import '../world.dart' show ClosedWorld;
import 'selector.dart' show Selector;
import 'universe.dart' show ReceiverConstraint;
@@ -21,7 +21,7 @@
final Map<String, FunctionSetNode> nodes = new Map<String, FunctionSetNode>();
FunctionSet(this.compiler);
- ClassWorld get classWorld => compiler.world;
+ ClosedWorld get closedWorld => compiler.closedWorld;
FunctionSetNode newNode(String name) => new FunctionSetNode(name);
@@ -64,15 +64,17 @@
/// set of classes that actually implement the selected member or implement
/// the handling 'noSuchMethod' where the selected member is unimplemented.
TypeMask receiverType(Selector selector, ReceiverConstraint constraint) {
- return query(selector, constraint).computeMask(classWorld);
+ return query(selector, constraint).computeMask(closedWorld);
}
- SelectorMask _createSelectorMask(
- Selector selector, ReceiverConstraint constraint, ClassWorld classWorld) {
+ SelectorMask _createSelectorMask(Selector selector,
+ ReceiverConstraint constraint, ClosedWorld closedWorld) {
return constraint != null
? new SelectorMask(selector, constraint)
- : new SelectorMask(selector,
- new TypeMask.subclass(classWorld.objectClass, classWorld));
+ : new SelectorMask(
+ selector,
+ new TypeMask.subclass(
+ closedWorld.coreClasses.objectClass, closedWorld));
}
/// Returns the set of functions that can be the target of a call to
@@ -81,21 +83,21 @@
FunctionSetQuery query(Selector selector, ReceiverConstraint constraint) {
String name = selector.name;
SelectorMask selectorMask =
- _createSelectorMask(selector, constraint, classWorld);
+ _createSelectorMask(selector, constraint, closedWorld);
SelectorMask noSuchMethodMask =
new SelectorMask(Selectors.noSuchMethod_, selectorMask.constraint);
FunctionSetNode node = nodes[name];
FunctionSetNode noSuchMethods = nodes[Identifiers.noSuchMethod_];
if (node != null) {
return node.query(
- selectorMask, classWorld, noSuchMethods, noSuchMethodMask);
+ selectorMask, closedWorld, noSuchMethods, noSuchMethodMask);
}
// If there is no method that matches [selector] we know we can
// only hit [:noSuchMethod:].
if (noSuchMethods == null) {
return const EmptyFunctionSetQuery();
}
- return noSuchMethods.query(noSuchMethodMask, classWorld);
+ return noSuchMethods.query(noSuchMethodMask, closedWorld);
}
void forEach(Function action) {
@@ -122,13 +124,13 @@
String get name => selector.name;
- bool applies(Element element, ClassWorld classWorld) {
- if (!selector.appliesUnnamed(element, classWorld)) return false;
- return constraint.canHit(element, selector, classWorld);
+ bool applies(Element element, ClosedWorld closedWorld) {
+ if (!selector.appliesUnnamed(element, closedWorld.backend)) return false;
+ return constraint.canHit(element, selector, closedWorld);
}
- bool needsNoSuchMethodHandling(ClassWorld classWorld) {
- return constraint.needsNoSuchMethodHandling(selector, classWorld);
+ bool needsNoSuchMethodHandling(ClosedWorld closedWorld) {
+ return constraint.needsNoSuchMethodHandling(selector, closedWorld);
}
bool operator ==(other) {
@@ -203,7 +205,7 @@
/// Returns the set of functions that can be the target of [selectorMask]
/// including no such method handling where applicable.
- FunctionSetQuery query(SelectorMask selectorMask, ClassWorld classWorld,
+ FunctionSetQuery query(SelectorMask selectorMask, ClosedWorld closedWorld,
[FunctionSetNode noSuchMethods, SelectorMask noSuchMethodMask]) {
assert(selectorMask.name == name);
FunctionSetQuery result = cache[selectorMask];
@@ -211,7 +213,7 @@
Setlet<Element> functions;
for (Element element in elements) {
- if (selectorMask.applies(element, classWorld)) {
+ if (selectorMask.applies(element, closedWorld)) {
if (functions == null) {
// Defer the allocation of the functions set until we are
// sure we need it. This allows us to return immutable empty
@@ -226,9 +228,9 @@
// add [noSuchMethod] implementations that apply to [mask] as
// potential targets.
if (noSuchMethods != null &&
- selectorMask.needsNoSuchMethodHandling(classWorld)) {
+ selectorMask.needsNoSuchMethodHandling(closedWorld)) {
FunctionSetQuery noSuchMethodQuery =
- noSuchMethods.query(noSuchMethodMask, classWorld);
+ noSuchMethods.query(noSuchMethodMask, closedWorld);
if (!noSuchMethodQuery.functions.isEmpty) {
if (functions == null) {
functions = new Setlet<Element>.from(noSuchMethodQuery.functions);
@@ -250,7 +252,7 @@
const FunctionSetQuery();
/// Compute the type of all potential receivers of this function set.
- TypeMask computeMask(ClassWorld classWorld);
+ TypeMask computeMask(ClosedWorld closedWorld);
/// Returns all potential targets of this function set.
Iterable<Element> get functions;
@@ -260,7 +262,8 @@
const EmptyFunctionSetQuery();
@override
- TypeMask computeMask(ClassWorld classWorld) => const TypeMask.nonNullEmpty();
+ TypeMask computeMask(ClosedWorld closedWorld) =>
+ const TypeMask.nonNullEmpty();
@override
Iterable<Element> get functions => const <Element>[];
@@ -275,23 +278,24 @@
FullFunctionSetQuery(this.functions);
@override
- TypeMask computeMask(ClassWorld classWorld) {
- assert(classWorld.hasAnyStrictSubclass(classWorld.objectClass));
+ TypeMask computeMask(ClosedWorld closedWorld) {
+ assert(
+ closedWorld.hasAnyStrictSubclass(closedWorld.coreClasses.objectClass));
if (_mask != null) return _mask;
return _mask = new TypeMask.unionOf(
functions.expand((element) {
ClassElement cls = element.enclosingClass;
- return [cls]..addAll(classWorld.mixinUsesOf(cls));
+ return [cls]..addAll(closedWorld.mixinUsesOf(cls));
}).map((cls) {
- if (classWorld.backend.isNullImplementation(cls)) {
+ if (closedWorld.backend.isNullImplementation(cls)) {
return const TypeMask.empty();
- } else if (classWorld.isInstantiated(cls.declaration)) {
- return new TypeMask.nonNullSubclass(cls.declaration, classWorld);
+ } else if (closedWorld.isInstantiated(cls.declaration)) {
+ return new TypeMask.nonNullSubclass(cls.declaration, closedWorld);
} else {
// TODO(johnniwinther): Avoid the need for this case.
return const TypeMask.empty();
}
}),
- classWorld);
+ closedWorld);
}
}
diff --git a/pkg/compiler/lib/src/universe/selector.dart b/pkg/compiler/lib/src/universe/selector.dart
index 19ce7c6..14d8b3a 100644
--- a/pkg/compiler/lib/src/universe/selector.dart
+++ b/pkg/compiler/lib/src/universe/selector.dart
@@ -16,7 +16,7 @@
LibraryElement,
PublicName;
import '../util/util.dart' show Hashing;
-import '../world.dart' show World;
+import '../common/resolution.dart' show Target;
import 'call_structure.dart' show CallStructure;
class SelectorKind {
@@ -217,20 +217,20 @@
return kind;
}
- bool appliesUnnamed(Element element, World world) {
- assert(sameNameHack(element, world));
- return appliesUntyped(element, world);
+ bool appliesUnnamed(Element element, Target target) {
+ assert(sameNameHack(element));
+ return appliesUntyped(element, target);
}
- bool appliesUntyped(Element element, World world) {
- assert(sameNameHack(element, world));
+ bool appliesUntyped(Element element, Target target) {
+ assert(sameNameHack(element));
if (Elements.isUnresolved(element)) return false;
if (memberName.isPrivate && memberName.library != element.library) {
// TODO(johnniwinther): Maybe this should be
// `memberName != element.memberName`.
return false;
}
- if (world.isForeign(element)) return true;
+ if (target.isForeign(element)) return true;
if (element.isSetter) return isSetter;
if (element.isGetter) return isGetter || isCall;
if (element.isField) {
@@ -248,14 +248,14 @@
return callStructure.signatureApplies(function.functionSignature);
}
- bool sameNameHack(Element element, World world) {
+ bool sameNameHack(Element element) {
// TODO(ngeoffray): Remove workaround checks.
return element.isConstructor || name == element.name;
}
- bool applies(Element element, World world) {
- if (!sameNameHack(element, world)) return false;
- return appliesUnnamed(element, world);
+ bool applies(Element element, Target target) {
+ if (!sameNameHack(element)) return false;
+ return appliesUnnamed(element, target);
}
bool match(SelectorKind kind, Name memberName, CallStructure callStructure) {
diff --git a/pkg/compiler/lib/src/universe/universe.dart b/pkg/compiler/lib/src/universe/universe.dart
index cb574bb..957b02b 100644
--- a/pkg/compiler/lib/src/universe/universe.dart
+++ b/pkg/compiler/lib/src/universe/universe.dart
@@ -11,7 +11,7 @@
import '../dart_types.dart';
import '../elements/elements.dart';
import '../util/util.dart';
-import '../world.dart' show ClassWorld, World;
+import '../world.dart' show ClassWorld, ClosedWorld, OpenWorld;
import 'selector.dart' show Selector;
import 'use.dart' show DynamicUse, DynamicUseKind, StaticUse, StaticUseKind;
@@ -106,8 +106,62 @@
/// [ClassWorld]. The concepts here and in [ClassWorld] 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"?
-class Universe {
+// 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, ClassWorld 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.
@@ -137,8 +191,6 @@
*
* 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 =
@@ -148,16 +200,7 @@
final Map<String, Map<Selector, SelectorConstraints>> _invokedSetters =
<String, Map<Selector, SelectorConstraints>>{};
- /**
- * Fields accessed. Currently only the codegen knows this
- * information. The resolver is too conservative when seeing a
- * getter and only registers an invoked getter.
- */
- final Set<Element> fieldGetters = new Set<Element>();
-
- /**
- * Fields set. See comment in [fieldGetters].
- */
+ /// Fields set.
final Set<Element> fieldSetters = new Set<Element>();
final Set<DartType> isChecks = new Set<DartType>();
@@ -190,7 +233,7 @@
final SelectorConstraintsStrategy selectorConstraintsStrategy;
- Universe(this.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
@@ -256,10 +299,10 @@
}
bool _hasMatchingSelector(Map<Selector, SelectorConstraints> selectors,
- Element member, World world) {
+ Element member, ClassWorld world) {
if (selectors == null) return false;
for (Selector selector in selectors.keys) {
- if (selector.appliesUnnamed(member, world)) {
+ if (selector.appliesUnnamed(member, world.backend)) {
SelectorConstraints masks = selectors[selector];
if (masks.applies(member, selector, world)) {
return true;
@@ -269,16 +312,256 @@
return false;
}
- bool hasInvocation(Element member, World world) {
+ bool hasInvocation(Element member, OpenWorld world) {
return _hasMatchingSelector(_invokedNames[member.name], member, world);
}
- bool hasInvokedGetter(Element member, World world) {
+ bool hasInvokedGetter(Element member, OpenWorld world) {
return _hasMatchingSelector(_invokedGetters[member.name], member, world) ||
member.isFunction && methodsNeedingSuperGetter.contains(member);
}
- bool hasInvokedSetter(Element member, World world) {
+ 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, world.backend)) {
+ 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);
}
@@ -359,30 +642,19 @@
case StaticUseKind.STATIC_TEAR_OFF:
staticFunctionsNeedingGetter.add(element);
break;
- case StaticUseKind.FIELD_GET:
- fieldGetters.add(element);
- break;
- case StaticUseKind.SUPER_FIELD_SET:
- case StaticUseKind.FIELD_SET:
- fieldSetters.add(element);
- break;
case StaticUseKind.SUPER_TEAR_OFF:
methodsNeedingSuperGetter.add(element);
break;
+ case StaticUseKind.SUPER_FIELD_SET:
+ case StaticUseKind.FIELD_SET:
case StaticUseKind.GENERAL:
- break;
case StaticUseKind.CLOSURE:
- allClosures.add(element);
+ case StaticUseKind.FIELD_GET:
break;
}
}
void forgetElement(Element element, Compiler compiler) {
- allClosures.remove(element);
- slowDirectlyNestedClosures(element).forEach(compiler.forgetElement);
- closurizedMembers.remove(element);
- fieldSetters.remove(element);
- fieldGetters.remove(element);
_directlyInstantiatedClasses.remove(element);
if (element is ClassElement) {
assert(invariant(element, element.thisType.isRaw,
@@ -390,14 +662,4 @@
_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;
- }));
- }
}
diff --git a/pkg/compiler/lib/src/universe/use.dart b/pkg/compiler/lib/src/universe/use.dart
index c1ab98f..a1756ed 100644
--- a/pkg/compiler/lib/src/universe/use.dart
+++ b/pkg/compiler/lib/src/universe/use.dart
@@ -38,7 +38,7 @@
DynamicUse(this.selector, this.mask);
bool appliesUnnamed(Element element, ClassWorld world) {
- return selector.appliesUnnamed(element, world) &&
+ return selector.appliesUnnamed(element, world.backend) &&
(mask == null || mask.canHit(element, selector, world));
}
diff --git a/pkg/compiler/lib/src/universe/world_impact.dart b/pkg/compiler/lib/src/universe/world_impact.dart
index 99c1c3c..723a87a 100644
--- a/pkg/compiler/lib/src/universe/world_impact.dart
+++ b/pkg/compiler/lib/src/universe/world_impact.dart
@@ -61,12 +61,18 @@
}
}
-class WorldImpactBuilder {
+abstract class WorldImpactBuilder {
+ void registerDynamicUse(DynamicUse dynamicUse);
+ void registerTypeUse(TypeUse typeUse);
+ void registerStaticUse(StaticUse staticUse);
+}
+
+class WorldImpactBuilderImpl extends WorldImpact implements WorldImpactBuilder {
// TODO(johnniwinther): Do we benefit from lazy initialization of the
// [Setlet]s?
- Setlet<DynamicUse> _dynamicUses;
- Setlet<StaticUse> _staticUses;
- Setlet<TypeUse> _typeUses;
+ Set<DynamicUse> _dynamicUses;
+ Set<StaticUse> _staticUses;
+ Set<TypeUse> _typeUses;
void registerDynamicUse(DynamicUse dynamicUse) {
assert(dynamicUse != null);
@@ -105,9 +111,60 @@
}
}
+/// [WorldImpactBuilder] that can create and collect a sequence of
+/// [WorldImpact]s.
+class StagedWorldImpactBuilder implements WorldImpactBuilder {
+ final bool collectImpacts;
+ WorldImpactBuilderImpl _currentBuilder;
+ List<WorldImpactBuilderImpl> _builders = <WorldImpactBuilderImpl>[];
+
+ StagedWorldImpactBuilder({this.collectImpacts: false});
+
+ void _ensureBuilder() {
+ if (_currentBuilder == null) {
+ _currentBuilder = new WorldImpactBuilderImpl();
+ if (collectImpacts) {
+ _builders.add(_currentBuilder);
+ }
+ }
+ }
+
+ @override
+ void registerTypeUse(TypeUse typeUse) {
+ _ensureBuilder();
+ _currentBuilder.registerTypeUse(typeUse);
+ }
+
+ @override
+ void registerDynamicUse(DynamicUse dynamicUse) {
+ _ensureBuilder();
+ _currentBuilder.registerDynamicUse(dynamicUse);
+ }
+
+ @override
+ void registerStaticUse(StaticUse staticUse) {
+ _ensureBuilder();
+ _currentBuilder.registerStaticUse(staticUse);
+ }
+
+ /// Returns the [WorldImpact] built so far with this builder. The builder
+ /// is reset, and if [collectImpacts] is `true` the impact is cached for
+ /// [worldImpacts].
+ WorldImpact flush() {
+ if (_currentBuilder == null) return const WorldImpact();
+ WorldImpact worldImpact = _currentBuilder;
+ _currentBuilder = null;
+ return worldImpact;
+ }
+
+ /// If [collectImpacts] is `true` this returns all [WorldImpact]s built with
+ /// this builder.
+ Iterable<WorldImpact> get worldImpacts => _builders;
+}
+
/// Mutable implementation of [WorldImpact] used to transform
/// [ResolutionImpact] or [CodegenImpact] to [WorldImpact].
-class TransformedWorldImpact implements WorldImpact {
+class TransformedWorldImpact implements WorldImpact, WorldImpactBuilder {
final WorldImpact worldImpact;
Setlet<StaticUse> _staticUses;
diff --git a/pkg/compiler/lib/src/use_unused_api.dart b/pkg/compiler/lib/src/use_unused_api.dart
index 5e0b379..da1cbdf 100644
--- a/pkg/compiler/lib/src/use_unused_api.dart
+++ b/pkg/compiler/lib/src/use_unused_api.dart
@@ -247,7 +247,7 @@
usedByTests() {
// TODO(ahe): We should try to avoid including API used only for tests. In
// most cases, such API can be moved to a test library.
- World world = null;
+ WorldImpl world = null;
type_graph_inferrer.TypeGraphInferrer typeGraphInferrer = null;
source_file_provider.SourceFileProvider sourceFileProvider = null;
sourceFileProvider.getSourceFile(null);
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
index 527240f..c348c77 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -20,7 +20,7 @@
VariableElement;
import 'js_backend/backend.dart' show JavaScriptBackend;
import 'ordered_typeset.dart';
-import 'types/masks.dart' show TypeMask, FlatTypeMask;
+import 'types/masks.dart' show CommonMasks, FlatTypeMask, TypeMask;
import 'universe/class_set.dart';
import 'universe/function_set.dart' show FunctionSet;
import 'universe/selector.dart' show Selector;
@@ -39,31 +39,45 @@
// TODO(johnniwinther): Refine this into a `BackendClasses` interface.
Backend get backend;
- // TODO(johnniwinther): Remove the need for this getter.
+ CoreClasses get coreClasses;
+
+ /// Returns `true` if the class world is closed.
+ bool get isClosed;
+
+ /// Returns `true` if closed-world assumptions can be made, that is,
+ /// incremental compilation isn't enabled.
+ bool get hasClosedWorldAssumption;
+
+ /// Returns a string representation of the closed world.
+ ///
+ /// If [cls] is provided, the dump will contain only classes related to [cls].
+ String dump([ClassElement cls]);
+
+ /// Returns [ClassHierarchyNode] for [cls] used to model the class hierarchies
+ /// of known classes.
+ ///
+ /// This method is only provided for testing. For queries on classes, use the
+ /// methods defined in [ClassWorld].
+ ClassHierarchyNode getClassHierarchyNode(ClassElement cls);
+
+ /// Returns [ClassSet] for [cls] used to model the extends and implements
+ /// relations of known classes.
+ ///
+ /// This method is only provided for testing. For queries on classes, use the
+ /// methods defined in [ClassWorld].
+ ClassSet getClassSet(ClassElement cls);
+
+ // TODO(johnniwinther): Find a better strategy for caching these.
@deprecated
- Compiler get compiler;
+ List<Map<ClassElement, TypeMask>> get canonicalizedTypeMasks;
+}
- /// The [ClassElement] for the [Object] class defined in 'dart:core'.
- ClassElement get objectClass;
-
- /// The [ClassElement] for the [Function] class defined in 'dart:core'.
- ClassElement get functionClass;
-
- /// The [ClassElement] for the [bool] class defined in 'dart:core'.
- ClassElement get boolClass;
-
- /// The [ClassElement] for the [num] class defined in 'dart:core'.
- ClassElement get numClass;
-
- /// The [ClassElement] for the [int] class defined in 'dart:core'.
- ClassElement get intClass;
-
- /// The [ClassElement] for the [double] class defined in 'dart:core'.
- ClassElement get doubleClass;
-
- /// The [ClassElement] for the [String] class defined in 'dart:core'.
- ClassElement get stringClass;
-
+/// The [ClosedWorld] represents the information known about a program when
+/// compiling with closed-world semantics.
+///
+/// This expands [ClassWorld] with information about live functions,
+/// side effects, and selectors with known single targets.
+abstract class ClosedWorld extends ClassWorld {
/// Returns `true` if [cls] is either directly or indirectly instantiated.
bool isInstantiated(ClassElement cls);
@@ -77,9 +91,6 @@
/// Returns `true` if [cls] is implemented by an instantiated class.
bool isImplemented(ClassElement cls);
- /// Returns `true` if the class world is closed.
- bool get isClosed;
-
/// Return `true` if [x] is a subclass of [y].
bool isSubclassOf(ClassElement x, ClassElement y);
@@ -178,25 +189,100 @@
/// Returns `true` if any subclass of [superclass] implements [type].
bool hasAnySubclassThatImplements(ClassElement superclass, ClassElement type);
- /// Returns `true` if closed-world assumptions can be made, that is,
- /// incremental compilation isn't enabled.
- bool get hasClosedWorldAssumption;
+ /// Returns the [FunctionSet] containing all live functions in the closed
+ /// world.
+ FunctionSet get allFunctions;
- /// Returns a string representation of the closed world.
- ///
- /// If [cls] is provided, the dump will contain only classes related to [cls].
- String dump([ClassElement cls]);
+ /// Returns `true` if the field [element] is known to be effectively final.
+ bool fieldNeverChanges(Element element);
+
+ /// Extends the receiver type [mask] for calling [selector] to take live
+ /// `noSuchMethod` handlers into account.
+ TypeMask extendMaskIfReachesAll(Selector selector, TypeMask mask);
+
+ /// Returns all resolved typedefs.
+ Iterable<TypedefElement> get allTypedefs;
+
+ /// Returns the single [Element] that matches a call to [selector] on a
+ /// receiver of type [mask]. If multiple targets exist, `null` is returned.
+ Element locateSingleElement(Selector selector, TypeMask mask);
+
+ /// Returns the single field that matches a call to [selector] on a
+ /// receiver of type [mask]. If multiple targets exist or the single target
+ /// is not a field, `null` is returned.
+ VariableElement locateSingleField(Selector selector, TypeMask mask);
+
+ /// Returns the side effects of executing [element].
+ SideEffects getSideEffectsOfElement(Element element);
+
+ /// Returns the side effects of calling [selector] on a receiver of type
+ /// [mask].
+ SideEffects getSideEffectsOfSelector(Selector selector, TypeMask mask);
+
+ /// Returns `true` if [element] is guaranteed not to throw an exception.
+ bool getCannotThrow(Element element);
+
+ /// Returns `true` if [element] is called in a loop.
+ // TODO(johnniwinther): Is this 'potentially called' or 'known to be called'?
+ bool isCalledInLoop(Element element);
+
+ /// Returns `true` if [element] might be passed to `Function.apply`.
+ // TODO(johnniwinther): Is this 'passed invocation target` or
+ // `passed as argument`?
+ bool getMightBePassedToApply(Element element);
}
-class World implements ClassWorld {
- ClassElement get objectClass => coreClasses.objectClass;
- ClassElement get functionClass => coreClasses.functionClass;
- ClassElement get boolClass => coreClasses.boolClass;
- ClassElement get numClass => coreClasses.numClass;
- ClassElement get intClass => coreClasses.intClass;
- ClassElement get doubleClass => coreClasses.doubleClass;
- ClassElement get stringClass => coreClasses.stringClass;
- ClassElement get nullClass => coreClasses.nullClass;
+/// Interface for computing side effects and uses of elements. This is used
+/// during type inference to compute the [ClosedWorld] for code generation.
+abstract class ClosedWorldRefiner {
+ /// Registers the side [effects] of executing [element].
+ void registerSideEffects(Element element, SideEffects effects);
+
+ /// Registers the executing of [element] as without side effects.
+ void registerSideEffectsFree(Element element);
+
+ /// Returns the currently known side effects of executing [element].
+ SideEffects getCurrentlyKnownSideEffects(Element element);
+
+ /// Registers that [element] might be passed to `Function.apply`.
+ // TODO(johnniwinther): Is this 'passed invocation target` or
+ // `passed as argument`?
+ void registerMightBePassedToApply(Element element);
+
+ /// Returns `true` if [element] might be passed to `Function.apply` given the
+ /// currently inferred information.
+ bool getCurrentlyKnownMightBePassedToApply(Element element);
+
+ /// Registers that [element] is called in a loop.
+ // TODO(johnniwinther): Is this 'potentially called' or 'known to be called'?
+ void addFunctionCalledInLoop(Element element);
+
+ /// Registers that [element] is guaranteed not to throw an exception.
+ void registerCannotThrow(Element element);
+
+ /// Adds the closure class [cls] to the inference world. The class is
+ /// considered directly instantiated.
+ void registerClosureClass(ClassElement cls);
+}
+
+abstract class OpenWorld implements ClassWorld {
+ /// Called to add [cls] to the set of known classes.
+ ///
+ /// This ensures that class hierarchy queries can be performed on [cls] and
+ /// classes that extend or implement it.
+ void registerClass(ClassElement cls);
+
+ void registerUsedElement(Element element);
+ void registerTypedef(TypedefElement typedef);
+
+ ClosedWorld closeWorld();
+
+ /// Returns an iterable over all mixin applications that mixin [cls].
+ Iterable<MixinApplicationElement> allMixinUsesOf(ClassElement cls);
+}
+
+class WorldImpl implements ClosedWorld, ClosedWorldRefiner, OpenWorld {
+ bool _closed = false;
/// Cache of [FlatTypeMask]s grouped by the 8 possible values of the
/// `FlatTypeMask.flags` property.
@@ -219,23 +305,25 @@
/// Returns `true` if [x] is a subtype of [y], that is, if [x] implements an
/// instance of [y].
bool isSubtypeOf(ClassElement x, ClassElement y) {
+ assert(isClosed);
assert(checkInvariants(x));
assert(checkInvariants(y, mustBeInstantiated: false));
- if (y == objectClass) return true;
- if (x == objectClass) return false;
+ if (y == coreClasses.objectClass) return true;
+ if (x == coreClasses.objectClass) return false;
if (x.asInstanceOf(y) != null) return true;
- if (y != functionClass) return false;
+ if (y != coreClasses.functionClass) return false;
return x.callType != null;
}
/// Return `true` if [x] is a (non-strict) subclass of [y].
bool isSubclassOf(ClassElement x, ClassElement y) {
+ assert(isClosed);
assert(checkInvariants(x));
assert(checkInvariants(y));
- if (y == objectClass) return true;
- if (x == objectClass) return false;
+ if (y == coreClasses.objectClass) return true;
+ if (x == coreClasses.objectClass) return false;
while (x != null && x.hierarchyDepth >= y.hierarchyDepth) {
if (x == y) return true;
x = x.superclass;
@@ -245,30 +333,35 @@
@override
bool isInstantiated(ClassElement cls) {
+ assert(isClosed);
ClassHierarchyNode node = _classHierarchyNodes[cls.declaration];
return node != null && node.isInstantiated;
}
@override
bool isDirectlyInstantiated(ClassElement cls) {
+ assert(isClosed);
ClassHierarchyNode node = _classHierarchyNodes[cls.declaration];
return node != null && node.isDirectlyInstantiated;
}
@override
bool isIndirectlyInstantiated(ClassElement cls) {
+ assert(isClosed);
ClassHierarchyNode node = _classHierarchyNodes[cls.declaration];
return node != null && node.isIndirectlyInstantiated;
}
/// Returns `true` if [cls] is implemented by an instantiated class.
bool isImplemented(ClassElement cls) {
- return compiler.resolverWorld.isImplemented(cls);
+ assert(isClosed);
+ return _compiler.resolverWorld.isImplemented(cls);
}
/// Returns an iterable over the directly instantiated classes that extend
/// [cls] possibly including [cls] itself, if it is live.
Iterable<ClassElement> subclassesOf(ClassElement cls) {
+ assert(isClosed);
ClassHierarchyNode hierarchy = _classHierarchyNodes[cls.declaration];
if (hierarchy == null) return const <ClassElement>[];
return hierarchy.subclassesByMask(ClassHierarchyNode.DIRECTLY_INSTANTIATED);
@@ -277,6 +370,7 @@
/// Returns an iterable over the directly instantiated classes that extend
/// [cls] _not_ including [cls] itself.
Iterable<ClassElement> strictSubclassesOf(ClassElement cls) {
+ assert(isClosed);
ClassHierarchyNode subclasses = _classHierarchyNodes[cls.declaration];
if (subclasses == null) return const <ClassElement>[];
return subclasses.subclassesByMask(ClassHierarchyNode.DIRECTLY_INSTANTIATED,
@@ -286,6 +380,7 @@
/// Returns the number of live classes that extend [cls] _not_
/// including [cls] itself.
int strictSubclassCount(ClassElement cls) {
+ assert(isClosed);
ClassHierarchyNode subclasses = _classHierarchyNodes[cls.declaration];
if (subclasses == null) return 0;
return subclasses.instantiatedSubclassCount;
@@ -295,6 +390,7 @@
/// itself.
void forEachStrictSubclassOf(
ClassElement cls, IterationStep f(ClassElement cls)) {
+ assert(isClosed);
ClassHierarchyNode subclasses = _classHierarchyNodes[cls.declaration];
if (subclasses == null) return;
subclasses.forEachSubclass(f, ClassHierarchyNode.DIRECTLY_INSTANTIATED,
@@ -304,6 +400,7 @@
/// Returns `true` if [predicate] applies to any live class that extend [cls]
/// _not_ including [cls] itself.
bool anyStrictSubclassOf(ClassElement cls, bool predicate(ClassElement cls)) {
+ assert(isClosed);
ClassHierarchyNode subclasses = _classHierarchyNodes[cls.declaration];
if (subclasses == null) return false;
return subclasses.anySubclass(
@@ -314,6 +411,7 @@
/// Returns an iterable over the directly instantiated that implement [cls]
/// possibly including [cls] itself, if it is live.
Iterable<ClassElement> subtypesOf(ClassElement cls) {
+ assert(isClosed);
ClassSet classSet = _classSets[cls.declaration];
if (classSet == null) {
return const <ClassElement>[];
@@ -325,6 +423,7 @@
/// Returns an iterable over the directly instantiated that implement [cls]
/// _not_ including [cls].
Iterable<ClassElement> strictSubtypesOf(ClassElement cls) {
+ assert(isClosed);
ClassSet classSet = _classSets[cls.declaration];
if (classSet == null) {
return const <ClassElement>[];
@@ -337,6 +436,7 @@
/// Returns the number of live classes that implement [cls] _not_
/// including [cls] itself.
int strictSubtypeCount(ClassElement cls) {
+ assert(isClosed);
ClassSet classSet = _classSets[cls.declaration];
if (classSet == null) return 0;
return classSet.instantiatedSubtypeCount;
@@ -346,6 +446,7 @@
/// itself.
void forEachStrictSubtypeOf(
ClassElement cls, IterationStep f(ClassElement cls)) {
+ assert(isClosed);
ClassSet classSet = _classSets[cls.declaration];
if (classSet == null) return;
classSet.forEachSubtype(f, ClassHierarchyNode.DIRECTLY_INSTANTIATED,
@@ -355,6 +456,7 @@
/// Returns `true` if [predicate] applies to any live class that extend [cls]
/// _not_ including [cls] itself.
bool anyStrictSubtypeOf(ClassElement cls, bool predicate(ClassElement cls)) {
+ assert(isClosed);
ClassSet classSet = _classSets[cls.declaration];
if (classSet == null) return false;
return classSet.anySubtype(
@@ -364,6 +466,7 @@
/// Returns `true` if [a] and [b] have any known common subtypes.
bool haveAnyCommonSubtypes(ClassElement a, ClassElement b) {
+ assert(isClosed);
ClassSet classSetA = _classSets[a.declaration];
ClassSet classSetB = _classSets[b.declaration];
if (classSetA == null || classSetB == null) return false;
@@ -380,6 +483,7 @@
/// Returns `true` if any directly instantiated class other than [cls] extends
/// [cls].
bool hasAnyStrictSubclass(ClassElement cls) {
+ assert(isClosed);
ClassHierarchyNode subclasses = _classHierarchyNodes[cls.declaration];
if (subclasses == null) return false;
return subclasses.isIndirectlyInstantiated;
@@ -394,8 +498,9 @@
/// Returns `true` if all directly instantiated classes that implement [cls]
/// extend it.
bool hasOnlySubclasses(ClassElement cls) {
+ assert(isClosed);
// TODO(johnniwinther): move this to ClassSet?
- if (cls == objectClass) return true;
+ if (cls == coreClasses.objectClass) return true;
ClassSet classSet = _classSets[cls.declaration];
if (classSet == null) {
// Vacuously true.
@@ -406,6 +511,7 @@
@override
ClassElement getLubOfInstantiatedSubclasses(ClassElement cls) {
+ assert(isClosed);
if (backend.isJsInterop(cls)) {
return backend.helpers.jsJavaScriptObjectClass;
}
@@ -417,6 +523,7 @@
@override
ClassElement getLubOfInstantiatedSubtypes(ClassElement cls) {
+ assert(isClosed);
if (backend.isJsInterop(cls)) {
return backend.helpers.jsJavaScriptObjectClass;
}
@@ -426,6 +533,7 @@
/// Returns an iterable over the common supertypes of the [classes].
Iterable<ClassElement> commonSupertypesOf(Iterable<ClassElement> classes) {
+ assert(isClosed);
Iterator<ClassElement> iterator = classes.iterator;
if (!iterator.moveNext()) return const <ClassElement>[];
@@ -449,7 +557,7 @@
List<ClassElement> commonSupertypes = <ClassElement>[];
OUTER:
for (Link<DartType> link = typeSet[depth];
- link.head.element != objectClass;
+ link.head.element != coreClasses.objectClass;
link = link.tail) {
ClassElement cls = link.head.element;
for (Link<OrderedTypeSet> link = otherTypeSets;
@@ -461,7 +569,7 @@
}
commonSupertypes.add(cls);
}
- commonSupertypes.add(objectClass);
+ commonSupertypes.add(coreClasses.objectClass);
return commonSupertypes;
}
@@ -502,12 +610,14 @@
/// Returns `true` if [cls] is mixed into a live class.
bool isUsedAsMixin(ClassElement cls) {
+ assert(isClosed);
return !mixinUsesOf(cls).isEmpty;
}
/// Returns `true` if any live class that mixes in [cls] implements [type].
bool hasAnySubclassOfMixinUseThatImplements(
ClassElement cls, ClassElement type) {
+ assert(isClosed);
return mixinUsesOf(cls)
.any((use) => hasAnySubclassThatImplements(use, type));
}
@@ -515,11 +625,13 @@
/// Returns `true` if any live class that mixes in [mixin] is also a subclass
/// of [superclass].
bool hasAnySubclassThatMixes(ClassElement superclass, ClassElement mixin) {
+ assert(isClosed);
return mixinUsesOf(mixin).any((each) => each.isSubclassOf(superclass));
}
/// Returns `true` if [cls] or any superclass mixes in [mixin].
bool isSubclassOfMixinUseOf(ClassElement cls, ClassElement mixin) {
+ assert(isClosed);
if (isUsedAsMixin(mixin)) {
ClassElement current = cls.declaration;
mixin = mixin.declaration;
@@ -538,6 +650,7 @@
/// Returns `true` if every subtype of [x] is a subclass of [y] or a subclass
/// of a mixin application of [y].
bool everySubtypeIsSubclassOfOrMixinUseOf(ClassElement x, ClassElement y) {
+ assert(isClosed);
x = x.declaration;
y = y.declaration;
Map<ClassElement, bool> secondMap =
@@ -549,18 +662,20 @@
/// Returns `true` if any subclass of [superclass] implements [type].
bool hasAnySubclassThatImplements(
ClassElement superclass, ClassElement type) {
+ assert(isClosed);
Set<ClassElement> subclasses = typesImplementedBySubclassesOf(superclass);
if (subclasses == null) return false;
return subclasses.contains(type);
}
- final Compiler compiler;
- JavaScriptBackend get backend => compiler.backend;
+ final Compiler _compiler;
+ JavaScriptBackend get backend => _compiler.backend;
+ CommonMasks get commonMasks => _compiler.commonMasks;
final FunctionSet allFunctions;
final Set<Element> functionsCalledInLoop = new Set<Element>();
final Map<Element, SideEffects> sideEffects = new Map<Element, SideEffects>();
- final Set<TypedefElement> allTypedefs = new Set<TypedefElement>();
+ final Set<TypedefElement> _allTypedefs = new Set<TypedefElement>();
final Map<ClassElement, Set<MixinApplicationElement>> _mixinUses =
new Map<ClassElement, Set<MixinApplicationElement>>();
@@ -587,37 +702,49 @@
final Set<Element> alreadyPopulated;
- bool get isClosed => compiler.phase > Compiler.PHASE_RESOLVING;
+ bool get isClosed => _closed;
// Used by selectors.
bool isForeign(Element element) {
- return compiler.backend.isForeign(element);
+ return backend.isForeign(element);
}
Set<ClassElement> typesImplementedBySubclassesOf(ClassElement cls) {
return _typesImplementedBySubclasses[cls.declaration];
}
- World(Compiler compiler)
+ WorldImpl(Compiler compiler)
: allFunctions = new FunctionSet(compiler),
- this.compiler = compiler,
+ this._compiler = compiler,
alreadyPopulated = compiler.cacheStrategy.newSet();
- CoreClasses get coreClasses => compiler.coreClasses;
+ CoreClasses get coreClasses => _compiler.coreClasses;
- DiagnosticReporter get reporter => compiler.reporter;
+ DiagnosticReporter get reporter => _compiler.reporter;
/// Called to add [cls] to the set of known classes.
///
/// This ensures that class hierarchy queries can be performed on [cls] and
/// classes that extend or implement it.
- void registerClass(ClassElement cls, {bool isDirectlyInstantiated: false}) {
+ void registerClass(ClassElement cls) => _registerClass(cls);
+
+ void registerClosureClass(ClassElement cls) {
+ _registerClass(cls, isDirectlyInstantiated: true);
+ }
+
+ void _registerClass(ClassElement cls, {bool isDirectlyInstantiated: false}) {
_ensureClassSet(cls);
if (isDirectlyInstantiated) {
_updateClassHierarchyNodeForClass(cls, directlyInstantiated: true);
}
}
+ void registerTypedef(TypedefElement typdef) {
+ _allTypedefs.add(typdef);
+ }
+
+ Iterable<TypedefElement> get allTypedefs => _allTypedefs;
+
/// Returns [ClassHierarchyNode] for [cls] used to model the class hierarchies
/// of known classes.
///
@@ -695,12 +822,12 @@
}
}
- void populate() {
+ ClosedWorld closeWorld() {
/// Updates the `isDirectlyInstantiated` and `isIndirectlyInstantiated`
/// properties of the [ClassHierarchyNode] for [cls].
void addSubtypes(ClassElement cls) {
- if (compiler.options.hasIncrementalSupport &&
+ if (_compiler.options.hasIncrementalSupport &&
!alreadyPopulated.add(cls)) {
return;
}
@@ -729,7 +856,10 @@
// classes: if the superclass of these classes require RTI, then
// they also need RTI, so that a constructor passes the type
// variables to the super constructor.
- compiler.resolverWorld.directlyInstantiatedClasses.forEach(addSubtypes);
+ _compiler.resolverWorld.directlyInstantiatedClasses.forEach(addSubtypes);
+
+ _closed = true;
+ return this;
}
@override
@@ -771,17 +901,17 @@
}
Element locateSingleElement(Selector selector, TypeMask mask) {
- mask ??= compiler.commonMasks.dynamicType;
- return mask.locateSingleElement(selector, compiler);
+ mask ??= commonMasks.dynamicType;
+ return mask.locateSingleElement(selector, _compiler);
}
TypeMask extendMaskIfReachesAll(Selector selector, TypeMask mask) {
bool canReachAll = true;
if (mask != null) {
- canReachAll = compiler.enabledInvokeOn &&
+ canReachAll = _compiler.enabledInvokeOn &&
mask.needsNoSuchMethodHandling(selector, this);
}
- return canReachAll ? compiler.commonMasks.dynamicType : mask;
+ return canReachAll ? commonMasks.dynamicType : mask;
}
void addFunctionCalledInLoop(Element element) {
@@ -806,8 +936,8 @@
return true;
}
if (element.isInstanceMember) {
- return !compiler.resolverWorld.hasInvokedSetter(element, this) &&
- !compiler.resolverWorld.fieldSetters.contains(element);
+ return !_compiler.resolverWorld.hasInvokedSetter(element, this) &&
+ !_compiler.resolverWorld.fieldSetters.contains(element);
}
return false;
}
@@ -826,6 +956,11 @@
});
}
+ @override
+ SideEffects getCurrentlyKnownSideEffects(Element element) {
+ return getSideEffectsOfElement(element);
+ }
+
void registerSideEffects(Element element, SideEffects effects) {
if (sideEffectsFreeElements.contains(element)) return;
sideEffects[element.declaration] = effects;
@@ -885,5 +1020,10 @@
return functionsThatMightBePassedToApply.contains(element);
}
- bool get hasClosedWorldAssumption => !compiler.options.hasIncrementalSupport;
+ @override
+ bool getCurrentlyKnownMightBePassedToApply(Element element) {
+ return getMightBePassedToApply(element);
+ }
+
+ bool get hasClosedWorldAssumption => !_compiler.options.hasIncrementalSupport;
}
diff --git a/pkg/dev_compiler/STRONG_MODE.md b/pkg/dev_compiler/STRONG_MODE.md
index 9b0b792..5a83747 100644
--- a/pkg/dev_compiler/STRONG_MODE.md
+++ b/pkg/dev_compiler/STRONG_MODE.md
@@ -27,20 +27,20 @@
However, in the following context, the info method prints “helloworld” in checked mode, without any static errors or warnings:
```dart
-import ‘dart:collection’;
-import ‘util.dart’;
+import 'dart:collection';
+import 'util.dart';
class MyList extends ListBase<int> implements List {
Object length;
MyList(this.length);
- operator[](index) => "world";
+ operator[](index) => 'world';
operator[]=(index, value) {}
}
void main() {
- List<int> list = new MyList("hello");
+ List<int> list = new MyList('hello');
info(list);
}
```
diff --git a/pkg/dev_compiler/lib/js/amd/dart_sdk.js b/pkg/dev_compiler/lib/js/amd/dart_sdk.js
index 8ec4be2..e4a67c2 100644
--- a/pkg/dev_compiler/lib/js/amd/dart_sdk.js
+++ b/pkg/dev_compiler/lib/js/amd/dart_sdk.js
@@ -4266,12 +4266,20 @@
});
_interceptors.JSMutableArray = JSMutableArray();
_interceptors.JSFixedArray$ = dart.generic(E => {
- class JSFixedArray extends _interceptors.JSMutableArray$(E) {}
+ class JSFixedArray extends _interceptors.JSMutableArray$(E) {
+ new() {
+ super.new();
+ }
+ }
return JSFixedArray;
});
_interceptors.JSFixedArray = JSFixedArray();
_interceptors.JSExtendableArray$ = dart.generic(E => {
- class JSExtendableArray extends _interceptors.JSMutableArray$(E) {}
+ class JSExtendableArray extends _interceptors.JSMutableArray$(E) {
+ new() {
+ super.new();
+ }
+ }
return JSExtendableArray;
});
_interceptors.JSExtendableArray = JSExtendableArray();
@@ -17068,6 +17076,7 @@
class _ControllerStream extends async._StreamImpl$(T) {
new(controller) {
this[_controller$] = controller;
+ super.new();
}
[_createSubscription](onData, onError, onDone, cancelOnError) {
return this[_controller$][_subscribe](onData, onError, onDone, cancelOnError);
@@ -20111,6 +20120,7 @@
new(pending) {
this[_pending] = pending;
this[_isUsed] = false;
+ super.new();
}
[_createSubscription](onData, onError, onDone, cancelOnError) {
if (dart.test(this[_isUsed])) dart.throw(new core.StateError("Stream has already been listened to."));
@@ -25577,7 +25587,7 @@
count++;
if (count > MAX_COUNT) {
while (dart.notNull(length) > LENGTH_LIMIT - ELLIPSIS_SIZE - OVERHEAD && count > HEAD_COUNT) {
- length = dart.notNull(length) - dart.notNull(core.int._check(dart.dsend(dart.dload(parts[dartx.removeLast](), 'length'), '+', OVERHEAD)));
+ length = dart.notNull(length) - dart.notNull(core.num._check(dart.dsend(dart.dload(parts[dartx.removeLast](), 'length'), '+', OVERHEAD)));
count--;
}
parts[dartx.add]("...");
@@ -25595,7 +25605,7 @@
length = dart.notNull(length) + (ELLIPSIS_SIZE + OVERHEAD);
}
while (dart.notNull(length) > LENGTH_LIMIT && dart.notNull(parts[dartx.length]) > HEAD_COUNT) {
- length = dart.notNull(length) - dart.notNull(core.int._check(dart.dsend(dart.dload(parts[dartx.removeLast](), 'length'), '+', OVERHEAD)));
+ length = dart.notNull(length) - dart.notNull(core.num._check(dart.dsend(dart.dload(parts[dartx.removeLast](), 'length'), '+', OVERHEAD)));
if (elision == null) {
elision = "...";
length = dart.notNull(length) + (ELLIPSIS_SIZE + OVERHEAD);
@@ -29213,6 +29223,7 @@
convert._ErrorHandlingAsciiDecoderSink = class _ErrorHandlingAsciiDecoderSink extends convert.ByteConversionSinkBase {
new(utf8Sink) {
this[_utf8Sink] = utf8Sink;
+ super.new();
}
close() {
this[_utf8Sink].close();
@@ -29247,6 +29258,7 @@
convert._SimpleAsciiDecoderSink = class _SimpleAsciiDecoderSink extends convert.ByteConversionSinkBase {
new(sink) {
this[_sink$] = sink;
+ super.new();
}
close() {
this[_sink$].close();
@@ -29535,6 +29547,9 @@
});
const _add$1 = Symbol('_add');
convert._Base64EncoderSink = class _Base64EncoderSink extends convert.ByteConversionSinkBase {
+ new() {
+ super.new();
+ }
add(source) {
this[_add$1](source, 0, source[dartx.length], false);
}
@@ -29557,6 +29572,7 @@
new(sink, urlSafe) {
this[_sink$] = sink;
this[_encoder] = new convert._BufferCachingBase64Encoder(urlSafe);
+ super.new();
}
[_add$1](source, start, end, isLast) {
let buffer = this[_encoder].encode(source, start, end, isLast);
@@ -29581,6 +29597,7 @@
new(sink, urlSafe) {
this[_sink$] = sink;
this[_encoder] = new convert._Base64Encoder(urlSafe);
+ super.new();
}
[_add$1](source, start, end, isLast) {
let buffer = this[_encoder].encode(source, start, end, isLast);
@@ -29932,6 +29949,7 @@
convert._ByteAdapterSink = class _ByteAdapterSink extends convert.ByteConversionSinkBase {
new(sink) {
this[_sink$] = sink;
+ super.new();
}
add(chunk) {
this[_sink$].add(chunk);
@@ -29956,6 +29974,7 @@
this[_buffer] = typed_data.Uint8List.new(convert._ByteCallbackSink._INITIAL_BUFFER_SIZE);
this[_callback] = callback;
this[_bufferIndex] = 0;
+ super.new();
}
add(chunk) {
let freeCount = dart.notNull(this[_buffer][dartx.length]) - dart.notNull(this[_bufferIndex]);
@@ -31301,6 +31320,7 @@
convert._Latin1DecoderSink = class _Latin1DecoderSink extends convert.ByteConversionSinkBase {
new(sink) {
this[_sink$] = sink;
+ super.new();
}
close() {
this[_sink$].close();
@@ -78396,13 +78416,13 @@
let val = 0;
for (let measurement of dimensions) {
if (augmentingMeasurement == html$._MARGIN) {
- val = dart.notNull(val) + dart.notNull(dart.asInt(new html$.Dimension.css(styles[dartx.getPropertyValue](dart.str`${augmentingMeasurement}-${measurement}`)).value));
+ val = dart.notNull(val) + dart.notNull(new html$.Dimension.css(styles[dartx.getPropertyValue](dart.str`${augmentingMeasurement}-${measurement}`)).value);
}
if (augmentingMeasurement == html$._CONTENT) {
- val = dart.notNull(val) - dart.notNull(dart.asInt(new html$.Dimension.css(styles[dartx.getPropertyValue](dart.str`${html$._PADDING}-${measurement}`)).value));
+ val = dart.notNull(val) - dart.notNull(new html$.Dimension.css(styles[dartx.getPropertyValue](dart.str`${html$._PADDING}-${measurement}`)).value);
}
if (augmentingMeasurement != html$._MARGIN) {
- val = dart.notNull(val) - dart.notNull(dart.asInt(new html$.Dimension.css(styles[dartx.getPropertyValue](dart.str`border-${measurement}-width`)).value));
+ val = dart.notNull(val) - dart.notNull(new html$.Dimension.css(styles[dartx.getPropertyValue](dart.str`border-${measurement}-width`)).value);
}
}
return val;
diff --git a/pkg/dev_compiler/lib/js/common/dart_sdk.js b/pkg/dev_compiler/lib/js/common/dart_sdk.js
index 1b39b69..8b9f7f9 100644
--- a/pkg/dev_compiler/lib/js/common/dart_sdk.js
+++ b/pkg/dev_compiler/lib/js/common/dart_sdk.js
@@ -4266,12 +4266,20 @@
});
_interceptors.JSMutableArray = JSMutableArray();
_interceptors.JSFixedArray$ = dart.generic(E => {
- class JSFixedArray extends _interceptors.JSMutableArray$(E) {}
+ class JSFixedArray extends _interceptors.JSMutableArray$(E) {
+ new() {
+ super.new();
+ }
+ }
return JSFixedArray;
});
_interceptors.JSFixedArray = JSFixedArray();
_interceptors.JSExtendableArray$ = dart.generic(E => {
- class JSExtendableArray extends _interceptors.JSMutableArray$(E) {}
+ class JSExtendableArray extends _interceptors.JSMutableArray$(E) {
+ new() {
+ super.new();
+ }
+ }
return JSExtendableArray;
});
_interceptors.JSExtendableArray = JSExtendableArray();
@@ -17068,6 +17076,7 @@
class _ControllerStream extends async._StreamImpl$(T) {
new(controller) {
this[_controller$] = controller;
+ super.new();
}
[_createSubscription](onData, onError, onDone, cancelOnError) {
return this[_controller$][_subscribe](onData, onError, onDone, cancelOnError);
@@ -20111,6 +20120,7 @@
new(pending) {
this[_pending] = pending;
this[_isUsed] = false;
+ super.new();
}
[_createSubscription](onData, onError, onDone, cancelOnError) {
if (dart.test(this[_isUsed])) dart.throw(new core.StateError("Stream has already been listened to."));
@@ -25577,7 +25587,7 @@
count++;
if (count > MAX_COUNT) {
while (dart.notNull(length) > LENGTH_LIMIT - ELLIPSIS_SIZE - OVERHEAD && count > HEAD_COUNT) {
- length = dart.notNull(length) - dart.notNull(core.int._check(dart.dsend(dart.dload(parts[dartx.removeLast](), 'length'), '+', OVERHEAD)));
+ length = dart.notNull(length) - dart.notNull(core.num._check(dart.dsend(dart.dload(parts[dartx.removeLast](), 'length'), '+', OVERHEAD)));
count--;
}
parts[dartx.add]("...");
@@ -25595,7 +25605,7 @@
length = dart.notNull(length) + (ELLIPSIS_SIZE + OVERHEAD);
}
while (dart.notNull(length) > LENGTH_LIMIT && dart.notNull(parts[dartx.length]) > HEAD_COUNT) {
- length = dart.notNull(length) - dart.notNull(core.int._check(dart.dsend(dart.dload(parts[dartx.removeLast](), 'length'), '+', OVERHEAD)));
+ length = dart.notNull(length) - dart.notNull(core.num._check(dart.dsend(dart.dload(parts[dartx.removeLast](), 'length'), '+', OVERHEAD)));
if (elision == null) {
elision = "...";
length = dart.notNull(length) + (ELLIPSIS_SIZE + OVERHEAD);
@@ -29213,6 +29223,7 @@
convert._ErrorHandlingAsciiDecoderSink = class _ErrorHandlingAsciiDecoderSink extends convert.ByteConversionSinkBase {
new(utf8Sink) {
this[_utf8Sink] = utf8Sink;
+ super.new();
}
close() {
this[_utf8Sink].close();
@@ -29247,6 +29258,7 @@
convert._SimpleAsciiDecoderSink = class _SimpleAsciiDecoderSink extends convert.ByteConversionSinkBase {
new(sink) {
this[_sink$] = sink;
+ super.new();
}
close() {
this[_sink$].close();
@@ -29535,6 +29547,9 @@
});
const _add$1 = Symbol('_add');
convert._Base64EncoderSink = class _Base64EncoderSink extends convert.ByteConversionSinkBase {
+ new() {
+ super.new();
+ }
add(source) {
this[_add$1](source, 0, source[dartx.length], false);
}
@@ -29557,6 +29572,7 @@
new(sink, urlSafe) {
this[_sink$] = sink;
this[_encoder] = new convert._BufferCachingBase64Encoder(urlSafe);
+ super.new();
}
[_add$1](source, start, end, isLast) {
let buffer = this[_encoder].encode(source, start, end, isLast);
@@ -29581,6 +29597,7 @@
new(sink, urlSafe) {
this[_sink$] = sink;
this[_encoder] = new convert._Base64Encoder(urlSafe);
+ super.new();
}
[_add$1](source, start, end, isLast) {
let buffer = this[_encoder].encode(source, start, end, isLast);
@@ -29932,6 +29949,7 @@
convert._ByteAdapterSink = class _ByteAdapterSink extends convert.ByteConversionSinkBase {
new(sink) {
this[_sink$] = sink;
+ super.new();
}
add(chunk) {
this[_sink$].add(chunk);
@@ -29956,6 +29974,7 @@
this[_buffer] = typed_data.Uint8List.new(convert._ByteCallbackSink._INITIAL_BUFFER_SIZE);
this[_callback] = callback;
this[_bufferIndex] = 0;
+ super.new();
}
add(chunk) {
let freeCount = dart.notNull(this[_buffer][dartx.length]) - dart.notNull(this[_bufferIndex]);
@@ -31301,6 +31320,7 @@
convert._Latin1DecoderSink = class _Latin1DecoderSink extends convert.ByteConversionSinkBase {
new(sink) {
this[_sink$] = sink;
+ super.new();
}
close() {
this[_sink$].close();
@@ -78396,13 +78416,13 @@
let val = 0;
for (let measurement of dimensions) {
if (augmentingMeasurement == html$._MARGIN) {
- val = dart.notNull(val) + dart.notNull(dart.asInt(new html$.Dimension.css(styles[dartx.getPropertyValue](dart.str`${augmentingMeasurement}-${measurement}`)).value));
+ val = dart.notNull(val) + dart.notNull(new html$.Dimension.css(styles[dartx.getPropertyValue](dart.str`${augmentingMeasurement}-${measurement}`)).value);
}
if (augmentingMeasurement == html$._CONTENT) {
- val = dart.notNull(val) - dart.notNull(dart.asInt(new html$.Dimension.css(styles[dartx.getPropertyValue](dart.str`${html$._PADDING}-${measurement}`)).value));
+ val = dart.notNull(val) - dart.notNull(new html$.Dimension.css(styles[dartx.getPropertyValue](dart.str`${html$._PADDING}-${measurement}`)).value);
}
if (augmentingMeasurement != html$._MARGIN) {
- val = dart.notNull(val) - dart.notNull(dart.asInt(new html$.Dimension.css(styles[dartx.getPropertyValue](dart.str`border-${measurement}-width`)).value));
+ val = dart.notNull(val) - dart.notNull(new html$.Dimension.css(styles[dartx.getPropertyValue](dart.str`border-${measurement}-width`)).value);
}
}
return val;
diff --git a/pkg/dev_compiler/lib/js/es6/dart_sdk.js b/pkg/dev_compiler/lib/js/es6/dart_sdk.js
index 5a1b9f8..c99499b 100644
--- a/pkg/dev_compiler/lib/js/es6/dart_sdk.js
+++ b/pkg/dev_compiler/lib/js/es6/dart_sdk.js
@@ -4264,12 +4264,20 @@
});
_interceptors.JSMutableArray = JSMutableArray();
_interceptors.JSFixedArray$ = dart.generic(E => {
- class JSFixedArray extends _interceptors.JSMutableArray$(E) {}
+ class JSFixedArray extends _interceptors.JSMutableArray$(E) {
+ new() {
+ super.new();
+ }
+ }
return JSFixedArray;
});
_interceptors.JSFixedArray = JSFixedArray();
_interceptors.JSExtendableArray$ = dart.generic(E => {
- class JSExtendableArray extends _interceptors.JSMutableArray$(E) {}
+ class JSExtendableArray extends _interceptors.JSMutableArray$(E) {
+ new() {
+ super.new();
+ }
+ }
return JSExtendableArray;
});
_interceptors.JSExtendableArray = JSExtendableArray();
@@ -17066,6 +17074,7 @@
class _ControllerStream extends async._StreamImpl$(T) {
new(controller) {
this[_controller] = controller;
+ super.new();
}
[_createSubscription](onData, onError, onDone, cancelOnError) {
return this[_controller][_subscribe](onData, onError, onDone, cancelOnError);
@@ -20109,6 +20118,7 @@
new(pending) {
this[_pending] = pending;
this[_isUsed] = false;
+ super.new();
}
[_createSubscription](onData, onError, onDone, cancelOnError) {
if (dart.test(this[_isUsed])) dart.throw(new core.StateError("Stream has already been listened to."));
@@ -25575,7 +25585,7 @@
count++;
if (count > MAX_COUNT) {
while (dart.notNull(length) > LENGTH_LIMIT - ELLIPSIS_SIZE - OVERHEAD && count > HEAD_COUNT) {
- length = dart.notNull(length) - dart.notNull(core.int._check(dart.dsend(dart.dload(parts[dartx.removeLast](), 'length'), '+', OVERHEAD)));
+ length = dart.notNull(length) - dart.notNull(core.num._check(dart.dsend(dart.dload(parts[dartx.removeLast](), 'length'), '+', OVERHEAD)));
count--;
}
parts[dartx.add]("...");
@@ -25593,7 +25603,7 @@
length = dart.notNull(length) + (ELLIPSIS_SIZE + OVERHEAD);
}
while (dart.notNull(length) > LENGTH_LIMIT && dart.notNull(parts[dartx.length]) > HEAD_COUNT) {
- length = dart.notNull(length) - dart.notNull(core.int._check(dart.dsend(dart.dload(parts[dartx.removeLast](), 'length'), '+', OVERHEAD)));
+ length = dart.notNull(length) - dart.notNull(core.num._check(dart.dsend(dart.dload(parts[dartx.removeLast](), 'length'), '+', OVERHEAD)));
if (elision == null) {
elision = "...";
length = dart.notNull(length) + (ELLIPSIS_SIZE + OVERHEAD);
@@ -29211,6 +29221,7 @@
convert._ErrorHandlingAsciiDecoderSink = class _ErrorHandlingAsciiDecoderSink extends convert.ByteConversionSinkBase {
new(utf8Sink) {
this[_utf8Sink] = utf8Sink;
+ super.new();
}
close() {
this[_utf8Sink].close();
@@ -29245,6 +29256,7 @@
convert._SimpleAsciiDecoderSink = class _SimpleAsciiDecoderSink extends convert.ByteConversionSinkBase {
new(sink) {
this[_sink] = sink;
+ super.new();
}
close() {
this[_sink].close();
@@ -29533,6 +29545,9 @@
});
const _add = Symbol('_add');
convert._Base64EncoderSink = class _Base64EncoderSink extends convert.ByteConversionSinkBase {
+ new() {
+ super.new();
+ }
add(source) {
this[_add](source, 0, source[dartx.length], false);
}
@@ -29555,6 +29570,7 @@
new(sink, urlSafe) {
this[_sink] = sink;
this[_encoder] = new convert._BufferCachingBase64Encoder(urlSafe);
+ super.new();
}
[_add](source, start, end, isLast) {
let buffer = this[_encoder].encode(source, start, end, isLast);
@@ -29579,6 +29595,7 @@
new(sink, urlSafe) {
this[_sink] = sink;
this[_encoder] = new convert._Base64Encoder(urlSafe);
+ super.new();
}
[_add](source, start, end, isLast) {
let buffer = this[_encoder].encode(source, start, end, isLast);
@@ -29930,6 +29947,7 @@
convert._ByteAdapterSink = class _ByteAdapterSink extends convert.ByteConversionSinkBase {
new(sink) {
this[_sink] = sink;
+ super.new();
}
add(chunk) {
this[_sink].add(chunk);
@@ -29954,6 +29972,7 @@
this[_buffer] = typed_data.Uint8List.new(convert._ByteCallbackSink._INITIAL_BUFFER_SIZE);
this[_callback] = callback;
this[_bufferIndex] = 0;
+ super.new();
}
add(chunk) {
let freeCount = dart.notNull(this[_buffer][dartx.length]) - dart.notNull(this[_bufferIndex]);
@@ -31299,6 +31318,7 @@
convert._Latin1DecoderSink = class _Latin1DecoderSink extends convert.ByteConversionSinkBase {
new(sink) {
this[_sink] = sink;
+ super.new();
}
close() {
this[_sink].close();
@@ -78394,13 +78414,13 @@
let val = 0;
for (let measurement of dimensions) {
if (augmentingMeasurement == html._MARGIN) {
- val = dart.notNull(val) + dart.notNull(dart.asInt(new html.Dimension.css(styles[dartx.getPropertyValue](dart.str`${augmentingMeasurement}-${measurement}`)).value));
+ val = dart.notNull(val) + dart.notNull(new html.Dimension.css(styles[dartx.getPropertyValue](dart.str`${augmentingMeasurement}-${measurement}`)).value);
}
if (augmentingMeasurement == html._CONTENT) {
- val = dart.notNull(val) - dart.notNull(dart.asInt(new html.Dimension.css(styles[dartx.getPropertyValue](dart.str`${html._PADDING}-${measurement}`)).value));
+ val = dart.notNull(val) - dart.notNull(new html.Dimension.css(styles[dartx.getPropertyValue](dart.str`${html._PADDING}-${measurement}`)).value);
}
if (augmentingMeasurement != html._MARGIN) {
- val = dart.notNull(val) - dart.notNull(dart.asInt(new html.Dimension.css(styles[dartx.getPropertyValue](dart.str`border-${measurement}-width`)).value));
+ val = dart.notNull(val) - dart.notNull(new html.Dimension.css(styles[dartx.getPropertyValue](dart.str`border-${measurement}-width`)).value);
}
}
return val;
diff --git a/pkg/dev_compiler/lib/js/legacy/dart_sdk.js b/pkg/dev_compiler/lib/js/legacy/dart_sdk.js
index 1292685..4c981ff 100644
--- a/pkg/dev_compiler/lib/js/legacy/dart_sdk.js
+++ b/pkg/dev_compiler/lib/js/legacy/dart_sdk.js
@@ -4267,12 +4267,20 @@
});
_interceptors.JSMutableArray = JSMutableArray();
_interceptors.JSFixedArray$ = dart.generic(E => {
- class JSFixedArray extends _interceptors.JSMutableArray$(E) {}
+ class JSFixedArray extends _interceptors.JSMutableArray$(E) {
+ new() {
+ super.new();
+ }
+ }
return JSFixedArray;
});
_interceptors.JSFixedArray = JSFixedArray();
_interceptors.JSExtendableArray$ = dart.generic(E => {
- class JSExtendableArray extends _interceptors.JSMutableArray$(E) {}
+ class JSExtendableArray extends _interceptors.JSMutableArray$(E) {
+ new() {
+ super.new();
+ }
+ }
return JSExtendableArray;
});
_interceptors.JSExtendableArray = JSExtendableArray();
@@ -17069,6 +17077,7 @@
class _ControllerStream extends async._StreamImpl$(T) {
new(controller) {
this[_controller$] = controller;
+ super.new();
}
[_createSubscription](onData, onError, onDone, cancelOnError) {
return this[_controller$][_subscribe](onData, onError, onDone, cancelOnError);
@@ -20112,6 +20121,7 @@
new(pending) {
this[_pending] = pending;
this[_isUsed] = false;
+ super.new();
}
[_createSubscription](onData, onError, onDone, cancelOnError) {
if (dart.test(this[_isUsed])) dart.throw(new core.StateError("Stream has already been listened to."));
@@ -25578,7 +25588,7 @@
count++;
if (count > MAX_COUNT) {
while (dart.notNull(length) > LENGTH_LIMIT - ELLIPSIS_SIZE - OVERHEAD && count > HEAD_COUNT) {
- length = dart.notNull(length) - dart.notNull(core.int._check(dart.dsend(dart.dload(parts[dartx.removeLast](), 'length'), '+', OVERHEAD)));
+ length = dart.notNull(length) - dart.notNull(core.num._check(dart.dsend(dart.dload(parts[dartx.removeLast](), 'length'), '+', OVERHEAD)));
count--;
}
parts[dartx.add]("...");
@@ -25596,7 +25606,7 @@
length = dart.notNull(length) + (ELLIPSIS_SIZE + OVERHEAD);
}
while (dart.notNull(length) > LENGTH_LIMIT && dart.notNull(parts[dartx.length]) > HEAD_COUNT) {
- length = dart.notNull(length) - dart.notNull(core.int._check(dart.dsend(dart.dload(parts[dartx.removeLast](), 'length'), '+', OVERHEAD)));
+ length = dart.notNull(length) - dart.notNull(core.num._check(dart.dsend(dart.dload(parts[dartx.removeLast](), 'length'), '+', OVERHEAD)));
if (elision == null) {
elision = "...";
length = dart.notNull(length) + (ELLIPSIS_SIZE + OVERHEAD);
@@ -29214,6 +29224,7 @@
convert._ErrorHandlingAsciiDecoderSink = class _ErrorHandlingAsciiDecoderSink extends convert.ByteConversionSinkBase {
new(utf8Sink) {
this[_utf8Sink] = utf8Sink;
+ super.new();
}
close() {
this[_utf8Sink].close();
@@ -29248,6 +29259,7 @@
convert._SimpleAsciiDecoderSink = class _SimpleAsciiDecoderSink extends convert.ByteConversionSinkBase {
new(sink) {
this[_sink$] = sink;
+ super.new();
}
close() {
this[_sink$].close();
@@ -29536,6 +29548,9 @@
});
const _add$1 = Symbol('_add');
convert._Base64EncoderSink = class _Base64EncoderSink extends convert.ByteConversionSinkBase {
+ new() {
+ super.new();
+ }
add(source) {
this[_add$1](source, 0, source[dartx.length], false);
}
@@ -29558,6 +29573,7 @@
new(sink, urlSafe) {
this[_sink$] = sink;
this[_encoder] = new convert._BufferCachingBase64Encoder(urlSafe);
+ super.new();
}
[_add$1](source, start, end, isLast) {
let buffer = this[_encoder].encode(source, start, end, isLast);
@@ -29582,6 +29598,7 @@
new(sink, urlSafe) {
this[_sink$] = sink;
this[_encoder] = new convert._Base64Encoder(urlSafe);
+ super.new();
}
[_add$1](source, start, end, isLast) {
let buffer = this[_encoder].encode(source, start, end, isLast);
@@ -29933,6 +29950,7 @@
convert._ByteAdapterSink = class _ByteAdapterSink extends convert.ByteConversionSinkBase {
new(sink) {
this[_sink$] = sink;
+ super.new();
}
add(chunk) {
this[_sink$].add(chunk);
@@ -29957,6 +29975,7 @@
this[_buffer] = typed_data.Uint8List.new(convert._ByteCallbackSink._INITIAL_BUFFER_SIZE);
this[_callback] = callback;
this[_bufferIndex] = 0;
+ super.new();
}
add(chunk) {
let freeCount = dart.notNull(this[_buffer][dartx.length]) - dart.notNull(this[_bufferIndex]);
@@ -31302,6 +31321,7 @@
convert._Latin1DecoderSink = class _Latin1DecoderSink extends convert.ByteConversionSinkBase {
new(sink) {
this[_sink$] = sink;
+ super.new();
}
close() {
this[_sink$].close();
@@ -78397,13 +78417,13 @@
let val = 0;
for (let measurement of dimensions) {
if (augmentingMeasurement == html$._MARGIN) {
- val = dart.notNull(val) + dart.notNull(dart.asInt(new html$.Dimension.css(styles[dartx.getPropertyValue](dart.str`${augmentingMeasurement}-${measurement}`)).value));
+ val = dart.notNull(val) + dart.notNull(new html$.Dimension.css(styles[dartx.getPropertyValue](dart.str`${augmentingMeasurement}-${measurement}`)).value);
}
if (augmentingMeasurement == html$._CONTENT) {
- val = dart.notNull(val) - dart.notNull(dart.asInt(new html$.Dimension.css(styles[dartx.getPropertyValue](dart.str`${html$._PADDING}-${measurement}`)).value));
+ val = dart.notNull(val) - dart.notNull(new html$.Dimension.css(styles[dartx.getPropertyValue](dart.str`${html$._PADDING}-${measurement}`)).value);
}
if (augmentingMeasurement != html$._MARGIN) {
- val = dart.notNull(val) - dart.notNull(dart.asInt(new html$.Dimension.css(styles[dartx.getPropertyValue](dart.str`border-${measurement}-width`)).value));
+ val = dart.notNull(val) - dart.notNull(new html$.Dimension.css(styles[dartx.getPropertyValue](dart.str`border-${measurement}-width`)).value);
}
}
return val;
diff --git a/pkg/dev_compiler/lib/src/analyzer/context.dart b/pkg/dev_compiler/lib/src/analyzer/context.dart
index 734731b..3545bca 100644
--- a/pkg/dev_compiler/lib/src/analyzer/context.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/context.dart
@@ -13,11 +13,11 @@
import 'package:analyzer/src/context/context.dart' show AnalysisContextImpl;
import 'package:analyzer/src/dart/sdk/sdk.dart' show FolderBasedDartSdk;
import 'package:analyzer/src/generated/engine.dart'
- show AnalysisContext, AnalysisEngine, AnalysisOptionsImpl;
+ show AnalysisEngine, AnalysisOptionsImpl;
import 'package:analyzer/src/generated/source.dart'
show DartUriResolver, SourceFactory, UriResolver;
import 'package:analyzer/src/summary/package_bundle_reader.dart'
- show InSummaryUriResolver, InputPackagesResultProvider, SummaryDataStore;
+ show InSummaryUriResolver, SummaryDataStore;
import 'package:analyzer/src/summary/summary_sdk.dart' show SummaryBasedDartSdk;
import 'package:cli_util/cli_util.dart' show getSdkDir;
import 'package:path/path.dart' as path;
@@ -98,39 +98,6 @@
}
}
-/// Creates an [AnalysisContext] with dev_compiler type rules and inference,
-/// using [createSourceFactory] to set up its [SourceFactory].
-AnalysisContext createAnalysisContextWithSources(AnalyzerOptions options,
- {DartUriResolver sdkResolver,
- List<UriResolver> fileResolvers,
- ResourceProvider resourceProvider}) {
- AnalysisEngine.instance.processRequiredPlugins();
-
- sdkResolver ??=
- createSdkPathResolver(options.dartSdkSummaryPath, options.dartSdkPath);
-
- // Read the summaries.
- SummaryDataStore summaryData;
- if (options.summaryPaths.isNotEmpty) {
- summaryData = new SummaryDataStore(options.summaryPaths);
- }
-
- var srcFactory = _createSourceFactory(options,
- sdkResolver: sdkResolver,
- fileResolvers: fileResolvers,
- summaryData: summaryData,
- resourceProvider: resourceProvider);
-
- var context = createAnalysisContext();
- context.sourceFactory = srcFactory;
- if (summaryData != null) {
- context.typeProvider = sdkResolver.dartSdk.context.typeProvider;
- context.resultProvider =
- new InputPackagesResultProvider(context, summaryData);
- }
- return context;
-}
-
/// Creates an analysis context that contains our restricted typing rules.
AnalysisContextImpl createAnalysisContext() {
var res = AnalysisEngine.instance.createAnalysisContext();
@@ -147,7 +114,7 @@
///
/// If supplied, [fileResolvers] will override the default `file:` and
/// `package:` URI resolvers.
-SourceFactory _createSourceFactory(AnalyzerOptions options,
+SourceFactory createSourceFactory(AnalyzerOptions options,
{DartUriResolver sdkResolver,
List<UriResolver> fileResolvers,
SummaryDataStore summaryData,
diff --git a/pkg/dev_compiler/lib/src/compiler/code_generator.dart b/pkg/dev_compiler/lib/src/compiler/code_generator.dart
index dd31245..1b306a7 100644
--- a/pkg/dev_compiler/lib/src/compiler/code_generator.dart
+++ b/pkg/dev_compiler/lib/src/compiler/code_generator.dart
@@ -1,4 +1,5 @@
// 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.
@@ -14,15 +15,22 @@
import 'package:analyzer/src/dart/element/element.dart'
show LocalVariableElementImpl;
import 'package:analyzer/src/dart/element/type.dart' show DynamicTypeImpl;
+import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
import 'package:analyzer/src/generated/resolver.dart'
show TypeProvider, NamespaceBuilder;
import 'package:analyzer/src/generated/type_system.dart'
show StrongTypeSystemImpl;
+import 'package:analyzer/src/summary/idl.dart' show UnlinkedUnit;
+import 'package:analyzer/src/summary/link.dart' as summary_link;
+import 'package:analyzer/src/summary/package_bundle_reader.dart';
+import 'package:analyzer/src/summary/summarize_ast.dart'
+ show serializeAstUnlinked;
import 'package:analyzer/src/summary/summarize_elements.dart'
show PackageBundleAssembler;
+import 'package:analyzer/src/summary/summary_sdk.dart';
import 'package:analyzer/src/task/strong/ast_properties.dart'
- show isDynamicInvoke, setIsDynamicInvoke;
+ show isDynamicInvoke, setIsDynamicInvoke, getImplicitAssignmentCast;
import 'package:path/path.dart' show separator;
import '../closure/closure_annotator.dart' show ClosureAnnotator;
@@ -47,6 +55,8 @@
class CodeGenerator extends GeneralizingAstVisitor
with ClosureAnnotator, JsTypeRefCodegen, NullableTypeInference {
final AnalysisContext context;
+ final SummaryDataStore summaryData;
+
final CompilerOptions options;
final rules = new StrongTypeSystemImpl();
@@ -138,7 +148,8 @@
/// Whether we are currently generating code for the body of a `JS()` call.
bool _isInForeignJS = false;
- CodeGenerator(AnalysisContext c, this.options, this._extensionTypes)
+ CodeGenerator(
+ AnalysisContext c, this.summaryData, this.options, this._extensionTypes)
: context = c,
types = c.typeProvider,
_asyncStreamIterator =
@@ -175,14 +186,37 @@
return new JSModuleFile(unit.name, errors, options, module, dartApiSummary);
}
- List<int> _summarizeModule(List<CompilationUnit> compilationUnits) {
+ List<int> _summarizeModule(List<CompilationUnit> units) {
if (!options.summarizeApi) return null;
+ if (!units.any((u) => u.element.librarySource.isInSystemLibrary)) {
+ var sdk = context.sourceFactory.dartSdk;
+ summaryData.addBundle(
+ null,
+ sdk is SummaryBasedDartSdk
+ ? sdk.bundle
+ : (sdk as FolderBasedDartSdk).getSummarySdkBundle(true));
+ }
+
var assembler = new PackageBundleAssembler();
- compilationUnits
- .map((u) => u.element.library)
- .toSet()
- .forEach(assembler.serializeLibraryElement);
+ assembler.recordDependencies(summaryData);
+
+ var uriToUnit = new Map<String, UnlinkedUnit>.fromIterable(units,
+ key: (u) => u.element.source.uri.toString(), value: (unit) {
+ var unlinked = serializeAstUnlinked(unit);
+ assembler.addUnlinkedUnit(unit.element.source, unlinked);
+ return unlinked;
+ });
+
+ summary_link
+ .link(
+ uriToUnit.keys.toSet(),
+ (uri) => summaryData.linkedMap[uri],
+ (uri) => summaryData.unlinkedMap[uri] ?? uriToUnit[uri],
+ context.declaredVariables.get,
+ true)
+ .forEach(assembler.addLinkedLibrary);
+
return assembler.assemble().toBuffer();
}
@@ -526,19 +560,13 @@
var type = _emitType(to,
nameType: options.nameTypeTests || options.hoistTypeTests,
hoistType: options.hoistTypeTests);
- if (isReifiedCoercion(node)) {
+ if (CoercionReifier.isImplicitCast(node)) {
return js.call('#._check(#)', [type, jsFrom]);
} else {
return js.call('#.as(#)', [type, jsFrom]);
}
}
- bool isReifiedCoercion(AstNode node) {
- // TODO(sra): Find a better way to recognize reified coercion, since we
- // can't set the isSynthetic attribute.
- return (node is AsExpression) && (node.asOperator.offset == 0);
- }
-
@override
visitIsExpression(IsExpression node) {
// Generate `is` as `dart.is` or `typeof` depending on the RHS type.
@@ -1856,8 +1884,6 @@
ClassDeclaration node,
List<FieldDeclaration> fields,
Map<FieldElement, JS.TemporaryId> virtualFields) {
- assert(_hasUnnamedConstructor(node.element) == fields.isNotEmpty);
-
// If we don't have a method body, skip this.
var superCall = _superConstructorCall(node.element);
if (fields.isEmpty && superCall == null) return null;
@@ -1897,8 +1923,8 @@
var fun = new JS.Fun(
params,
- js.statement(
- '{ return $newKeyword #(#); }', [_visit(redirect), params]),
+ js.statement('{ return $newKeyword #(#); }',
+ [_visit(redirect) as JS.Node, params]),
returnType: returnType);
return annotate(
new JS.Method(name, fun, isStatic: true), node, node.element);
@@ -2031,7 +2057,7 @@
return null;
}
- if (superCtor.name == '' && !_shouldCallUnnamedSuperCtor(element)) {
+ if (superCtor.name == '' && !_hasUnnamedSuperConstructor(element)) {
return null;
}
@@ -2040,7 +2066,7 @@
return annotate(js.statement('super.#(#);', [name, args]), node);
}
- bool _shouldCallUnnamedSuperCtor(ClassElement e) {
+ bool _hasUnnamedSuperConstructor(ClassElement e) {
var supertype = e.supertype;
if (supertype == null) return false;
if (_hasUnnamedConstructor(supertype.element)) return true;
@@ -2053,7 +2079,8 @@
bool _hasUnnamedConstructor(ClassElement e) {
if (e.type.isObject) return false;
if (!e.unnamedConstructor.isSynthetic) return true;
- return e.fields.any((f) => !f.isStatic && !f.isSynthetic);
+ if (e.fields.any((f) => !f.isStatic && !f.isSynthetic)) return true;
+ return _hasUnnamedSuperConstructor(e);
}
/// Initialize fields. They follow the sequence:
@@ -2981,9 +3008,12 @@
// (for example, x is IndexExpression) we evaluate those once.
var vars = <JS.MetaLetVariable, JS.Expression>{};
var lhs = _bindLeftHandSide(vars, left, context: context);
- var inc = AstBuilder.binaryExpression(lhs, op, right);
- inc.staticElement = element;
- inc.staticType = getStaticType(left);
+ Expression inc = AstBuilder.binaryExpression(lhs, op, right)
+ ..staticElement = element
+ ..staticType = getStaticType(lhs);
+
+ var castTo = getImplicitAssignmentCast(left);
+ if (castTo != null) inc = CoercionReifier.castExpression(inc, castTo);
return new JS.MetaLet(vars, [_emitSet(lhs, inc)]);
}
@@ -4511,7 +4541,8 @@
}
}
if (tail.isEmpty) return _visit(node);
- return js.call('dart.nullSafe(#, #)', [_visit(node), tail.reversed]);
+ return js.call(
+ 'dart.nullSafe(#, #)', [_visit(node) as JS.Expression, tail.reversed]);
}
static Token _getOperator(Expression node) {
@@ -4664,8 +4695,8 @@
// dynamic dispatch
var dynamicHelper = const {'[]': 'dindex', '[]=': 'dsetindex'}[name];
if (dynamicHelper != null) {
- return js.call(
- 'dart.$dynamicHelper(#, #)', [_visit(target), _visitList(args)]);
+ return js.call('dart.$dynamicHelper(#, #)',
+ [_visit(target) as JS.Expression, _visitList(args)]);
} else {
return js.call('dart.dsend(#, #, #)',
[_visit(target), memberName, _visitList(args)]);
@@ -5019,7 +5050,7 @@
// TODO(jmesserly): we can likely make these faster.
JS.Expression emitMap() {
var entries = node.entries;
- var mapArguments = null;
+ Object mapArguments = null;
var type = node.staticType as InterfaceType;
var typeArgs = type.typeArguments;
var reifyTypeArgs = typeArgs.any((t) => !t.isDynamic);
@@ -5141,10 +5172,9 @@
if (op == '&&') return shortCircuit('# && #');
if (op == '||') return shortCircuit('# || #');
}
- if (isReifiedCoercion(node)) {
- AsExpression asNode = node;
- assert(asNode.staticType == types.boolType);
- return js.call('dart.test(#)', _visit(asNode.expression));
+ if (node is AsExpression && CoercionReifier.isImplicitCast(node)) {
+ assert(node.staticType == types.boolType);
+ return js.call('dart.test(#)', _visit(node.expression));
}
JS.Expression result = _visit(node);
if (isNullable(node)) result = js.call('dart.test(#)', result);
@@ -5425,7 +5455,8 @@
uri.path.substring(libraryRoot.length).replaceAll('/', separator);
} else {
// We don't have a unique name.
- throw 'Invalid library root. $libraryRoot does not contain ${uri.toFilePath()}';
+ throw 'Invalid library root. $libraryRoot does not contain ${uri
+ .toFilePath()}';
}
return pathToJSIdentifier(qualifiedPath);
}
@@ -5446,10 +5477,12 @@
/// everywhere in the tree where they are treated as the same variable.
class TemporaryVariableElement extends LocalVariableElementImpl {
final JS.Expression jsVariable;
+
TemporaryVariableElement.forNode(Identifier name, this.jsVariable)
: super.forNode(name);
int get hashCode => identityHashCode(this);
+
bool operator ==(Object other) => identical(this, other);
}
diff --git a/pkg/dev_compiler/lib/src/compiler/compiler.dart b/pkg/dev_compiler/lib/src/compiler/compiler.dart
index bc1ae50..e789bca 100644
--- a/pkg/dev_compiler/lib/src/compiler/compiler.dart
+++ b/pkg/dev_compiler/lib/src/compiler/compiler.dart
@@ -9,12 +9,13 @@
import 'package:analyzer/analyzer.dart'
show AnalysisError, CompilationUnit, ErrorSeverity;
import 'package:analyzer/file_system/file_system.dart' show ResourceProvider;
-import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
+import 'package:analyzer/src/generated/engine.dart'
+ show AnalysisContext, AnalysisEngine;
import 'package:analyzer/src/generated/source.dart' show DartUriResolver;
import 'package:analyzer/src/generated/source_io.dart'
show Source, SourceKind, UriResolver;
import 'package:analyzer/src/summary/package_bundle_reader.dart'
- show InSummarySource;
+ show InSummarySource, InputPackagesResultProvider, SummaryDataStore;
import 'package:args/args.dart' show ArgParser, ArgResults;
import 'package:args/src/usage_exception.dart' show UsageException;
import 'package:func/func.dart' show Func1;
@@ -22,7 +23,11 @@
import 'package:source_maps/source_maps.dart';
import '../analyzer/context.dart'
- show AnalyzerOptions, createAnalysisContextWithSources;
+ show
+ AnalyzerOptions,
+ createAnalysisContext,
+ createSdkPathResolver,
+ createSourceFactory;
import '../js_ast/js_ast.dart' as JS;
import 'code_generator.dart' show CodeGenerator;
import 'error_helpers.dart' show errorSeverity, formatError, sortErrors;
@@ -50,9 +55,10 @@
/// about them.
class ModuleCompiler {
final AnalysisContext context;
+ final SummaryDataStore summaryData;
final ExtensionTypeSet _extensionTypes;
- ModuleCompiler.withContext(AnalysisContext context)
+ ModuleCompiler.withContext(AnalysisContext context, this.summaryData)
: context = context,
_extensionTypes = new ExtensionTypeSet(context) {
if (!context.analysisOptions.strongMode) {
@@ -63,14 +69,33 @@
}
}
- ModuleCompiler(AnalyzerOptions analyzerOptions,
+ factory ModuleCompiler(AnalyzerOptions options,
{DartUriResolver sdkResolver,
ResourceProvider resourceProvider,
- List<UriResolver> fileResolvers})
- : this.withContext(createAnalysisContextWithSources(analyzerOptions,
- sdkResolver: sdkResolver,
- fileResolvers: fileResolvers,
- resourceProvider: resourceProvider));
+ List<UriResolver> fileResolvers}) {
+ AnalysisEngine.instance.processRequiredPlugins();
+
+ sdkResolver ??=
+ createSdkPathResolver(options.dartSdkSummaryPath, options.dartSdkPath);
+
+ // Read the summaries.
+ var summaryData =
+ new SummaryDataStore(options.summaryPaths, recordDependencyInfo: true);
+
+ var srcFactory = createSourceFactory(options,
+ sdkResolver: sdkResolver,
+ fileResolvers: fileResolvers,
+ summaryData: summaryData,
+ resourceProvider: resourceProvider);
+
+ var context = createAnalysisContext();
+ context.sourceFactory = srcFactory;
+ context.typeProvider = sdkResolver.dartSdk.context.typeProvider;
+ context.resultProvider =
+ new InputPackagesResultProvider(context, summaryData);
+
+ return new ModuleCompiler.withContext(context, summaryData);
+ }
/// Compiles a single Dart build unit into a JavaScript module.
///
@@ -145,7 +170,8 @@
return new JSModuleFile.invalid(unit.name, messages, options);
}
- var codeGenerator = new CodeGenerator(context, options, _extensionTypes);
+ var codeGenerator =
+ new CodeGenerator(context, summaryData, options, _extensionTypes);
return codeGenerator.compile(unit, trees, messages);
}
}
@@ -479,6 +505,7 @@
// Fall back to a relative path.
return path.toUri(path.relative(path.fromUri(uri), from: dir)).toString();
}
+
for (int i = 0; i < list.length; i++) {
list[i] = transformUri(list[i]);
}
diff --git a/pkg/dev_compiler/lib/src/compiler/reify_coercions.dart b/pkg/dev_compiler/lib/src/compiler/reify_coercions.dart
index dd87fde..c0a9f72 100644
--- a/pkg/dev_compiler/lib/src/compiler/reify_coercions.dart
+++ b/pkg/dev_compiler/lib/src/compiler/reify_coercions.dart
@@ -31,6 +31,22 @@
return units.map(cr.visitCompilationUnit).toList(growable: false);
}
+ /// Returns true if the `as` [node] was created by this class.
+ // TODO(sra): Find a better way to recognize reified coercion, since we
+ // can't set the isSynthetic attribute.
+ static bool isImplicitCast(AsExpression node) => node.asOperator.offset == 0;
+
+ /// Creates an implicit cast for expression [e] to [toType].
+ static Expression castExpression(Expression e, DartType toType) {
+ // We use an empty name in the AST, because the JS code generator only cares
+ // about the target type. It does not look at the AST name.
+ var typeName = new TypeName(AstBuilder.identifierFromString(''), null);
+ typeName.type = toType;
+ var cast = AstBuilder.asExpression(e, typeName);
+ cast.staticType = toType;
+ return cast;
+ }
+
@override
CompilationUnit visitCompilationUnit(CompilationUnit node) {
if (ast_properties.hasImplicitCasts(node)) {
@@ -47,7 +63,7 @@
var castType = ast_properties.getImplicitCast(node);
if (castType != null) {
- _replaceNode(node.parent, node, _castExpression(node, castType));
+ _replaceNode(node.parent, node, castExpression(node, castType));
}
}
@@ -79,7 +95,7 @@
// Build the cast. We will place this cast in the body, so need to clone
// the variable's AST node and clear out its static type (otherwise we
// will optimize away the cast).
- var cast = _castExpression(
+ var cast = castExpression(
_clone(variable)..staticType = DynamicTypeImpl.instance, castType);
var body = node.body;
@@ -102,16 +118,6 @@
}
}
- Expression _castExpression(Expression e, DartType toType) {
- // We use an empty name in the AST, because the JS code generator only cares
- // about the target type. It does not look at the AST name.
- var typeName = new TypeName(AstBuilder.identifierFromString(''), null);
- typeName.type = toType;
- var cast = AstBuilder.asExpression(e, typeName);
- cast.staticType = toType;
- return cast;
- }
-
/*=T*/ _clone/*<T extends AstNode>*/(/*=T*/ node) {
var copy = node.accept(cloner) as dynamic/*=T*/;
ResolutionCopier.copyResolutionData(node, copy);
diff --git a/pkg/dev_compiler/pubspec.lock b/pkg/dev_compiler/pubspec.lock
deleted file mode 100644
index 792de61..0000000
--- a/pkg/dev_compiler/pubspec.lock
+++ /dev/null
@@ -1,335 +0,0 @@
-# Generated by pub
-# See http://pub.dartlang.org/doc/glossary.html#lockfile
-packages:
- analyzer:
- description:
- path: "../analyzer"
- relative: true
- source: path
- version: "0.29.0-alpha.0"
- archive:
- description:
- name: archive
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.0.25"
- args:
- description:
- name: args
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.13.5"
- async:
- description:
- name: async
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.11.1"
- barback:
- description:
- name: barback
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.15.2+9"
- bazel_worker:
- description:
- name: bazel_worker
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.1.1"
- boolean_selector:
- description:
- name: boolean_selector
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.0.2"
- browser:
- description:
- name: browser
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.10.0+2"
- charcode:
- description:
- name: charcode
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.1.0"
- cli_util:
- description:
- name: cli_util
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.0.1+2"
- collection:
- description:
- name: collection
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.9.1"
- convert:
- description:
- name: convert
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.0.1"
- crypto:
- description:
- name: crypto
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.0.1"
- csslib:
- description:
- name: csslib
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.13.2"
- dart_style:
- description:
- name: dart_style
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.2.4"
- fixnum:
- description:
- name: fixnum
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.10.5"
- func:
- description:
- name: func
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.1.0"
- glob:
- description:
- name: glob
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.1.3"
- html:
- description:
- name: html
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.12.2+2"
- http:
- description:
- name: http
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.11.3+9"
- http_multi_server:
- description:
- name: http_multi_server
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.0.2"
- http_parser:
- description:
- name: http_parser
- url: "https://pub.dartlang.org"
- source: hosted
- version: "3.0.2"
- isolate:
- description:
- name: isolate
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.2.3"
- js:
- description:
- name: js
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.6.1"
- logging:
- description:
- name: logging
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.11.3+1"
- matcher:
- description:
- name: matcher
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.12.0+2"
- meta:
- description:
- path: "../meta"
- relative: true
- source: path
- version: "1.0.3"
- mime:
- description:
- name: mime
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.9.3"
- package_config:
- description:
- name: package_config
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.0.0"
- package_resolver:
- description:
- name: package_resolver
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.0.2"
- path:
- description:
- name: path
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.3.9"
- plugin:
- description:
- name: plugin
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.2.0"
- pool:
- description:
- name: pool
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.2.4"
- protobuf:
- description:
- name: protobuf
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.5.3"
- pub_semver:
- description:
- name: pub_semver
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.3.0"
- shelf:
- description:
- name: shelf
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.6.5+3"
- shelf_packages_handler:
- description:
- name: shelf_packages_handler
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.0.0"
- shelf_static:
- description:
- name: shelf_static
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.2.4"
- shelf_web_socket:
- description:
- name: shelf_web_socket
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.2.1"
- source_map_stack_trace:
- description:
- name: source_map_stack_trace
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.1.3"
- source_maps:
- description:
- name: source_maps
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.10.1+1"
- source_span:
- description:
- name: source_span
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.2.3"
- stack_trace:
- description:
- name: stack_trace
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.6.6"
- stream_channel:
- description:
- name: stream_channel
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.5.0"
- string_scanner:
- description:
- name: string_scanner
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.0.0"
- test:
- description:
- name: test
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.12.15+6"
- typed_data:
- description:
- name: typed_data
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.1.3"
- unittest:
- description:
- name: unittest
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.11.6+4"
- utf:
- description:
- name: utf
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.9.0+3"
- watcher:
- description:
- name: watcher
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.9.7+3"
- web_socket_channel:
- description:
- name: web_socket_channel
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.0.4"
- webdriver:
- description:
- name: webdriver
- url: "https://pub.dartlang.org"
- source: hosted
- version: "1.2.1"
- when:
- description:
- name: when
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.2.0"
- which:
- description:
- name: which
- url: "https://pub.dartlang.org"
- source: hosted
- version: "0.1.3"
- yaml:
- description:
- name: yaml
- url: "https://pub.dartlang.org"
- source: hosted
- version: "2.1.10"
-sdks:
- dart: ">=1.19.0-dev.0.0 <2.0.0"
diff --git a/pkg/dev_compiler/test/codegen/corelib/collection_test.dart b/pkg/dev_compiler/test/codegen/corelib/collection_test.dart
index 680e20a..1b56960 100644
--- a/pkg/dev_compiler/test/codegen/corelib/collection_test.dart
+++ b/pkg/dev_compiler/test/codegen/corelib/collection_test.dart
@@ -8,13 +8,13 @@
import 'dart:collection' show Queue;
class CollectionTest {
- CollectionTest(Iterable iterable) {
+ CollectionTest(Iterable<int> iterable) {
testFold(iterable);
}
- void testFold(Iterable iterable) {
- Expect.equals(28, iterable.fold(0, (prev, element) => prev + element));
- Expect.equals(3024, iterable.fold(1, (prev, element) => prev * element));
+ void testFold(Iterable<int> iterable) {
+ Expect.equals(28, iterable.fold/*<int>*/(0, (prev, element) => prev + element));
+ Expect.equals(3024, iterable.fold/*<int>*/(1, (prev, element) => prev * element));
}
}
@@ -25,7 +25,7 @@
new CollectionTest(TEST_ELEMENTS);
// Fixed size list.
- var fixedList = new List(TEST_ELEMENTS.length);
+ var fixedList = new List<int>(TEST_ELEMENTS.length);
for (int i = 0; i < TEST_ELEMENTS.length; i++) {
fixedList[i] = TEST_ELEMENTS[i];
}
diff --git a/pkg/dev_compiler/test/codegen/corelib/list_map_test.dart b/pkg/dev_compiler/test/codegen/corelib/list_map_test.dart
index 947f40a..a5f48a8 100644
--- a/pkg/dev_compiler/test/codegen/corelib/list_map_test.dart
+++ b/pkg/dev_compiler/test/codegen/corelib/list_map_test.dart
@@ -52,7 +52,7 @@
void testList(List list) {
var throws = const ThrowMarker();
- List mappedList = new List(list.length);
+ var mappedList = new List<int>(list.length);
for (int i = 0; i < list.length; i++) {
mappedList[i] = rev(list[i]);
}
@@ -78,7 +78,7 @@
}
}
- void testOp(operation(Iterable mappedList), name) {
+ void testOp(operation(Iterable<int> mappedList), name) {
var expect;
try {
expect = operation(mappedList);
@@ -115,7 +115,7 @@
testOp((i) => i.every((n) => n < 5), "every<5");
testOp((i) => i.every((n) => n < 10), "every<10");
testOp((i) => i.reduce((a, b) => a + b), "reduce-sum");
- testOp((i) => i.fold(0, (a, b) => a + b), "fold-sum");
+ testOp((i) => i.fold/*<int>*/(0, (a, b) => a + b), "fold-sum");
testOp((i) => i.join("-"), "join-");
testOp((i) => i.join(""), "join");
testOp((i) => i.join(), "join-null");
diff --git a/pkg/dev_compiler/test/codegen/corelib/list_reversed_test.dart b/pkg/dev_compiler/test/codegen/corelib/list_reversed_test.dart
index ea1e780..05dba7a 100644
--- a/pkg/dev_compiler/test/codegen/corelib/list_reversed_test.dart
+++ b/pkg/dev_compiler/test/codegen/corelib/list_reversed_test.dart
@@ -16,12 +16,12 @@
void testOperations() {
// Comparison lists.
- List l = const [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
- List r = const [10, 9, 8, 7, 6, 5, 4, 3, 2, 1];
+ var l = const [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
+ var r = const [10, 9, 8, 7, 6, 5, 4, 3, 2, 1];
// A base list that starts out like l.
- List base = l.toList();
+ var base = l.toList();
// A lazy reverse of base.
- Iterable reversed = base.reversed;
+ var reversed = base.reversed;
Expect.listEquals(r, reversed.toList());
Expect.listEquals(l, reversed.toList().reversed.toList());
@@ -49,7 +49,7 @@
reversed.skip(2).toList().reversed.skip(2).toList().reversed.toList());
- void testList(List list) {
+ void testList(List<int> list) {
var throws = const ThrowMarker();
void testEquals(v1, v2, path) {
if (v1 is Iterable) {
@@ -71,12 +71,12 @@
}
}
- void testOp(operation(Iterable reversedList), name) {
- List reversedList = new List(list.length);
+ void testOp(operation(Iterable<int> reversedList), name) {
+ var reversedList = new List<int>(list.length);
for (int i = 0; i < list.length; i++) {
reversedList[i] = list[list.length - 1 - i];
}
- Iterable reversed = list.reversed;
+ var reversed = list.reversed;
var expect;
try {
expect = operation(reversedList);
@@ -107,7 +107,7 @@
testOp((i) => i.every((n) => n < 5), "every<5");
testOp((i) => i.every((n) => n < 10), "every<10");
testOp((i) => i.reduce((a, b) => a + b), "reduce-sum");
- testOp((i) => i.fold(0, (a, b) => a + b), "fold-sum");
+ testOp((i) => i.fold/*<int>*/(0, (a, b) => a + b), "fold-sum");
testOp((i) => i.join("-"), "join-");
testOp((i) => i.join(""), "join");
testOp((i) => i.join(), "join-null");
diff --git a/pkg/dev_compiler/test/codegen/language/implicit_super_constructor_test.dart b/pkg/dev_compiler/test/codegen/language/implicit_super_constructor_test.dart
new file mode 100644
index 0000000..2c31206
--- /dev/null
+++ b/pkg/dev_compiler/test/codegen/language/implicit_super_constructor_test.dart
@@ -0,0 +1,20 @@
+// 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";
+
+abstract class A {
+ int _x = 42;
+}
+
+abstract class B extends A {}
+
+class C extends B {
+ C() {}
+}
+
+main() {
+ // Regression test for https://github.com/dart-lang/sdk/issues/27421
+ Expect.equals(new C()._x, 42);
+}
diff --git a/pkg/dev_compiler/test/codegen/language/map_literal5_test.dart b/pkg/dev_compiler/test/codegen/language/map_literal5_test.dart
index 365f218..0c2fa17 100644
--- a/pkg/dev_compiler/test/codegen/language/map_literal5_test.dart
+++ b/pkg/dev_compiler/test/codegen/language/map_literal5_test.dart
@@ -32,7 +32,7 @@
}
}
-create(bool b) {
+Map create(bool b) {
return {
b: 0,
m(b): n(b),
@@ -40,5 +40,5 @@
};
}
-m(bool b) => b ? 2 : "bar";
-n(bool b) => b ? 3 : "baz";
\ No newline at end of file
+Object m(bool b) => b ? 2 : "bar";
+Object n(bool b) => b ? 3 : "baz";
\ No newline at end of file
diff --git a/pkg/dev_compiler/test/codegen/language/regress_21998_3_test.dart b/pkg/dev_compiler/test/codegen/language/regress_21998_3_test.dart
index 2eac880..92a4ae1 100644
--- a/pkg/dev_compiler/test/codegen/language/regress_21998_3_test.dart
+++ b/pkg/dev_compiler/test/codegen/language/regress_21998_3_test.dart
@@ -15,6 +15,6 @@
max(a) => a;
m() {
- return max(Math.max(lib2_max(1, 2), lib1.max('a', 'b', 'cd').length));
+ return max(Math.max/*<num>*/(lib2_max(1, 2), lib1.max('a', 'b', 'cd').length));
}
}
\ No newline at end of file
diff --git a/pkg/dev_compiler/test/codegen/language/regress_21998_4_test.dart b/pkg/dev_compiler/test/codegen/language/regress_21998_4_test.dart
index 7afe1ac..5de6774 100644
--- a/pkg/dev_compiler/test/codegen/language/regress_21998_4_test.dart
+++ b/pkg/dev_compiler/test/codegen/language/regress_21998_4_test.dart
@@ -16,7 +16,7 @@
max(a) => a;
m() {
- return max(Math.max(
+ return max(Math.max/*<num>*/(
lib3_max(0, lib2_max(1, 2)), lib1.max('a', 'b', 'cd').length));
}
}
\ No newline at end of file
diff --git a/pkg/dev_compiler/test/codegen/language/regress_21998_lib2.dart b/pkg/dev_compiler/test/codegen/language/regress_21998_lib2.dart
index 8d1ac893..d92071d 100644
--- a/pkg/dev_compiler/test/codegen/language/regress_21998_lib2.dart
+++ b/pkg/dev_compiler/test/codegen/language/regress_21998_lib2.dart
@@ -6,4 +6,4 @@
import 'dart:math';
-lib2_max(a, b) => max(a, b);
\ No newline at end of file
+lib2_max(a, b) => max/*<num>*/(a, b);
\ No newline at end of file
diff --git a/pkg/dev_compiler/test/codegen/language/regress_21998_lib3.dart b/pkg/dev_compiler/test/codegen/language/regress_21998_lib3.dart
index a18f2ff..5b8f488 100644
--- a/pkg/dev_compiler/test/codegen/language/regress_21998_lib3.dart
+++ b/pkg/dev_compiler/test/codegen/language/regress_21998_lib3.dart
@@ -6,4 +6,4 @@
import 'dart:math' as math;
-lib3_max(a, b) => math.max(a, b);
\ No newline at end of file
+lib3_max(a, b) => math.max/*<num>*/(a, b);
\ No newline at end of file
diff --git a/pkg/dev_compiler/test/codegen/language/string_optimizations_test.dart b/pkg/dev_compiler/test/codegen/language/string_optimizations_test.dart
index 1374bb3..afaf7ea 100644
--- a/pkg/dev_compiler/test/codegen/language/string_optimizations_test.dart
+++ b/pkg/dev_compiler/test/codegen/language/string_optimizations_test.dart
@@ -21,7 +21,7 @@
}
main() {
- var a = [foo(path: '42'), foo(), 42, bar(path: '54')];
+ var a = <Object>[foo(path: '42'), foo(), 42, bar(path: '54')];
Expect.isTrue(a[1] is String);
Expect.throws(() => bar().concat('54'), (e) => e is NoSuchMethodError);
}
diff --git a/pkg/dev_compiler/test/not_yet_strong_tests.dart b/pkg/dev_compiler/test/not_yet_strong_tests.dart
index 8ae6e78..f0d4c34 100644
--- a/pkg/dev_compiler/test/not_yet_strong_tests.dart
+++ b/pkg/dev_compiler/test/not_yet_strong_tests.dart
@@ -1478,8 +1478,6 @@
'language/regress_21793_test_01_multi',
'language/regress_21912_test_01_multi',
'language/regress_21912_test_02_multi',
- 'language/regress_21998_3_test',
- 'language/regress_21998_4_test',
'language/regress_22438_test',
'language/regress_22936_test_01_multi',
'language/regress_23038_test_01_multi',
diff --git a/pkg/dev_compiler/tool/global_compile.dart b/pkg/dev_compiler/tool/global_compile.dart
index cded0c7..b604099 100644
--- a/pkg/dev_compiler/tool/global_compile.dart
+++ b/pkg/dev_compiler/tool/global_compile.dart
@@ -28,6 +28,8 @@
defaultsTo: 'out.js')
..addFlag('unsafe-force-compile',
help: 'Generate code with undefined behavior', negatable: false)
+ ..addFlag('emit-metadata',
+ help: 'Preserve annotations in generated code', negatable: false)
..addOption('package-root',
help: 'Directory containing packages',
abbr: 'p',
@@ -47,16 +49,22 @@
var unsafe = options['unsafe-force-compile'] as bool;
var log = options['log'] as bool;
var tmp = options['tmp'] as String;
+ var metadata = options['emit-metadata'] as bool;
// Build an invocation to dartdevc
var dartPath = Platform.resolvedExecutable;
var ddcPath = path.dirname(path.dirname(Platform.script.toFilePath()));
var template = [
'$ddcPath/bin/dartdevc.dart',
- '--no-source-map', // Invalid as we're just concatenating files below
+ '--modules=legacy', // TODO(vsm): Change this to use common format.
+ '--single-out-file',
+ '--inline-source-map',
'-p',
packageRoot
];
+ if (metadata) {
+ template.add('--emit-metadata');
+ }
if (unsafe) {
template.add('--unsafe-force-compile');
}
@@ -78,11 +86,12 @@
// Prepend Dart runtime files to the output
var out = new File(outfile);
var dartLibrary =
- new File(path.join(ddcPath, 'lib', 'runtime', 'dart_library.js'))
+ new File(path.join(ddcPath, 'lib', 'js', 'legacy', 'dart_library.js'))
.readAsStringSync();
out.writeAsStringSync(dartLibrary);
- var dartSdk = new File(path.join(ddcPath, 'lib', 'runtime', 'dart_sdk.js'))
- .readAsStringSync();
+ var dartSdk =
+ new File(path.join(ddcPath, 'lib', 'js', 'legacy', 'dart_sdk.js'))
+ .readAsStringSync();
out.writeAsStringSync(dartSdk, mode: FileMode.APPEND);
// Linearize module concatenation for deterministic output
diff --git a/pkg/pkg.status b/pkg/pkg.status
index a647224..db253b5 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -19,6 +19,9 @@
dart_messages/test/dart_messages_test: Skip # Requires a package root.
+[ $compiler == dart2analyzer ]
+dev_compiler/gen/*: SkipByDesign
+
[ $compiler == none && ($runtime == drt || $runtime == dartium) ]
mutation_observer: Skip # Issue 21149
unittest/*: Skip # Issue 21949
diff --git a/runtime/BUILD.gn b/runtime/BUILD.gn
index df10d3a..afc963ab 100644
--- a/runtime/BUILD.gn
+++ b/runtime/BUILD.gn
@@ -2,10 +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.
-# TODO(zra): These build arguments should likely be moved to a gni file that is
-# included in BUILD.gn files that care about the values of the flags. For now,
-# since the GN build only happens as part of a Mojo build there is no need for
-# the indirection.
declare_args() {
# Instead of using is_debug, we introduce a different flag for specifying a
# Debug build of Dart so that clients can still use a Release build of Dart
@@ -20,6 +16,10 @@
# CPU profiling features enabled.
# 'release' - The VM is built to run with AOT compiled code with no developer
# features enabled.
+ #
+ # These settings are only used for Flutter, at the moment. A standalone build
+ # of the Dart VM should leave this set to "develop", and should set
+ # 'is_debug', 'is_release', or 'is_product'.
dart_runtime_mode = "develop"
# Explicitly set the target architecture in case of precompilation. Leaving
@@ -36,8 +36,8 @@
]
}
-# Controls PRODUCT #define.
-config("dart_product_config") {
+# Adds PRODUCT define if Flutter has specified "release" for dart_runtime_mode
+config("dart_maybe_product_config") {
defines = []
if ((dart_runtime_mode != "develop") &&
@@ -56,8 +56,9 @@
}
}
-# Controls DART_PRECOMPILED_RUNTIME #define.
-config("dart_precompiled_runtime_config") {
+# Adds the DART_PRECOMPILED_RUNTIME define if Flutter has specified "profile" or
+# "release" for dart_runtime_mode.
+config("dart_maybe_precompiled_runtime_config") {
defines = []
if ((dart_runtime_mode != "develop") &&
@@ -83,12 +84,22 @@
}
}
+config("dart_precompiled_runtime_config") {
+ defines = []
+ defines += ["DART_PRECOMPILED_RUNTIME"]
+}
+
# Controls DART_PRECOMPILER #define.
config("dart_precompiler_config") {
defines = []
defines += ["DART_PRECOMPILER"]
}
+config("dart_no_snapshot_config") {
+ defines = []
+ defines += ["DART_NO_SNAPSHOT"]
+}
+
config("dart_config") {
defines = []
@@ -97,23 +108,39 @@
}
if (dart_target_arch != "") {
- if (dart_target_arch == "arm") {
+ if ((dart_target_arch == "arm") ||
+ (dart_target_arch == "simarm")) {
defines += [ "TARGET_ARCH_ARM" ]
if (target_os == "mac" || target_os == "ios") {
defines += [ "TARGET_ABI_IOS" ]
} else {
defines += [ "TARGET_ABI_EABI" ]
}
- } else if (dart_target_arch == "arm64") {
+ } else if ((dart_target_arch == "armv6") ||
+ (dart_target_arch == "simarmv6")) {
+ defines += [ "TARGET_ARCH_ARM" ]
+ defines += [ "TARGET_ARCH_ARM_6" ]
+ defines += [ "TARGET_ABI_EABI" ]
+ } else if ((dart_target_arch == "armv5te") ||
+ (dart_target_arch == "simarmv5te")) {
+ defines += [ "TARGET_ARCH_ARM" ]
+ defines += [ "TARGET_ARCH_ARM_5TE" ]
+ defines += [ "TARGET_ABI_EABI" ]
+ } else if ((dart_target_arch == "arm64") ||
+ (dart_target_arch == "simarm64")) {
defines += [ "TARGET_ARCH_ARM64" ]
- } else if (dart_target_arch == "mips") {
+ } else if ((dart_target_arch == "mips") ||
+ (dart_target_arch == "simmips")) {
defines += [ "TARGET_ARCH_MIPS" ]
} else if (dart_target_arch == "x64") {
defines += [ "TARGET_ARCH_X64" ]
} else if (dart_target_arch == "ia32") {
defines += [ "TARGET_ARCH_IA32" ]
- } else if (dart_target_arch == "dbc") {
+ } else if ((dart_target_arch == "dbc") ||
+ (dart_target_arch == "simdbc") ||
+ (dart_target_arch == "simdbc64")) {
defines += [ "TARGET_ARCH_DBC" ]
+ defines += [ "USING_SIMULATOR" ]
} else {
print("Invalid |dart_target_arch|")
assert(false)
@@ -159,31 +186,97 @@
}
}
-static_library("libdart") {
- configs += [":dart_config",
- ":dart_product_config",
- ":dart_precompiled_runtime_config"]
- deps = [
+template("libdart_library") {
+ extra_configs = []
+ if (defined(invoker.extra_configs)) {
+ extra_configs += invoker.extra_configs
+ }
+ extra_deps = []
+ if (defined(invoker.extra_deps)) {
+ extra_deps += invoker.extra_deps
+ }
+ static_library(target_name) {
+ configs += [
+ ":dart_config",
+ ":dart_maybe_product_config"
+ ] + extra_configs
+ deps = [
+ "vm:libdart_platform",
+ "third_party/double-conversion/src:libdouble_conversion",
+ ":generate_version_cc_file",
+ ] + extra_deps
+ include_dirs = [
+ ".",
+ ]
+ public_configs = [":dart_public_config"]
+ sources = [
+ "include/dart_api.h",
+ "include/dart_mirrors_api.h",
+ "include/dart_native_api.h",
+ "include/dart_tools_api.h",
+ "vm/dart_api_impl.cc",
+ "vm/debugger_api_impl.cc",
+ "vm/mirrors_api_impl.cc",
+ "vm/native_api_impl.cc",
+ "vm/version.h",
+ "$target_gen_dir/version.cc",
+ ]
+ defines = [
+ "DART_SHARED_LIB",
+ ]
+ }
+}
+
+libdart_library("libdart") {
+ extra_configs = [
+ ":dart_maybe_precompiled_runtime_config"
+ ]
+ extra_deps = [
"vm:libdart_lib",
"vm:libdart_vm",
- "third_party/double-conversion/src:libdouble_conversion",
- ":generate_version_cc_file",
]
- include_dirs = [
- ".",
+}
+
+libdart_library("libdart_precompiled_runtime") {
+ extra_configs = [
+ ":dart_precompiled_runtime_config"
]
- public_configs = [":dart_public_config"]
- sources = [
- "include/dart_api.h",
- "include/dart_mirrors_api.h",
- "include/dart_native_api.h",
- "include/dart_tools_api.h",
- "vm/dart_api_impl.cc",
- "vm/debugger_api_impl.cc",
- "vm/mirrors_api_impl.cc",
- "vm/native_api_impl.cc",
- "vm/version.h",
- "$target_gen_dir/version.cc",
+ extra_deps = [
+ "vm:libdart_lib_precompiled_runtime",
+ "vm:libdart_vm_precompiled_runtime",
+ ]
+}
+
+libdart_library("libdart_nosnapshot") {
+ extra_configs = [
+ ":dart_no_snapshot_config",
+ ":dart_maybe_precompiled_runtime_config"
+ ]
+ extra_deps = [
+ "vm:libdart_lib_nosnapshot",
+ "vm:libdart_vm_nosnapshot",
+ ]
+}
+
+libdart_library("libdart_nosnapshot_precompiled_runtime") {
+ extra_configs = [
+ ":dart_no_snapshot_config",
+ ":dart_precompiled_runtime_config"
+ ]
+ extra_deps = [
+ "vm:libdart_lib_nosnapshot_precompiled_runtime",
+ "vm:libdart_vm_nosnapshot_precompiled_runtime",
+ ]
+}
+
+libdart_library("libdart_nosnapshot_with_precompiler") {
+ extra_configs = [
+ ":dart_no_snapshot_config",
+ ":dart_precompiler_config",
+ ]
+ extra_deps = [
+ "vm:libdart_lib_nosnapshot_with_precompiler",
+ "vm:libdart_vm_nosnapshot_with_precompiler",
]
}
@@ -211,8 +304,7 @@
executable("libdart_dependency_helper") {
configs += [":dart_config",
- ":dart_product_config",
- ":dart_precompiled_runtime_config"]
+ ":dart_maybe_product_config"]
deps = [
"vm:libdart_lib_nosnapshot",
"vm:libdart_lib",
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index d03757b..549807b 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -2,6 +2,22 @@
# 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.
+declare_args() {
+ # Whether to fall back to built-in root certificates when they cannot be
+ # verified at the operating system level.
+ dart_use_fallback_root_certificates = false
+
+ # The BUILD.gn file that we pull from chromium as part of zlib has a
+ # dependence on //base, which we don't pull in. In a standalone build of the
+ # VM, we set this to //runtime/bin/zlib where we have a BUILD.gn file without
+ # a dependence on //base.
+ dart_zlib_path = "//third_party/zlib"
+
+ # Whether to link the standalone VM against tcmalloc. The standalone build of
+ # the VM enables this only for Linux builds.
+ dart_use_tcmalloc = false
+}
+
resources_sources_gypi =
exec_script("../../tools/gypi_to_gn.py",
[rebase_path("vmservice/vmservice_sources.gypi")],
@@ -31,7 +47,6 @@
] + rebase_path(sources, root_build_dir)
}
-
template("gen_library_src_path") {
assert(defined(invoker.sources), "Need sources in $target_name")
assert(defined(invoker.output), "Need output in $target_name")
@@ -45,17 +60,20 @@
outputs = [ invoker.output, ]
name = invoker.name
kind = invoker.kind
+ library_name = "dart:${name}"
+ if (defined(invoker.library_name)) {
+ library_name = invoker.library_name
+ }
args = [
"--output", rebase_path(invoker.output, root_build_dir),
"--input_cc", rebase_path("builtin_in.cc", root_build_dir),
"--include", "bin/builtin.h",
"--var_name", "dart::bin::Builtin::${name}_${kind}_paths_",
- "--library_name", "dart:${name}",] +
+ "--library_name", library_name,] +
rebase_path(invoker.sources, root_build_dir)
}
}
-
builtin_sources_gypi =
exec_script("../../tools/gypi_to_gn.py",
[rebase_path("builtin_sources.gypi")],
@@ -69,7 +87,6 @@
output = "$target_gen_dir/builtin_gen.cc"
}
-
sdk_io_sources_gypi =
exec_script("../../tools/gypi_to_gn.py",
[rebase_path("../../sdk/lib/io/io_sources.gypi")],
@@ -98,14 +115,105 @@
output = "$target_gen_dir/io_patch_gen.cc"
}
+gen_library_src_path("generate_html_cc_file") {
+ name = "html"
+ kind = "source"
+ sources = ["../../sdk/lib/html/dartium/html_dartium.dart"]
+ output = "$target_gen_dir/html_gen.cc"
+}
+
+gen_library_src_path("generate_html_common_cc_file") {
+ name = "html_common"
+ kind = "source"
+ sources = [
+ "../../sdk/lib/html/html_common/html_common.dart",
+ "../../sdk/lib/html/html_common/css_class_set.dart",
+ "../../sdk/lib/html/html_common/device.dart",
+ "../../sdk/lib/html/html_common/filtered_element_list.dart",
+ "../../sdk/lib/html/html_common/lists.dart",
+ "../../sdk/lib/html/html_common/conversions.dart",
+ "../../sdk/lib/html/html_common/conversions_dartium.dart",
+ ]
+ output = "$target_gen_dir/html_common_gen.cc"
+}
+
+gen_library_src_path("generate_js_cc_file") {
+ name = "js"
+ kind = "source"
+ sources = ["../../sdk/lib/js/dartium/js_dartium.dart"]
+ output = "$target_gen_dir/js_gen.cc"
+}
+
+gen_library_src_path("generate_blink_cc_file") {
+ name = "_blink"
+ kind = "source"
+ sources = ["../../sdk/lib/_blink/dartium/_blink_dartium.dart"]
+ output = "$target_gen_dir/blink_gen.cc"
+}
+
+gen_library_src_path("generate_indexed_db_cc_file") {
+ name = "indexed_db"
+ kind = "source"
+ sources = ["../../sdk/lib/indexed_db/dartium/indexed_db_dartium.dart"]
+ output = "$target_gen_dir/indexed_db_gen.cc"
+}
+
+gen_library_src_path("generate_cached_patches_cc_file") {
+ name = "cached_patches"
+ library_name = "cached_patches.dart"
+ kind = "sources"
+ sources = ["../../sdk/lib/js/dartium/cached_patches.dart"]
+ output = "$target_gen_dir/cached_patches_gen.cc"
+}
+
+gen_library_src_path("generate_web_gl_cc_file") {
+ name = "web_gl"
+ kind = "source"
+ sources = ["../../sdk/lib/web_gl/dartium/web_gl_dartium.dart"]
+ output = "$target_gen_dir/web_gl_gen.cc"
+}
+
+gen_library_src_path("generate_metadata_cc_file") {
+ name = "metadata"
+ library_name = "metadata.dart"
+ kind = "source"
+ sources = ["../../sdk/lib/html/html_common/metadata.dart"]
+ output = "$target_gen_dir/metadata_gen.cc"
+}
+
+gen_library_src_path("generate_web_sql_cc_file") {
+ name = "web_sql"
+ kind = "source"
+ sources = ["../../sdk/lib/web_sql/dartium/web_sql_dartium.dart"]
+ output = "$target_gen_dir/web_sql_gen.cc"
+}
+
+gen_library_src_path("generate_svg_cc_file") {
+ name = "svg"
+ kind = "source"
+ sources = ["../../sdk/lib/svg/dartium/svg_dartium.dart"]
+ output = "$target_gen_dir/svg_gen.cc"
+}
+
+gen_library_src_path("generate_web_audio_cc_file") {
+ name = "web_audio"
+ kind = "source"
+ sources = ["../../sdk/lib/web_audio/dartium/web_audio_dartium.dart"]
+ output = "$target_gen_dir/web_audio_gen.cc"
+}
config("libdart_builtin_config") {
libs = [
"dl",
]
+ if (is_android) {
+ libs += [
+ "android",
+ "log",
+ ]
+ }
}
-
builtin_impl_sources_gypi =
exec_script("../../tools/gypi_to_gn.py",
[rebase_path("builtin_impl_sources.gypi")],
@@ -113,12 +221,24 @@
["builtin_impl_sources.gypi"])
static_library("libdart_builtin") {
- configs += ["..:dart_config", "..:dart_product_config"]
+ configs += ["..:dart_config",
+ "..:dart_maybe_product_config"]
public_configs = [":libdart_builtin_config"]
deps = [
":generate_builtin_cc_file",
":generate_io_cc_file",
":generate_io_patch_cc_file",
+ ":generate_html_cc_file",
+ ":generate_html_common_cc_file",
+ ":generate_js_cc_file",
+ ":generate_blink_cc_file",
+ ":generate_indexed_db_cc_file",
+ ":generate_cached_patches_cc_file",
+ ":generate_web_gl_cc_file",
+ ":generate_metadata_cc_file",
+ ":generate_web_sql_cc_file",
+ ":generate_svg_cc_file",
+ ":generate_web_audio_cc_file",
]
include_dirs = [
"..",
@@ -133,74 +253,6 @@
] + builtin_impl_sources_gypi.sources
}
-
-static_library("libdart_nosnapshot") {
- configs += ["..:dart_config",
- "..:dart_product_config",
- "..:dart_precompiled_runtime_config"]
- deps = [
- "../vm:libdart_lib_nosnapshot",
- "../vm:libdart_vm_nosnapshot",
- "../vm:libdart_platform",
- "../third_party/double-conversion/src:libdouble_conversion",
- "..:generate_version_cc_file",
- ]
-
- sources = [
- "../include/dart_api.h",
- "../include/dart_mirrors_api.h",
- "../include/dart_native_api.h",
- "../include/dart_tools_api.h",
- "../vm/dart_api_impl.cc",
- "../vm/debugger_api_impl.cc",
- "../vm/mirrors_api_impl.cc",
- "../vm/native_api_impl.cc",
- "$target_gen_dir/../version.cc",
- ]
-
- include_dirs = [
- "..",
- ]
-
- defines = [
- "DART_SHARED_LIB",
- ]
-}
-
-
-static_library("libdart_nosnapshot_with_precompiler") {
- configs += ["..:dart_config",
- "..:dart_product_config",
- "..:dart_precompiler_config"]
- deps = [
- "../vm:libdart_lib_nosnapshot_with_precompiler",
- "../vm:libdart_vm_nosnapshot_with_precompiler",
- "../vm:libdart_platform",
- "../third_party/double-conversion/src:libdouble_conversion",
- "..:generate_version_cc_file",
- ]
-
- sources = [
- "../include/dart_api.h",
- "../include/dart_mirrors_api.h",
- "../include/dart_native_api.h",
- "../include/dart_tools_api.h",
- "../vm/dart_api_impl.cc",
- "../vm/debugger_api_impl.cc",
- "../vm/mirrors_api_impl.cc",
- "../vm/native_api_impl.cc",
- "$target_gen_dir/../version.cc",
- ]
-
- include_dirs = [
- "..",
- ]
-
- defines = [
- "DART_SHARED_LIB",
- ]
-}
-
io_impl_sources_gypi =
exec_script("../../tools/gypi_to_gn.py",
[ rebase_path("io_impl_sources.gypi") ],
@@ -209,7 +261,7 @@
executable("gen_snapshot") {
configs += ["..:dart_config",
- "..:dart_product_config",
+ "..:dart_maybe_product_config",
"..:dart_precompiler_config"]
deps = [
":gen_resources_cc",
@@ -218,7 +270,7 @@
":generate_io_cc_file",
":generate_io_patch_cc_file",
":libdart_builtin",
- ":libdart_nosnapshot_with_precompiler",
+ "..:libdart_nosnapshot_with_precompiler",
]
sources = [
@@ -254,11 +306,11 @@
# (without secure sockets) suitable for linking with gen_snapshot.
source_set("gen_snapshot_dart_io") {
configs += ["..:dart_config",
- "..:dart_product_config",
+ "..:dart_maybe_product_config",
"..:dart_precompiler_config"]
deps = [
- "//third_party/zlib",
+ "$dart_zlib_path",
]
custom_sources_filter = [
@@ -293,22 +345,16 @@
source_set("libdart_embedder_noio") {
configs += ["..:dart_config",
- "..:dart_product_config",
- "..:dart_precompiled_runtime_config"]
+ "..:dart_maybe_product_config"]
deps = [
"..:libdart",
- "../vm:libdart_platform",
]
}
-
-# A source set for the implementation of 'dart:io' library
-# (without secure sockets).
+# A source set for the implementation of 'dart:io' library.
source_set("embedded_dart_io") {
configs += ["..:dart_config",
- "..:dart_product_config",
- "..:dart_precompiled_runtime_config"]
-
+ "..:dart_maybe_product_config"]
custom_sources_filter = [
"*_test.cc",
"*_test.h",
@@ -324,12 +370,15 @@
}
set_sources_assignment_filter(custom_sources_filter)
+ defines = []
if (is_mac || is_ios) {
libs = [
+ "CoreFoundation.framework",
+ "CoreServices.framework",
"Security.framework",
]
} else if (defined(is_fuchsia) && is_fuchsia) {
- defines = [
+ defines += [
"DART_IO_SECURE_SOCKET_DISABLED"
]
} else {
@@ -352,8 +401,15 @@
"log_win.cc",
"log.h",
]
- if (is_linux) {
- sources += [ "../../third_party/root_certificates/root_certificates.cc"]
+
+ if (is_linux || is_win) {
+ if (dart_use_fallback_root_certificates) {
+ sources += [ "//third_party/root_certificates/root_certificates.cc"]
+ } else {
+ defines += [
+ "DART_IO_ROOT_CERTS_DISABLED",
+ ]
+ }
}
include_dirs = [
@@ -362,7 +418,6 @@
]
}
-
action("generate_snapshot_bin") {
deps = [
"../bin:gen_snapshot($host_toolchain)",
@@ -395,7 +450,6 @@
]
}
-
action("generate_snapshot_file") {
deps = [
":generate_snapshot_bin",
@@ -426,7 +480,6 @@
]
}
-
source_set("dart_snapshot_cc") {
sources = [
"$root_gen_dir/dart_snapshot.cc",
@@ -437,114 +490,104 @@
]
}
-if (defined(is_fuchsia) && is_fuchsia) {
- copy("hello_fuchsia") {
- sources = [ "../tests/vm/dart/hello_fuchsia_test.dart" ]
- outputs = [ "$root_out_dir/hello_fuchsia.dart" ]
+template("dart_executable") {
+ extra_configs = []
+ if (defined(invoker.extra_configs)) {
+ extra_configs += invoker.extra_configs
}
+ extra_deps = []
+ if (defined(invoker.extra_deps)) {
+ extra_deps += invoker.extra_deps
+ }
+ extra_defines = []
+ if (defined(invoker.extra_defines)) {
+ extra_defines = invoker.extra_defines
+ }
+ extra_sources = []
+ if (defined(invoker.extra_sources)) {
+ extra_sources += invoker.extra_sources
+ }
+ executable(target_name) {
+ configs += [
+ "..:dart_config",
+ "..:dart_maybe_product_config"
+ ] + extra_configs
- executable("dart_no_observatory") {
- configs += ["..:dart_config",
- "..:dart_product_config",
- "..:dart_precompiled_runtime_config",]
deps = [
- ":hello_fuchsia",
":gen_resources_cc",
":embedded_dart_io",
":libdart_builtin",
- "../vm:libdart_platform",
- "..:libdart",
- ":dart_snapshot_cc",
- "//third_party/zlib",
- ]
+ "$dart_zlib_path",
+ ] + extra_deps
- defines = [
- "NO_OBSERVATORY",
- ]
+ if (dart_use_tcmalloc) {
+ deps += [
+ "//third_party/tcmalloc",
+ ]
+ }
+
+ defines = extra_defines
sources = [
"main.cc",
- "observatory_assets_empty.cc",
"vmservice_impl.cc",
"vmservice_impl.h",
"$target_gen_dir/resources_gen.cc",
- ]
+ ] + extra_sources
include_dirs = [
"..",
"//third_party",
]
- }
- action("generate_snapshot_test_dat_file") {
- snapshot_test_dat_file = "$root_gen_dir/snapshot_test.dat"
- snapshot_test_in_dat_file = "../vm/snapshot_test_in.dat"
- snapshot_test_dart_file = "../vm/snapshot_test.dart"
- inputs = [
- "../tools/create_string_literal.py",
- snapshot_test_in_dat_file,
- snapshot_test_dart_file,
- ]
-
- outputs = [
- snapshot_test_dat_file,
- ]
-
- script = "../tools/create_string_literal.py"
- args = [
- "--output",
- rebase_path(snapshot_test_dat_file),
- "--input_cc",
- rebase_path(snapshot_test_in_dat_file),
- "--include",
- "INTENTIONALLY_LEFT_BLANK",
- "--var_name",
- "INTENTIONALLY_LEFT_BLANK_TOO",
- rebase_path(snapshot_test_dart_file),
+ ldflags = [
+ "-rdynamic",
]
}
+}
- executable("run_vm_tests") {
- testonly = true
- configs += ["..:dart_config",
- "..:dart_product_config",
- "..:dart_precompiled_runtime_config",]
- deps = [
+if (!defined(is_fuchsia) || !is_fuchsia) {
+ dart_executable("dart") {
+ extra_deps = [
"..:libdart",
- ":libdart_builtin",
- ":embedded_dart_io",
":dart_snapshot_cc",
- ":generate_snapshot_test_dat_file",
- "../vm:libdart_platform",
- "//third_party/zlib",
+ "../observatory:standalone_observatory_archive",
]
- include_dirs = [
- "..",
- "$target_gen_dir",
+ }
+
+ dart_executable("dart_precompiled_runtime") {
+ extra_configs = [
+ "..:dart_precompiled_runtime_config"
]
- defines = [
- "TESTING",
+ extra_deps = [
+ "..:libdart_precompiled_runtime",
+ ":dart_snapshot_cc",
+ "../observatory:standalone_observatory_archive",
]
+ }
+}
- vm_tests_list = exec_script("../../tools/gypi_to_gn.py",
- [rebase_path("../vm/vm_sources.gypi"),
- "--keep_only=_test.cc",
- "--keep_only=_test.h",],
- "scope",
- ["../vm/vm_sources.gypi"])
- vm_tests = rebase_path(vm_tests_list.sources, ".", "../vm")
+dart_executable("dart_bootstrap") {
+ extra_configs = [
+ "..:dart_precompiler_config",
+ "..:dart_no_snapshot_config",
+ ]
+ extra_deps = [
+ "..:libdart",
+ ]
+ extra_defines = [
+ "NO_OBSERVATORY",
+ ]
+ extra_sources = [
+ "observatory_assets_empty.cc",
+ "snapshot_empty.cc",
+ ]
+}
- builtin_impl_tests_list =
- exec_script("../../tools/gypi_to_gn.py",
- [rebase_path("builtin_impl_sources.gypi"),
- "--keep_only=_test.cc",
- "--keep_only=_test.h",],
- "scope",
- ["builtin_impl_sources.gypi"])
-
- sources = [
- "run_vm_tests.cc",
- ] + builtin_impl_tests_list.sources + vm_tests
+if (defined(is_fuchsia) && is_fuchsia) {
+ copy("hello_fuchsia") {
+ sources = [ "../tests/vm/dart/hello_fuchsia_test.dart" ]
+ outputs = [ "$root_out_dir/hello_fuchsia.dart" ]
}
executable("run_vm_tests_fuchsia") {
@@ -559,4 +602,144 @@
"runtime",
]
}
-} # defined(is_fuchsia) && is_fuchsia
+}
+
+# This is only needed for the Fuchsia target build until the Observatory is
+# supported.
+dart_executable("dart_no_observatory") {
+ extra_deps = [
+ "..:libdart",
+ ":dart_snapshot_cc",
+ ]
+ if (defined(is_fuchsia) && is_fuchsia) {
+ extra_deps += [ ":hello_fuchsia" ]
+ }
+ extra_defines = [
+ "NO_OBSERVATORY",
+ ]
+ extra_sources = [
+ "observatory_assets_empty.cc",
+ ]
+}
+
+executable("process_test") {
+ sources = [
+ "process_test.cc",
+ ]
+}
+
+action("generate_snapshot_test_dat_file") {
+ snapshot_test_dat_file = "$root_gen_dir/snapshot_test.dat"
+ snapshot_test_in_dat_file = "../vm/snapshot_test_in.dat"
+ snapshot_test_dart_file = "../vm/snapshot_test.dart"
+ inputs = [
+ "../tools/create_string_literal.py",
+ snapshot_test_in_dat_file,
+ snapshot_test_dart_file,
+ ]
+
+ outputs = [
+ snapshot_test_dat_file,
+ ]
+
+ script = "../tools/create_string_literal.py"
+ args = [
+ "--output",
+ rebase_path(snapshot_test_dat_file),
+ "--input_cc",
+ rebase_path(snapshot_test_in_dat_file),
+ "--include",
+ "INTENTIONALLY_LEFT_BLANK",
+ "--var_name",
+ "INTENTIONALLY_LEFT_BLANK_TOO",
+ rebase_path(snapshot_test_dart_file),
+ ]
+}
+
+executable("run_vm_tests") {
+ configs += ["..:dart_config",
+ "..:dart_maybe_product_config"]
+ deps = [
+ "..:libdart",
+ ":libdart_builtin",
+ ":embedded_dart_io",
+ ":dart_snapshot_cc",
+ ":generate_snapshot_test_dat_file",
+ "$dart_zlib_path",
+ ]
+ include_dirs = [
+ "..",
+ "$target_gen_dir",
+ ]
+ defines = [
+ "TESTING",
+ ]
+
+ if (dart_use_tcmalloc) {
+ deps += [
+ "//third_party/tcmalloc",
+ ]
+ }
+
+ # The VM sources are already included in libdart, so we just want to add in
+ # the tests here.
+ vm_tests_list = exec_script("../../tools/gypi_to_gn.py",
+ [rebase_path("../vm/vm_sources.gypi"),
+ "--keep_only=_test.cc",
+ "--keep_only=_test.h",],
+ "scope",
+ ["../vm/vm_sources.gypi"])
+ vm_tests = rebase_path(vm_tests_list.sources, ".", "../vm")
+
+ builtin_impl_tests_list =
+ exec_script("../../tools/gypi_to_gn.py",
+ [rebase_path("builtin_impl_sources.gypi"),
+ "--keep_only=_test.cc",
+ "--keep_only=_test.h",],
+ "scope",
+ ["builtin_impl_sources.gypi"])
+
+ sources = [
+ "run_vm_tests.cc",
+ ] + builtin_impl_tests_list.sources + vm_tests
+
+ ldflags = [
+ "-rdynamic",
+ ]
+}
+
+if (!defined(is_fuchsia) || !is_fuchsia) {
+ shared_library("test_extension") {
+ deps = [
+ ":dart",
+ ]
+ sources = [
+ "test_extension.c",
+ "test_extension_dllmain_win.cc",
+ ]
+ include_dirs = [
+ "..",
+ ]
+ defines = [
+ # The only effect of DART_SHARED_LIB is to export the Dart API.
+ "DART_SHARED_LIB",
+ ]
+ }
+
+ shared_library("sample_extension") {
+ deps = [
+ ":dart",
+ ]
+ sources = [
+ "../../samples/sample_extension/sample_extension.cc",
+ "../../samples/sample_extension/sample_extension_dllmain_win.cc",
+ ]
+ include_dirs = [
+ "..",
+ ]
+ defines = [
+ # The only effect of DART_SHARED_LIB is to export the Dart API.
+ "DART_SHARED_LIB",
+ ]
+ }
+}
diff --git a/runtime/bin/bin.gypi b/runtime/bin/bin.gypi
index a31cb93..650f587 100644
--- a/runtime/bin/bin.gypi
+++ b/runtime/bin/bin.gypi
@@ -290,7 +290,7 @@
'--output', '<(blink_cc_file)',
'--input_cc', '<(builtin_in_cc_file)',
'--include', 'bin/builtin.h',
- '--var_name', 'dart::bin::Builtin::blink_source_paths_',
+ '--var_name', 'dart::bin::Builtin::_blink_source_paths_',
'--library_name', 'dart:_blink',
'<@(_sources)',
],
@@ -322,7 +322,7 @@
'--output', '<(indexeddb_cc_file)',
'--input_cc', '<(builtin_in_cc_file)',
'--include', 'bin/builtin.h',
- '--var_name', 'dart::bin::Builtin::indexeddb_source_paths_',
+ '--var_name', 'dart::bin::Builtin::indexed_db_source_paths_',
'--library_name', 'dart:indexed_db',
'<@(_sources)',
],
@@ -450,7 +450,7 @@
'--output', '<(websql_cc_file)',
'--input_cc', '<(builtin_in_cc_file)',
'--include', 'bin/builtin.h',
- '--var_name', 'dart::bin::Builtin::websql_source_paths_',
+ '--var_name', 'dart::bin::Builtin::web_sql_source_paths_',
'--library_name', 'dart:web_sql',
'<@(_sources)',
],
@@ -514,7 +514,7 @@
'--output', '<(webaudio_cc_file)',
'--input_cc', '<(builtin_in_cc_file)',
'--include', 'bin/builtin.h',
- '--var_name', 'dart::bin::Builtin::webaudio_source_paths_',
+ '--var_name', 'dart::bin::Builtin::web_audio_source_paths_',
'--library_name', 'dart:web_audio',
'<@(_sources)',
],
diff --git a/runtime/bin/builtin.cc b/runtime/bin/builtin.cc
index 2c303a1..b3215bb 100644
--- a/runtime/bin/builtin.cc
+++ b/runtime/bin/builtin.cc
@@ -25,14 +25,14 @@
{ "dart:html_common", html_common_source_paths_, NULL, NULL, true},
{ "dart:js", js_source_paths_, NULL, NULL, true},
{ "dart:js_util", js_util_source_paths_, NULL, NULL, true},
- { "dart:_blink", blink_source_paths_, NULL, NULL, true },
- { "dart:indexed_db", indexeddb_source_paths_, NULL, NULL, true },
+ { "dart:_blink", _blink_source_paths_, NULL, NULL, true },
+ { "dart:indexed_db", indexed_db_source_paths_, NULL, NULL, true },
{ "cached_patches.dart", cached_patches_source_paths_, NULL, NULL, true },
{ "dart:web_gl", web_gl_source_paths_, NULL, NULL, true },
{ "metadata.dart", metadata_source_paths_, NULL, NULL, true },
- { "dart:web_sql", websql_source_paths_, NULL, NULL, true },
+ { "dart:web_sql", web_sql_source_paths_, NULL, NULL, true },
{ "dart:svg", svg_source_paths_, NULL, NULL, true },
- { "dart:web_audio", webaudio_source_paths_, NULL, NULL, true },
+ { "dart:web_audio", web_audio_source_paths_, NULL, NULL, true },
#endif // defined(DART_NO_SNAPSHOT)
// End marker.
diff --git a/runtime/bin/builtin.h b/runtime/bin/builtin.h
index d90223a..d7e1e4c 100644
--- a/runtime/bin/builtin.h
+++ b/runtime/bin/builtin.h
@@ -75,14 +75,14 @@
static const char* html_common_source_paths_[];
static const char* js_source_paths_[];
static const char* js_util_source_paths_[];
- static const char* blink_source_paths_[];
- static const char* indexeddb_source_paths_[];
+ static const char* _blink_source_paths_[];
+ static const char* indexed_db_source_paths_[];
static const char* cached_patches_source_paths_[];
static const char* web_gl_source_paths_[];
static const char* metadata_source_paths_[];
- static const char* websql_source_paths_[];
+ static const char* web_sql_source_paths_[];
static const char* svg_source_paths_[];
- static const char* webaudio_source_paths_[];
+ static const char* web_audio_source_paths_[];
static Dart_Port load_port_;
static const int num_libs_;
diff --git a/runtime/bin/dart_product_entries.txt b/runtime/bin/dart_product_entries.txt
index 098d0a0..057c6db 100644
--- a/runtime/bin/dart_product_entries.txt
+++ b/runtime/bin/dart_product_entries.txt
@@ -3,5 +3,6 @@
dart:_builtin,::,_getUriBaseClosure
dart:_builtin,::,_setWorkingDirectory
dart:_builtin,::,_setPackageRoot
+dart:_builtin,::,_setPackagesMap
dart:_builtin,::,_loadPackagesMap
dart:_builtin,::,_loadDataAsync
diff --git a/runtime/bin/eventhandler_fuchsia.cc b/runtime/bin/eventhandler_fuchsia.cc
index 69c2190..cdd4fad 100644
--- a/runtime/bin/eventhandler_fuchsia.cc
+++ b/runtime/bin/eventhandler_fuchsia.cc
@@ -20,9 +20,9 @@
namespace bin {
EventHandlerImplementation::EventHandlerImplementation() {
- mx_status_t status = mx_message_pipe_create(interrupt_handles_, 0);
+ mx_status_t status = mx_msgpipe_create(interrupt_handles_, 0);
if (status != NO_ERROR) {
- FATAL1("mx_message_pipe_create failed: %s\n", mx_strstatus(status));
+ FATAL1("mx_msgpipe_create failed: %s\n", mx_strstatus(status));
}
}
@@ -48,9 +48,9 @@
msg.data = data;
mx_status_t status =
- mx_message_write(interrupt_handles_[1], &msg, sizeof(msg), NULL, 0, 0);
+ mx_msgpipe_write(interrupt_handles_[1], &msg, sizeof(msg), NULL, 0, 0);
if (status != NO_ERROR) {
- FATAL1("mx_message_write failed: %s\n", mx_strstatus(status));
+ FATAL1("mx_msgpipe_write failed: %s\n", mx_strstatus(status));
}
}
@@ -60,7 +60,7 @@
uint32_t bytes = kInterruptMessageSize;
mx_status_t status;
while (true) {
- status = mx_message_read(
+ status = mx_msgpipe_read(
interrupt_handles_[0], &msg, &bytes, NULL, NULL, 0);
if (status != NO_ERROR) {
break;
@@ -77,7 +77,7 @@
// status == ERR_BAD_STATE when we try to read and there are no messages
// available, so it is an error if we get here and status != ERR_BAD_STATE.
if (status != ERR_BAD_STATE) {
- FATAL1("mx_message_read failed: %s\n", mx_strstatus(status));
+ FATAL1("mx_msgpipe_read failed: %s\n", mx_strstatus(status));
}
}
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 277220e..8a80c7e 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -78,6 +78,7 @@
// Global flag that is used to indicate that we want to compile all the
// dart functions and not run anything.
static bool compile_all = false;
+static bool parse_all = false;
// Global flag that is used to indicate that we want to use blobs/mmap instead
@@ -324,6 +325,17 @@
}
+static bool ProcessParseAllOption(const char* arg,
+ CommandLineOptions* vm_options) {
+ ASSERT(arg != NULL);
+ if (*arg != '\0') {
+ return false;
+ }
+ parse_all = true;
+ return true;
+}
+
+
static bool ProcessUseBlobsOption(const char* arg,
CommandLineOptions* vm_options) {
ASSERT(arg != NULL);
@@ -547,6 +559,7 @@
// VM specific options to the standalone dart program.
{ "--compile_all", ProcessCompileAllOption },
+ { "--parse_all", ProcessParseAllOption },
{ "--enable-vm-service", ProcessEnableVmServiceOption },
{ "--disable-service-origin-check", ProcessDisableServiceOriginCheckOption },
{ "--observe", ProcessObserveOption },
@@ -1515,6 +1528,15 @@
CHECK_RESULT(result);
}
+ if (parse_all) {
+ result = Dart_ParseAll();
+ CHECK_RESULT(result);
+ Dart_ExitScope();
+ // Shutdown the isolate.
+ Dart_ShutdownIsolate();
+ return false;
+ }
+
if (is_noopt || (gen_snapshot_kind == kAppAOT)) {
Dart_QualifiedFunctionName standalone_entry_points[] = {
{ "dart:_builtin", "::", "_getMainClosure" },
@@ -1523,6 +1545,7 @@
{ "dart:_builtin", "::", "_resolveInWorkingDirectory" },
{ "dart:_builtin", "::", "_setWorkingDirectory" },
{ "dart:_builtin", "::", "_setPackageRoot" },
+ { "dart:_builtin", "::", "_setPackagesMap" },
{ "dart:_builtin", "::", "_libraryFilePath" },
{ "dart:io", "::", "_makeUint8ListView" },
{ "dart:io", "::", "_makeDatagram" },
diff --git a/runtime/bin/socket_patch.dart b/runtime/bin/socket_patch.dart
index 0244e79..4850827 100644
--- a/runtime/bin/socket_patch.dart
+++ b/runtime/bin/socket_patch.dart
@@ -70,6 +70,12 @@
static bool _listSupported() native "NetworkInterface_ListSupported";
}
+void _throwOnBadPort(int port) {
+ if ((port == null) || (port < 0) || (port > 0xFFFF)) {
+ throw new ArgumentError("Invalid port $port");
+ }
+}
+
class _InternetAddress implements InternetAddress {
static const int _ADDRESS_LOOPBACK_IP_V4 = 0;
static const int _ADDRESS_LOOPBACK_IP_V6 = 1;
@@ -387,6 +393,7 @@
}
static Future<_NativeSocket> connect(host, int port, sourceAddress) {
+ _throwOnBadPort(port);
if (sourceAddress != null && sourceAddress is! _InternetAddress) {
if (sourceAddress is String) {
sourceAddress = new InternetAddress(sourceAddress);
@@ -488,6 +495,7 @@
int backlog,
bool v6Only,
bool shared) {
+ _throwOnBadPort(port);
return new Future.value(host)
.then((host) {
if (host is _InternetAddress) return host;
@@ -526,6 +534,7 @@
static Future<_NativeSocket> bindDatagram(
host, int port, bool reuseAddress) {
+ _throwOnBadPort(port);
return new Future.value(host)
.then((host) {
if (host is _InternetAddress) return host;
@@ -676,6 +685,7 @@
int send(List<int> buffer, int offset, int bytes,
InternetAddress address, int port) {
+ _throwOnBadPort(port);
if (isClosing || isClosed) return 0;
_BufferAndStart bufferAndStart =
_ensureFastAndSerializableByteData(
@@ -1116,8 +1126,7 @@
int backlog,
bool v6Only,
bool shared) {
- if (port < 0 || port > 0xFFFF)
- throw new ArgumentError("Invalid port $port");
+ _throwOnBadPort(port);
if (backlog < 0) throw new ArgumentError("Invalid backlog $backlog");
return _NativeSocket.bind(address, port, backlog, v6Only, shared)
.then((socket) => new _RawServerSocket(socket, v6Only));
@@ -1762,8 +1771,7 @@
static Future<RawDatagramSocket> bind(
host, int port, bool reuseAddress) {
- if (port < 0 || port > 0xffff)
- throw new ArgumentError("Invalid port $port");
+ _throwOnBadPort(port);
return _NativeSocket.bindDatagram(host, port, reuseAddress)
.then((socket) => new _RawDatagramSocket(socket));
}
diff --git a/runtime/bin/zlib/BUILD.gn b/runtime/bin/zlib/BUILD.gn
new file mode 100644
index 0000000..ad78238
--- /dev/null
+++ b/runtime/bin/zlib/BUILD.gn
@@ -0,0 +1,56 @@
+# 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.
+
+config("zlib_config") {
+ include_dirs = [ "//third_party/zlib" ]
+}
+
+static_library("zlib") {
+ if (!is_win) {
+ # Don't stomp on "libzlib" on other platforms.
+ output_name = "chrome_zlib"
+ }
+
+ zlib_path = "//third_party/zlib"
+ sources = [
+ "$zlib_path/adler32.c",
+ "$zlib_path/compress.c",
+ "$zlib_path/crc32.c",
+ "$zlib_path/crc32.h",
+ "$zlib_path/deflate.c",
+ "$zlib_path/deflate.h",
+ "$zlib_path/gzclose.c",
+ "$zlib_path/gzguts.h",
+ "$zlib_path/gzlib.c",
+ "$zlib_path/gzread.c",
+ "$zlib_path/gzwrite.c",
+ "$zlib_path/infback.c",
+ "$zlib_path/inffast.c",
+ "$zlib_path/inffast.h",
+ "$zlib_path/inffixed.h",
+ "$zlib_path/inflate.c",
+ "$zlib_path/inflate.h",
+ "$zlib_path/inftrees.c",
+ "$zlib_path/inftrees.h",
+ "$zlib_path/mozzconf.h",
+ "$zlib_path/trees.c",
+ "$zlib_path/trees.h",
+ "$zlib_path/uncompr.c",
+ "$zlib_path/zconf.h",
+ "$zlib_path/zlib.h",
+ "$zlib_path/zutil.c",
+ "$zlib_path/zutil.h",
+ ]
+
+ configs -= [ "//build/config/compiler:chromium_code" ]
+ configs += [ "//build/config/compiler:no_chromium_code" ]
+
+ all_dependent_configs = [ ":zlib_config" ]
+
+ if (is_clang) {
+ cflags = [
+ "-Wno-shift-negative-value",
+ ]
+ }
+}
diff --git a/runtime/include/dart_native_api.h b/runtime/include/dart_native_api.h
index 7dce495..74237c1 100644
--- a/runtime/include/dart_native_api.h
+++ b/runtime/include/dart_native_api.h
@@ -170,4 +170,10 @@
*/
DART_EXPORT Dart_Handle Dart_CompileAll();
+/**
+ * Parses all loaded functions in the current isolate..
+ *
+ */
+DART_EXPORT Dart_Handle Dart_ParseAll();
+
#endif /* INCLUDE_DART_NATIVE_API_H_ */ /* NOLINT */
diff --git a/runtime/observatory/.packages b/runtime/observatory/.packages
new file mode 100644
index 0000000..4730e62
--- /dev/null
+++ b/runtime/observatory/.packages
@@ -0,0 +1,43 @@
+# Generated by pub on 2016-09-23 00:19:32.016148.
+analyzer:../../third_party/observatory_pub_packages/packages/analyzer/lib/
+args:../../third_party/observatory_pub_packages/packages/args/lib/
+async:../../third_party/observatory_pub_packages/packages/async/lib/
+barback:../../third_party/observatory_pub_packages/packages/barback/lib/
+browser:../../third_party/observatory_pub_packages/packages/browser/lib/
+charcode:../../third_party/observatory_pub_packages/packages/charcode/lib/
+charted:../../third_party/observatory_pub_packages/packages/charted/lib/
+cli_util:../../third_party/observatory_pub_packages/packages/cli_util/lib/
+code_transformers:../../third_party/observatory_pub_packages/packages/code_transformers/lib/
+collection:../../third_party/observatory_pub_packages/packages/collection/lib/
+csslib:../../third_party/observatory_pub_packages/packages/csslib/lib/
+dart_style:../../third_party/observatory_pub_packages/packages/dart_style/lib/
+dart_to_js_script_rewriter:../../third_party/observatory_pub_packages/packages/dart_to_js_script_rewriter/lib/
+glob:../../third_party/observatory_pub_packages/packages/glob/lib/
+html:../../third_party/observatory_pub_packages/packages/html/lib/
+initialize:../../third_party/observatory_pub_packages/packages/initialize/lib/
+intl:../../third_party/observatory_pub_packages/packages/intl/lib/
+logging:../../third_party/observatory_pub_packages/packages/logging/lib/
+matcher:../../third_party/observatory_pub_packages/packages/matcher/lib/
+observe:../../third_party/observatory_pub_packages/packages/observe/lib/
+package_config:../../third_party/observatory_pub_packages/packages/package_config/lib/
+path:../../third_party/observatory_pub_packages/packages/path/lib/
+petitparser:../../third_party/observatory_pub_packages/packages/petitparser/lib/
+plugin:../../third_party/observatory_pub_packages/packages/plugin/lib/
+pool:../../third_party/observatory_pub_packages/packages/pool/lib/
+quiver:../../third_party/observatory_pub_packages/packages/quiver/lib/
+quiver_iterables:../../third_party/observatory_pub_packages/packages/quiver_iterables/lib/
+smoke:../../third_party/observatory_pub_packages/packages/smoke/lib/
+source_maps:../../third_party/observatory_pub_packages/packages/source_maps/lib/
+source_span:../../third_party/observatory_pub_packages/packages/source_span/lib/
+stack_trace:../../third_party/observatory_pub_packages/packages/stack_trace/lib/
+string_scanner:../../third_party/observatory_pub_packages/packages/string_scanner/lib/
+template_binding:../../third_party/observatory_pub_packages/packages/template_binding/lib/
+unittest:../../third_party/observatory_pub_packages/packages/unittest/lib/
+usage:../../third_party/observatory_pub_packages/packages/usage/lib/
+utf:../../third_party/observatory_pub_packages/packages/utf/lib/
+watcher:../../third_party/observatory_pub_packages/packages/watcher/lib/
+web_components:../../third_party/observatory_pub_packages/packages/web_components/lib/
+when:../../third_party/observatory_pub_packages/packages/when/lib/
+which:../../third_party/observatory_pub_packages/packages/which/lib/
+yaml:../../third_party/observatory_pub_packages/packages/yaml/lib/
+observatory:lib/
diff --git a/runtime/observatory/BUILD.gn b/runtime/observatory/BUILD.gn
index 3943253..a476414 100644
--- a/runtime/observatory/BUILD.gn
+++ b/runtime/observatory/BUILD.gn
@@ -41,23 +41,24 @@
rebase_path("pubspec.yaml"),
]
+ current_dir = rebase_path(".", "//")
args = [
"--silent=True",
"--pub-executable",
dart_host_pub_exe,
"--directory",
- rebase_path("$root_gen_dir/observatory_copy/dart/runtime/observatory/"),
+ rebase_path("$root_gen_dir/observatory_copy/$current_dir/"),
"--command",
"rewrite",
rebase_path("../observatory/pubspec.yaml"),
rebase_path(
- "$root_gen_dir/observatory_copy/dart/runtime/observatory/pubspec.yaml"),
+ "$root_gen_dir/observatory_copy/$current_dir/pubspec.yaml"),
"../../third_party/",
rebase_path("../../third_party/"),
]
outputs = [
- "$root_gen_dir/observatory_copy/dart/runtime/observatory/pubspec.yaml",
+ "$root_gen_dir/observatory_copy/$current_dir/pubspec.yaml",
]
}
@@ -68,9 +69,10 @@
script = "../../tools/observatory_tool.py"
+ current_dir = rebase_path(".", "//")
inputs = [
script,
- "$root_gen_dir/observatory_copy/dart/runtime/observatory/pubspec.yaml",
+ "$root_gen_dir/observatory_copy/$current_dir/pubspec.yaml",
]
args = [
@@ -78,23 +80,24 @@
"--pub-executable",
dart_host_pub_exe,
"--stamp",
- rebase_path("$root_gen_dir/observatory_copy/dart/runtime/observatory/packages.stamp"),
+ rebase_path("$root_gen_dir/observatory_copy/$current_dir/packages.stamp"),
"--directory",
- rebase_path("$root_gen_dir/observatory_copy/dart/runtime/observatory/"),
+ rebase_path("$root_gen_dir/observatory_copy/$current_dir/"),
"--command",
"get",
]
outputs = [
- "$root_gen_dir/observatory_copy/dart/runtime/observatory/packages.stamp",
+ "$root_gen_dir/observatory_copy/$current_dir/packages.stamp",
]
}
action("pub_build_observatory") {
+ current_dir = rebase_path(".", "//")
sources =
rebase_path(observatory_sources_gypi.sources,
"",
- "$root_gen_dir/observatory_copy/dart/runtime/observatory")
+ "$root_gen_dir/observatory_copy/$current_dir")
deps = [
":copy_observatory",
@@ -105,7 +108,7 @@
inputs = [
script,
- "$root_gen_dir/observatory_copy/dart/runtime/observatory/packages.stamp",
+ "$root_gen_dir/observatory_copy/$current_dir/packages.stamp",
]
inputs += sources
@@ -114,7 +117,7 @@
"--pub-executable",
dart_host_pub_exe,
"--directory",
- rebase_path("$root_gen_dir/observatory_copy/dart/runtime/observatory/"),
+ rebase_path("$root_gen_dir/observatory_copy/$current_dir/"),
"--command",
"build",
rebase_path("$root_out_dir/observatory/build"),
@@ -152,41 +155,70 @@
]
}
-action("archive_observatory") {
- deps = [
- ":deploy_observatory",
- ]
+template("observatory_archive") {
+ assert(defined(invoker.inner_namespace),
+ "Need inner_namespace in $target_name")
+ assert(defined(invoker.outer_namespace),
+ "Need outer_namespace in $target_name")
+ action(target_name) {
+ deps = [
+ ":deploy_observatory",
+ ]
- script = "../tools/create_archive.py"
+ script = "../tools/create_archive.py"
inputs = [
script,
"$root_out_dir/observatory/deployed/web/main.dart.js",
]
- args = [
- "--output",
- rebase_path("$root_gen_dir/observatory/observatory_archive.cc"),
- "--tar_output",
- rebase_path("$root_gen_dir/observatory/observatory_archive.tar"),
- "--outer_namespace", "dart",
- "--inner_namespace", "observatory",
- "--name", "observatory_assets_archive",
- "--client_root", rebase_path("$root_out_dir/observatory/deployed/web/"),
- ]
+ inner_namespace = invoker.inner_namespace
+ outer_namespace = invoker.outer_namespace
+ output_name = target_name
+ args = [
+ "--output",
+ rebase_path("$root_gen_dir/observatory/${output_name}.cc"),
+ "--tar_output",
+ rebase_path("$root_gen_dir/observatory/${output_name}.tar"),
+ "--outer_namespace", outer_namespace,
+ "--inner_namespace", inner_namespace,
+ "--name", "observatory_assets_archive",
+ "--client_root", rebase_path("$root_out_dir/observatory/deployed/web/"),
+ ]
- outputs = [
- "$root_gen_dir/observatory/observatory_archive.cc",
- "$root_gen_dir/observatory/observatory_archive.tar",
- ]
+ outputs = [
+ "$root_gen_dir/observatory/${output_name}.cc",
+ "$root_gen_dir/observatory/${output_name}.tar",
+ ]
+ }
+}
+
+observatory_archive("embedded_archive_observatory") {
+ outer_namespace = "dart"
+ inner_namespace = "observatory"
}
source_set("embedded_observatory_archive") {
deps = [
- ":archive_observatory",
+ ":embedded_archive_observatory",
]
sources = [
- rebase_path("$root_gen_dir/observatory/observatory_archive.cc"),
+ rebase_path("$root_gen_dir/observatory/embedded_archive_observatory.cc"),
+ ]
+}
+
+observatory_archive("standalone_archive_observatory") {
+ outer_namespace = "dart"
+ inner_namespace = "bin"
+}
+
+source_set("standalone_observatory_archive") {
+ deps = [
+ ":standalone_archive_observatory",
+ ]
+
+ sources = [
+ rebase_path("$root_gen_dir/observatory/standalone_archive_observatory.cc"),
]
}
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index 51ac8eb..85d9385 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -2256,7 +2256,8 @@
final classes = <Class>[];
final variables = <Field>[];
final functions = <ServiceFunction>[];
-
+ bool _debuggable;
+ bool get debuggable => _debuggable;
bool get immutable => false;
bool isDart(String libraryName) {
@@ -2284,6 +2285,7 @@
return;
}
_loaded = true;
+ _debuggable = map['debuggable'];
dependencies.clear();
dependencies.addAll(map["dependencies"].map(LibraryDependency._fromMap));
scripts.clear();
diff --git a/runtime/observatory/observatory.gypi b/runtime/observatory/observatory.gypi
index ed241c5..be393ca 100644
--- a/runtime/observatory/observatory.gypi
+++ b/runtime/observatory/observatory.gypi
@@ -8,42 +8,10 @@
},
'targets': [
{
- 'target_name': 'fetch_observatory_deps',
- 'type': 'none',
- 'dependencies': [
- 'dart_bootstrap#host',
- ],
- 'toolsets': ['host'],
- 'actions': [
- {
- 'action_name': 'get_obsevatory_dependencies',
- 'inputs': [
- '../../tools/observatory_tool.py',
- 'pubspec.yaml',
- ],
- 'outputs': [
- '<(gen_source_dir)/observatory_packages.stamp'
- ],
- 'action': [
- 'python',
- '../tools/observatory_tool.py',
- '--sdk=True',
- '--stamp',
- '<(gen_source_dir)/observatory_packages.stamp',
- '--dart-executable',
- '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart_bootstrap<(EXECUTABLE_SUFFIX)',
- '--directory', 'observatory',
- '--command', 'get',
- ],
- }
- ],
- },
- {
'target_name': 'build_observatory',
'type': 'none',
'dependencies': [
'dart_bootstrap#host',
- 'fetch_observatory_deps#host',
],
'toolsets': ['host'],
'includes': [
@@ -54,7 +22,6 @@
'action_name': 'pub_build_observatory',
'inputs': [
'../../tools/observatory_tool.py',
- '<(gen_source_dir)/observatory_packages.stamp',
'<@(_sources)',
],
'outputs': [
diff --git a/runtime/observatory/tests/observatory_ui/observatory_ui.status b/runtime/observatory/tests/observatory_ui/observatory_ui.status
index f2ade5c..f683fd8 100644
--- a/runtime/observatory/tests/observatory_ui/observatory_ui.status
+++ b/runtime/observatory/tests/observatory_ui/observatory_ui.status
@@ -5,9 +5,6 @@
[ $browser == false || $runtime == drt || $fast_startup]
*: SkipByDesign
-[ $runtime == dartium || $runtime == chrome || $runtime == ff ]
-vm_connect/element_test: Skip # Times out. Issue 27397
-
[ $runtime == dartium ]
isolate/*: Skip
allocation_profile: Skip
diff --git a/runtime/observatory/tests/service/issue_27238_test.dart b/runtime/observatory/tests/service/issue_27238_test.dart
new file mode 100644
index 0000000..052b107
--- /dev/null
+++ b/runtime/observatory/tests/service/issue_27238_test.dart
@@ -0,0 +1,46 @@
+// 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 --verbose_debug
+
+import 'package:observatory/service_io.dart';
+import 'service_test_common.dart';
+import 'dart:async';
+import 'test_helper.dart';
+import 'dart:developer';
+
+const int LINE_A = 20;
+const int LINE_B = 23;
+const int LINE_C = 24;
+const int LINE_D = 26;
+const int LINE_E = 27;
+
+testMain() async {
+ debugger();
+ Future future1 = new Future.value(); // LINE_A.
+ Future future2 = new Future.value();
+
+ await future1; // LINE_B.
+ await future2; // LINE_C.
+
+ print('foo1'); // LINE_D.
+ print('foo2'); // LINE_E.
+}
+
+var tests = [
+ hasStoppedAtBreakpoint,
+ stoppedAtLine(LINE_A),
+ smartNext,
+ hasStoppedAtBreakpoint,
+ smartNext,
+ stoppedAtLine(LINE_B),
+ smartNext,
+ hasStoppedAtBreakpoint,
+ stoppedAtLine(LINE_C),
+ smartNext,
+ hasStoppedAtBreakpoint,
+ stoppedAtLine(LINE_D),
+ resumeIsolate,
+];
+
+main(args) => runIsolateTests(args, tests, testeeConcurrent: testMain);
diff --git a/runtime/observatory/tests/service/issue_27287_test.dart b/runtime/observatory/tests/service/issue_27287_test.dart
new file mode 100644
index 0000000..58633b33
--- /dev/null
+++ b/runtime/observatory/tests/service/issue_27287_test.dart
@@ -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.
+// VMOptions=--error_on_bad_type --error_on_bad_override --verbose_debug
+
+import 'package:observatory/service_io.dart';
+import 'service_test_common.dart';
+import 'dart:async';
+import 'test_helper.dart';
+import 'dart:developer';
+
+const int LINE_A = 19;
+const int LINE_B = 20;
+
+var libVariable;
+
+testMain() {
+ debugger();
+ print("Before"); // LINE_A
+ libVariable = 0; // LINE_B
+ print("and after");
+}
+
+var tests = [
+ hasStoppedAtBreakpoint,
+ stoppedAtLine(LINE_A),
+ stepOver,
+ // Check that debugger stops at assignment to top-level variable.
+ stoppedAtLine(LINE_B),
+ resumeIsolate,
+];
+
+main(args) => runIsolateTests(args, tests, testeeConcurrent: testMain);
diff --git a/runtime/observatory/tests/service/service.status b/runtime/observatory/tests/service/service.status
index 1e49905..e3cc4de 100644
--- a/runtime/observatory/tests/service/service.status
+++ b/runtime/observatory/tests/service/service.status
@@ -7,6 +7,7 @@
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
+debugger_location_test: Skip # Issue 27434
[ ($compiler == none || $compiler == precompiler) && ($runtime == vm || $runtime == dart_precompiled) ]
evaluate_activation_test/instance: RuntimeError # http://dartbug.com/20047
diff --git a/runtime/observatory/tests/service/service_test_common.dart b/runtime/observatory/tests/service/service_test_common.dart
index 4b3dc36..935d426 100644
--- a/runtime/observatory/tests/service/service_test_common.dart
+++ b/runtime/observatory/tests/service/service_test_common.dart
@@ -28,6 +28,43 @@
streamSubscriptions.remove(streamName);
}
+Future smartNext(Isolate isolate) async {
+ print('smartNext');
+ if (isolate.status == M.IsolateStatus.paused) {
+ var event = isolate.pauseEvent;
+ if (event.atAsyncSuspension) {
+ return asyncNext(isolate);
+ } else {
+ return syncNext(isolate);
+ }
+ } else {
+ throw 'The program is already running';
+ }
+}
+
+Future asyncNext(Isolate isolate) async {
+ print('asyncNext');
+ if (isolate.status == M.IsolateStatus.paused) {
+ var event = isolate.pauseEvent;
+ if (!event.atAsyncSuspension) {
+ throw 'No async continuation at this location';
+ } else {
+ return isolate.stepOverAsyncSuspension();
+ }
+ } else {
+ throw 'The program is already running';
+ }
+}
+
+Future syncNext(Isolate isolate) async {
+ print('syncNext');
+ if (isolate.status == M.IsolateStatus.paused) {
+ return isolate.stepOver();
+ } else {
+ throw 'The program is already running';
+ }
+}
+
Future asyncStepOver(Isolate isolate) async {
final Completer pausedAtSyntheticBreakpoint = new Completer();
StreamSubscription subscription;
@@ -191,13 +228,50 @@
Script script = await top.location.script.load();
int actualLine = script.tokenToLine(top.location.tokenPos);
if (actualLine != line) {
- var sb = new StringBuffer();
+ StringBuffer sb = new StringBuffer();
sb.write("Expected to be at line $line but actually at line $actualLine");
sb.write("\nFull stack trace:\n");
for (Frame f in stack['frames']) {
sb.write(" $f [${await f.location.getLine()}]\n");
}
throw sb.toString();
+ } else {
+ print('Program is stopped at line: $line');
+ }
+ };
+}
+
+
+IsolateTest stoppedInFunction(String functionName, {bool contains: false}) {
+ return (Isolate isolate) async {
+ print("Checking we are in function: $functionName");
+
+ ServiceMap stack = await isolate.getStack();
+ expect(stack.type, equals('Stack'));
+
+ List<Frame> frames = stack['frames'];
+ expect(frames.length, greaterThanOrEqualTo(1));
+
+ Frame topFrame = stack['frames'][0];
+ ServiceFunction function = await topFrame.function.load();
+ final bool matches =
+ contains ? function.name.contains(functionName) :
+ function.name == functionName;
+ if (!matches) {
+ StringBuffer sb = new StringBuffer();
+ sb.write("Expected to be in function $functionName but "
+ "actually in function ${function.name}");
+ sb.write("\nFull stack trace:\n");
+ for (Frame f in stack['frames']) {
+ await f.function.load();
+ await (f.function.dartOwner as ServiceObject).load();
+ String name = f.function.name;
+ String ownerName = (f.function.dartOwner as ServiceObject).name;
+ sb.write(" $f [$name] [$ownerName]\n");
+ }
+ throw sb.toString();
+ } else {
+ print('Program is stopped in function: $functionName');
}
};
}
@@ -253,6 +327,12 @@
return hasStoppedAtBreakpoint(isolate);
}
+Future<Isolate> stepOut(Isolate isolate) async {
+ await isolate.stepOut();
+ return hasStoppedAtBreakpoint(isolate);
+}
+
+
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/observatory/tests/service/set_library_debuggable_rpc_test.dart b/runtime/observatory/tests/service/set_library_debuggable_rpc_test.dart
index fe51ff7..0571376 100644
--- a/runtime/observatory/tests/service/set_library_debuggable_rpc_test.dart
+++ b/runtime/observatory/tests/service/set_library_debuggable_rpc_test.dart
@@ -57,6 +57,29 @@
}
expect(caughtException, isTrue);
},
+
+ // illegal (dart:_*) library.
+ (Isolate isolate) async {
+ await isolate.load();
+ Library dartInternal = isolate.libraries.firstWhere(
+ (Library library) => library.uri == 'dart:_internal');
+ var params = {
+ 'libraryId': dartInternal.id,
+ 'isDebuggable': false,
+ };
+ bool caughtException;
+ try {
+ await isolate.invokeRpcNoUpgrade('setLibraryDebuggable', params);
+ expect(false, isTrue, reason:'Unreachable');
+ } on ServerRpcException catch(e) {
+ caughtException = true;
+ expect(e.code, equals(ServerRpcException.kInvalidParams));
+ expect(e.message,
+ "setLibraryDebuggable: "
+ "illegal 'libraryId' parameter: ${dartInternal.id}");
+ }
+ expect(caughtException, isTrue);
+ },
];
main(args) async => runIsolateTests(args, tests);
diff --git a/runtime/observatory/tests/service/set_library_debuggable_test.dart b/runtime/observatory/tests/service/set_library_debuggable_test.dart
new file mode 100644
index 0000000..d76569c
--- /dev/null
+++ b/runtime/observatory/tests/service/set_library_debuggable_test.dart
@@ -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.
+// VMOptions=--error_on_bad_type --error_on_bad_override
+
+library set_library_debuggable_test;
+
+import 'dart:developer';
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+import 'service_test_common.dart';
+import 'test_helper.dart';
+
+const LINE_A = 20;
+const LINE_B = 21;
+const LINE_C = 22;
+
+testMain() async {
+ debugger();
+ print('hi'); // LINE_A.
+ print('yep'); // LINE_B.
+ print('zoo'); // LINE_C.
+}
+
+var tests = [
+ (Isolate isolate) async {
+ await isolate.reload();
+ Library dartCore = isolate.libraries.firstWhere(
+ (Library library) => library.uri == 'dart:core');
+ await dartCore.load();
+ expect(dartCore.debuggable, equals(true));
+ },
+ stoppedInFunction('testMain', contains:true),
+ stoppedAtLine(LINE_A),
+ stepInto,
+ stoppedInFunction('print'),
+ stepOut,
+ stoppedInFunction('testMain', contains:true),
+ stoppedAtLine(LINE_B),
+ (Isolate isolate) async {
+ // Mark 'dart:core' as not debuggable.
+ await isolate.reload();
+ Library dartCore = isolate.libraries.firstWhere(
+ (Library library) => library.uri == 'dart:core');
+ await dartCore.load();
+ expect(dartCore.debuggable, equals(true));
+ var setDebugParams = {
+ 'libraryId': dartCore.id,
+ 'isDebuggable': false,
+ };
+ Map<String, dynamic> result =
+ await isolate.invokeRpcNoUpgrade('setLibraryDebuggable',
+ setDebugParams);
+ expect(result['type'], equals('Success'));
+ await dartCore.reload();
+ expect(dartCore.debuggable, equals(false));
+ },
+ stoppedInFunction('testMain', contains:true),
+ stoppedAtLine(LINE_B),
+ stepInto,
+ stoppedInFunction('testMain', contains:true),
+ stoppedAtLine(LINE_C),
+];
+
+main(args) async => runIsolateTests(args, tests, testeeConcurrent: testMain);
diff --git a/runtime/observatory/tests/service/step_over_await_test.dart b/runtime/observatory/tests/service/step_over_await_test.dart
index 5b5f4ed..1bbb3b7 100644
--- a/runtime/observatory/tests/service/step_over_await_test.dart
+++ b/runtime/observatory/tests/service/step_over_await_test.dart
@@ -13,164 +13,33 @@
import 'package:observatory/service_io.dart';
import 'package:unittest/unittest.dart';
-const int LINE_A = 25;
-const int LINE_B = 27;
-const int LINE_C = 29;
-const int LINE_D = 30;
+const int LINE_A = 22;
+const int LINE_B = 24;
-// This tests the low level synthetic breakpoint added / paused / removed
-// machinery triggered by the step OverAwait command.
-asyncWithoutAwait() async {
+// This tests the asyncStepOver command.
+asyncFunction() async {
debugger();
print('a'); // LINE_A
await new Future.delayed(new Duration(seconds: 2));
print('b'); // LINE_B
- debugger(); // LINE_C
- debugger(); // LINE_D
}
testMain() {
- asyncWithoutAwait();
+ asyncFunction();
}
-Breakpoint syntheticBreakpoint;
-
-Future<Isolate> testLowLevelAwaitOver(
- Isolate isolate) {
- assert(M.isAtAsyncSuspension(isolate.pauseEvent));
-
- int state = 0;
- bool firstResume = true;
- handleBreakpointAdded(ServiceEvent event) {
- expect(syntheticBreakpoint, isNull);
- expect(state, 0);
- if (!event.breakpoint.isSyntheticAsyncContinuation) {
- // Not a synthetic async breakpoint.
- return;
- }
- if (event.owner != isolate) {
- // Wrong isolate.
- return;
- }
- syntheticBreakpoint = event.breakpoint;
- print('!!!! Synthetic async breakpoint added ${syntheticBreakpoint}');
- state = 1;
- }
-
- handleResume(ServiceEvent event) {
- if (firstResume) {
- expect(state, 1);
- if (event.owner != isolate) {
- // Wrong isolate.
- return;
- }
- print('!!!! Got first resume.');
- state = 2;
- firstResume = false;
- } else {
- expect(state, 3);
- if (event.owner != isolate) {
- // Wrong isolate.
- return;
- }
- print('!!!! Got second resume.');
- state = 4;
- }
-
- }
-
- handlePauseBreakpoint(ServiceEvent event) {
- expect(syntheticBreakpoint, isNotNull);
- expect(state, 2);
- if (!event.breakpoint.isSyntheticAsyncContinuation) {
- // Not a synthetic async breakpoint.
- return;
- }
- if (event.owner != isolate) {
- // Wrong isolate.
- return;
- }
- expect(event.breakpoint, equals(syntheticBreakpoint));
- print('!!!! Paused at synthetic async breakpoint ${syntheticBreakpoint}');
- state = 3;
- }
-
- handleBreakpointRemoved(ServiceEvent event) {
- expect(syntheticBreakpoint, isNotNull);
- expect(state, 4);
- if (!event.breakpoint.isSyntheticAsyncContinuation) {
- // Not a synthetic async breakpoint.
- return;
- }
- if (event.owner != isolate) {
- // Wrong isolate.
- return;
- }
- expect(event.breakpoint, equals(syntheticBreakpoint));
- print('!!!! Synthetic async breakpoint removed ${syntheticBreakpoint}');
- state = 5;
- syntheticBreakpoint = null;
- }
-
- // Set up a listener to wait for debugger events.
- Completer completer = new Completer();
- isolate.vm.getEventStream(VM.kDebugStream).then((stream) {
- var subscription;
- subscription = stream.listen((ServiceEvent event) async {
- if (event.kind == ServiceEvent.kBreakpointAdded) {
- handleBreakpointAdded(event);
- expect(state, 1);
- } else if (event.kind == ServiceEvent.kResume) {
- if (firstResume) {
- handleResume(event);
- expect(state, 2);
- } else {
- handleResume(event);
- expect(state, 4);
- }
- } else if (event.kind == ServiceEvent.kPauseBreakpoint) {
- handlePauseBreakpoint(event);
- expect(state, 3);
- // Check that we are paused after the await statement.
- await (stoppedAtLine(LINE_B)(isolate));
- // Resume the isolate so that we trigger the breakpoint removal.
- print('!!!! Triggering synthetic breakpoint removal.');
- isolate.resume();
- } else if (event.kind == ServiceEvent.kBreakpointRemoved) {
- handleBreakpointRemoved(event);
- expect(state, 5);
- subscription.cancel();
- if (completer != null) {
- // Reload to update isolate.pauseEvent.
- completer.complete(isolate.reload());
- completer = null;
- }
- }
- });
- });
-
- isolate.stepOverAsyncSuspension();
-
- return completer.future; // Will complete when breakpoint added.
-}
-
-
var tests = [
hasStoppedAtBreakpoint,
stoppedAtLine(LINE_A),
- stepOver,
- stepOver,
- stepOver,
+ stepOver, // At new Duration().
+ stepOver, // At new Future.delayed().
+ stepOver, // At async.
+ // Check that we are at the async statement
(Isolate isolate) async {
expect(M.isAtAsyncSuspension(isolate.pauseEvent), isTrue);
- expect(syntheticBreakpoint, isNull);
},
- testLowLevelAwaitOver,
- hasStoppedAtBreakpoint,
- stoppedAtLine(LINE_C),
- resumeIsolate,
- hasStoppedAtBreakpoint,
- stoppedAtLine(LINE_D),
+ asyncStepOver,
+ stoppedAtLine(LINE_B),
resumeIsolate,
];
diff --git a/runtime/vm/BUILD.gn b/runtime/vm/BUILD.gn
index 5f0a1ba..225afdf 100644
--- a/runtime/vm/BUILD.gn
+++ b/runtime/vm/BUILD.gn
@@ -25,7 +25,8 @@
static_library("libdart_platform") {
- configs += ["..:dart_config", "..:dart_product_config"]
+ configs += ["..:dart_config",
+ "..:dart_maybe_product_config"]
public_configs = [":libdart_vm_config"]
platform_headers_gypi =
@@ -59,7 +60,20 @@
static_library("libdart_vm") {
configs += ["..:dart_config",
- "..:dart_product_config",
+ "..:dart_maybe_product_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",
"..:dart_precompiled_runtime_config"]
public_configs = [":libdart_vm_config"]
set_sources_assignment_filter(["*_test.cc", "*_test.h"])
@@ -72,10 +86,24 @@
static_library("libdart_vm_nosnapshot") {
configs += ["..:dart_config",
- "..:dart_product_config",
- "..:dart_precompiled_runtime_config"]
+ "..:dart_maybe_product_config",
+ "..:dart_maybe_precompiled_runtime_config",
+ "..:dart_no_snapshot_config",]
public_configs = [":libdart_vm_config"]
- defines = [ "DART_NO_SNAPSHOT" ]
+ set_sources_assignment_filter(["*_test.cc", "*_test.h"])
+ sources = vm_sources_list.sources
+ include_dirs = [
+ "..",
+ ]
+}
+
+
+static_library("libdart_vm_nosnapshot_precompiled_runtime") {
+ configs += ["..:dart_config",
+ "..:dart_maybe_product_config",
+ "..:dart_precompiled_runtime_config",
+ "..:dart_no_snapshot_config",]
+ public_configs = [":libdart_vm_config"]
set_sources_assignment_filter(["*_test.cc", "*_test.h"])
sources = vm_sources_list.sources
include_dirs = [
@@ -86,10 +114,10 @@
static_library("libdart_vm_nosnapshot_with_precompiler") {
configs += ["..:dart_config",
- "..:dart_product_config",
- "..:dart_precompiler_config"]
+ "..:dart_maybe_product_config",
+ "..:dart_precompiler_config",
+ "..:dart_no_snapshot_config",]
public_configs = [":libdart_vm_config"]
- defines = [ "DART_NO_SNAPSHOT" ]
set_sources_assignment_filter(["*_test.cc", "*_test.h"])
sources = vm_sources_list.sources
include_dirs = [
@@ -190,7 +218,17 @@
static_library("libdart_lib_nosnapshot") {
configs += ["..:dart_config",
- "..:dart_product_config",
+ "..:dart_maybe_product_config",
+ "..:dart_maybe_precompiled_runtime_config"]
+ deps = libdeps
+ sources = libsources + ["bootstrap.cc"] + liboutputs
+ include_dirs = [
+ "..",
+ ]
+ }
+ static_library("libdart_lib_nosnapshot_precompiled_runtime") {
+ configs += ["..:dart_config",
+ "..:dart_maybe_product_config",
"..:dart_precompiled_runtime_config"]
deps = libdeps
sources = libsources + ["bootstrap.cc"] + liboutputs
@@ -200,7 +238,7 @@
}
static_library("libdart_lib_nosnapshot_with_precompiler") {
configs += ["..:dart_config",
- "..:dart_product_config",
+ "..:dart_maybe_product_config",
"..:dart_precompiler_config" ]
deps = libdeps
sources = libsources + [ "bootstrap.cc"] + liboutputs
@@ -210,7 +248,16 @@
}
static_library("libdart_lib") {
configs += ["..:dart_config",
- "..:dart_product_config",
+ "..:dart_maybe_product_config",
+ "..:dart_maybe_precompiled_runtime_config"]
+ sources = libsources + [ "bootstrap_nocore.cc"]
+ include_dirs = [
+ "..",
+ ]
+ }
+ static_library("libdart_lib_precompiled_runtime") {
+ configs += ["..:dart_config",
+ "..:dart_maybe_product_config",
"..:dart_precompiled_runtime_config"]
sources = libsources + [ "bootstrap_nocore.cc"]
include_dirs = [
diff --git a/runtime/vm/allocation.cc b/runtime/vm/allocation.cc
index b5f0f6c..6353cc8 100644
--- a/runtime/vm/allocation.cc
+++ b/runtime/vm/allocation.cc
@@ -26,7 +26,7 @@
void* ZoneAllocated::operator new(uword size, Zone* zone) {
- ASSERT(zone == Thread::Current()->zone());
+ ASSERT(Thread::Current()->ZoneIsOwnedByThread(zone));
return Allocate(size, zone);
}
diff --git a/runtime/vm/assembler_x64.cc b/runtime/vm/assembler_x64.cc
index 48e2613..213b8cb 100644
--- a/runtime/vm/assembler_x64.cc
+++ b/runtime/vm/assembler_x64.cc
@@ -3767,7 +3767,7 @@
static const char* cpu_reg_names[kNumberOfCpuRegisters] = {
"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi",
- "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15"
+ "r8", "r9", "r10", "r11", "r12", "r13", "thr", "pp"
};
diff --git a/runtime/vm/ast_printer.cc b/runtime/vm/ast_printer.cc
index eb5dd3b..6b47267 100644
--- a/runtime/vm/ast_printer.cc
+++ b/runtime/vm/ast_printer.cc
@@ -14,45 +14,47 @@
namespace dart {
-AstPrinter::AstPrinter() : indent_(0) { }
+AstPrinter::AstPrinter(bool log)
+ : indent_(0),
+ logger_(log ? Log::Current() : Log::NoOpLog()) { }
AstPrinter::~AstPrinter() { }
void AstPrinter::VisitGenericAstNode(AstNode* node) {
- THR_Print("(%s ", node->Name());
+ logger_->Print("(%s ", node->Name());
node->VisitChildren(this);
- THR_Print(")");
+ logger_->Print(")");
}
void AstPrinter::VisitSequenceNode(SequenceNode* node) {
indent_++;
LocalScope* scope = node->scope();
- THR_Print("(%s (scope \"%p\"", node->Name(), scope);
+ logger_->Print("(%s (scope \"%p\"", node->Name(), scope);
if (scope != NULL) {
- THR_Print(" (%s-%s) loop %d",
+ logger_->Print(" (%s-%s) loop %d",
scope->begin_token_pos().ToCString(),
scope->end_token_pos().ToCString(),
scope->loop_level());
if (scope->HasContextLevel()) {
- THR_Print(" context %d captures %d",
+ logger_->Print(" context %d captures %d",
scope->context_level(),
scope->num_context_variables());
} else {
ASSERT(scope->num_context_variables() == 0);
}
}
- THR_Print(")");
+ logger_->Print(")");
for (int i = 0; i < node->length(); ++i) {
- THR_Print("\n");
+ logger_->Print("\n");
for (intptr_t p = 0; p < indent_; p++) {
- THR_Print(" ");
+ logger_->Print(" ");
}
node->NodeAt(i)->Visit(this);
}
- THR_Print(")");
+ logger_->Print(")");
indent_--;
}
@@ -83,29 +85,31 @@
kind = "";
UNREACHABLE();
}
- THR_Print("(%s %s", node->Name(), kind);
+ logger_->Print("(%s %s", node->Name(), kind);
node->VisitChildren(this);
- THR_Print(")");
+ logger_->Print(")");
}
void AstPrinter::VisitGenericLocalNode(AstNode* node,
const LocalVariable& var) {
- THR_Print("(%s %s%s \"%s\"",
+ logger_->Print("(%s %s%s \"%s\"",
node->Name(),
var.is_final() ? "final " : "",
String::Handle(var.type().Name()).ToCString(),
var.name().ToCString());
if (var.HasIndex()) {
if (var.is_captured()) {
- THR_Print(" (context %d %d)", var.owner()->context_level(), var.index());
+ logger_->Print(" (context %d %d)",
+ var.owner()->context_level(),
+ var.index());
} else {
- THR_Print(" (stack %d)", var.index());
+ logger_->Print(" (stack %d)", var.index());
}
}
- THR_Print(" ");
+ logger_->Print(" ");
node->VisitChildren(this);
- THR_Print(")");
+ logger_->Print(")");
}
@@ -120,14 +124,14 @@
void AstPrinter::VisitGenericFieldNode(AstNode* node, const Field& field) {
- THR_Print("(%s %s%s \"%s\" ",
+ logger_->Print("(%s %s%s \"%s\" ",
node->Name(),
field.is_final() ? "final " : "",
String::Handle(AbstractType::Handle(field.type()).Name()).
ToCString(),
String::Handle(field.name()).ToCString());
node->VisitChildren(this);
- THR_Print(")");
+ logger_->Print(")");
}
@@ -168,13 +172,13 @@
void AstPrinter::VisitLiteralNode(LiteralNode* node) {
const Instance& literal = node->literal();
- THR_Print("(%s \"%s\")", node->Name(), literal.ToCString());
+ logger_->Print("(%s \"%s\")", node->Name(), literal.ToCString());
}
void AstPrinter::VisitTypeNode(TypeNode* node) {
const AbstractType& type = node->type();
- THR_Print("(%s \"%s\")",
+ logger_->Print("(%s \"%s\")",
node->Name(),
String::Handle(type.Name()).ToCString());
}
@@ -183,24 +187,24 @@
void AstPrinter::VisitAssignableNode(AssignableNode* node) {
const AbstractType& type = node->type();
const String& dst_name = node->dst_name();
- THR_Print("(%s (type \"%s\") (of \"%s\") ",
+ logger_->Print("(%s (type \"%s\") (of \"%s\") ",
node->Name(),
String::Handle(type.Name()).ToCString(),
dst_name.ToCString());
node->VisitChildren(this);
- THR_Print(")");
+ logger_->Print(")");
}
void AstPrinter::VisitAwaitNode(AwaitNode* node) {
- THR_Print("(*****%s***** (scope \"%p\") ", node->Name(), node->scope());
+ logger_->Print("(*****%s***** (scope \"%p\") ", node->Name(), node->scope());
node->VisitChildren(this);
- THR_Print(")");
+ logger_->Print(")");
}
void AstPrinter::VisitAwaitMarkerNode(AwaitMarkerNode* node) {
- THR_Print("(%s (async_scope \"%p\" await_scope \"%p\"))",
+ logger_->Print("(%s (async_scope \"%p\" await_scope \"%p\"))",
node->Name(),
node->async_scope(),
node->await_scope());
@@ -208,30 +212,30 @@
void AstPrinter::VisitPrimaryNode(PrimaryNode* node) {
- THR_Print("(*****%s***** \"%s\")",
+ logger_->Print("(*****%s***** \"%s\")",
node->Name(),
node->primary().ToCString());
}
void AstPrinter::VisitComparisonNode(ComparisonNode* node) {
- THR_Print("(%s %s ", node->Name(), node->TokenName());
+ logger_->Print("(%s %s ", node->Name(), node->TokenName());
node->VisitChildren(this);
- THR_Print(")");
+ logger_->Print(")");
}
void AstPrinter::VisitBinaryOpNode(BinaryOpNode* node) {
- THR_Print("(%s %s ", node->Name(), node->TokenName());
+ logger_->Print("(%s %s ", node->Name(), node->TokenName());
node->VisitChildren(this);
- THR_Print(")");
+ logger_->Print(")");
}
void AstPrinter::VisitUnaryOpNode(UnaryOpNode* node) {
- THR_Print("(%s %s ", node->Name(), node->TokenName());
+ logger_->Print("(%s %s ", node->Name(), node->TokenName());
node->VisitChildren(this);
- THR_Print(")");
+ logger_->Print(")");
}
@@ -246,16 +250,16 @@
void AstPrinter::VisitCaseNode(CaseNode* node) {
- THR_Print("(%s (", node->Name());
+ logger_->Print("(%s (", node->Name());
for (int i = 0; i < node->case_expressions()->length(); i++) {
node->case_expressions()->NodeAt(i)->Visit(this);
}
if (node->contains_default()) {
- THR_Print(" default");
+ logger_->Print(" default");
}
- THR_Print(")");
+ logger_->Print(")");
node->statements()->Visit(this);
- THR_Print(")");
+ logger_->Print(")");
}
@@ -272,17 +276,17 @@
void AstPrinter::VisitForNode(ForNode* node) {
// Complicated because the condition is optional and so we clearly want to
// indicate the subparts.
- THR_Print("(%s (init ", node->Name());
+ logger_->Print("(%s (init ", node->Name());
node->initializer()->Visit(this);
if (node->condition() != NULL) {
- THR_Print(") (cond ");
+ logger_->Print(") (cond ");
node->condition()->Visit(this);
}
- THR_Print(") (update ");
+ logger_->Print(") (update ");
node->increment()->Visit(this);
- THR_Print(") ");
+ logger_->Print(") ");
node->body()->Visit(this);
- THR_Print(")");
+ logger_->Print(")");
}
@@ -292,7 +296,7 @@
void AstPrinter::VisitJumpNode(JumpNode* node) {
- THR_Print("(%s %s %s (scope \"%p\"))",
+ logger_->Print("(%s %s %s (scope \"%p\"))",
node->Name(),
node->TokenName(),
node->label()->name().ToCString(),
@@ -301,25 +305,25 @@
void AstPrinter::VisitInstanceCallNode(InstanceCallNode* node) {
- THR_Print("(%s \"%s\" ",
+ logger_->Print("(%s \"%s\" ",
node->Name(),
node->function_name().ToCString());
node->VisitChildren(this);
- THR_Print(")");
+ logger_->Print(")");
}
void AstPrinter::VisitStaticCallNode(StaticCallNode* node) {
const char* function_fullname = node->function().ToFullyQualifiedCString();
- THR_Print("(%s \"%s\" ", node->Name(), function_fullname);
+ logger_->Print("(%s \"%s\" ", node->Name(), function_fullname);
node->VisitChildren(this);
- THR_Print(")");
+ logger_->Print(")");
}
void AstPrinter::VisitClosureNode(ClosureNode* node) {
const char* function_fullname = node->function().ToFullyQualifiedCString();
- THR_Print("(%s \"%s\")", node->Name(), function_fullname);
+ logger_->Print("(%s \"%s\")", node->Name(), function_fullname);
}
@@ -331,28 +335,28 @@
void AstPrinter::VisitConstructorCallNode(ConstructorCallNode* node) {
const char* kind = node->constructor().IsFactory() ? "factory " : "";
const char* constructor_name = node->constructor().ToFullyQualifiedCString();
- THR_Print("(%s %s \"%s\" ", node->Name(), kind, constructor_name);
+ logger_->Print("(%s %s \"%s\" ", node->Name(), kind, constructor_name);
node->VisitChildren(this);
- THR_Print(")");
+ logger_->Print(")");
}
void AstPrinter::VisitInstanceGetterNode(InstanceGetterNode* node) {
- THR_Print("(%s \"%s\" ", node->Name(), node->field_name().ToCString());
+ logger_->Print("(%s \"%s\" ", node->Name(), node->field_name().ToCString());
node->VisitChildren(this);
- THR_Print(")");
+ logger_->Print(")");
}
void AstPrinter::VisitInstanceSetterNode(InstanceSetterNode* node) {
- THR_Print("(%s \"%s\" ", node->Name(), node->field_name().ToCString());
+ logger_->Print("(%s \"%s\" ", node->Name(), node->field_name().ToCString());
node->VisitChildren(this);
- THR_Print(")");
+ logger_->Print(")");
}
void AstPrinter::VisitInitStaticFieldNode(InitStaticFieldNode* node) {
- THR_Print("(%s \"%s\")",
+ logger_->Print("(%s \"%s\")",
node->Name(),
String::Handle(node->field().name()).ToCString());
}
@@ -360,7 +364,7 @@
void AstPrinter::VisitStaticGetterNode(StaticGetterNode* node) {
String& class_name = String::Handle(node->cls().Name());
- THR_Print("(%s \"%s.%s\")",
+ logger_->Print("(%s \"%s.%s\")",
node->Name(),
class_name.ToCString(),
node->field_name().ToCString());
@@ -369,31 +373,31 @@
void AstPrinter::VisitStaticSetterNode(StaticSetterNode* node) {
String& class_name = String::Handle(node->cls().Name());
- THR_Print("(%s \"%s.%s\" ",
+ logger_->Print("(%s \"%s.%s\" ",
node->Name(),
class_name.ToCString(),
node->field_name().ToCString());
node->VisitChildren(this);
- THR_Print(")");
+ logger_->Print(")");
}
void AstPrinter::VisitLoadIndexedNode(LoadIndexedNode* node) {
- THR_Print("(%s%s ", node->Name(), node->IsSuperLoad() ? " super" : "");
+ logger_->Print("(%s%s ", node->Name(), node->IsSuperLoad() ? " super" : "");
node->VisitChildren(this);
- THR_Print(")");
+ logger_->Print(")");
}
void AstPrinter::VisitStoreIndexedNode(StoreIndexedNode* node) {
- THR_Print("(%s%s ", node->Name(), node->IsSuperStore() ? " super" : "");
+ logger_->Print("(%s%s ", node->Name(), node->IsSuperStore() ? " super" : "");
node->VisitChildren(this);
- THR_Print(")");
+ logger_->Print(")");
}
void AstPrinter::VisitNativeBodyNode(NativeBodyNode* node) {
- THR_Print("(%s \"%s\" (%" Pd " args))",
+ logger_->Print("(%s \"%s\" (%" Pd " args))",
node->Name(),
node->native_c_function_name().ToCString(),
NativeArguments::ParameterCountForResolution(node->function()));
@@ -406,15 +410,15 @@
void AstPrinter::VisitTryCatchNode(TryCatchNode* node) {
- THR_Print("(%s ", node->Name());
+ logger_->Print("(%s ", node->Name());
node->try_block()->Visit(this);
node->catch_block()->Visit(this);
if (node->finally_block() != NULL) {
- THR_Print("(finally ");
+ logger_->Print("(finally ");
node->finally_block()->Visit(this);
- THR_Print(")");
+ logger_->Print(")");
}
- THR_Print(")");
+ logger_->Print(")");
}
@@ -424,7 +428,7 @@
void AstPrinter::VisitStopNode(StopNode* node) {
- THR_Print("(%s %s)", node->Name(), node->message());
+ logger_->Print("(%s %s)", node->Name(), node->message());
}
@@ -437,13 +441,13 @@
ASSERT(node != NULL);
AstPrinter ast_printer;
node->Visit(&ast_printer);
- THR_Print("\n");
+ logger_->Print("\n");
}
-static void IndentN(int count) {
+void AstPrinter::IndentN(int count) {
for (int i = 0; i < count; i++) {
- THR_Print(" ");
+ logger_->Print(" ");
}
}
@@ -454,22 +458,22 @@
ASSERT(scope != NULL);
ASSERT(var != NULL);
IndentN(indent);
- THR_Print("(%s%s '%s'",
+ logger_->Print("(%s%s '%s'",
var->is_final() ? "final " : "",
String::Handle(var->type().Name()).ToCString(),
var->name().ToCString());
if (var->owner() != scope) {
- THR_Print(" alias");
+ logger_->Print(" alias");
}
if (var->HasIndex()) {
- THR_Print(" @%d", var->index());
+ logger_->Print(" @%d", var->index());
if (var->is_captured()) {
- THR_Print(" ctx %d", var->owner()->context_level());
+ logger_->Print(" ctx %d", var->owner()->context_level());
}
} else if (var->owner()->function_level() != 0) {
- THR_Print(" lev %d", var->owner()->function_level());
+ logger_->Print(" lev %d", var->owner()->function_level());
}
- THR_Print(" valid %s-%s)\n",
+ logger_->Print(" valid %s-%s)\n",
var->token_pos().ToCString(),
scope->end_token_pos().ToCString());
}
@@ -486,16 +490,16 @@
const LocalScope* child = scope->child();
while (child != NULL) {
IndentN(indent);
- THR_Print("{scope %p ", child);
+ logger_->Print("{scope %p ", child);
if (child->HasContextLevel()) {
- THR_Print("ctx %d numctxvar %d ",
+ logger_->Print("ctx %d numctxvar %d ",
child->context_level(),
child->num_context_variables());
}
- THR_Print("llev %d\n", child->loop_level());
+ logger_->Print("llev %d\n", child->loop_level());
PrintLocalScope(child, 0, indent + kScopeIndent);
IndentN(indent);
- THR_Print("}\n");
+ logger_->Print("}\n");
child = child->sibling();
}
}
@@ -509,13 +513,13 @@
const LocalScope* scope = node_sequence->scope();
ASSERT(scope != NULL);
const char* function_name = function.ToFullyQualifiedCString();
- THR_Print("Scope for function '%s'\n{scope %p ", function_name, scope);
+ logger_->Print("Scope for function '%s'\n{scope %p ", function_name, scope);
if (scope->HasContextLevel()) {
- THR_Print("ctx %d numctxvar %d ",
+ logger_->Print("ctx %d numctxvar %d ",
scope->context_level(),
scope->num_context_variables());
}
- THR_Print("llev %d\n", scope->loop_level());
+ logger_->Print("llev %d\n", scope->loop_level());
const int num_fixed_params = function.num_fixed_parameters();
const int num_params = num_fixed_params + function.NumOptionalParameters();
// Parameters must be listed first and must all appear in the top scope.
@@ -526,7 +530,7 @@
LocalVariable* param = scope->VariableAt(pos);
ASSERT(param->owner() == scope); // No aliases should precede parameters.
IndentN(indent);
- THR_Print("(param %s%s '%s'",
+ logger_->Print("(param %s%s '%s'",
param->is_final() ? "final " : "",
String::Handle(param->type().Name()).ToCString(),
param->name().ToCString());
@@ -534,22 +538,22 @@
if (pos >= num_fixed_params && pos < num_params) {
const Instance& default_parameter_value =
parsed_function.DefaultParameterValueAt(pos - num_fixed_params);
- THR_Print(" =%s", default_parameter_value.ToCString());
+ logger_->Print(" =%s", default_parameter_value.ToCString());
}
if (param->HasIndex()) {
- THR_Print(" @%d", param->index());
+ logger_->Print(" @%d", param->index());
if (param->is_captured()) {
- THR_Print(" ctx %d", param->owner()->context_level());
+ logger_->Print(" ctx %d", param->owner()->context_level());
}
}
- THR_Print(" valid %s-%s)\n",
+ logger_->Print(" valid %s-%s)\n",
param->token_pos().ToCString(),
scope->end_token_pos().ToCString());
pos++;
}
// Visit remaining non-parameter variables and children scopes.
PrintLocalScope(scope, pos, indent);
- THR_Print("}\n");
+ logger_->Print("}\n");
}
@@ -557,12 +561,11 @@
HANDLESCOPE(parsed_function.thread());
SequenceNode* node_sequence = parsed_function.node_sequence();
ASSERT(node_sequence != NULL);
- AstPrinter ast_printer;
const char* function_name =
parsed_function.function().ToFullyQualifiedCString();
- THR_Print("Ast for function '%s' {\n", function_name);
- node_sequence->Visit(&ast_printer);
- THR_Print("}\n");
+ logger_->Print("Ast for function '%s' {\n", function_name);
+ node_sequence->Visit(this);
+ logger_->Print("}\n");
}
} // namespace dart
diff --git a/runtime/vm/ast_printer.h b/runtime/vm/ast_printer.h
index 7c43ef6..b5ee0bd 100644
--- a/runtime/vm/ast_printer.h
+++ b/runtime/vm/ast_printer.h
@@ -12,12 +12,16 @@
// Forward declaration.
class ParsedFunction;
+class Log;
class AstPrinter : public AstNodeVisitor {
public:
- static void PrintNode(AstNode* node);
- static void PrintFunctionScope(const ParsedFunction& parsed_function);
- static void PrintFunctionNodes(const ParsedFunction& parsed_function);
+ explicit AstPrinter(bool log = true);
+ ~AstPrinter();
+
+ void PrintNode(AstNode* node);
+ void PrintFunctionScope(const ParsedFunction& parsed_function);
+ void PrintFunctionNodes(const ParsedFunction& parsed_function);
#define DECLARE_VISITOR_FUNCTION(BaseName) \
virtual void Visit##BaseName##Node(BaseName##Node* node);
@@ -26,23 +30,22 @@
#undef DECLARE_VISITOR_FUNCTION
private:
- AstPrinter();
- ~AstPrinter();
-
static const int kScopeIndent = 2;
- static void PrintLocalScopeVariable(const LocalScope* scope,
- LocalVariable* var,
- int indent = 0);
- static void PrintLocalScope(const LocalScope* scope,
- int variable_index,
- int indent = 0);
+ void IndentN(int count);
+ void PrintLocalScopeVariable(const LocalScope* scope,
+ LocalVariable* var,
+ int indent = 0);
+ void PrintLocalScope(const LocalScope* scope,
+ int variable_index,
+ int indent = 0);
void VisitGenericAstNode(AstNode* node);
void VisitGenericLocalNode(AstNode* node, const LocalVariable& local);
void VisitGenericFieldNode(AstNode* node, const Field& field);
intptr_t indent_;
+ Log* logger_;
DISALLOW_COPY_AND_ASSIGN(AstPrinter);
};
diff --git a/runtime/vm/ast_printer_test.cc b/runtime/vm/ast_printer_test.cc
index 5b774e8..888fdda 100644
--- a/runtime/vm/ast_printer_test.cc
+++ b/runtime/vm/ast_printer_test.cc
@@ -21,21 +21,22 @@
String::ZoneHandle(Symbols::New(thread, "wurscht")),
Type::ZoneHandle(Type::DynamicType()));
v->set_index(5);
+ AstPrinter ast_printer;
LoadLocalNode* ll = new LoadLocalNode(kPos, v);
ReturnNode* r = new ReturnNode(kPos, ll);
- AstPrinter::PrintNode(r);
+ ast_printer.PrintNode(r);
AstNode* l = new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(3)));
ReturnNode* rl = new ReturnNode(kPos, l);
- AstPrinter::PrintNode(rl);
+ ast_printer.PrintNode(rl);
- AstPrinter::PrintNode(new ReturnNode(kPos));
+ ast_printer.PrintNode(new ReturnNode(kPos));
- AstPrinter::PrintNode(new BinaryOpNode(kPos,
- Token::kADD,
- new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(3))),
- new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(5)))));
- AstPrinter::PrintNode(new UnaryOpNode(kPos, Token::kNEGATE, ll));
+ ast_printer.PrintNode(new BinaryOpNode(kPos,
+ Token::kADD,
+ new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(3))),
+ new LiteralNode(kPos, Smi::ZoneHandle(Smi::New(5)))));
+ ast_printer.PrintNode(new UnaryOpNode(kPos, Token::kNEGATE, ll));
}
#endif // !PRODUCT
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index 629f3b0..7fce179 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -2089,6 +2089,86 @@
#if !defined(DART_PRECOMPILED_RUNTIME)
+class UnlinkedCallSerializationCluster : public SerializationCluster {
+ public:
+ UnlinkedCallSerializationCluster() { }
+ virtual ~UnlinkedCallSerializationCluster() { }
+
+ void Trace(Serializer* s, RawObject* object) {
+ RawUnlinkedCall* unlinked = UnlinkedCall::RawCast(object);
+ objects_.Add(unlinked);
+
+ RawObject** from = unlinked->from();
+ RawObject** to = unlinked->to();
+ for (RawObject** p = from; p <= to; p++) {
+ s->Push(*p);
+ }
+ }
+
+ void WriteAlloc(Serializer* s) {
+ s->WriteCid(kUnlinkedCallCid);
+ intptr_t count = objects_.length();
+ s->Write<int32_t>(count);
+ for (intptr_t i = 0; i < count; i++) {
+ RawUnlinkedCall* unlinked = objects_[i];
+ s->AssignRef(unlinked);
+ }
+ }
+
+ void WriteFill(Serializer* s) {
+ intptr_t count = objects_.length();
+ for (intptr_t i = 0; i < count; i++) {
+ RawUnlinkedCall* unlinked = objects_[i];
+ RawObject** from = unlinked->from();
+ RawObject** to = unlinked->to();
+ for (RawObject** p = from; p <= to; p++) {
+ s->WriteRef(*p);
+ }
+ }
+ }
+
+ private:
+ GrowableArray<RawUnlinkedCall*> objects_;
+};
+#endif // !DART_PRECOMPILED_RUNTIME
+
+
+class UnlinkedCallDeserializationCluster : public DeserializationCluster {
+ public:
+ UnlinkedCallDeserializationCluster() { }
+ virtual ~UnlinkedCallDeserializationCluster() { }
+
+ 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,
+ UnlinkedCall::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++) {
+ RawUnlinkedCall* unlinked =
+ reinterpret_cast<RawUnlinkedCall*>(d->Ref(id));
+ Deserializer::InitializeHeader(unlinked, kUnlinkedCallCid,
+ UnlinkedCall::InstanceSize(),
+ is_vm_object);
+ RawObject** from = unlinked->from();
+ RawObject** to = unlinked->to();
+ for (RawObject** p = from; p <= to; p++) {
+ *p = d->ReadRef();
+ }
+ }
+ }
+};
+
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
class ICDataSerializationCluster : public SerializationCluster {
public:
ICDataSerializationCluster() { }
@@ -4271,6 +4351,7 @@
return new (Z) ExceptionHandlersSerializationCluster();
case kContextCid: return new (Z) ContextSerializationCluster();
case kContextScopeCid: return new (Z) ContextScopeSerializationCluster();
+ case kUnlinkedCallCid: return new (Z) UnlinkedCallSerializationCluster();
case kICDataCid: return new (Z) ICDataSerializationCluster();
case kMegamorphicCacheCid:
return new (Z) MegamorphicCacheSerializationCluster();
@@ -4436,7 +4517,7 @@
}
ClassTable* table = isolate()->class_table();
- for (intptr_t cid = kClassCid; cid <= kUnwindErrorCid; cid++) {
+ for (intptr_t cid = kClassCid; cid < kInstanceCid; cid++) {
// Error has no class object.
if (cid != kErrorCid) {
ASSERT(table->HasValidClassAt(cid));
@@ -4593,6 +4674,7 @@
return new (Z) ExceptionHandlersDeserializationCluster();
case kContextCid: return new (Z) ContextDeserializationCluster();
case kContextScopeCid: return new (Z) ContextScopeDeserializationCluster();
+ case kUnlinkedCallCid: return new (Z) UnlinkedCallDeserializationCluster();
case kICDataCid: return new (Z) ICDataDeserializationCluster();
case kMegamorphicCacheCid:
return new (Z) MegamorphicCacheDeserializationCluster();
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index 51e70e8..ee94ebf 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -1106,16 +1106,21 @@
}
if (old_target.raw() == target_function.raw()) {
- intptr_t lower, upper;
+ intptr_t lower, upper, unchecked_lower, unchecked_upper;
if (receiver.GetClassId() < cache.lower_limit()) {
lower = receiver.GetClassId();
+ unchecked_lower = receiver.GetClassId();
upper = cache.upper_limit();
+ unchecked_upper = cache.lower_limit() - 1;
} else {
lower = cache.lower_limit();
+ unchecked_lower = cache.upper_limit() + 1;
upper = receiver.GetClassId();
+ unchecked_upper = receiver.GetClassId();
}
- if (IsSingleTarget(isolate, zone, lower, upper, target_function, name)) {
+ if (IsSingleTarget(isolate, zone, unchecked_lower, unchecked_upper,
+ target_function, name)) {
cache.set_lower_limit(lower);
cache.set_upper_limit(upper);
// Return the ICData. The single target stub will jump to continue in the
@@ -1141,6 +1146,81 @@
}
+DEFINE_RUNTIME_ENTRY(UnlinkedCall, 2) {
+#if defined(TARGET_ARCH_DBC)
+ // DBC does not use switchable calls.
+ UNREACHABLE();
+#else
+ const Instance& receiver = Instance::CheckedHandle(zone, arguments.ArgAt(0));
+ const UnlinkedCall& unlinked =
+ UnlinkedCall::CheckedHandle(zone, arguments.ArgAt(1));
+
+ DartFrameIterator iterator;
+ StackFrame* caller_frame = iterator.NextFrame();
+ ASSERT(caller_frame->IsDartFrame());
+ const Code& caller_code =
+ Code::Handle(zone, caller_frame->LookupDartCode());
+ const Function& caller_function =
+ Function::Handle(zone, caller_frame->LookupDartFunction());
+
+ const String& name = String::Handle(zone, unlinked.target_name());
+ const Array& descriptor = Array::Handle(zone, unlinked.args_descriptor());
+ const ICData& ic_data =
+ ICData::Handle(zone, ICData::New(caller_function,
+ name,
+ descriptor,
+ Thread::kNoDeoptId,
+ 1, /* args_tested */
+ false /* static_call */));
+
+ Class& cls = Class::Handle(zone, receiver.clazz());
+ ArgumentsDescriptor args_desc(descriptor);
+ Function& target_function = Function::Handle(zone,
+ Resolver::ResolveDynamicForReceiverClass(cls,
+ name,
+ args_desc));
+ if (target_function.IsNull()) {
+ target_function = InlineCacheMissHelper(receiver, descriptor, name);
+ }
+ if (target_function.IsNull()) {
+ ASSERT(!FLAG_lazy_dispatchers);
+ } else {
+ ic_data.AddReceiverCheck(receiver.GetClassId(), target_function);
+ }
+
+ if (!target_function.IsNull() &&
+ !target_function.HasOptionalParameters()) {
+ // Patch to monomorphic call.
+ ASSERT(target_function.HasCode());
+ const Code& target_code =
+ Code::Handle(zone, target_function.CurrentCode());
+ const Smi& expected_cid =
+ Smi::Handle(zone, Smi::New(receiver.GetClassId()));
+ CodePatcher::PatchSwitchableCallAt(caller_frame->pc(), caller_code,
+ expected_cid, target_code);
+
+ // Return the ICData. The miss stub will jump to continue in the IC call
+ // stub.
+ arguments.SetReturn(ic_data);
+ return;
+ }
+
+ // Patch to call through stub.
+ const Code& stub =
+ Code::Handle(zone, StubCode::ICCallThroughCode_entry()->code());
+ ASSERT(!Isolate::Current()->compilation_allowed());
+ CodePatcher::PatchSwitchableCallAt(caller_frame->pc(),
+ caller_code,
+ ic_data,
+ stub);
+
+ // Return the ICData. The miss stub will jump to continue in the IC lookup
+ // stub.
+ arguments.SetReturn(ic_data);
+#endif // !DBC
+}
+
+
// Handle a miss of a megamorphic cache.
// Arg0: Receiver.
// Returns: the ICData used to continue with a polymorphic call.
@@ -1949,11 +2029,23 @@
{
WritableInstructionsScope writable(instrs.PayloadStart(), instrs.size());
CodePatcher::InsertDeoptimizationCallAt(pc, lazy_deopt_jump);
- }
- if (FLAG_trace_patching) {
- const String& name = String::Handle(function.name());
- OS::PrintErr("InsertDeoptimizationCallAt: %" Px " to %" Px " for %s\n", pc,
- lazy_deopt_jump, name.ToCString());
+ 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, name.ToCString());
+ }
+ const ExceptionHandlers& handlers =
+ ExceptionHandlers::Handle(zone, optimized_code.exception_handlers());
+ RawExceptionHandlers::HandlerInfo info;
+ 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);
+ if (FLAG_trace_patching) {
+ OS::PrintErr(" at handler 0x%" Px "\n", patch_pc);
+ }
+ }
}
// Mark code as dead (do not GC its embedded objects).
optimized_code.set_is_alive(false);
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index 93898ad..25fad98 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -1316,9 +1316,12 @@
// We got an error during compilation.
error = thread->sticky_error();
thread->clear_sticky_error();
- // The non-optimizing compiler should not bail out.
- ASSERT(error.IsLanguageError() &&
- LanguageError::Cast(error).kind() != Report::kBailout);
+ // The non-optimizing compiler can get an unhandled exception
+ // due to OOM or Stack overflow errors, it should not however
+ // bail out.
+ ASSERT(error.IsUnhandledException() ||
+ (error.IsLanguageError() &&
+ LanguageError::Cast(error).kind() != Report::kBailout));
return error.raw();
}
}
@@ -1339,11 +1342,13 @@
if (FLAG_disassemble && FlowGraphPrinter::ShouldPrint(function)) {
SafepointOperationScope safepoint_scope(thread);
+ NoHeapGrowthControlScope no_growth_control;
Disassembler::DisassembleCode(function, optimized);
} else if (FLAG_disassemble_optimized &&
optimized &&
FlowGraphPrinter::ShouldPrint(function)) {
SafepointOperationScope safepoint_scope(thread);
+ NoHeapGrowthControlScope no_growth_control;
Disassembler::DisassembleCode(function, true);
}
@@ -1374,6 +1379,65 @@
}
+static RawError* ParseFunctionHelper(CompilationPipeline* pipeline,
+ const Function& function,
+ bool optimized,
+ intptr_t osr_id) {
+ ASSERT(!FLAG_precompiled_mode);
+ ASSERT(!optimized || function.was_compiled());
+ LongJumpScope jump;
+ if (setjmp(*jump.Set()) == 0) {
+ Thread* const thread = Thread::Current();
+ StackZone stack_zone(thread);
+ Zone* const zone = stack_zone.GetZone();
+ const bool trace_compiler =
+ FLAG_trace_compiler ||
+ (FLAG_trace_optimizing_compiler && optimized);
+
+ if (trace_compiler) {
+ const intptr_t token_size = function.end_token_pos().Pos() -
+ function.token_pos().Pos();
+ THR_Print("Parsing %s%sfunction %s: '%s' @ token %s, size %" Pd "\n",
+ (osr_id == Compiler::kNoOSRDeoptId ? "" : "osr "),
+ (optimized ? "optimized " : ""),
+ (Compiler::IsBackgroundCompilation() ? "(background)" : ""),
+ function.ToFullyQualifiedCString(),
+ function.token_pos().ToCString(),
+ token_size);
+ }
+ ParsedFunction* parsed_function = new(zone) ParsedFunction(
+ thread, Function::ZoneHandle(zone, function.raw()));
+ pipeline->ParseFunction(parsed_function);
+ // For now we just walk thru the AST nodes and in DEBUG mode we print
+ // them otherwise just skip through them, this will be need to be
+ // wired to generate the IR format.
+#if !defined(PRODUCT)
+#if defined(DEBUG)
+ AstPrinter ast_printer(true);
+#else
+ AstPrinter ast_printer(false);
+#endif // defined(DEBUG).
+ ast_printer.PrintFunctionNodes(*parsed_function);
+#endif // !defined(PRODUCT).
+ return Error::null();
+ } else {
+ Thread* const thread = Thread::Current();
+ StackZone stack_zone(thread);
+ Error& error = Error::Handle();
+ // We got an error during compilation or it is a bailout from background
+ // compilation (e.g., during parsing with EnsureIsFinalized).
+ error = thread->sticky_error();
+ thread->clear_sticky_error();
+ // Unoptimized compilation or precompilation may encounter compile-time
+ // errors, but regular optimized compilation should not.
+ ASSERT(!optimized);
+ return error.raw();
+ }
+ UNREACHABLE();
+ return Error::null();
+}
+
+
RawError* Compiler::CompileFunction(Thread* thread,
const Function& function) {
#ifdef DART_PRECOMPILER
@@ -1404,6 +1468,31 @@
}
+RawError* Compiler::ParseFunction(Thread* thread,
+ const Function& function) {
+ Isolate* isolate = thread->isolate();
+NOT_IN_PRODUCT(
+ VMTagScope tagScope(thread, VMTag::kCompileUnoptimizedTagId);
+ TIMELINE_FUNCTION_COMPILATION_DURATION(thread, "ParseFunction", function);
+) // !PRODUCT
+
+ if (!isolate->compilation_allowed()) {
+ FATAL3("Precompilation missed function %s (%s, %s)\n",
+ function.ToLibNamePrefixedQualifiedCString(),
+ function.token_pos().ToCString(),
+ Function::KindToCString(function.kind()));
+ }
+
+ CompilationPipeline* pipeline =
+ CompilationPipeline::New(thread->zone(), function);
+
+ return ParseFunctionHelper(pipeline,
+ function,
+ /* optimized = */ false,
+ kNoOSRDeoptId);
+}
+
+
RawError* Compiler::EnsureUnoptimizedCode(Thread* thread,
const Function& function) {
if (function.unoptimized_code() != Object::null()) {
@@ -1555,6 +1644,40 @@
}
+RawError* Compiler::ParseAllFunctions(const Class& cls) {
+ Thread* thread = Thread::Current();
+ Zone* zone = thread->zone();
+ Error& error = Error::Handle(zone);
+ Array& functions = Array::Handle(zone, cls.functions());
+ Function& func = Function::Handle(zone);
+ // Class dynamic lives in the vm isolate. Its array fields cannot be set to
+ // an empty array.
+ if (functions.IsNull()) {
+ ASSERT(cls.IsDynamicClass());
+ return error.raw();
+ }
+ // Compile all the regular functions.
+ for (int i = 0; i < functions.Length(); i++) {
+ func ^= functions.At(i);
+ ASSERT(!func.IsNull());
+ if (!func.is_abstract() && !func.IsRedirectingFactory()) {
+ if ((cls.is_mixin_app_alias() || cls.IsMixinApplication()) &&
+ func.HasOptionalParameters()) {
+ // Skipping optional parameters in mixin application.
+ continue;
+ }
+ error = ParseFunction(thread, func);
+ if (!error.IsNull()) {
+ return error.raw();
+ }
+ func.ClearICDataArray();
+ func.ClearCode();
+ }
+ }
+ return error.raw();
+}
+
+
RawObject* Compiler::EvaluateStaticInitializer(const Field& field) {
#ifdef DART_PRECOMPILER
if (FLAG_precompiled_mode) {
@@ -1633,7 +1756,8 @@
if (FLAG_trace_compiler) {
THR_Print("compiling expression: ");
if (FLAG_support_ast_printer) {
- AstPrinter::PrintNode(fragment);
+ AstPrinter ast_printer;
+ ast_printer.PrintNode(fragment);
}
}
@@ -2091,6 +2215,13 @@
}
+RawError* Compiler::ParseFunction(Thread* thread,
+ const Function& function) {
+ UNREACHABLE();
+ return Error::null();
+}
+
+
RawError* Compiler::EnsureUnoptimizedCode(Thread* thread,
const Function& function) {
UNREACHABLE();
@@ -2124,6 +2255,12 @@
}
+RawError* Compiler::ParseAllFunctions(const Class& cls) {
+ UNREACHABLE();
+ return Error::null();
+}
+
+
RawObject* Compiler::EvaluateStaticInitializer(const Field& field) {
ASSERT(field.HasPrecompiledInitializer());
const Function& initializer =
diff --git a/runtime/vm/compiler.h b/runtime/vm/compiler.h
index 1e8e3fc..4ec478f 100644
--- a/runtime/vm/compiler.h
+++ b/runtime/vm/compiler.h
@@ -100,6 +100,7 @@
//
// Returns Error::null() if there is no compilation error.
static RawError* CompileFunction(Thread* thread, const Function& function);
+ static RawError* ParseFunction(Thread* thread, const Function& function);
// Generates unoptimized code if not present, current code is unchanged.
static RawError* EnsureUnoptimizedCode(Thread* thread,
@@ -143,6 +144,7 @@
//
// Returns Error::null() if there is no compilation error.
static RawError* CompileAllFunctions(const Class& cls);
+ static RawError* ParseAllFunctions(const Class& cls);
// Notify the compiler that background (optimized) compilation has failed
// because the mutator thread changed the state (e.g., deoptimization,
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index d5d7998..c1a2f36 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -50,7 +50,7 @@
namespace dart {
-// Facilitate quick access to the current zone once we have the curren thread.
+// Facilitate quick access to the current zone once we have the current thread.
#define Z (T->zone())
@@ -1486,7 +1486,8 @@
DART_EXPORT bool Dart_HasStickyError() {
- Isolate* isolate = Isolate::Current();
+ Thread* T = Thread::Current();
+ Isolate* isolate = T->isolate();
CHECK_ISOLATE(isolate);
NoSafepointScope no_safepoint_scope;
return isolate->sticky_error() != Error::null();
@@ -1494,12 +1495,13 @@
DART_EXPORT Dart_Handle Dart_GetStickyError() {
- Isolate* I = Isolate::Current();
+ Thread* T = Thread::Current();
+ Isolate* I = T->isolate();
CHECK_ISOLATE(I);
NoSafepointScope no_safepoint_scope;
- if (I->sticky_error() != Object::null()) {
+ if (I->sticky_error() != Error::null()) {
Dart_Handle error =
- Api::NewHandle(Thread::Current(), I->sticky_error());
+ Api::NewHandle(T, I->sticky_error());
return error;
}
return Dart_Null();
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index a4afc16..51c6721 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -371,10 +371,16 @@
Breakpoint* BreakpointLocation::AddPerClosure(Debugger* dbg,
const Instance& closure,
bool for_over_await) {
- Breakpoint* bpt = breakpoints();
- while (bpt != NULL) {
- if (bpt->IsPerClosure() && bpt->closure() == closure.raw()) break;
- bpt = bpt->next();
+ Breakpoint* bpt = NULL;
+ // Do not reuse existing breakpoints for stepping over await clauses.
+ // A second async step-over command will set a new breakpoint before
+ // the existing one gets deleted when first async step-over resumes.
+ if (!for_over_await) {
+ bpt = breakpoints();
+ while (bpt != NULL) {
+ if (bpt->IsPerClosure() && (bpt->closure() == closure.raw())) break;
+ bpt = bpt->next();
+ }
}
if (bpt == NULL) {
bpt = new Breakpoint(dbg->nextId(), this);
@@ -2607,9 +2613,6 @@
if (!func.is_debuggable()) {
return false;
}
- if (ServiceIsolate::IsRunning()) {
- return true;
- }
const Class& cls = Class::Handle(func.Owner());
const Library& lib = Library::Handle(cls.library());
return lib.IsDebuggable();
@@ -2678,7 +2681,7 @@
// There is an "interesting frame" set. Only pause at appropriate
// locations in this frame.
if (IsCalleeFrameOf(stepping_fp_, frame->fp())) {
- // We are i n a callee of the frame we're interested in.
+ // We are in a callee of the frame we're interested in.
// Ignore this stepping break.
return Error::null();
} else if (IsCalleeFrameOf(frame->fp(), stepping_fp_)) {
@@ -2857,10 +2860,6 @@
return;
}
- if (!NeedsDebugEvents()) {
- OS::Print("Hit debugger!");
- }
-
DebuggerStackTrace* stack_trace = CollectStackTrace();
ASSERT(stack_trace->Length() > 0);
ASSERT(stack_trace_ == NULL);
diff --git a/runtime/vm/debugger_api_impl_test.cc b/runtime/vm/debugger_api_impl_test.cc
index 80311f1..a41d10b 100644
--- a/runtime/vm/debugger_api_impl_test.cc
+++ b/runtime/vm/debugger_api_impl_test.cc
@@ -38,6 +38,29 @@
}
+static void DisableDebuggabilityOfDartColonLibraries() {
+ const char* dart_colon = "dart:";
+ const intptr_t dart_colon_length = strlen(dart_colon);
+ // Disable debuggability of all dart: libraries.
+ Dart_Handle library_ids = Dart_GetLibraryIds();
+ intptr_t library_ids_length;
+ Dart_ListLength(library_ids, &library_ids_length);
+ for (intptr_t i = 0; i < library_ids_length; i++) {
+ Dart_Handle library_id_handle = Dart_ListGetAt(library_ids, i);
+ int64_t library_id;
+ Dart_IntegerToInt64(library_id_handle, &library_id);
+ Dart_Handle library_url_handle = Dart_GetLibraryURL(library_id);
+ const char* library_url;
+ Dart_StringToCString(library_url_handle, &library_url);
+ if (strncmp(library_url, dart_colon, dart_colon_length) == 0) {
+ Dart_SetLibraryDebuggable(library_id, false);
+ } else {
+ Dart_SetLibraryDebuggable(library_id, true);
+ }
+ }
+}
+
+
static Dart_Handle Invoke(const char* func_name) {
ASSERT(script_lib != NULL);
ASSERT(!Dart_IsError(script_lib));
@@ -741,6 +764,8 @@
LoadScript(kScriptChars);
Dart_SetPausedEventHandler(&TestStepIntoHandler);
+ DisableDebuggabilityOfDartColonLibraries();
+
SetBreakpointAtEntry("", "main");
breakpoint_hit = false;
breakpoint_hit_counter = 0;
diff --git a/runtime/vm/disassembler_arm.cc b/runtime/vm/disassembler_arm.cc
index 67c0afb..6419c08 100644
--- a/runtime/vm/disassembler_arm.cc
+++ b/runtime/vm/disassembler_arm.cc
@@ -116,10 +116,10 @@
static const char* reg_names[kNumberOfCpuRegisters] = {
#if defined(TARGET_ABI_IOS)
"r0", "r1", "r2", "r3", "r4", "pp", "r6", "fp",
- "r8", "r9", "r10", "r11", "ip", "sp", "lr", "pc",
+ "r8", "r9", "thr", "r11", "ip", "sp", "lr", "pc",
#elif defined(TARGET_ABI_EABI)
"r0", "r1", "r2", "r3", "r4", "pp", "r6", "r7",
- "r8", "r9", "r10", "fp", "ip", "sp", "lr", "pc",
+ "r8", "r9", "thr", "fp", "ip", "sp", "lr", "pc",
#else
#error Unknown ABI
#endif
diff --git a/runtime/vm/disassembler_arm64.cc b/runtime/vm/disassembler_arm64.cc
index dd7d00c..6bbc3c7 100644
--- a/runtime/vm/disassembler_arm64.cc
+++ b/runtime/vm/disassembler_arm64.cc
@@ -92,7 +92,7 @@
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
"ip0", "ip1", "r18", "sp", "r20", "r21", "r22", "r23",
- "r24", "r25", "r26", "pp", "ctx", "fp", "lr", "r31",
+ "r24", "r25", "thr", "pp", "ctx", "fp", "lr", "r31",
};
diff --git a/runtime/vm/disassembler_mips.cc b/runtime/vm/disassembler_mips.cc
index 78831a7..49fbb33 100644
--- a/runtime/vm/disassembler_mips.cc
+++ b/runtime/vm/disassembler_mips.cc
@@ -79,10 +79,10 @@
static const char* reg_names[kNumberOfCpuRegisters] = {
- "r0" , "r1" , "r2" , "r3" , "r4" , "r5" , "r6" , "r7" ,
- "r8" , "r9" , "r10", "r11", "r12", "r13", "r14", "r15",
- "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
- "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31",
+ "zr", "at", "v0", "v1" , "a0", "a1", "a2", "a3",
+ "t0", "t1", "t2", "t3" , "t4", "t5", "t6", "t7",
+ "s0", "s1", "s2", "thr", "s4", "s5", "s6", "pp",
+ "t8", "t9", "k0", "k1" , "gp", "sp", "fp", "ra",
};
diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc
index edfad99..7c9d71d 100644
--- a/runtime/vm/exceptions.cc
+++ b/runtime/vm/exceptions.cc
@@ -330,7 +330,6 @@
&handler_needs_stacktrace);
if (handler_pc == 0) {
// No Dart frame.
- ASSERT(!thread->IsMutatorThread());
ASSERT(incoming_exception.raw() ==
isolate->object_store()->out_of_memory());
const UnhandledException& error = UnhandledException::Handle(
diff --git a/runtime/vm/flow_graph.cc b/runtime/vm/flow_graph.cc
index 89ed20d..f513b30 100644
--- a/runtime/vm/flow_graph.cc
+++ b/runtime/vm/flow_graph.cc
@@ -2009,7 +2009,9 @@
!block_it.Done();
block_it.Advance()) {
BlockEntryInstr* block = block_it.Current();
- block->RemoveEnvironment();
+ if (!block->IsCatchBlockEntry()) {
+ block->RemoveEnvironment();
+ }
for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
Instruction* current = it.Current();
if (!current->CanDeoptimize()) {
diff --git a/runtime/vm/flow_graph_allocator.cc b/runtime/vm/flow_graph_allocator.cc
index 558e6f7..7b62e37 100644
--- a/runtime/vm/flow_graph_allocator.cc
+++ b/runtime/vm/flow_graph_allocator.cc
@@ -616,6 +616,9 @@
// TODO(vegorov) support try-catch/finally for DBC.
flow_graph_.parsed_function().Bailout("FlowGraphAllocator", "Catch");
#endif
+
+ ProcessEnvironmentUses(catch_entry, catch_entry); // For lazy deopt
+
for (intptr_t i = 0;
i < catch_entry->initial_definitions()->length();
i++) {
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index 7a01480..ffdf3de 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -3586,10 +3586,14 @@
// call. Exception: don't do this when assigning to or from internal
// variables, or for generated code that has no source position.
if (FLAG_support_debugger) {
- if ((node->value()->IsLiteralNode() ||
- (node->value()->IsLoadLocalNode() &&
- !node->value()->AsLoadLocalNode()->local().IsInternal()) ||
- node->value()->IsClosureNode()) &&
+ AstNode* rhs = node->value();
+ if (rhs->IsAssignableNode()) {
+ rhs = rhs->AsAssignableNode()->expr();
+ }
+ if ((rhs->IsLiteralNode() ||
+ (rhs->IsLoadLocalNode() &&
+ !rhs->AsLoadLocalNode()->local().IsInternal()) ||
+ rhs->IsClosureNode()) &&
!node->local().IsInternal() &&
node->token_pos().IsDebugPause()) {
AddInstruction(new(Z) DebugStepCheckInstr(
@@ -3704,6 +3708,23 @@
StoreStaticFieldNode* node,
bool result_is_needed,
TokenPosition token_pos) {
+ if (FLAG_support_debugger) {
+ // If the right hand side is an expression that does not contain
+ // a safe point for the debugger to stop, add an explicit stub
+ // call.
+ AstNode* rhs = node->value();
+ if (rhs->IsAssignableNode()) {
+ rhs = rhs->AsAssignableNode()->expr();
+ }
+ if ((rhs->IsLiteralNode() ||
+ rhs->IsLoadLocalNode() ||
+ rhs->IsClosureNode()) &&
+ node->token_pos().IsDebugPause()) {
+ AddInstruction(new(Z) DebugStepCheckInstr(
+ node->token_pos(), RawPcDescriptors::kRuntimeCall));
+ }
+ }
+
ValueGraphVisitor for_value(owner());
node->value()->Visit(&for_value);
Append(for_value);
@@ -4300,7 +4321,8 @@
try_handler_index,
catch_block->exception_var(),
catch_block->stacktrace_var(),
- catch_block->needs_stacktrace());
+ catch_block->needs_stacktrace(),
+ Thread::Current()->GetNextDeoptId());
owner()->AddCatchEntry(catch_entry);
AppendFragment(catch_entry, for_catch);
@@ -4346,7 +4368,8 @@
catch_handler_index,
catch_block->exception_var(),
catch_block->stacktrace_var(),
- catch_block->needs_stacktrace());
+ catch_block->needs_stacktrace(),
+ Thread::Current()->GetNextDeoptId());
owner()->AddCatchEntry(finally_entry);
AppendFragment(finally_entry, for_finally);
}
@@ -4577,10 +4600,12 @@
FLAG_profile_vm);
if (FLAG_support_ast_printer && FLAG_print_ast) {
// Print the function ast before IL generation.
- AstPrinter::PrintFunctionNodes(parsed_function());
+ AstPrinter ast_printer;
+ ast_printer.PrintFunctionNodes(parsed_function());
}
if (FLAG_support_ast_printer && FLAG_print_scopes) {
- AstPrinter::PrintFunctionScope(parsed_function());
+ AstPrinter ast_printer;
+ ast_printer.PrintFunctionScope(parsed_function());
}
TargetEntryInstr* normal_entry =
new(Z) TargetEntryInstr(AllocateBlockId(),
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index e668652..4e0d2c7 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -536,7 +536,10 @@
entry->set_offset(assembler()->CodeSize());
BeginCodeSourceRange();
+ ASSERT(pending_deoptimization_env_ == NULL);
+ pending_deoptimization_env_ = entry->env();
entry->EmitNativeCode(this);
+ pending_deoptimization_env_ = NULL;
EndCodeSourceRange(entry->token_pos());
// Compile all successors until an exit, branch, or a block entry.
for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
@@ -805,8 +808,7 @@
}
-void FlowGraphCompiler::AddDeoptIndexAtCall(intptr_t deopt_id,
- TokenPosition token_pos) {
+void FlowGraphCompiler::AddDeoptIndexAtCall(intptr_t deopt_id) {
ASSERT(is_optimizing());
ASSERT(!intrinsic_mode());
CompilerDeoptInfo* info =
diff --git a/runtime/vm/flow_graph_compiler.h b/runtime/vm/flow_graph_compiler.h
index d6c74cb..31a627a 100644
--- a/runtime/vm/flow_graph_compiler.h
+++ b/runtime/vm/flow_graph_compiler.h
@@ -536,7 +536,7 @@
uint16_t ToEmbeddableCid(intptr_t cid, Instruction* instruction);
#endif // defined(TARGET_ARCH_DBC)
- void AddDeoptIndexAtCall(intptr_t deopt_id, TokenPosition token_pos);
+ void AddDeoptIndexAtCall(intptr_t deopt_id);
void AddSlowPathCode(SlowPathCode* slow_path);
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index dadc66a..38db33b 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -1163,7 +1163,7 @@
// deoptimization point in optimized code, after call.
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
if (is_optimizing()) {
- AddDeoptIndexAtCall(deopt_id_after, token_pos);
+ AddDeoptIndexAtCall(deopt_id_after);
} else {
// Add deoptimization continuation point after the call and before the
// arguments are removed.
@@ -1191,7 +1191,7 @@
// deoptimization point in optimized code, after call.
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
if (is_optimizing()) {
- AddDeoptIndexAtCall(deopt_id_after, token_pos);
+ AddDeoptIndexAtCall(deopt_id_after);
} else {
// Add deoptimization continuation point after the call and before the
// arguments are removed.
@@ -1215,7 +1215,7 @@
// deoptimization point in optimized code, after call.
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
if (is_optimizing()) {
- AddDeoptIndexAtCall(deopt_id_after, token_pos);
+ AddDeoptIndexAtCall(deopt_id_after);
} else {
// Add deoptimization continuation point after the call and before the
// arguments are removed.
@@ -1354,7 +1354,7 @@
} else if (is_optimizing()) {
AddCurrentDescriptor(RawPcDescriptors::kOther,
Thread::kNoDeoptId, token_pos);
- AddDeoptIndexAtCall(deopt_id_after, token_pos);
+ AddDeoptIndexAtCall(deopt_id_after);
} else {
AddCurrentDescriptor(RawPcDescriptors::kOther,
Thread::kNoDeoptId, token_pos);
@@ -1389,7 +1389,7 @@
RecordSafepoint(locs);
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
if (is_optimizing()) {
- AddDeoptIndexAtCall(deopt_id_after, token_pos);
+ AddDeoptIndexAtCall(deopt_id_after);
} else {
// Add deoptimization continuation point after the call and before the
// arguments are removed.
diff --git a/runtime/vm/flow_graph_compiler_arm64.cc b/runtime/vm/flow_graph_compiler_arm64.cc
index 304dcb3..2634ae2b 100644
--- a/runtime/vm/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/flow_graph_compiler_arm64.cc
@@ -1157,7 +1157,7 @@
// deoptimization point in optimized code, after call.
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
if (is_optimizing()) {
- AddDeoptIndexAtCall(deopt_id_after, token_pos);
+ AddDeoptIndexAtCall(deopt_id_after);
} else {
// Add deoptimization continuation point after the call and before the
// arguments are removed.
@@ -1184,7 +1184,7 @@
// deoptimization point in optimized code, after call.
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
if (is_optimizing()) {
- AddDeoptIndexAtCall(deopt_id_after, token_pos);
+ AddDeoptIndexAtCall(deopt_id_after);
} else {
// Add deoptimization continuation point after the call and before the
// arguments are removed.
@@ -1207,7 +1207,7 @@
// deoptimization point in optimized code, after call.
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
if (is_optimizing()) {
- AddDeoptIndexAtCall(deopt_id_after, token_pos);
+ AddDeoptIndexAtCall(deopt_id_after);
} else {
// Add deoptimization continuation point after the call and before the
// arguments are removed.
@@ -1336,7 +1336,7 @@
} else if (is_optimizing()) {
AddCurrentDescriptor(RawPcDescriptors::kOther,
Thread::kNoDeoptId, token_pos);
- AddDeoptIndexAtCall(deopt_id_after, token_pos);
+ AddDeoptIndexAtCall(deopt_id_after);
} else {
AddCurrentDescriptor(RawPcDescriptors::kOther,
Thread::kNoDeoptId, token_pos);
@@ -1370,7 +1370,7 @@
RecordSafepoint(locs);
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
if (is_optimizing()) {
- AddDeoptIndexAtCall(deopt_id_after, token_pos);
+ AddDeoptIndexAtCall(deopt_id_after);
} else {
// Add deoptimization continuation point after the call and before the
// arguments are removed.
diff --git a/runtime/vm/flow_graph_compiler_dbc.cc b/runtime/vm/flow_graph_compiler_dbc.cc
index fc1534d..69dd8ad 100644
--- a/runtime/vm/flow_graph_compiler_dbc.cc
+++ b/runtime/vm/flow_graph_compiler_dbc.cc
@@ -198,7 +198,7 @@
// On all other architectures caller drops outgoing arguments itself
// hence the difference.
pending_deoptimization_env_->DropArguments(instr->ArgumentCount());
- AddDeoptIndexAtCall(deopt_id_after, instr->token_pos());
+ AddDeoptIndexAtCall(deopt_id_after);
} else {
// Add deoptimization continuation point after the call and before the
// arguments are removed.
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index 461785a..90ec1f2 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -1170,7 +1170,7 @@
// deoptimization point in optimized code, after call.
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
if (is_optimizing()) {
- AddDeoptIndexAtCall(deopt_id_after, token_pos);
+ AddDeoptIndexAtCall(deopt_id_after);
} else {
// Add deoptimization continuation point after the call and before the
// arguments are removed.
@@ -1192,7 +1192,7 @@
// deoptimization point in optimized code, after call.
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
if (is_optimizing()) {
- AddDeoptIndexAtCall(deopt_id_after, token_pos);
+ AddDeoptIndexAtCall(deopt_id_after);
} else {
// Add deoptimization continuation point after the call and before the
// arguments are removed.
@@ -1322,7 +1322,7 @@
// Precompilation not implemented on ia32 platform.
ASSERT(!FLAG_precompiled_mode);
if (is_optimizing()) {
- AddDeoptIndexAtCall(deopt_id_after, token_pos);
+ AddDeoptIndexAtCall(deopt_id_after);
} else {
// Add deoptimization continuation point after the call and before the
// arguments are removed.
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index f27c80a..fb3eadb 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -1177,7 +1177,7 @@
// deoptimization point in optimized code, after call.
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
if (is_optimizing()) {
- AddDeoptIndexAtCall(deopt_id_after, token_pos);
+ AddDeoptIndexAtCall(deopt_id_after);
} else {
// Add deoptimization continuation point after the call and before the
// arguments are removed.
@@ -1206,7 +1206,7 @@
// deoptimization point in optimized code, after call.
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
if (is_optimizing()) {
- AddDeoptIndexAtCall(deopt_id_after, token_pos);
+ AddDeoptIndexAtCall(deopt_id_after);
} else {
// Add deoptimization continuation point after the call and before the
// arguments are removed.
@@ -1231,7 +1231,7 @@
// deoptimization point in optimized code, after call.
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
if (is_optimizing()) {
- AddDeoptIndexAtCall(deopt_id_after, token_pos);
+ AddDeoptIndexAtCall(deopt_id_after);
} else {
// Add deoptimization continuation point after the call and before the
// arguments are removed.
@@ -1360,7 +1360,7 @@
} else if (is_optimizing()) {
AddCurrentDescriptor(RawPcDescriptors::kOther,
Thread::kNoDeoptId, token_pos);
- AddDeoptIndexAtCall(deopt_id_after, token_pos);
+ AddDeoptIndexAtCall(deopt_id_after);
} else {
AddCurrentDescriptor(RawPcDescriptors::kOther,
Thread::kNoDeoptId, token_pos);
@@ -1394,7 +1394,7 @@
RecordSafepoint(locs);
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
if (is_optimizing()) {
- AddDeoptIndexAtCall(deopt_id_after, token_pos);
+ AddDeoptIndexAtCall(deopt_id_after);
} else {
// Add deoptimization continuation point after the call and before the
// arguments are removed.
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index fb521bf..0c0444a 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -1172,7 +1172,7 @@
// deoptimization point in optimized code, after call.
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
if (is_optimizing()) {
- AddDeoptIndexAtCall(deopt_id_after, token_pos);
+ AddDeoptIndexAtCall(deopt_id_after);
} else {
// Add deoptimization continuation point after the call and before the
// arguments are removed.
@@ -1199,7 +1199,7 @@
// deoptimization point in optimized code, after call.
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
if (is_optimizing()) {
- AddDeoptIndexAtCall(deopt_id_after, token_pos);
+ AddDeoptIndexAtCall(deopt_id_after);
} else {
// Add deoptimization continuation point after the call and before the
// arguments are removed.
@@ -1222,7 +1222,7 @@
// deoptimization point in optimized code, after call.
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
if (is_optimizing()) {
- AddDeoptIndexAtCall(deopt_id_after, token_pos);
+ AddDeoptIndexAtCall(deopt_id_after);
} else {
// Add deoptimization continuation point after the call and before the
// arguments are removed.
@@ -1360,7 +1360,7 @@
} else if (is_optimizing()) {
AddCurrentDescriptor(RawPcDescriptors::kOther,
Thread::kNoDeoptId, token_pos);
- AddDeoptIndexAtCall(deopt_id_after, token_pos);
+ AddDeoptIndexAtCall(deopt_id_after);
} else {
AddCurrentDescriptor(RawPcDescriptors::kOther,
Thread::kNoDeoptId, token_pos);
@@ -1394,7 +1394,7 @@
RecordSafepoint(locs);
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
if (is_optimizing()) {
- AddDeoptIndexAtCall(deopt_id_after, token_pos);
+ AddDeoptIndexAtCall(deopt_id_after);
} else {
// Add deoptimization continuation point after the call and before the
// arguments are removed.
diff --git a/runtime/vm/heap.cc b/runtime/vm/heap.cc
index fd22740..c3353d2 100644
--- a/runtime/vm/heap.cc
+++ b/runtime/vm/heap.cc
@@ -89,18 +89,18 @@
// If we are in the process of running a sweep, wait for the sweeper to free
// memory.
Thread* thread = Thread::Current();
- {
- MonitorLocker ml(old_space_.tasks_lock());
- addr = old_space_.TryAllocate(size, type);
- while ((addr == 0) && (old_space_.tasks() > 0)) {
- ml.WaitWithSafepointCheck(thread);
- addr = old_space_.TryAllocate(size, type);
- }
- }
- if (addr != 0) {
- return addr;
- }
if (thread->CanCollectGarbage()) {
+ {
+ MonitorLocker ml(old_space_.tasks_lock());
+ addr = old_space_.TryAllocate(size, type);
+ while ((addr == 0) && (old_space_.tasks() > 0)) {
+ ml.WaitWithSafepointCheck(thread);
+ addr = old_space_.TryAllocate(size, type);
+ }
+ }
+ if (addr != 0) {
+ return addr;
+ }
// All GC tasks finished without allocating successfully. Run a full GC.
CollectAllGarbage();
addr = old_space_.TryAllocate(size, type);
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 3a5ab03..102f6b8 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -8,7 +8,6 @@
#include "vm/allocation.h"
#include "vm/ast.h"
#include "vm/growable_array.h"
-#include "vm/handles_impl.h"
#include "vm/locations.h"
#include "vm/method_recognizer.h"
#include "vm/object.h"
@@ -898,6 +897,7 @@
friend class ComparisonInstr;
friend class Scheduler;
friend class BlockEntryInstr;
+ friend class CatchBlockEntryInstr; // deopt_id_
// Fetch deopt id without checking if this computation can deoptimize.
intptr_t GetDeoptId() const {
@@ -1565,7 +1565,8 @@
intptr_t catch_try_index,
const LocalVariable& exception_var,
const LocalVariable& stacktrace_var,
- bool needs_stacktrace)
+ bool needs_stacktrace,
+ intptr_t deopt_id)
: BlockEntryInstr(block_id, try_index),
graph_entry_(graph_entry),
predecessor_(NULL),
@@ -1573,7 +1574,9 @@
catch_try_index_(catch_try_index),
exception_var_(exception_var),
stacktrace_var_(stacktrace_var),
- needs_stacktrace_(needs_stacktrace) { }
+ needs_stacktrace_(needs_stacktrace) {
+ deopt_id_ = deopt_id;
+ }
DECLARE_INSTRUCTION(CatchBlockEntry)
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
index b4e27f0..9827a4d 100644
--- a/runtime/vm/intermediate_language_arm.cc
+++ b/runtime/vm/intermediate_language_arm.cc
@@ -13,6 +13,7 @@
#include "vm/flow_graph.h"
#include "vm/flow_graph_compiler.h"
#include "vm/flow_graph_range_analysis.h"
+#include "vm/instructions.h"
#include "vm/locations.h"
#include "vm/object_store.h"
#include "vm/parser.h"
@@ -232,7 +233,7 @@
// deoptimization point in optimized code, after call.
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id());
if (compiler->is_optimizing()) {
- compiler->AddDeoptIndexAtCall(deopt_id_after, token_pos());
+ compiler->AddDeoptIndexAtCall(deopt_id_after);
}
// Add deoptimization continuation point after the call and before the
// arguments are removed.
@@ -2836,16 +2837,30 @@
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(),
compiler->assembler()->CodeSize(),
catch_handler_types_,
needs_stacktrace());
- // Restore the pool pointer.
- __ RestoreCodePointer();
- __ LoadPoolPointer();
-
+ // On lazy deoptimization we patch the optimized code here to enter the
+ // deoptimization stub.
+ const intptr_t deopt_id = Thread::ToDeoptAfter(GetDeoptId());
+ if (compiler->is_optimizing()) {
+ compiler->AddDeoptIndexAtCall(deopt_id);
+ } else {
+ compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt,
+ deopt_id,
+ TokenPosition::kNoSource);
+ }
if (HasParallelMove()) {
compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
}
diff --git a/runtime/vm/intermediate_language_arm64.cc b/runtime/vm/intermediate_language_arm64.cc
index b5f235f..af9f56d 100644
--- a/runtime/vm/intermediate_language_arm64.cc
+++ b/runtime/vm/intermediate_language_arm64.cc
@@ -12,6 +12,7 @@
#include "vm/flow_graph.h"
#include "vm/flow_graph_compiler.h"
#include "vm/flow_graph_range_analysis.h"
+#include "vm/instructions.h"
#include "vm/locations.h"
#include "vm/object_store.h"
#include "vm/parser.h"
@@ -229,7 +230,7 @@
// deoptimization point in optimized code, after call.
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id());
if (compiler->is_optimizing()) {
- compiler->AddDeoptIndexAtCall(deopt_id_after, token_pos());
+ compiler->AddDeoptIndexAtCall(deopt_id_after);
}
// Add deoptimization continuation point after the call and before the
// arguments are removed.
@@ -2553,17 +2554,30 @@
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(),
compiler->assembler()->CodeSize(),
catch_handler_types_,
needs_stacktrace());
-
- // Restore the pool pointer.
- __ RestoreCodePointer();
- __ LoadPoolPointer();
-
+ // On lazy deoptimization we patch the optimized code here to enter the
+ // deoptimization stub.
+ const intptr_t deopt_id = Thread::ToDeoptAfter(GetDeoptId());
+ if (compiler->is_optimizing()) {
+ compiler->AddDeoptIndexAtCall(deopt_id);
+ } else {
+ compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt,
+ deopt_id,
+ TokenPosition::kNoSource);
+ }
if (HasParallelMove()) {
compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
}
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index 1595297..597fd43 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -12,6 +12,7 @@
#include "vm/flow_graph.h"
#include "vm/flow_graph_compiler.h"
#include "vm/flow_graph_range_analysis.h"
+#include "vm/instructions.h"
#include "vm/locations.h"
#include "vm/object_store.h"
#include "vm/parser.h"
@@ -2547,12 +2548,26 @@
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(),
compiler->assembler()->CodeSize(),
catch_handler_types_,
needs_stacktrace());
+ // On lazy deoptimization we patch the optimized code here to enter the
+ // deoptimization stub.
+ const intptr_t deopt_id = Thread::ToDeoptAfter(GetDeoptId());
+ if (compiler->is_optimizing()) {
+ compiler->AddDeoptIndexAtCall(deopt_id);
+ } else {
+ compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt,
+ deopt_id,
+ TokenPosition::kNoSource);
+ }
if (HasParallelMove()) {
compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
}
@@ -6784,7 +6799,7 @@
// deoptimization point in optimized code, after call.
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id());
if (compiler->is_optimizing()) {
- compiler->AddDeoptIndexAtCall(deopt_id_after, token_pos());
+ compiler->AddDeoptIndexAtCall(deopt_id_after);
}
// Add deoptimization continuation point after the call and before the
// arguments are removed.
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc
index f583fa1..6ec28cc 100644
--- a/runtime/vm/intermediate_language_mips.cc
+++ b/runtime/vm/intermediate_language_mips.cc
@@ -12,6 +12,7 @@
#include "vm/flow_graph.h"
#include "vm/flow_graph_compiler.h"
#include "vm/flow_graph_range_analysis.h"
+#include "vm/instructions.h"
#include "vm/locations.h"
#include "vm/object_store.h"
#include "vm/parser.h"
@@ -278,7 +279,7 @@
// deoptimization point in optimized code, after call.
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id());
if (compiler->is_optimizing()) {
- compiler->AddDeoptIndexAtCall(deopt_id_after, token_pos());
+ compiler->AddDeoptIndexAtCall(deopt_id_after);
}
// Add deoptimization continuation point after the call and before the
// arguments are removed.
@@ -2667,20 +2668,33 @@
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(),
compiler->assembler()->CodeSize(),
catch_handler_types_,
needs_stacktrace());
- // Restore pool pointer.
- __ RestoreCodePointer();
- __ LoadPoolPointer();
-
+ // On lazy deoptimization we patch the optimized code here to enter the
+ // deoptimization stub.
+ const intptr_t deopt_id = Thread::ToDeoptAfter(GetDeoptId());
+ if (compiler->is_optimizing()) {
+ compiler->AddDeoptIndexAtCall(deopt_id);
+ } else {
+ compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt,
+ deopt_id,
+ TokenPosition::kNoSource);
+ }
if (HasParallelMove()) {
compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
}
-
// Restore SP from FP as we are coming from a throw and the code for
// popping arguments has not been run.
const intptr_t fp_sp_dist =
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index b4eefbf..b8a57bb 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -12,6 +12,7 @@
#include "vm/flow_graph.h"
#include "vm/flow_graph_compiler.h"
#include "vm/flow_graph_range_analysis.h"
+#include "vm/instructions.h"
#include "vm/locations.h"
#include "vm/object_store.h"
#include "vm/parser.h"
@@ -2563,17 +2564,26 @@
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(),
compiler->assembler()->CodeSize(),
catch_handler_types_,
needs_stacktrace());
-
- // Restore the pool pointer.
- __ RestoreCodePointer();
- __ LoadPoolPointer(PP);
-
+ // On lazy deoptimization we patch the optimized code here to enter the
+ // deoptimization stub.
+ const intptr_t deopt_id = Thread::ToDeoptAfter(GetDeoptId());
+ if (compiler->is_optimizing()) {
+ compiler->AddDeoptIndexAtCall(deopt_id);
+ } else {
+ compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt,
+ deopt_id,
+ TokenPosition::kNoSource);
+ }
if (HasParallelMove()) {
compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
}
@@ -6507,7 +6517,7 @@
// deoptimization point in optimized code, after call.
const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id());
if (compiler->is_optimizing()) {
- compiler->AddDeoptIndexAtCall(deopt_id_after, token_pos());
+ compiler->AddDeoptIndexAtCall(deopt_id_after);
}
// Add deoptimization continuation point after the call and before the
// arguments are removed.
diff --git a/runtime/vm/megamorphic_cache_table.cc b/runtime/vm/megamorphic_cache_table.cc
index 1fdd8e2..e3d34dd 100644
--- a/runtime/vm/megamorphic_cache_table.cc
+++ b/runtime/vm/megamorphic_cache_table.cc
@@ -5,7 +5,6 @@
#include "vm/megamorphic_cache_table.h"
#include <stdlib.h>
-#include "vm/handles_impl.h"
#include "vm/object.h"
#include "vm/object_store.h"
#include "vm/stub_code.h"
diff --git a/runtime/vm/native_api_impl.cc b/runtime/vm/native_api_impl.cc
index 7abd52e..48d9289 100644
--- a/runtime/vm/native_api_impl.cc
+++ b/runtime/vm/native_api_impl.cc
@@ -129,4 +129,28 @@
return result;
}
+
+static void ParseAll(Thread* thread, Dart_Handle* result) {
+ ASSERT(thread != NULL);
+ const Error& error = Error::Handle(thread->zone(),
+ Library::ParseAll(thread));
+ if (error.IsNull()) {
+ *result = Api::Success();
+ } else {
+ *result = Api::NewHandle(thread, error.raw());
+ }
+}
+
+
+DART_EXPORT Dart_Handle Dart_ParseAll() {
+ DARTSCOPE(Thread::Current());
+ Dart_Handle result = Api::CheckAndFinalizePendingClasses(T);
+ if (::Dart_IsError(result)) {
+ return result;
+ }
+ CHECK_CALLBACK_STATE(T);
+ ParseAll(T, &result);
+ return result;
+}
+
} // namespace dart
diff --git a/runtime/vm/native_arguments.h b/runtime/vm/native_arguments.h
index 7035a50..77c67ed 100644
--- a/runtime/vm/native_arguments.h
+++ b/runtime/vm/native_arguments.h
@@ -8,7 +8,6 @@
#include "platform/assert.h"
#include "platform/memory_sanitizer.h"
#include "vm/globals.h"
-#include "vm/handles_impl.h"
#include "vm/simulator.h"
#include "vm/stub_code.h"
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 2456ed6..a368c52 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -153,6 +153,7 @@
RawClass* Object::context_scope_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
RawClass* Object::singletargetcache_class_ =
reinterpret_cast<RawClass*>(RAW_NULL);
+RawClass* Object::unlinkedcall_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
RawClass* Object::icdata_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
RawClass* Object::megamorphic_cache_class_ =
reinterpret_cast<RawClass*>(RAW_NULL);
@@ -656,6 +657,9 @@
cls = Class::New<SingleTargetCache>();
singletargetcache_class_ = cls.raw();
+ cls = Class::New<UnlinkedCall>();
+ unlinkedcall_class_ = cls.raw();
+
cls = Class::New<ICData>();
icdata_class_ = cls.raw();
@@ -998,6 +1002,7 @@
SET_CLASS_NAME(context, Context);
SET_CLASS_NAME(context_scope, ContextScope);
SET_CLASS_NAME(singletargetcache, SingleTargetCache);
+ SET_CLASS_NAME(unlinkedcall, UnlinkedCall);
SET_CLASS_NAME(icdata, ICData);
SET_CLASS_NAME(megamorphic_cache, MegamorphicCache);
SET_CLASS_NAME(subtypetestcache, SubtypeTestCache);
@@ -5977,13 +5982,13 @@
bool Function::IsOptimizable() const {
+ if (FLAG_precompiled_mode) {
+ return true;
+ }
if (is_native()) {
// Native methods don't need to be optimized.
return false;
}
- if (FLAG_precompiled_mode) {
- return true;
- }
const intptr_t function_length = end_token_pos().Pos() - token_pos().Pos();
if (is_optimizable() && (script() != Script::null()) &&
(function_length < FLAG_huge_method_cutoff_in_tokens)) {
@@ -10478,6 +10483,9 @@
ASSERT(thread->IsMutatorThread());
// Force the url to have a hash code.
url.Hash();
+ const bool dart_scheme = url.StartsWith(Symbols::DartScheme());
+ const bool dart_private_scheme =
+ dart_scheme && url.StartsWith(Symbols::DartSchemePrivate());
const Library& result = Library::Handle(zone, Library::New());
result.StorePointer(&result.raw_ptr()->name_, Symbols::Empty().raw());
result.StorePointer(&result.raw_ptr()->url_, url.raw());
@@ -10501,8 +10509,8 @@
result.set_native_entry_symbol_resolver(NULL);
result.set_is_in_fullsnapshot(false);
result.StoreNonPointer(&result.raw_ptr()->corelib_imported_, true);
- result.set_debuggable(false);
- result.set_is_dart_scheme(url.StartsWith(Symbols::DartScheme()));
+ result.set_debuggable(!dart_private_scheme);
+ result.set_is_dart_scheme(dart_scheme);
result.StoreNonPointer(&result.raw_ptr()->load_state_,
RawLibrary::kAllocated);
result.StoreNonPointer(&result.raw_ptr()->index_, -1);
@@ -11414,6 +11422,51 @@
}
+RawError* Library::ParseAll(Thread* thread) {
+ Zone* zone = thread->zone();
+ Error& error = Error::Handle(zone);
+ Isolate* isolate = thread->isolate();
+ const GrowableObjectArray& libs = GrowableObjectArray::Handle(
+ isolate->object_store()->libraries());
+ Library& lib = Library::Handle(zone);
+ Class& cls = Class::Handle(zone);
+ for (int i = 0; i < libs.Length(); i++) {
+ lib ^= libs.At(i);
+ ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate);
+ while (it.HasNext()) {
+ cls = it.GetNextClass();
+ error = cls.EnsureIsFinalized(thread);
+ if (!error.IsNull()) {
+ return error.raw();
+ }
+ error = Compiler::ParseAllFunctions(cls);
+ if (!error.IsNull()) {
+ return error.raw();
+ }
+ }
+ }
+
+ // Inner functions get added to the closures array. As part of compilation
+ // more closures can be added to the end of the array. Compile all the
+ // closures until we have reached the end of the "worklist".
+ const GrowableObjectArray& closures = GrowableObjectArray::Handle(zone,
+ Isolate::Current()->object_store()->closure_functions());
+ Function& func = Function::Handle(zone);
+ for (int i = 0; i < closures.Length(); i++) {
+ func ^= closures.At(i);
+ if (!func.HasCode()) {
+ error = Compiler::ParseFunction(thread, func);
+ if (!error.IsNull()) {
+ return error.raw();
+ }
+ func.ClearICDataArray();
+ func.ClearCode();
+ }
+ }
+ return error.raw();
+}
+
+
// Return Function::null() if function does not exist in libs.
RawFunction* Library::GetFunction(const GrowableArray<Library*>& libs,
const char* class_name,
@@ -12600,6 +12653,29 @@
}
+void UnlinkedCall::set_target_name(const String& value) const {
+ StorePointer(&raw_ptr()->target_name_, value.raw());
+}
+
+
+void UnlinkedCall::set_args_descriptor(const Array& value) const {
+ StorePointer(&raw_ptr()->args_descriptor_, value.raw());
+}
+
+
+const char* UnlinkedCall::ToCString() const {
+ return "UnlinkedCall";
+}
+
+
+RawUnlinkedCall* UnlinkedCall::New() {
+ RawObject* raw = Object::Allocate(UnlinkedCall::kClassId,
+ UnlinkedCall::InstanceSize(),
+ Heap::kOld);
+ return reinterpret_cast<RawUnlinkedCall*>(raw);
+}
+
+
void ICData::ResetSwitchable(Zone* zone) const {
ASSERT(NumArgsTested() == 1);
set_ic_data_array(Array::Handle(zone, CachedEmptyICDataArray(1)));
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index f0074a51f..fbc72e2 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -542,6 +542,7 @@
static RawClass* singletargetcache_class() {
return singletargetcache_class_;
}
+ static RawClass* unlinkedcall_class() { return unlinkedcall_class_; }
static RawClass* icdata_class() { return icdata_class_; }
static RawClass* megamorphic_cache_class() {
return megamorphic_cache_class_;
@@ -794,6 +795,7 @@
static RawClass* context_class_; // Class of the Context vm object.
static RawClass* context_scope_class_; // Class of ContextScope vm object.
static RawClass* singletargetcache_class_; // Class of SingleTargetCache.
+ static RawClass* unlinkedcall_class_; // Class of UnlinkedCall.
static RawClass* icdata_class_; // Class of ICData.
static RawClass* megamorphic_cache_class_; // Class of MegamorphiCache.
static RawClass* subtypetestcache_class_; // Class of SubtypeTestCache.
@@ -1858,6 +1860,25 @@
};
+class UnlinkedCall : public Object {
+ public:
+ RawString* target_name() const { return raw_ptr()->target_name_; }
+ void set_target_name(const String& target_name) const;
+ RawArray* args_descriptor() const { return raw_ptr()->args_descriptor_; }
+ void set_args_descriptor(const Array& args_descriptor) const;
+
+ static intptr_t InstanceSize() {
+ return RoundedAllocationSize(sizeof(RawUnlinkedCall));
+ }
+
+ static RawUnlinkedCall* New();
+
+ private:
+ FINAL_HEAP_OBJECT_IMPLEMENTATION(UnlinkedCall, Object);
+ friend class Class;
+};
+
+
// Object holding information about an IC: test classes and their
// corresponding targets. The owner of the ICData can be either the function
// or the original ICData object. In case of background compilation we
@@ -3858,6 +3879,7 @@
// Eagerly compile all classes and functions in the library.
static RawError* CompileAll();
+ static RawError* ParseAll(Thread* thread);
#if defined(DART_NO_SNAPSHOT)
// Checks function fingerprints. Prints mismatches and aborts if
diff --git a/runtime/vm/object_reload.cc b/runtime/vm/object_reload.cc
index dd15a1f..f3b06e0 100644
--- a/runtime/vm/object_reload.cc
+++ b/runtime/vm/object_reload.cc
@@ -392,6 +392,9 @@
old_closure = old_func.ImplicitStaticClosure();
new_func = new_func.ImplicitClosureFunction();
new_closure = new_func.ImplicitStaticClosure();
+ if (old_closure.IsCanonical()) {
+ new_closure.SetCanonical();
+ }
irc->AddBecomeMapping(old_closure, new_closure);
}
}
diff --git a/runtime/vm/object_service.cc b/runtime/vm/object_service.cc
index fc95622..bb0bb26 100644
--- a/runtime/vm/object_service.cc
+++ b/runtime/vm/object_service.cc
@@ -754,6 +754,11 @@
}
+void UnlinkedCall::PrintJSONImpl(JSONStream* stream, bool ref) const {
+ Object::PrintJSONImpl(stream, ref);
+}
+
+
void ICData::PrintJSONImpl(JSONStream* stream, bool ref) const {
JSONObject jsobj(stream);
AddCommonObjectProperties(&jsobj, "Object", ref);
diff --git a/runtime/vm/pages.cc b/runtime/vm/pages.cc
index 80527f2..f2bbdf2 100644
--- a/runtime/vm/pages.cc
+++ b/runtime/vm/pages.cc
@@ -1153,39 +1153,70 @@
SpaceUsage before, SpaceUsage after, int64_t start, int64_t end) {
ASSERT(end >= start);
history_.AddGarbageCollectionTime(start, end);
- int gc_time_fraction = history_.GarbageCollectionTimeFraction();
+ const int gc_time_fraction = history_.GarbageCollectionTimeFraction();
heap_->RecordData(PageSpace::kGCTimeFraction, gc_time_fraction);
// Assume garbage increases linearly with allocation:
// G = kA, and estimate k from the previous cycle.
- intptr_t allocated_since_previous_gc =
+ const intptr_t allocated_since_previous_gc =
before.used_in_words - last_usage_.used_in_words;
- intptr_t garbage = before.used_in_words - after.used_in_words;
- double k = garbage / static_cast<double>(allocated_since_previous_gc);
- heap_->RecordData(PageSpace::kGarbageRatio, static_cast<int>(k * 100));
+ if (allocated_since_previous_gc > 0) {
+ const intptr_t garbage = before.used_in_words - after.used_in_words;
+ ASSERT(garbage >= 0);
+ const double k = garbage / static_cast<double>(allocated_since_previous_gc);
+ const int garbage_ratio = static_cast<int>(k * 100);
+ heap_->RecordData(PageSpace::kGarbageRatio, garbage_ratio);
- // Define GC to be 'worthwhile' iff at least fraction t of heap is garbage.
- double t = 1.0 - desired_utilization_;
- // If we spend too much time in GC, strive for even more free space.
- if (gc_time_fraction > garbage_collection_time_ratio_) {
- t += (gc_time_fraction - garbage_collection_time_ratio_) / 100.0;
- }
-
- // Find minimum 'grow_heap_' such that after increasing capacity by
- // 'grow_heap_' pages and filling them, we expect a GC to be worthwhile.
- for (grow_heap_ = 0; grow_heap_ < heap_growth_max_; ++grow_heap_) {
- intptr_t limit =
- after.capacity_in_words + (grow_heap_ * PageSpace::kPageSizeInWords);
- intptr_t allocated_before_next_gc = limit - after.used_in_words;
- double estimated_garbage = k * allocated_before_next_gc;
- if (t <= estimated_garbage / limit) {
- break;
+ // Define GC to be 'worthwhile' iff at least fraction t of heap is garbage.
+ double t = 1.0 - desired_utilization_;
+ // If we spend too much time in GC, strive for even more free space.
+ if (gc_time_fraction > garbage_collection_time_ratio_) {
+ t += (gc_time_fraction - garbage_collection_time_ratio_) / 100.0;
}
+
+ const intptr_t grow_ratio = (
+ static_cast<intptr_t>(after.capacity_in_words / desired_utilization_) -
+ after.capacity_in_words) / PageSpace::kPageSizeInWords;
+ if (garbage_ratio == 0) {
+ // No garbage in the previous cycle so it would be hard to compute a
+ // grow_heap_ size based on estimated garbage so we use growth ratio
+ // heuristics instead.
+ grow_heap_ = Utils::Maximum(static_cast<intptr_t>(heap_growth_max_),
+ grow_ratio);
+ } else {
+ // Find minimum 'grow_heap_' such that after increasing capacity by
+ // 'grow_heap_' pages and filling them, we expect a GC to be worthwhile.
+ intptr_t max = heap_growth_max_;
+ intptr_t min = 0;
+ intptr_t local_grow_heap = 0;
+ while (min < max) {
+ local_grow_heap = (max + min) / 2;
+ const intptr_t limit = after.capacity_in_words +
+ (grow_heap_ * PageSpace::kPageSizeInWords);
+ const intptr_t allocated_before_next_gc = limit - after.used_in_words;
+ const double estimated_garbage = k * allocated_before_next_gc;
+ if (t <= estimated_garbage / limit) {
+ max = local_grow_heap - 1;
+ } else {
+ min = local_grow_heap + 1;
+ }
+ }
+ grow_heap_ = local_grow_heap;
+ ASSERT(grow_heap_ >= 0);
+ // If we are going to grow by heap_grow_max_ then ensure that we
+ // will be growing the heap at least by the growth ratio heuristics.
+ if ((grow_heap_ == heap_growth_max_) && (grow_ratio > grow_heap_)) {
+ grow_heap_ = grow_ratio;
+ }
+ }
+ } else {
+ heap_->RecordData(PageSpace::kGarbageRatio, 100);
+ grow_heap_ = 0;
}
heap_->RecordData(PageSpace::kPageGrowth, grow_heap_);
// Limit shrinkage: allow growth by at least half the pages freed by GC.
- intptr_t freed_pages =
+ const intptr_t freed_pages =
(before.capacity_in_words - after.capacity_in_words) /
PageSpace::kPageSizeInWords;
grow_heap_ = Utils::Maximum(grow_heap_, freed_pages / 2);
diff --git a/runtime/vm/pages.h b/runtime/vm/pages.h
index 640e771..06e3ab5 100644
--- a/runtime/vm/pages.h
+++ b/runtime/vm/pages.h
@@ -412,8 +412,13 @@
// Unlimited.
return true;
}
- ASSERT(CapacityInWords() <= max_capacity_in_words_);
- return increase_in_words <= (max_capacity_in_words_ - CapacityInWords());
+ // TODO(issue 27413): Make the check against capacity and the bump
+ // of capacity atomic so that CapacityInWords does not exceed
+ // max_capacity_in_words_.
+ intptr_t free_capacity_in_words =
+ (max_capacity_in_words_ - CapacityInWords());
+ return ((free_capacity_in_words > 0) &&
+ (increase_in_words <= free_capacity_in_words));
}
FreeList freelist_[HeapPage::kNumPageTypes];
diff --git a/runtime/vm/parser_test.cc b/runtime/vm/parser_test.cc
index 319b13d..14fae8e 100644
--- a/runtime/vm/parser_test.cc
+++ b/runtime/vm/parser_test.cc
@@ -40,7 +40,8 @@
EXPECT(parsed_function->node_sequence() != NULL);
printf("Class %s function %s:\n", cname, fname);
if (FLAG_support_ast_printer) {
- AstPrinter::PrintFunctionNodes(*parsed_function);
+ AstPrinter ast_printer;
+ ast_printer.PrintFunctionNodes(*parsed_function);
} else {
OS::Print("AST printer not supported.");
}
diff --git a/runtime/vm/precompiler.cc b/runtime/vm/precompiler.cc
index 2981e17d..d55a6f1 100644
--- a/runtime/vm/precompiler.cc
+++ b/runtime/vm/precompiler.cc
@@ -1197,7 +1197,8 @@
Thread* const thread = Thread::Current();
if (FLAG_support_ast_printer && FLAG_trace_compiler) {
THR_Print("compiling expression: ");
- AstPrinter::PrintNode(fragment);
+ AstPrinter ast_printer;
+ ast_printer.PrintNode(fragment);
}
// Create a dummy function object for the code generator.
@@ -2112,7 +2113,11 @@
pool_(ObjectPool::Handle(zone)),
entry_(Object::Handle(zone)),
ic_(ICData::Handle(zone)),
- target_code_(Code::Handle(zone)) {
+ target_name_(String::Handle(zone)),
+ args_descriptor_(Array::Handle(zone)),
+ unlinked_(UnlinkedCall::Handle(zone)),
+ target_code_(Code::Handle(zone)),
+ canonical_unlinked_calls_() {
}
void Visit(const Function& function) {
@@ -2130,21 +2135,45 @@
// calls.
ic_ ^= entry_.raw();
ic_.ResetSwitchable(zone_);
+
+ unlinked_ = UnlinkedCall::New();
+ target_name_ = ic_.target_name();
+ unlinked_.set_target_name(target_name_);
+ args_descriptor_ = ic_.arguments_descriptor();
+ unlinked_.set_args_descriptor(args_descriptor_);
+ unlinked_ = DedupUnlinkedCall(unlinked_);
+ pool_.SetObjectAt(i, unlinked_);
} else if (entry_.raw() ==
StubCode::ICCallThroughFunction_entry()->code()) {
- target_code_ = StubCode::ICCallThroughCode_entry()->code();
+ target_code_ = StubCode::UnlinkedCall_entry()->code();
pool_.SetObjectAt(i, target_code_);
}
}
}
+ RawUnlinkedCall* DedupUnlinkedCall(const UnlinkedCall& unlinked) {
+ const UnlinkedCall* canonical_unlinked =
+ canonical_unlinked_calls_.LookupValue(&unlinked);
+ if (canonical_unlinked == NULL) {
+ canonical_unlinked_calls_.Insert(
+ &UnlinkedCall::ZoneHandle(zone_, unlinked.raw()));
+ return unlinked.raw();
+ } else {
+ return canonical_unlinked->raw();
+ }
+ }
+
private:
Zone* zone_;
Code& code_;
ObjectPool& pool_;
Object& entry_;
ICData& ic_;
+ String& target_name_;
+ Array& args_descriptor_;
+ UnlinkedCall& unlinked_;
Code& target_code_;
+ UnlinkedCallSet canonical_unlinked_calls_;
};
ASSERT(!I->compilation_allowed());
diff --git a/runtime/vm/precompiler.h b/runtime/vm/precompiler.h
index 67c54e1..90b5f82 100644
--- a/runtime/vm/precompiler.h
+++ b/runtime/vm/precompiler.h
@@ -157,6 +157,30 @@
typedef DirectChainedHashMap<InstructionsKeyValueTrait> InstructionsSet;
+class UnlinkedCallKeyValueTrait {
+ public:
+ // Typedefs needed for the DirectChainedHashMap template.
+ typedef const UnlinkedCall* Key;
+ typedef const UnlinkedCall* Value;
+ typedef const UnlinkedCall* Pair;
+
+ static Key KeyOf(Pair kv) { return kv; }
+
+ static Value ValueOf(Pair kv) { return kv; }
+
+ static inline intptr_t Hashcode(Key key) {
+ return String::Handle(key->target_name()).Hash();
+ }
+
+ static inline bool IsKeyEqual(Pair pair, Key key) {
+ return (pair->target_name() == key->target_name()) &&
+ (pair->args_descriptor() == key->args_descriptor());
+ }
+};
+
+typedef DirectChainedHashMap<UnlinkedCallKeyValueTrait> UnlinkedCallSet;
+
+
class FunctionKeyValueTrait {
public:
// Typedefs needed for the DirectChainedHashMap template.
diff --git a/runtime/vm/profiler_service.cc b/runtime/vm/profiler_service.cc
index d5ffcb9..1a80017 100644
--- a/runtime/vm/profiler_service.cc
+++ b/runtime/vm/profiler_service.cc
@@ -5,7 +5,6 @@
#include "vm/profiler_service.h"
#include "vm/growable_array.h"
-#include "vm/handles_impl.h"
#include "vm/hash_map.h"
#include "vm/log.h"
#include "vm/native_symbol.h"
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index 991b2e0..d777f68 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -646,6 +646,13 @@
}
+intptr_t RawUnlinkedCall::VisitUnlinkedCallPointers(
+ RawUnlinkedCall* raw_obj, ObjectPointerVisitor* visitor) {
+ visitor->VisitPointers(raw_obj->from(), raw_obj->to());
+ return UnlinkedCall::InstanceSize();
+}
+
+
intptr_t RawICData::VisitICDataPointers(RawICData* raw_obj,
ObjectPointerVisitor* visitor) {
visitor->VisitPointers(raw_obj->from(), raw_obj->to());
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 9e40136..66b2d4c 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -40,6 +40,7 @@
V(Context) \
V(ContextScope) \
V(SingleTargetCache) \
+ V(UnlinkedCall) \
V(ICData) \
V(MegamorphicCache) \
V(SubtypeTestCache) \
@@ -1509,6 +1510,19 @@
};
+class RawUnlinkedCall : public RawObject {
+ RAW_HEAP_OBJECT_IMPLEMENTATION(UnlinkedCall);
+ RawObject** from() {
+ return reinterpret_cast<RawObject**>(&ptr()->target_name_);
+ }
+ RawString* target_name_;
+ RawArray* args_descriptor_;
+ RawObject** to() {
+ return reinterpret_cast<RawObject**>(&ptr()->args_descriptor_);
+ }
+};
+
+
class RawICData : public RawObject {
RAW_HEAP_OBJECT_IMPLEMENTATION(ICData);
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index 7829e95..f345a19 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -1543,6 +1543,24 @@
}
+RawUnlinkedCall* UnlinkedCall::ReadFrom(SnapshotReader* reader,
+ intptr_t object_id,
+ intptr_t tags,
+ Snapshot::Kind kind,
+ bool as_reference) {
+ UNREACHABLE();
+ return UnlinkedCall::null();
+}
+
+
+void RawUnlinkedCall::WriteTo(SnapshotWriter* writer,
+ intptr_t object_id,
+ Snapshot::Kind kind,
+ bool as_reference) {
+ UNREACHABLE();
+}
+
+
RawICData* ICData::ReadFrom(SnapshotReader* reader,
intptr_t object_id,
intptr_t tags,
diff --git a/runtime/vm/runtime_entry_list.h b/runtime/vm/runtime_entry_list.h
index f816769..9564146 100644
--- a/runtime/vm/runtime_entry_list.h
+++ b/runtime/vm/runtime_entry_list.h
@@ -46,6 +46,7 @@
V(CompileFunction) \
V(MonomorphicMiss) \
V(SingleTargetMiss) \
+ V(UnlinkedCall) \
#define LEAF_RUNTIME_ENTRY_LIST(V) \
V(void, PrintStopMessage, const char*) \
diff --git a/runtime/vm/scanner.cc b/runtime/vm/scanner.cc
index f7ae4ac..cd8abf5 100644
--- a/runtime/vm/scanner.cc
+++ b/runtime/vm/scanner.cc
@@ -484,9 +484,7 @@
}
}
}
- if (is_valid &&
- ((Utf::IsOutOfRange(*code_point) ||
- (Utf16::IsSurrogate(*code_point))))) {
+ if (is_valid && (Utf::IsOutOfRange(*code_point))) {
ErrorMsg("invalid code point");
}
}
diff --git a/runtime/vm/scanner_test.cc b/runtime/vm/scanner_test.cc
index 3d8d70c..b6d4d23 100644
--- a/runtime/vm/scanner_test.cc
+++ b/runtime/vm/scanner_test.cc
@@ -192,62 +192,6 @@
static void InvalidStringEscapes() {
- const GrowableTokenStream& high_start_4 =
- Scan("\"\\uD800\"");
- EXPECT_EQ(2, high_start_4.length());
- CheckKind(high_start_4, 0, Token::kERROR);
- EXPECT(high_start_4[0].literal->Equals("invalid code point"));
- CheckKind(high_start_4, 1, Token::kEOS);
-
- const GrowableTokenStream& high_start_seq =
- Scan("\"\\u{D800}\"");
- EXPECT_EQ(2, high_start_seq.length());
- CheckKind(high_start_seq, 0, Token::kERROR);
- EXPECT(high_start_seq[0].literal->Equals("invalid code point"));
- CheckKind(high_start_seq, 1, Token::kEOS);
-
- const GrowableTokenStream& high_end_4 =
- Scan("\"\\uDBFF\"");
- EXPECT_EQ(2, high_end_4.length());
- CheckKind(high_end_4, 0, Token::kERROR);
- EXPECT(high_end_4[0].literal->Equals("invalid code point"));
- CheckKind(high_end_4, 1, Token::kEOS);
-
- const GrowableTokenStream& high_end_seq =
- Scan("\"\\u{DBFF}\"");
- EXPECT_EQ(2, high_end_seq.length());
- CheckKind(high_end_seq, 0, Token::kERROR);
- EXPECT(high_end_seq[0].literal->Equals("invalid code point"));
- CheckKind(high_end_seq, 1, Token::kEOS);
-
- const GrowableTokenStream& low_start_4 =
- Scan("\"\\uDC00\"");
- EXPECT_EQ(2, low_start_4.length());
- CheckKind(low_start_4, 0, Token::kERROR);
- EXPECT(low_start_4[0].literal->Equals("invalid code point"));
- CheckKind(low_start_4, 1, Token::kEOS);
-
- const GrowableTokenStream& low_start_seq =
- Scan("\"\\u{DC00}\"");
- EXPECT_EQ(2, low_start_seq.length());
- CheckKind(low_start_seq, 0, Token::kERROR);
- EXPECT(low_start_seq[0].literal->Equals("invalid code point"));
- CheckKind(low_start_seq, 1, Token::kEOS);
-
- const GrowableTokenStream& low_end_4 =
- Scan("\"\\uDFFF\"");
- EXPECT_EQ(2, low_end_4.length());
- CheckKind(low_end_4, 0, Token::kERROR);
- EXPECT(low_end_4[0].literal->Equals("invalid code point"));
- CheckKind(low_end_4, 1, Token::kEOS);
-
- const GrowableTokenStream& low_end_seq =
- Scan("\"\\u{DFFF}\"");
- EXPECT_EQ(2, low_end_seq.length());
- CheckKind(low_end_seq, 0, Token::kERROR);
- EXPECT(low_end_seq[0].literal->Equals("invalid code point"));
- CheckKind(low_end_seq, 1, Token::kEOS);
-
const GrowableTokenStream& out_of_range_low =
Scan("\"\\u{110000}\"");
EXPECT_EQ(2, out_of_range_low.length());
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index d35f0e1..efc5c24 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -241,6 +241,14 @@
}
+static void PrintIllegalParamError(JSONStream* js,
+ const char* param) {
+ js->PrintError(kInvalidParams,
+ "%s: illegal '%s' parameter: %s",
+ js->method(), param, js->LookupParam(param));
+}
+
+
static void PrintUnrecognizedMethodError(JSONStream* js) {
js->PrintError(kMethodNotFound, NULL);
}
@@ -3977,6 +3985,13 @@
BoolParameter::Parse(js->LookupParam("isDebuggable"), false);
if (obj.IsLibrary()) {
const Library& lib = Library::Cast(obj);
+ if (lib.is_dart_scheme()) {
+ const String& url = String::Handle(lib.url());
+ if (url.StartsWith(Symbols::DartSchemePrivate())) {
+ PrintIllegalParamError(js, "libraryId");
+ return true;
+ }
+ }
lib.set_debuggable(is_debuggable);
PrintSuccess(js);
return true;
diff --git a/runtime/vm/simulator_arm.cc b/runtime/vm/simulator_arm.cc
index 3077c8b6..9c3e3cf 100644
--- a/runtime/vm/simulator_arm.cc
+++ b/runtime/vm/simulator_arm.cc
@@ -3906,6 +3906,13 @@
ASSERT(raw_exception != Object::null());
set_register(kExceptionObjectReg, bit_cast<int32_t>(raw_exception));
set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace));
+ // Restore pool pointer.
+ int32_t code = *reinterpret_cast<int32_t*>(
+ fp + kPcMarkerSlotFromFp * kWordSize);
+ int32_t pp = *reinterpret_cast<int32_t*>(
+ code + Code::object_pool_offset() - kHeapObjectTag);
+ set_register(CODE_REG, code);
+ set_register(PP, pp);
buf->Longjmp();
}
diff --git a/runtime/vm/simulator_arm64.cc b/runtime/vm/simulator_arm64.cc
index 610b857..0cfcb2a 100644
--- a/runtime/vm/simulator_arm64.cc
+++ b/runtime/vm/simulator_arm64.cc
@@ -3604,6 +3604,14 @@
ASSERT(raw_exception != Object::null());
set_register(NULL, kExceptionObjectReg, bit_cast<int64_t>(raw_exception));
set_register(NULL, kStackTraceObjectReg, bit_cast<int64_t>(raw_stacktrace));
+ // Restore pool pointer.
+ int64_t code = *reinterpret_cast<int64_t*>(
+ fp + kPcMarkerSlotFromFp * kWordSize);
+ int64_t pp = *reinterpret_cast<int64_t*>(
+ code + Code::object_pool_offset() - kHeapObjectTag);
+ pp -= kHeapObjectTag; // In the PP register, the pool pointer is untagged.
+ set_register(NULL, CODE_REG, code);
+ set_register(NULL, PP, pp);
buf->Longjmp();
}
diff --git a/runtime/vm/simulator_mips.cc b/runtime/vm/simulator_mips.cc
index eb03c49..f42b3fa 100644
--- a/runtime/vm/simulator_mips.cc
+++ b/runtime/vm/simulator_mips.cc
@@ -2530,6 +2530,13 @@
ASSERT(raw_exception != Object::null());
set_register(kExceptionObjectReg, bit_cast<int32_t>(raw_exception));
set_register(kStackTraceObjectReg, bit_cast<int32_t>(raw_stacktrace));
+ // Restore pool pointer.
+ int32_t code = *reinterpret_cast<int32_t*>(
+ fp + kPcMarkerSlotFromFp * kWordSize);
+ int32_t pp = *reinterpret_cast<int32_t*>(
+ code + Code::object_pool_offset() - kHeapObjectTag);
+ set_register(CODE_REG, code);
+ set_register(PP, pp);
buf->Longjmp();
}
diff --git a/runtime/vm/stub_code.h b/runtime/vm/stub_code.h
index e961342..c179cac 100644
--- a/runtime/vm/stub_code.h
+++ b/runtime/vm/stub_code.h
@@ -37,6 +37,7 @@
V(OptimizeFunction) \
V(InvokeDartCode) \
V(DebugStepCheck) \
+ V(UnlinkedCall) \
V(MonomorphicMiss) \
V(SingleTargetCall) \
V(ICCallThroughFunction) \
diff --git a/runtime/vm/stub_code_arm.cc b/runtime/vm/stub_code_arm.cc
index 82c50a1..c000508 100644
--- a/runtime/vm/stub_code_arm.cc
+++ b/runtime/vm/stub_code_arm.cc
@@ -286,7 +286,7 @@
// calling into the runtime.
__ EnterStubFrame();
// Setup space on stack for return value and preserve arguments descriptor.
- __ LoadObject(R0, Object::null_object());
+ __ LoadImmediate(R0, 0);
__ PushList((1 << R0) | (1 << R4));
__ CallRuntime(kPatchStaticCallRuntimeEntry, 0);
// Get Code object result and restore arguments descriptor array.
@@ -312,7 +312,7 @@
// calling into the runtime.
__ EnterStubFrame();
// Setup space on stack for return value and preserve arguments descriptor.
- __ LoadObject(R0, Object::null_object());
+ __ LoadImmediate(R0, 0);
__ PushList((1 << R0) | (1 << R4));
__ CallRuntime(kFixCallersTargetRuntimeEntry, 0);
// Get Code object result and restore arguments descriptor array.
@@ -335,7 +335,7 @@
__ ldr(CODE_REG, Address(THR, Thread::fix_allocation_stub_code_offset()));
__ EnterStubFrame();
// Setup space on stack for return value.
- __ LoadObject(R0, Object::null_object());
+ __ LoadImmediate(R0, 0);
__ Push(R0);
__ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0);
// Get Code object result.
@@ -542,7 +542,8 @@
__ ldr(R2, FieldAddress(R4, ArgumentsDescriptor::count_offset()));
__ add(IP, FP, Operand(R2, LSL, 1)); // R2 is Smi.
__ ldr(R8, Address(IP, kParamEndSlotFromFp * kWordSize));
- __ PushObject(Object::null_object());
+ __ LoadImmediate(IP, 0);
+ __ Push(IP); // Result slot.
__ Push(R8); // Receiver.
__ Push(R9); // ICData/MegamorphicCache.
__ Push(R4); // Arguments descriptor.
@@ -568,8 +569,8 @@
// Preserve IC data and arguments descriptor.
__ PushList((1 << R4) | (1 << R9));
- __ LoadObject(IP, Object::null_object());
- __ Push(IP); // result
+ __ LoadImmediate(IP, 0);
+ __ Push(IP); // result slot
__ Push(R8); // receiver
__ Push(R9); // ICData
__ Push(R4); // arguments descriptor
@@ -710,7 +711,7 @@
// Create a stub frame as we are pushing some objects on the stack before
// calling into the runtime.
__ EnterStubFrame();
- __ LoadObject(IP, Object::null_object());
+ __ LoadImmediate(IP, 0);
// Setup space on stack for return value.
// Push array length as Smi and element type.
__ PushList((1 << R1) | (1 << R2) | (1 << IP));
@@ -952,7 +953,7 @@
// calling into the runtime.
__ EnterStubFrame();
// Setup space on stack for return value.
- __ LoadObject(R2, Object::null_object());
+ __ LoadImmediate(R2, 0);
__ SmiTag(R1);
__ PushList((1 << R1) | (1 << R2));
__ CallRuntime(kAllocateContextRuntimeEntry, 1); // Allocate context.
@@ -1193,7 +1194,7 @@
// Push space for the return value.
// Push the receiver.
// Push arguments descriptor array.
- __ LoadObject(IP, Object::null_object());
+ __ LoadImmediate(IP, 0);
__ PushList((1 << R4) | (1 << R8) | (1 << IP));
// R2: Smi-tagged arguments array length.
@@ -1422,7 +1423,7 @@
// Create a stub frame as we are pushing some objects on the stack before
// calling into the runtime.
__ EnterStubFrame();
- __ LoadObject(R0, Object::null_object());
+ __ LoadImmediate(R0, 0);
// Preserve IC data object and arguments descriptor array and
// setup space on stack for result (target code object).
__ PushList((1 << R0) | (1 << R4) | (1 << R9));
@@ -1655,7 +1656,7 @@
// R9: Contains an ICData.
void StubCode::GenerateICCallBreakpointStub(Assembler* assembler) {
__ EnterStubFrame();
- __ LoadObject(R0, Object::null_object());
+ __ LoadImmediate(R0, 0);
// Preserve arguments descriptor and make room for result.
__ PushList((1 << R0) | (1 << R9));
__ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
@@ -1669,7 +1670,7 @@
void StubCode::GenerateRuntimeCallBreakpointStub(Assembler* assembler) {
__ EnterStubFrame();
- __ LoadObject(R0, Object::null_object());
+ __ LoadImmediate(R0, 0);
// Make room for result.
__ PushList((1 << R0));
__ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
@@ -1841,6 +1842,9 @@
// Clear top exit frame.
__ LoadImmediate(R2, 0);
__ StoreToOffset(kWord, R2, THR, Thread::top_exit_frame_info_offset());
+ // Restore the pool pointer.
+ __ RestoreCodePointer();
+ __ LoadPoolPointer();
__ bx(LR); // Jump to the exception handler code.
}
@@ -1851,7 +1855,7 @@
void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) {
__ EnterStubFrame();
__ Push(R4);
- __ LoadObject(IP, Object::null_object());
+ __ LoadImmediate(IP, 0);
__ Push(IP); // Setup space on stack for return value.
__ Push(R8);
__ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1);
@@ -2125,6 +2129,32 @@
// Called from switchable IC calls.
// R0: receiver
+// R9: UnlinkedCall
+void StubCode::GenerateUnlinkedCallStub(Assembler* assembler) {
+ __ NoMonomorphicCheckedEntry();
+
+ __ EnterStubFrame();
+ __ Push(R0); // Preserve receiver.
+
+ __ LoadImmediate(IP, 0);
+ __ Push(IP); // Result slot
+ __ Push(R0); // Arg0: Receiver
+ __ Push(R9); // Arg1: UnlinkedCall
+ __ CallRuntime(kUnlinkedCallRuntimeEntry, 2);
+ __ Drop(2);
+ __ Pop(R9); // result = IC
+
+ __ Pop(R0); // Restore receiver.
+ __ LeaveStubFrame();
+
+ __ ldr(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset()));
+ __ ldr(R1, FieldAddress(CODE_REG, Code::checked_entry_point_offset()));
+ __ bx(R1);
+}
+
+
+// Called from switchable IC calls.
+// R0: receiver
// R9: SingleTargetCache
// Passed to target:
// CODE_REG: target Code object
@@ -2150,8 +2180,9 @@
__ EnterStubFrame();
__ Push(R0); // Preserve receiver.
- __ PushObject(Object::null_object()); // Result.
- __ Push(R0); // Arg0: Receiver
+ __ LoadImmediate(IP, 0);
+ __ Push(IP); // Result slot
+ __ Push(R0); // Arg0: Receiver
__ CallRuntime(kSingleTargetMissRuntimeEntry, 1);
__ Drop(1);
__ Pop(R9); // result = IC
@@ -2171,8 +2202,9 @@
__ EnterStubFrame();
__ Push(R0); // Preserve receiver.
- __ PushObject(Object::null_object()); // Result.
- __ Push(R0); // Arg0: Receiver
+ __ LoadImmediate(IP, 0);
+ __ Push(IP); // Result slot
+ __ Push(R0); // Arg0: Receiver
__ CallRuntime(kMonomorphicMissRuntimeEntry, 1);
__ Drop(1);
__ Pop(R9); // result = IC
diff --git a/runtime/vm/stub_code_arm64.cc b/runtime/vm/stub_code_arm64.cc
index f550777..6d97d6a 100644
--- a/runtime/vm/stub_code_arm64.cc
+++ b/runtime/vm/stub_code_arm64.cc
@@ -324,7 +324,7 @@
__ EnterStubFrame();
// Setup space on stack for return value and preserve arguments descriptor.
__ Push(R4);
- __ PushObject(Object::null_object());
+ __ Push(ZR);
__ CallRuntime(kPatchStaticCallRuntimeEntry, 0);
// Get Code object result and restore arguments descriptor array.
__ Pop(CODE_REG);
@@ -350,7 +350,7 @@
__ EnterStubFrame();
// Setup space on stack for return value and preserve arguments descriptor.
__ Push(R4);
- __ PushObject(Object::null_object());
+ __ Push(ZR);
__ CallRuntime(kFixCallersTargetRuntimeEntry, 0);
// Get Code object result and restore arguments descriptor array.
__ Pop(CODE_REG);
@@ -372,7 +372,7 @@
__ ldr(CODE_REG, Address(THR, Thread::fix_allocation_stub_code_offset()));
__ EnterStubFrame();
// Setup space on stack for return value.
- __ PushObject(Object::null_object());
+ __ Push(ZR);
__ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0);
// Get Code object result.
__ Pop(CODE_REG);
@@ -563,7 +563,7 @@
__ LoadFieldFromOffset(R2, R4, ArgumentsDescriptor::count_offset());
__ add(TMP, FP, Operand(R2, LSL, 2)); // R2 is Smi.
__ LoadFromOffset(R6, TMP, kParamEndSlotFromFp * kWordSize);
- __ PushObject(Object::null_object());
+ __ Push(ZR); // Result slot.
__ Push(R6); // Receiver.
__ Push(R5); // ICData/MegamorphicCache.
__ Push(R4); // Arguments descriptor.
@@ -594,7 +594,7 @@
// Push the receiver.
// Push IC data object.
// Push arguments descriptor array.
- __ PushObject(Object::null_object());
+ __ Push(ZR);
__ Push(R6);
__ Push(R5);
__ Push(R4);
@@ -756,7 +756,7 @@
__ EnterStubFrame();
// Setup space on stack for return value.
// Push array length as Smi and element type.
- __ PushObject(Object::null_object());
+ __ Push(ZR);
__ Push(R2);
__ Push(R1);
__ CallRuntime(kAllocateArrayRuntimeEntry, 2);
@@ -1189,8 +1189,7 @@
// Create a stub frame as we are pushing some objects on the stack before
// calling into the runtime.
__ EnterStubFrame(); // Uses pool pointer to pass cls to runtime.
- // Setup space on stack for return value.
- __ PushObject(Object::null_object());
+ __ Push(ZR); // Result slot.
__ PushObject(cls); // Push class of object to be allocated.
if (is_cls_parameterized) {
// Push type arguments.
@@ -1227,7 +1226,7 @@
// Push space for the return value.
// Push the receiver.
// Push arguments descriptor array.
- __ PushObject(Object::null_object());
+ __ Push(ZR);
__ Push(R6);
__ Push(R4);
@@ -1482,7 +1481,7 @@
__ Push(R4); // Preserve arguments descriptor array.
__ Push(R5); // Preserve IC Data.
// Setup space on stack for the result (target code object).
- __ PushObject(Object::null_object());
+ __ Push(ZR);
// Push call arguments.
for (intptr_t i = 0; i < num_args; i++) {
__ LoadFromOffset(TMP, R7, -i * kWordSize);
@@ -1713,7 +1712,7 @@
void StubCode::GenerateICCallBreakpointStub(Assembler* assembler) {
__ EnterStubFrame();
__ Push(R5);
- __ PushObject(Object::null_object()); // Space for result.
+ __ Push(ZR); // Space for result.
__ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
__ Pop(CODE_REG);
__ Pop(R5);
@@ -1725,7 +1724,7 @@
void StubCode::GenerateRuntimeCallBreakpointStub(Assembler* assembler) {
__ EnterStubFrame();
- __ PushObject(Object::null_object()); // Space for result.
+ __ Push(ZR); // Space for result.
__ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
__ Pop(CODE_REG);
__ LeaveStubFrame();
@@ -1895,6 +1894,9 @@
__ StoreToOffset(R2, THR, Thread::vm_tag_offset());
// Clear top exit frame.
__ StoreToOffset(ZR, THR, Thread::top_exit_frame_info_offset());
+ // Restore the pool pointer.
+ __ RestoreCodePointer();
+ __ LoadPoolPointer();
__ ret(); // Jump to the exception handler code.
}
@@ -1906,7 +1908,7 @@
__ EnterStubFrame();
__ Push(R4);
// Setup space on stack for the return value.
- __ PushObject(Object::null_object());
+ __ Push(ZR);
__ Push(R6);
__ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1);
__ Pop(R0); // Discard argument.
@@ -2186,6 +2188,31 @@
// Called from switchable IC calls.
// R0: receiver
// R5: SingleTargetCache
+void StubCode::GenerateUnlinkedCallStub(Assembler* assembler) {
+ __ NoMonomorphicCheckedEntry();
+
+ __ EnterStubFrame();
+ __ Push(R0); // Preserve receiver.
+
+ __ Push(ZR); // Result slot.
+ __ Push(R0); // Arg0: Receiver
+ __ Push(R5); // Arg1: UnlinkedCall
+ __ CallRuntime(kUnlinkedCallRuntimeEntry, 2);
+ __ Drop(2);
+ __ Pop(R5); // result = IC
+
+ __ Pop(R0); // Restore receiver.
+ __ LeaveStubFrame();
+
+ __ ldr(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset()));
+ __ ldr(R1, FieldAddress(CODE_REG, Code::checked_entry_point_offset()));
+ __ br(R1);
+}
+
+
+// Called from switchable IC calls.
+// R0: receiver
+// R5: SingleTargetCache
// Passed to target:
// CODE_REG: target Code object
void StubCode::GenerateSingleTargetCallStub(Assembler* assembler) {
@@ -2212,8 +2239,8 @@
__ EnterStubFrame();
__ Push(R0); // Preserve receiver.
- __ PushObject(Object::null_object()); // Result.
- __ Push(R0); // Arg0: Receiver
+ __ Push(ZR); // Result slot.
+ __ Push(R0); // Arg0: Receiver
__ CallRuntime(kSingleTargetMissRuntimeEntry, 1);
__ Drop(1);
__ Pop(R5); // result = IC
@@ -2233,8 +2260,8 @@
__ EnterStubFrame();
__ Push(R0); // Preserve receiver.
- __ PushObject(Object::null_object()); // Result.
- __ Push(R0); // Arg0: Receiver
+ __ Push(ZR); // Result slot.
+ __ Push(R0); // Arg0: Receiver
__ CallRuntime(kMonomorphicMissRuntimeEntry, 1);
__ Drop(1);
__ Pop(R5); // result = IC
diff --git a/runtime/vm/stub_code_ia32.cc b/runtime/vm/stub_code_ia32.cc
index 3b1ba83..cb805c6 100644
--- a/runtime/vm/stub_code_ia32.cc
+++ b/runtime/vm/stub_code_ia32.cc
@@ -248,11 +248,9 @@
// Input parameters:
// EDX: arguments descriptor array.
void StubCode::GenerateCallStaticFunctionStub(Assembler* assembler) {
- const Immediate& raw_null =
- Immediate(reinterpret_cast<intptr_t>(Object::null()));
__ EnterStubFrame();
__ pushl(EDX); // Preserve arguments descriptor array.
- __ pushl(raw_null); // Setup space on stack for return value.
+ __ pushl(Immediate(0)); // Setup space on stack for return value.
__ CallRuntime(kPatchStaticCallRuntimeEntry, 0);
__ popl(EAX); // Get Code object result.
__ popl(EDX); // Restore arguments descriptor array.
@@ -268,13 +266,11 @@
// (invalid because its function was optimized or deoptimized).
// EDX: arguments descriptor array.
void StubCode::GenerateFixCallersTargetStub(Assembler* assembler) {
- const Immediate& raw_null =
- Immediate(reinterpret_cast<intptr_t>(Object::null()));
// Create a stub frame as we are pushing some objects on the stack before
// calling into the runtime.
__ EnterStubFrame();
__ pushl(EDX); // Preserve arguments descriptor array.
- __ pushl(raw_null); // Setup space on stack for return value.
+ __ pushl(Immediate(0)); // Setup space on stack for return value.
__ CallRuntime(kFixCallersTargetRuntimeEntry, 0);
__ popl(EAX); // Get Code object.
__ popl(EDX); // Restore arguments descriptor array.
@@ -288,10 +284,8 @@
// Called from object allocate instruction when the allocation stub has been
// disabled.
void StubCode::GenerateFixAllocationStubTargetStub(Assembler* assembler) {
- const Immediate& raw_null =
- Immediate(reinterpret_cast<intptr_t>(Object::null()));
__ EnterStubFrame();
- __ pushl(raw_null); // Setup space on stack for return value.
+ __ pushl(Immediate(0)); // Setup space on stack for return value.
__ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0);
__ popl(EAX); // Get Code object.
__ movl(EAX, FieldAddress(EAX, Code::entry_point_offset()));
@@ -476,7 +470,7 @@
__ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
__ movl(EAX, Address(
EBP, EDI, TIMES_HALF_WORD_SIZE, kParamEndSlotFromFp * kWordSize));
- __ pushl(raw_null); // Setup space on stack for result.
+ __ pushl(Immediate(0)); // Setup space on stack for result.
__ pushl(EAX); // Receiver.
__ pushl(ECX); // ICData/MegamorphicCache.
__ pushl(EDX); // Arguments descriptor array.
@@ -504,9 +498,7 @@
__ pushl(ECX);
__ pushl(EDX);
- const Immediate& raw_null =
- Immediate(reinterpret_cast<intptr_t>(Instructions::null()));
- __ pushl(raw_null); // Space for the result of the runtime call.
+ __ pushl(Immediate(0)); // Space for the result of the runtime call.
__ pushl(EAX); // Pass receiver.
__ pushl(ECX); // Pass IC data.
__ pushl(EDX); // Pass arguments descriptor.
@@ -539,8 +531,6 @@
// The newly allocated object is returned in EAX.
void StubCode::GenerateAllocateArrayStub(Assembler* assembler) {
Label slow_case;
- const Immediate& raw_null =
- Immediate(reinterpret_cast<intptr_t>(Object::null()));
// Compute the size to be allocated, it is based on the array length
// and is computed as:
// RoundedAllocationSize((array_length * kwordSize) + sizeof(RawArray)).
@@ -661,7 +651,7 @@
// Create a stub frame as we are pushing some objects on the stack before
// calling into the runtime.
__ EnterStubFrame();
- __ pushl(raw_null); // Setup space on stack for return value.
+ __ pushl(Immediate(0)); // Setup space on stack for return value.
__ pushl(EDX); // Array length as Smi.
__ pushl(ECX); // Element type.
__ CallRuntime(kAllocateArrayRuntimeEntry, 2);
@@ -789,8 +779,6 @@
// EAX: new allocated RawContext object.
// EBX and EDX are destroyed.
void StubCode::GenerateAllocateContextStub(Assembler* assembler) {
- const Immediate& raw_null =
- Immediate(reinterpret_cast<intptr_t>(Object::null()));
if (FLAG_inline_alloc) {
Label slow_case;
// First compute the rounded instance size.
@@ -905,7 +893,7 @@
// Create a stub frame as we are pushing some objects on the stack before
// calling into the runtime.
__ EnterStubFrame();
- __ pushl(raw_null); // Setup space on stack for return value.
+ __ pushl(Immediate(0)); // Setup space on stack for return value.
__ SmiTag(EDX);
__ pushl(EDX);
__ CallRuntime(kAllocateContextRuntimeEntry, 1); // Allocate context.
@@ -1133,9 +1121,7 @@
__ movl(EDI, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
__ movl(EAX, Address(EBP, EDI, TIMES_2, kParamEndSlotFromFp * kWordSize));
- const Immediate& raw_null =
- Immediate(reinterpret_cast<intptr_t>(Object::null()));
- __ pushl(raw_null); // Setup space on stack for result from noSuchMethod.
+ __ pushl(Immediate(0)); // Setup space on stack for result from noSuchMethod.
__ pushl(EAX); // Receiver.
__ pushl(EDX); // Arguments descriptor array.
@@ -1368,8 +1354,6 @@
__ j(NOT_EQUAL, &loop, Assembler::kNearJump);
__ Comment("IC miss");
- const Immediate& raw_null =
- Immediate(reinterpret_cast<intptr_t>(Object::null()));
// Compute address of arguments (first read number of arguments from
// arguments descriptor array and then compute address on the stack).
__ movl(EAX, FieldAddress(EDX, ArgumentsDescriptor::count_offset()));
@@ -1379,7 +1363,7 @@
__ EnterStubFrame();
__ pushl(EDX); // Preserve arguments descriptor array.
__ pushl(ECX); // Preserve IC data object.
- __ pushl(raw_null); // Setup space on stack for result (target code object).
+ __ pushl(Immediate(0)); // Result slot.
// Push call arguments.
for (intptr_t i = 0; i < num_args; i++) {
__ movl(EBX, Address(EAX, -kWordSize * i));
@@ -1624,9 +1608,7 @@
__ pushl(ECX);
// Room for result. Debugger stub returns address of the
// unpatched runtime stub.
- const Immediate& raw_null =
- Immediate(reinterpret_cast<intptr_t>(Object::null()));
- __ pushl(raw_null); // Room for result.
+ __ pushl(Immediate(0)); // Room for result.
__ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
__ popl(EAX); // Code of original stub.
__ popl(ECX); // Restore IC data.
@@ -1641,9 +1623,7 @@
__ EnterStubFrame();
// Room for result. Debugger stub returns address of the
// unpatched runtime stub.
- const Immediate& raw_null =
- Immediate(reinterpret_cast<intptr_t>(Object::null()));
- __ pushl(raw_null); // Room for result.
+ __ pushl(Immediate(0)); // Room for result.
__ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
__ popl(EAX); // Code of the original stub
__ LeaveFrame();
@@ -1827,11 +1807,9 @@
// EBX: function to be reoptimized.
// EDX: argument descriptor (preserved).
void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) {
- const Immediate& raw_null =
- Immediate(reinterpret_cast<intptr_t>(Object::null()));
__ EnterStubFrame();
__ pushl(EDX);
- __ pushl(raw_null); // Setup space on stack for return value.
+ __ pushl(Immediate(0)); // Setup space on stack for return value.
__ pushl(EBX);
__ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1);
__ popl(EAX); // Discard argument.
@@ -2044,6 +2022,11 @@
}
+void StubCode::GenerateUnlinkedCallStub(Assembler* assembler) {
+ __ int3();
+}
+
+
void StubCode::GenerateSingleTargetCallStub(Assembler* assembler) {
__ int3();
}
diff --git a/runtime/vm/stub_code_mips.cc b/runtime/vm/stub_code_mips.cc
index 6560d9f..e6384d8 100644
--- a/runtime/vm/stub_code_mips.cc
+++ b/runtime/vm/stub_code_mips.cc
@@ -299,8 +299,7 @@
__ addiu(SP, SP, Immediate(-2 * kWordSize));
__ sw(S4, Address(SP, 1 * kWordSize));
- __ LoadObject(TMP, Object::null_object());
- __ sw(TMP, Address(SP, 0 * kWordSize));
+ __ sw(ZR, Address(SP, 0 * kWordSize));
__ CallRuntime(kPatchStaticCallRuntimeEntry, 0);
__ Comment("CallStaticFunctionStub return");
@@ -331,8 +330,7 @@
// Setup space on stack for return value and preserve arguments descriptor.
__ addiu(SP, SP, Immediate(-2 * kWordSize));
__ sw(S4, Address(SP, 1 * kWordSize));
- __ LoadObject(TMP, Object::null_object());
- __ sw(TMP, Address(SP, 0 * kWordSize));
+ __ sw(ZR, Address(SP, 0 * kWordSize));
__ CallRuntime(kFixCallersTargetRuntimeEntry, 0);
// Get Code object result and restore arguments descriptor array.
__ lw(CODE_REG, Address(SP, 0 * kWordSize));
@@ -357,8 +355,7 @@
__ EnterStubFrame();
// Setup space on stack for return value.
__ addiu(SP, SP, Immediate(-1 * kWordSize));
- __ LoadObject(TMP, Object::null_object());
- __ sw(TMP, Address(SP, 0 * kWordSize));
+ __ sw(ZR, Address(SP, 0 * kWordSize));
__ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0);
// Get Code object result.
__ lw(CODE_REG, Address(SP, 0 * kWordSize));
@@ -564,8 +561,7 @@
// Push arguments descriptor array.
// Push original arguments array.
__ addiu(SP, SP, Immediate(-4 * kWordSize));
- __ LoadObject(TMP, Object::null_object());
- __ sw(TMP, Address(SP, 3 * kWordSize));
+ __ sw(ZR, Address(SP, 3 * kWordSize));
__ sw(T6, Address(SP, 2 * kWordSize));
__ sw(S5, Address(SP, 1 * kWordSize));
__ sw(S4, Address(SP, 0 * kWordSize));
@@ -598,8 +594,7 @@
// Push the receiver.
// Push IC data object.
// Push arguments descriptor array.
- __ LoadObject(TMP, Object::null_object());
- __ sw(TMP, Address(SP, 3 * kWordSize));
+ __ sw(ZR, Address(SP, 3 * kWordSize));
__ sw(T6, Address(SP, 2 * kWordSize));
__ sw(S5, Address(SP, 1 * kWordSize));
__ sw(S4, Address(SP, 0 * kWordSize));
@@ -757,8 +752,7 @@
// Setup space on stack for return value.
// Push array length as Smi and element type.
__ addiu(SP, SP, Immediate(-3 * kWordSize));
- __ LoadObject(TMP, Object::null_object());
- __ sw(TMP, Address(SP, 2 * kWordSize));
+ __ sw(ZR, Address(SP, 2 * kWordSize));
__ sw(A1, Address(SP, 1 * kWordSize));
__ sw(A0, Address(SP, 0 * kWordSize));
__ CallRuntime(kAllocateArrayRuntimeEntry, 2);
@@ -1260,8 +1254,7 @@
// Push arguments descriptor array.
const intptr_t kNumArgs = 3;
__ addiu(SP, SP, Immediate(-kNumArgs * kWordSize));
- __ LoadObject(TMP, Object::null_object());
- __ sw(TMP, Address(SP, 2 * kWordSize));
+ __ sw(ZR, Address(SP, 2 * kWordSize));
__ sw(T6, Address(SP, 1 * kWordSize));
__ sw(S4, Address(SP, 0 * kWordSize));
@@ -1524,8 +1517,7 @@
__ addiu(SP, SP, Immediate(-num_slots * kWordSize));
__ sw(S5, Address(SP, (num_slots - 1) * kWordSize));
__ sw(S4, Address(SP, (num_slots - 2) * kWordSize));
- __ LoadObject(TMP, Object::null_object());
- __ sw(TMP, Address(SP, (num_slots - 3) * kWordSize));
+ __ sw(ZR, Address(SP, (num_slots - 3) * kWordSize));
// Push call arguments.
for (intptr_t i = 0; i < num_args; i++) {
__ lw(TMP, Address(T1, -i * kWordSize));
@@ -1777,8 +1769,7 @@
__ EnterStubFrame();
__ addiu(SP, SP, Immediate(-2 * kWordSize));
__ sw(S5, Address(SP, 1 * kWordSize));
- __ LoadObject(TMP, Object::null_object());
- __ sw(TMP, Address(SP, 0 * kWordSize));
+ __ sw(ZR, Address(SP, 0 * kWordSize));
__ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
@@ -1795,8 +1786,7 @@
__ Comment("RuntimeCallBreakpoint stub");
__ EnterStubFrame();
__ addiu(SP, SP, Immediate(-1 * kWordSize));
- __ LoadObject(TMP, Object::null_object());
- __ sw(TMP, Address(SP, 0 * kWordSize));
+ __ sw(ZR, Address(SP, 0 * kWordSize));
__ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
@@ -1977,7 +1967,9 @@
__ sw(A2, Assembler::VMTagAddress());
// Clear top exit frame.
__ sw(ZR, Address(THR, Thread::top_exit_frame_info_offset()));
-
+ // Restore pool pointer.
+ __ RestoreCodePointer();
+ __ LoadPoolPointer();
__ jr(A0); // Jump to the exception handler code.
__ delay_slot()->mov(SP, A1); // Stack pointer.
}
@@ -1992,8 +1984,7 @@
__ addiu(SP, SP, Immediate(-3 * kWordSize));
__ sw(S4, Address(SP, 2 * kWordSize));
// Setup space on stack for return value.
- __ LoadObject(TMP, Object::null_object());
- __ sw(TMP, Address(SP, 1 * kWordSize));
+ __ sw(ZR, Address(SP, 1 * kWordSize));
__ sw(T0, Address(SP, 0 * kWordSize));
__ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1);
__ Comment("OptimizeFunctionStub return");
@@ -2277,6 +2268,30 @@
}
+// Called from switchable IC calls.
+// T0: receiver
+// S5: SingleTargetCache
+void StubCode::GenerateUnlinkedCallStub(Assembler* assembler) {
+ __ NoMonomorphicCheckedEntry();
+
+ __ EnterStubFrame();
+ __ Push(T0); // Preserve receiver.
+
+ __ Push(ZR); // Result slot.
+ __ Push(T0); // Arg0: Receiver
+ __ Push(S5); // Arg1: UnlinkedCall
+ __ CallRuntime(kUnlinkedCallRuntimeEntry, 2);
+ __ Drop(2);
+ __ Pop(S5); // result = IC
+
+ __ Pop(T0); // Restore receiver.
+ __ LeaveStubFrame();
+
+ __ lw(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset()));
+ __ lw(T1, FieldAddress(CODE_REG, Code::checked_entry_point_offset()));
+ __ jr(T1);
+}
+
// Called from switchable IC calls.
// T0: receiver
@@ -2303,8 +2318,8 @@
__ EnterStubFrame();
__ Push(T0); // Preserve receiver.
- __ PushObject(Object::null_object()); // Result.
- __ Push(T0); // Arg0: Receiver
+ __ Push(ZR); // Result slot.
+ __ Push(T0); // Arg0: Receiver
__ CallRuntime(kSingleTargetMissRuntimeEntry, 1);
__ Drop(1);
__ Pop(S5); // result = IC
@@ -2324,8 +2339,8 @@
__ EnterStubFrame();
__ Push(T0); // Preserve receiver.
- __ PushObject(Object::null_object()); // Result.
- __ Push(T0); // Arg0: Receiver
+ __ Push(ZR); // Result slot.
+ __ Push(T0); // Arg0: Receiver
__ CallRuntime(kMonomorphicMissRuntimeEntry, 1);
__ Drop(1);
__ Pop(S5); // result = IC
diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
index daf1e5e..5c4384c 100644
--- a/runtime/vm/stub_code_x64.cc
+++ b/runtime/vm/stub_code_x64.cc
@@ -261,7 +261,7 @@
__ EnterStubFrame();
__ pushq(R10); // Preserve arguments descriptor array.
// Setup space on stack for return value.
- __ PushObject(Object::null_object());
+ __ pushq(Immediate(0));
__ CallRuntime(kPatchStaticCallRuntimeEntry, 0);
__ popq(CODE_REG); // Get Code object result.
__ popq(R10); // Restore arguments descriptor array.
@@ -284,7 +284,7 @@
__ EnterStubFrame();
__ pushq(R10); // Preserve arguments descriptor array.
// Setup space on stack for return value.
- __ PushObject(Object::null_object());
+ __ pushq(Immediate(0));
__ CallRuntime(kFixCallersTargetRuntimeEntry, 0);
__ popq(CODE_REG); // Get Code object.
__ popq(R10); // Restore arguments descriptor array.
@@ -304,7 +304,7 @@
__ movq(CODE_REG, Address(THR, Thread::fix_allocation_stub_code_offset()));
__ EnterStubFrame();
// Setup space on stack for return value.
- __ PushObject(Object::null_object());
+ __ pushq(Immediate(0));
__ CallRuntime(kFixAllocationStubTargetRuntimeEntry, 0);
__ popq(CODE_REG); // Get Code object.
__ movq(RAX, FieldAddress(CODE_REG, Code::entry_point_offset()));
@@ -505,7 +505,7 @@
__ movq(RDI, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
__ movq(RAX, Address(
RBP, RDI, TIMES_HALF_WORD_SIZE, kParamEndSlotFromFp * kWordSize));
- __ PushObject(Object::null_object()); // Setup space on stack for result.
+ __ pushq(Immediate(0)); // Setup space on stack for result.
__ pushq(RAX); // Receiver.
__ pushq(RBX); // ICData/MegamorphicCache.
__ pushq(R10); // Arguments descriptor array.
@@ -535,7 +535,7 @@
__ pushq(R10);
// Space for the result of the runtime call.
- __ PushObject(Object::null_object());
+ __ pushq(Immediate(0));
__ pushq(RAX); // Receiver.
__ pushq(RBX); // IC data.
__ pushq(R10); // Arguments descriptor.
@@ -682,7 +682,7 @@
// calling into the runtime.
__ EnterStubFrame();
// Setup space on stack for return value.
- __ PushObject(Object::null_object());
+ __ pushq(Immediate(0));
__ pushq(R10); // Array length as Smi.
__ pushq(RBX); // Element type.
__ CallRuntime(kAllocateArrayRuntimeEntry, 2);
@@ -1168,8 +1168,7 @@
__ movq(R13, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
__ movq(RAX, Address(RBP, R13, TIMES_4, kParamEndSlotFromFp * kWordSize));
- __ LoadObject(R12, Object::null_object());
- __ pushq(R12); // Setup space on stack for result from noSuchMethod.
+ __ pushq(Immediate(0)); // Result slot.
__ pushq(RAX); // Receiver.
__ pushq(R10); // Arguments descriptor array.
@@ -1400,7 +1399,6 @@
__ j(NOT_EQUAL, &loop, Assembler::kNearJump);
__ Comment("IC miss");
- __ LoadObject(R13, Object::null_object());
// Compute address of arguments (first read number of arguments from
// arguments descriptor array and then compute address on the stack).
__ movq(RAX, FieldAddress(R10, ArgumentsDescriptor::count_offset()));
@@ -1408,7 +1406,7 @@
__ EnterStubFrame();
__ pushq(R10); // Preserve arguments descriptor array.
__ pushq(RBX); // Preserve IC data object.
- __ pushq(R13); // Setup space on stack for result (target code object).
+ __ pushq(Immediate(0)); // Result slot.
// Push call arguments.
for (intptr_t i = 0; i < num_args; i++) {
__ movq(RCX, Address(RAX, -kWordSize * i));
@@ -1667,14 +1665,10 @@
// TOS(0): return address (Dart code).
void StubCode::GenerateICCallBreakpointStub(Assembler* assembler) {
__ EnterStubFrame();
- // Preserve IC data.
- __ pushq(RBX);
- // Room for result. Debugger stub returns address of the
- // unpatched runtime stub.
- __ LoadObject(R12, Object::null_object());
- __ pushq(R12); // Room for result.
+ __ pushq(RBX); // Preserve IC data.
+ __ pushq(Immediate(0)); // Result slot.
__ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
- __ popq(CODE_REG); // Address of original.
+ __ popq(CODE_REG); // Original stub.
__ popq(RBX); // Restore IC data.
__ LeaveStubFrame();
@@ -1686,12 +1680,9 @@
// TOS(0): return address (Dart code).
void StubCode::GenerateRuntimeCallBreakpointStub(Assembler* assembler) {
__ EnterStubFrame();
- // Room for result. Debugger stub returns address of the
- // unpatched runtime stub.
- __ LoadObject(R12, Object::null_object());
- __ pushq(R12); // Room for result.
+ __ pushq(Immediate(0)); // Result slot.
__ CallRuntime(kBreakpointRuntimeHandlerRuntimeEntry, 0);
- __ popq(CODE_REG); // Address of original.
+ __ popq(CODE_REG); // Original stub.
__ LeaveStubFrame();
__ movq(RAX, FieldAddress(CODE_REG, Code::entry_point_offset()));
@@ -1874,6 +1865,9 @@
// Clear top exit frame.
__ movq(Address(THR, Thread::top_exit_frame_info_offset()),
Immediate(0));
+ // Restore the pool pointer.
+ __ RestoreCodePointer();
+ __ LoadPoolPointer(PP);
__ jmp(CallingConventions::kArg1Reg); // Jump to the exception handler code.
}
@@ -1883,10 +1877,9 @@
// R10: argument descriptor (preserved).
void StubCode::GenerateOptimizeFunctionStub(Assembler* assembler) {
__ EnterStubFrame();
- __ LoadObject(R12, Object::null_object());
- __ pushq(R10);
- __ pushq(R12); // Setup space on stack for return value.
- __ pushq(RDI);
+ __ pushq(R10); // Preserve args descriptor.
+ __ pushq(Immediate(0)); // Result slot.
+ __ pushq(RDI); // Arg0: function to optimize
__ CallRuntime(kOptimizeInvokedFunctionRuntimeEntry, 1);
__ popq(RAX); // Disard argument.
__ popq(CODE_REG); // Get Code object.
@@ -2167,6 +2160,31 @@
}
+// RDI: receiver
+// RBX: UnlinkedCall
+void StubCode::GenerateUnlinkedCallStub(Assembler* assembler) {
+ __ NoMonomorphicCheckedEntry();
+
+ __ EnterStubFrame();
+ __ pushq(RDI); // Preserve receiver.
+
+ __ pushq(Immediate(0)); // Result slot.
+ __ pushq(RDI); // Arg0: Receiver
+ __ pushq(RBX); // Arg1: UnlinkedCall
+ __ CallRuntime(kUnlinkedCallRuntimeEntry, 2);
+ __ popq(RBX);
+ __ popq(RBX);
+ __ popq(RBX); // result = IC
+
+ __ popq(RDI); // Restore receiver.
+ __ LeaveStubFrame();
+
+ __ movq(CODE_REG, Address(THR, Thread::ic_lookup_through_code_stub_offset()));
+ __ movq(RCX, FieldAddress(CODE_REG, Code::checked_entry_point_offset()));
+ __ jmp(RCX);
+}
+
+
// Called from switchable IC calls.
// RDI: receiver
// RBX: SingleTargetCache
@@ -2191,8 +2209,8 @@
__ EnterStubFrame();
__ pushq(RDI); // Preserve receiver.
- __ PushObject(Object::null_object()); // Result.
- __ pushq(RDI); // Arg0: Receiver
+ __ pushq(Immediate(0)); // Result slot.
+ __ pushq(RDI); // Arg0: Receiver
__ CallRuntime(kSingleTargetMissRuntimeEntry, 1);
__ popq(RBX);
__ popq(RBX); // result = IC
@@ -2212,8 +2230,8 @@
__ EnterStubFrame();
__ pushq(RDI); // Preserve receiver.
- __ PushObject(Object::null_object()); // Result.
- __ pushq(RDI); // Arg0: Receiver
+ __ pushq(Immediate(0)); // Result slot.
+ __ pushq(RDI); // Arg0: Receiver
__ CallRuntime(kMonomorphicMissRuntimeEntry, 1);
__ popq(RBX);
__ popq(RBX); // result = IC
diff --git a/runtime/vm/symbols.cc b/runtime/vm/symbols.cc
index a0b6c83..0f91fb6 100644
--- a/runtime/vm/symbols.cc
+++ b/runtime/vm/symbols.cc
@@ -5,7 +5,6 @@
#include "vm/symbols.h"
#include "vm/handles.h"
-#include "vm/handles_impl.h"
#include "vm/hash_table.h"
#include "vm/isolate.h"
#include "vm/object.h"
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index 8730c9e..29cdb8a 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -175,6 +175,7 @@
V(Context, "Context") \
V(ContextScope, "ContextScope") \
V(SingleTargetCache, "SingleTargetCache") \
+ V(UnlinkedCall, "UnlinkedCall") \
V(ICData, "ICData") \
V(MegamorphicCache, "MegamorphicCache") \
V(SubtypeTestCache, "SubtypeTestCache") \
diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc
index 967bac0..d3534af 100644
--- a/runtime/vm/thread.cc
+++ b/runtime/vm/thread.cc
@@ -21,6 +21,7 @@
#include "vm/thread_interrupter.h"
#include "vm/thread_registry.h"
#include "vm/timeline.h"
+#include "vm/zone.h"
namespace dart {
@@ -423,6 +424,19 @@
}
+bool Thread::ZoneIsOwnedByThread(Zone* zone) const {
+ ASSERT(zone != NULL);
+ Zone* current = zone_;
+ while (current != NULL) {
+ if (current == zone) {
+ return true;
+ }
+ current = current->previous();
+ }
+ return false;
+}
+
+
void Thread::DeferOOBMessageInterrupts() {
MonitorLocker ml(thread_lock_);
defer_oob_messages_count_++;
@@ -553,10 +567,13 @@
bool Thread::CanCollectGarbage() const {
- // We have non mutator threads grow the heap instead of triggering
- // a garbage collection when they are at a safepoint (e.g: background
- // compiler thread finalizing and installing code at a safepoint).
- return (IsMutatorThread() || IsAtSafepoint());
+ // We grow the heap instead of triggering a garbage collection when a
+ // thread is at a safepoint in the following situations :
+ // - background compiler thread finalizing and installing code
+ // - disassembly of the generated code is done after compilation
+ // So essentially we state that garbage collection is possible only
+ // when we are not at a safepoint.
+ return !IsAtSafepoint();
}
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h
index 149a8e1..50b5c47 100644
--- a/runtime/vm/thread.h
+++ b/runtime/vm/thread.h
@@ -259,6 +259,8 @@
// The topmost zone used for allocation in this thread.
Zone* zone() const { return zone_; }
+ bool ZoneIsOwnedByThread(Zone* zone) const;
+
// The reusable api local scope for this thread.
ApiLocalScope* api_reusable_scope() const { return api_reusable_scope_; }
void set_api_reusable_scope(ApiLocalScope* value) {
diff --git a/runtime/vm/virtual_memory_fuchsia.cc b/runtime/vm/virtual_memory_fuchsia.cc
index b7b8b89..8cbc836 100644
--- a/runtime/vm/virtual_memory_fuchsia.cc
+++ b/runtime/vm/virtual_memory_fuchsia.cc
@@ -26,7 +26,7 @@
VirtualMemory* VirtualMemory::ReserveInternal(intptr_t size) {
- mx_handle_t vmo = mx_vm_object_create(size);
+ mx_handle_t vmo = mx_vmo_create(size);
if (vmo <= 0) {
return NULL;
}
diff --git a/runtime/vm/zone.cc b/runtime/vm/zone.cc
index 743727a..ac79f35 100644
--- a/runtime/vm/zone.cc
+++ b/runtime/vm/zone.cc
@@ -72,6 +72,31 @@
}
+Zone::Zone()
+ : initial_buffer_(buffer_, kInitialChunkSize),
+ position_(initial_buffer_.start()),
+ limit_(initial_buffer_.end()),
+ head_(NULL),
+ large_segments_(NULL),
+ handles_(),
+ previous_(NULL) {
+ ASSERT(Utils::IsAligned(position_, kAlignment));
+#ifdef DEBUG
+ // Zap the entire initial buffer.
+ memset(initial_buffer_.pointer(), kZapUninitializedByte,
+ initial_buffer_.size());
+#endif
+}
+
+
+Zone::~Zone() {
+ if (FLAG_trace_zones) {
+ DumpZoneSizes();
+ }
+ DeleteAll();
+}
+
+
void Zone::DeleteAll() {
// Traverse the chained list of segments, zapping (in debug mode)
// and freeing every zone segment.
@@ -234,4 +259,25 @@
}
+StackZone::StackZone(Thread* thread) : StackResource(thread), zone_() {
+ if (FLAG_trace_zones) {
+ OS::PrintErr("*** Starting a new Stack zone 0x%" Px "(0x%" Px ")\n",
+ reinterpret_cast<intptr_t>(this),
+ reinterpret_cast<intptr_t>(&zone_));
+ }
+ zone_.Link(thread->zone());
+ thread->set_zone(&zone_);
+}
+
+
+StackZone::~StackZone() {
+ ASSERT(thread()->zone() == &zone_);
+ thread()->set_zone(zone_.previous_);
+ if (FLAG_trace_zones) {
+ OS::PrintErr("*** Deleting Stack zone 0x%" Px "(0x%" Px ")\n",
+ reinterpret_cast<intptr_t>(this),
+ reinterpret_cast<intptr_t>(&zone_));
+ }
+}
+
} // namespace dart
diff --git a/runtime/vm/zone.h b/runtime/vm/zone.h
index 29d2765..0d274ad 100644
--- a/runtime/vm/zone.h
+++ b/runtime/vm/zone.h
@@ -70,29 +70,11 @@
void VisitObjectPointers(ObjectPointerVisitor* visitor);
- private:
- Zone()
- : initial_buffer_(buffer_, kInitialChunkSize),
- position_(initial_buffer_.start()),
- limit_(initial_buffer_.end()),
- head_(NULL),
- large_segments_(NULL),
- handles_(),
- previous_(NULL) {
- ASSERT(Utils::IsAligned(position_, kAlignment));
-#ifdef DEBUG
- // Zap the entire initial buffer.
- memset(initial_buffer_.pointer(), kZapUninitializedByte,
- initial_buffer_.size());
-#endif
- }
+ Zone* previous() const { return previous_; }
- ~Zone() { // Delete all memory associated with the zone.
- if (FLAG_trace_zones) {
- DumpZoneSizes();
- }
- DeleteAll();
- }
+ private:
+ Zone();
+ ~Zone(); // Delete all memory associated with the zone.
// All pointers returned from AllocateUnsafe() and New() have this alignment.
static const intptr_t kAlignment = kDoubleSize;
@@ -185,26 +167,10 @@
class StackZone : public StackResource {
public:
// Create an empty zone and set is at the current zone for the Thread.
- explicit StackZone(Thread* thread) : StackResource(thread), zone_() {
- if (FLAG_trace_zones) {
- OS::PrintErr("*** Starting a new Stack zone 0x%" Px "(0x%" Px ")\n",
- reinterpret_cast<intptr_t>(this),
- reinterpret_cast<intptr_t>(&zone_));
- }
- zone_.Link(thread->zone());
- thread->set_zone(&zone_);
- }
+ explicit StackZone(Thread* thread);
// Delete all memory associated with the zone.
- ~StackZone() {
- ASSERT(thread()->zone() == &zone_);
- thread()->set_zone(zone_.previous_);
- if (FLAG_trace_zones) {
- OS::PrintErr("*** Deleting Stack zone 0x%" Px "(0x%" Px ")\n",
- reinterpret_cast<intptr_t>(this),
- reinterpret_cast<intptr_t>(&zone_));
- }
- }
+ ~StackZone();
// Compute the total size of this zone. This includes wasted space that is
// due to internal fragmentation in the segments.
diff --git a/sdk/bin/dart2js b/sdk/bin/dart2js
index 17559bf..d2e9833 100755
--- a/sdk/bin/dart2js
+++ b/sdk/bin/dart2js
@@ -52,4 +52,4 @@
DART2JS="$DART_ROOT/pkg/compiler/lib/src/dart2js.dart"
-exec "$DART" "${EXTRA_VM_OPTIONS[@]}" "$DART2JS" "${EXTRA_OPTIONS[@]}" "$@"
+exec "$DART" "--packages=$DART_ROOT/.packages" "${EXTRA_VM_OPTIONS[@]}" "$DART2JS" "${EXTRA_OPTIONS[@]}" "$@"
diff --git a/sdk/bin/dart2js.bat b/sdk/bin/dart2js.bat
index 4c6669a..7660182 100644
--- a/sdk/bin/dart2js.bat
+++ b/sdk/bin/dart2js.bat
@@ -39,7 +39,7 @@
set DART2JS=%DART_ROOT%\pkg\compiler\lib\src\dart2js.dart
-"%DART%" %EXTRA_VM_OPTIONS% "%DART2JS%" %EXTRA_OPTIONS% %*
+"%DART%" "--packages=%DART_ROOT%\.packages" %EXTRA_VM_OPTIONS% "%DART2JS%" %EXTRA_OPTIONS% %*
endlocal
diff --git a/sdk/bin/dartanalyzer b/sdk/bin/dartanalyzer
index c508c62..34ce895 100755
--- a/sdk/bin/dartanalyzer
+++ b/sdk/bin/dartanalyzer
@@ -45,4 +45,4 @@
ANALYZER="$DART_ROOT/pkg/analyzer_cli/bin/analyzer.dart"
-exec "$DART" "${EXTRA_VM_OPTIONS[@]}" "$ANALYZER" "$SDK_ARG" "$@"
+exec "$DART" "--packages=$DART_ROOT/.packages" "${EXTRA_VM_OPTIONS[@]}" "$ANALYZER" "$SDK_ARG" "$@"
diff --git a/sdk/bin/dartanalyzer.bat b/sdk/bin/dartanalyzer.bat
index f03dfbd..4e8ba54 100644
--- a/sdk/bin/dartanalyzer.bat
+++ b/sdk/bin/dartanalyzer.bat
@@ -40,7 +40,7 @@
set ANALYZER=%DART_ROOT%\pkg\analyzer_cli\bin\analyzer.dart
-"%DART%" %EXTRA_VM_OPTIONS% "%ANALYZER%" "%SDK_ARG%" %*
+"%DART%" "--packages=%DART_ROOT%\.packages" %EXTRA_VM_OPTIONS% "%ANALYZER%" "%SDK_ARG%" %*
endlocal
diff --git a/sdk/bin/dartdevc b/sdk/bin/dartdevc
index 246f6b7..5b75ad2 100755
--- a/sdk/bin/dartdevc
+++ b/sdk/bin/dartdevc
@@ -45,4 +45,4 @@
DEV_COMPILER="$DART_ROOT/pkg/dev_compiler/bin/dartdevc.dart"
-exec "$DART" "${EXTRA_VM_OPTIONS[@]}" "$DEV_COMPILER" "$SDK_ARG" "$@"
+exec "$DART" "--packages=$DART_ROOT/.packages" "${EXTRA_VM_OPTIONS[@]}" "$DEV_COMPILER" "$SDK_ARG" "$@"
diff --git a/sdk/bin/dartdevc.bat b/sdk/bin/dartdevc.bat
index 5c714ca..dd49b43 100644
--- a/sdk/bin/dartdevc.bat
+++ b/sdk/bin/dartdevc.bat
@@ -36,7 +36,7 @@
set DEV_COMPILER=%DART_ROOT%\third_party\pkg\dev_compiler\bin\dartdevc.dart
-"%DART%" %EXTRA_VM_OPTIONS% "DEV_COMPILER%" "%SDK_ARG%" %*
+"%DART%" "--packages=%DART_ROOT%\.packages" %EXTRA_VM_OPTIONS% "DEV_COMPILER%" "%SDK_ARG%" %*
endlocal
diff --git a/sdk/bin/dartfmt b/sdk/bin/dartfmt
index a671c50..ad54140 100755
--- a/sdk/bin/dartfmt
+++ b/sdk/bin/dartfmt
@@ -28,4 +28,4 @@
DARTFMT="$DART_ROOT/third_party/pkg_tested/dart_style/bin/format.dart"
-exec "$DART" "$DARTFMT" "$@"
+exec "$DART" "--packages=$DART_ROOT/.packages" "$DARTFMT" "$@"
diff --git a/sdk/bin/dartfmt.bat b/sdk/bin/dartfmt.bat
index edab2dd..cd59302 100644
--- a/sdk/bin/dartfmt.bat
+++ b/sdk/bin/dartfmt.bat
@@ -27,7 +27,7 @@
set DARTFMT=%DART_ROOT%\third_party\pkg_tested\dart_style\bin\format.dart
-"%DART%" "%DARTFMT%" %*
+"%DART%" "--packages=%DART_ROOT%\.packages" "%DARTFMT%" %*
endlocal
diff --git a/sdk/bin/pub b/sdk/bin/pub
index 403635f..20e9d3d 100755
--- a/sdk/bin/pub
+++ b/sdk/bin/pub
@@ -82,4 +82,4 @@
# Run pub.
PUB="$SDK_DIR/../third_party/pkg/pub/bin/pub.dart"
-exec "$DART" "${VM_OPTIONS[@]}" "$PUB" "$@"
+exec "$DART" "--packages=$SDK_DIR/../.packages" "${VM_OPTIONS[@]}" "$PUB" "$@"
diff --git a/sdk/bin/pub.bat b/sdk/bin/pub.bat
index 03c7bf0..2ad2baa 100644
--- a/sdk/bin/pub.bat
+++ b/sdk/bin/pub.bat
@@ -35,7 +35,7 @@
rem Run pub.
set PUB="%SDK_DIR%\..\third_party\pkg\pub\bin\pub.dart"
-"%DART%" %VM_OPTIONS% "%PUB%" %*
+"%DART%" "--packages=%SDK_DIR%\..\.packages" %VM_OPTIONS% "%PUB%" %*
endlocal
diff --git a/sdk/lib/async/stream.dart b/sdk/lib/async/stream.dart
index f4abf9a..9a9487a 100644
--- a/sdk/lib/async/stream.dart
+++ b/sdk/lib/async/stream.dart
@@ -1767,7 +1767,7 @@
factory StreamIterator(Stream<T> stream)
// TODO(lrn): use redirecting factory constructor when type
// arguments are supported.
- => new _StreamIteratorImpl<T>(stream);
+ => new _StreamIterator<T>(stream);
/**
* Wait for the next stream value to be available.
@@ -1809,7 +1809,7 @@
* automatically closed, you must call [cancel] to ensure that the stream
* is properly closed.
*
- * If [moveNext] has been called when the iterator is cancelled,
+ * If [moveNext] has been called when the iterator is canceled,
* its returned future will complete with `false` as value,
* as will all further calls to [moveNext].
*
diff --git a/sdk/lib/async/stream_impl.dart b/sdk/lib/async/stream_impl.dart
index cb2e20d..7f89464 100644
--- a/sdk/lib/async/stream_impl.dart
+++ b/sdk/lib/async/stream_impl.dart
@@ -86,7 +86,6 @@
static const int _STATE_IN_CALLBACK = 32;
static const int _STATE_HAS_PENDING = 64;
static const int _STATE_PAUSE_COUNT = 128;
- static const int _STATE_PAUSE_COUNT_SHIFT = 7;
/* Event handlers provided in constructor. */
_DataHandler<T> _onData;
@@ -239,15 +238,6 @@
}
/**
- * Increment the pause count.
- *
- * Also marks input as paused.
- */
- void _incrementPauseCount() {
- _state = (_state + _STATE_PAUSE_COUNT) | _STATE_INPUT_PAUSED;
- }
-
- /**
* Decrements the pause count.
*
* Does not automatically unpause the input (call [_onResume]) when
@@ -722,25 +712,6 @@
}
}
-class _BroadcastLinkedList {
- _BroadcastLinkedList _next;
- _BroadcastLinkedList _previous;
-
- void _unlink() {
- _previous._next = _next;
- _next._previous = _previous;
- _next = _previous = this;
- }
-
- void _insertBefore(_BroadcastLinkedList newNext) {
- _BroadcastLinkedList newPrevious = newNext._previous;
- newPrevious._next = this;
- newNext._previous = _previous;
- _previous._next = newNext;
- _previous = newPrevious;
- }
-}
-
typedef void _BroadcastCallback<T>(StreamSubscription<T> subscription);
/**
@@ -941,156 +912,139 @@
/**
* Simple implementation of [StreamIterator].
+ *
+ * Pauses the stream between calls to [moveNext].
*/
-class _StreamIteratorImpl<T> implements StreamIterator<T> {
- // Internal state of the stream iterator.
- // At any time, it is in one of these states.
- // The interpretation of the [_futureOrPrefecth] field depends on the state.
- // In _STATE_MOVING, the _data field holds the most recently returned
- // future.
- // When in one of the _STATE_EXTRA_* states, the it may hold the
- // next data/error object, and the subscription is paused.
-
- /// The simple state where [_data] holds the data to return, and [moveNext]
- /// is allowed. The subscription is actively listening.
- static const int _STATE_FOUND = 0;
- /// State set after [moveNext] has returned false or an error,
- /// or after calling [cancel]. The subscription is always canceled.
- static const int _STATE_DONE = 1;
- /// State set after calling [moveNext], but before its returned future has
- /// completed. Calling [moveNext] again is not allowed in this state.
- /// The subscription is actively listening.
- static const int _STATE_MOVING = 2;
- /// States set when another event occurs while in _STATE_FOUND.
- /// This extra overflow event is cached until the next call to [moveNext],
- /// which will complete as if it received the event normally.
- /// The subscription is paused in these states, so we only ever get one
- /// event too many.
- static const int _STATE_EXTRA_DATA = 3;
- static const int _STATE_EXTRA_ERROR = 4;
- static const int _STATE_EXTRA_DONE = 5;
+class _StreamIterator<T> implements StreamIterator<T> {
+ // The stream iterator is always in one of four states.
+ // The value of the [_stateData] field depends on the state.
+ //
+ // When `_subscription == null` and `_stateData != null`:
+ // The stream iterator has been created, but [moveNext] has not been called
+ // yet. The [_stateData] field contains the stream to listen to on the first
+ // call to [moveNext] and [current] returns `null`.
+ //
+ // When `_subscription != null` and `!_isPaused`:
+ // The user has called [moveNext] and the iterator is waiting for the next
+ // event. The [_stateData] field contains the [_Future] returned by the
+ // [_moveNext] call and [current] returns `null.`
+ //
+ // When `_subscription != null` and `_isPaused`:
+ // The most recent call to [moveNext] has completed with a `true` value
+ // and [current] provides the value of the data event.
+ // The [_stateData] field contains the [current] value.
+ //
+ // When `_subscription == null` and `_stateData == null`:
+ // The stream has completed or been canceled using [cancel].
+ // The stream completes on either a done event or an error event.
+ // The last call to [moveNext] has completed with `false` and [current]
+ // returns `null`.
/// Subscription being listened to.
+ ///
+ /// Set to `null` when the stream subscription is done or canceled.
StreamSubscription _subscription;
- /// The current element represented by the most recent call to moveNext.
+ /// Data value depending on the current state.
///
- /// Is null between the time moveNext is called and its future completes.
- T _current = null;
-
- /// The future returned by the most recent call to [moveNext].
+ /// Before first call to [moveNext]: The stream to listen to.
///
- /// Also used to store the next value/error in case the stream provides an
- /// event before [moveNext] is called again. In that case, the stream will
- /// be paused to prevent further events.
- var/*Future<bool> or T*/ _futureOrPrefetch = null;
+ /// After calling [moveNext] but before the returned future completes:
+ /// The returned future.
+ ///
+ /// After calling [moveNext] and the returned future has completed
+ /// with `true`: The value of [current].
+ ///
+ /// After calling [moveNext] and the returned future has completed
+ /// with `false`, or after calling [cancel]: `null`.
+ Object _stateData;
- /// The current state.
- int _state = _STATE_FOUND;
+ /// Whether the iterator is between calls to `moveNext`.
+ /// This will usually cause the [_subscription] to be paused, but as an
+ /// optimization, we only pause after the [moveNext] future has been
+ /// completed.
+ bool _isPaused = false;
- _StreamIteratorImpl(final Stream<T> stream) {
- _subscription = stream.listen(_onData,
- onError: _onError,
- onDone: _onDone,
- cancelOnError: true);
+ _StreamIterator(final Stream<T> stream) : _stateData = stream;
+
+ T get current {
+ if (_subscription != null && _isPaused) {
+ return _stateData as Object /*=T*/;
+ }
+ return null;
}
- T get current => _current;
-
Future<bool> moveNext() {
- if (_state == _STATE_DONE) {
- return new _Future<bool>.immediate(false);
- }
- if (_state == _STATE_MOVING) {
+ if (_subscription != null) {
+ if (_isPaused) {
+ var future = new _Future<bool>();
+ _stateData = future;
+ _isPaused = false;
+ _subscription.resume();
+ return future;
+ }
throw new StateError("Already waiting for next.");
}
- if (_state == _STATE_FOUND) {
- _state = _STATE_MOVING;
- _current = null;
- var result = new _Future<bool>();
- _futureOrPrefetch = result;
- return result;
- } else {
- assert(_state >= _STATE_EXTRA_DATA);
- switch (_state) {
- case _STATE_EXTRA_DATA:
- _state = _STATE_FOUND;
- _current = _futureOrPrefetch as Object /*=T*/;
- _futureOrPrefetch = null;
- _subscription.resume();
- return new _Future<bool>.immediate(true);
- case _STATE_EXTRA_ERROR:
- AsyncError prefetch = _futureOrPrefetch;
- _clear();
- return new _Future<bool>.immediateError(prefetch.error,
- prefetch.stackTrace);
- case _STATE_EXTRA_DONE:
- _clear();
- return new _Future<bool>.immediate(false);
- }
- }
+ return _initializeOrDone();
}
- /** Clears up the internal state when the iterator ends. */
- void _clear() {
- _subscription = null;
- _futureOrPrefetch = null;
- _current = null;
- _state = _STATE_DONE;
+ /// Called if there is no active subscription when [moveNext] is called.
+ ///
+ /// Either starts listening on the stream if this is the first call to
+ /// [moveNext], or returns a `false` future because the stream has already
+ /// ended.
+ Future<bool> _initializeOrDone() {
+ assert(_subscription == null);
+ var stateData = _stateData;
+ if (stateData != null) {
+ Stream<T> stream = stateData as Object /*=Stream<T>*/;
+ _subscription = stream.listen(
+ _onData, onError: _onError, onDone: _onDone, cancelOnError: true);
+ var future = new _Future<bool>();
+ _stateData = future;
+ return future;
+ }
+ return new _Future<bool>.immediate(false);
}
Future cancel() {
- StreamSubscription subscription = _subscription;
- if (subscription == null) return Future._nullFuture;
- if (_state == _STATE_MOVING) {
- _Future<bool> hasNext = _futureOrPrefetch as Object /*=_Future<bool>*/;
- _clear();
- hasNext._complete(false);
- } else {
- _clear();
+ StreamSubscription<T> subscription = _subscription;
+ Object stateData = _stateData;
+ _stateData = null;
+ if (subscription != null) {
+ _subscription = null;
+ if (!_isPaused) {
+ _Future<bool> future = stateData as Object /*=_Future<bool>*/;
+ future._asyncComplete(false);
+ }
+ return subscription.cancel();
}
- return subscription.cancel();
+ return Future._nullFuture;
}
void _onData(T data) {
- if (_state == _STATE_MOVING) {
- _current = data;
- _Future<bool> hasNext = _futureOrPrefetch as Object /*=_Future<bool>*/;
- _futureOrPrefetch = null;
- _state = _STATE_FOUND;
- hasNext._complete(true);
- return;
- }
- _subscription.pause();
- assert(_futureOrPrefetch == null);
- _futureOrPrefetch = data;
- _state = _STATE_EXTRA_DATA;
+ assert(_subscription != null && !_isPaused);
+ _Future<bool> moveNextFuture = _stateData as Object /*=_Future<bool>*/;
+ _stateData = data;
+ _isPaused = true;
+ moveNextFuture._complete(true);
+ if (_subscription != null && _isPaused) _subscription.pause();
}
void _onError(Object error, [StackTrace stackTrace]) {
- if (_state == _STATE_MOVING) {
- _Future<bool> hasNext = _futureOrPrefetch as Object /*=_Future<bool>*/;
- // We have cancelOnError: true, so the subscription is canceled.
- _clear();
- hasNext._completeError(error, stackTrace);
- return;
- }
- _subscription.pause();
- assert(_futureOrPrefetch == null);
- _futureOrPrefetch = new AsyncError(error, stackTrace);
- _state = _STATE_EXTRA_ERROR;
+ assert(_subscription != null && !_isPaused);
+ _Future<bool> moveNextFuture = _stateData as Object /*=_Future<bool>*/;
+ _subscription = null;
+ _stateData = null;
+ moveNextFuture._completeError(error, stackTrace);
}
void _onDone() {
- if (_state == _STATE_MOVING) {
- _Future<bool> hasNext = _futureOrPrefetch as Object /*=_Future<bool>*/;
- _clear();
- hasNext._complete(false);
- return;
- }
- _subscription.pause();
- _futureOrPrefetch = null;
- _state = _STATE_EXTRA_DONE;
+ assert(_subscription != null && !_isPaused);
+ _Future<bool> moveNextFuture = _stateData as Object /*=_Future<bool>*/;
+ _subscription = null;
+ _stateData = null;
+ moveNextFuture._complete(false);
}
}
diff --git a/sdk/lib/internal/iterable.dart b/sdk/lib/internal/iterable.dart
index 2bedb48..0e7b171 100644
--- a/sdk/lib/internal/iterable.dart
+++ b/sdk/lib/internal/iterable.dart
@@ -426,6 +426,10 @@
WhereIterable(this._iterable, bool this._f(E element));
Iterator<E> get iterator => new WhereIterator<E>(_iterable.iterator, _f);
+
+ // Specialization of [Iterable.map] to non-EfficientLength.
+ Iterable/*<T>*/ map/*<T>*/(/*=T*/ f(E element)) =>
+ new MappedIterable<E, dynamic/*=T*/>._(this, f);
}
class WhereIterator<E> extends Iterator<E> {
diff --git a/tests/compiler/dart2js/class_set_test.dart b/tests/compiler/dart2js/class_set_test.dart
index 52f436f..64442b1 100644
--- a/tests/compiler/dart2js/class_set_test.dart
+++ b/tests/compiler/dart2js/class_set_test.dart
@@ -50,7 +50,7 @@
}
""",
useMockCompiler: false);
- World world = env.compiler.world;
+ ClosedWorld world = env.compiler.closedWorld;
ClassElement A = env.getElement("A");
ClassElement B = env.getElement("B");
@@ -383,7 +383,7 @@
}
""",
useMockCompiler: false);
- World world = env.compiler.world;
+ ClosedWorld world = env.compiler.closedWorld;
ClassElement A = env.getElement("A");
ClassElement B = env.getElement("B");
diff --git a/tests/compiler/dart2js/compiler_helper.dart b/tests/compiler/dart2js/compiler_helper.dart
index ad2c0f7..c9bd508 100644
--- a/tests/compiler/dart2js/compiler_helper.dart
+++ b/tests/compiler/dart2js/compiler_helper.dart
@@ -75,7 +75,7 @@
compiler.backend.enqueueHelpers(
compiler.enqueuer.resolution, compiler.globalDependencies);
compiler.processQueue(compiler.enqueuer.resolution, element);
- compiler.world.populate();
+ compiler.openWorld.closeWorld();
compiler.backend.onResolutionComplete();
ResolutionWorkItem resolutionWork = new ResolutionWorkItem(element);
resolutionWork.run(compiler, compiler.enqueuer.resolution);
@@ -210,17 +210,17 @@
Expect.isNotNull(element, 'Could not locate $name');
switch (how) {
case 'exact':
- return new types.TypeMask.exact(element, compiler.world);
+ return new types.TypeMask.exact(element, compiler.closedWorld);
case 'nonNullExact':
- return new types.TypeMask.nonNullExact(element, compiler.world);
+ return new types.TypeMask.nonNullExact(element, compiler.closedWorld);
case 'subclass':
- return new types.TypeMask.subclass(element, compiler.world);
+ return new types.TypeMask.subclass(element, compiler.closedWorld);
case 'nonNullSubclass':
- return new types.TypeMask.nonNullSubclass(element, compiler.world);
+ return new types.TypeMask.nonNullSubclass(element, compiler.closedWorld);
case 'subtype':
- return new types.TypeMask.subtype(element, compiler.world);
+ return new types.TypeMask.subtype(element, compiler.closedWorld);
case 'nonNullSubtype':
- return new types.TypeMask.nonNullSubtype(element, compiler.world);
+ return new types.TypeMask.nonNullSubtype(element, compiler.closedWorld);
}
Expect.fail('Unknown TypeMask constructor $how');
return null;
diff --git a/tests/compiler/dart2js/concrete_type_inference_test.dart b/tests/compiler/dart2js/concrete_type_inference_test.dart
index 1be4e18..e3833ad 100644
--- a/tests/compiler/dart2js/concrete_type_inference_test.dart
+++ b/tests/compiler/dart2js/concrete_type_inference_test.dart
@@ -60,8 +60,8 @@
Expect.identical(compiler.commonMasks.nullType, type);
});
checkPrintType('"foo"', (compiler, type) {
- Expect.isTrue(
- compiler.commonMasks.stringType.containsOnlyString(compiler.world));
+ Expect.isTrue(compiler.commonMasks.stringType
+ .containsOnlyString(compiler.closedWorld));
});
}
diff --git a/tests/compiler/dart2js/container_mask_equal_test.dart b/tests/compiler/dart2js/container_mask_equal_test.dart
index 54e71e1..21836b7 100644
--- a/tests/compiler/dart2js/container_mask_equal_test.dart
+++ b/tests/compiler/dart2js/container_mask_equal_test.dart
@@ -44,7 +44,7 @@
element = compiler.mainApp.find('d');
var mask4 = typesInferrer.getReturnTypeOfElement(element);
- Expect.notEquals(
- mask1.union(mask2, compiler.world), mask3.union(mask4, compiler.world));
+ Expect.notEquals(mask1.union(mask2, compiler.closedWorld),
+ mask3.union(mask4, compiler.closedWorld));
});
}
diff --git a/tests/compiler/dart2js/dictionary_types_test.dart b/tests/compiler/dart2js/dictionary_types_test.dart
index 2f52323..0a169d6 100644
--- a/tests/compiler/dart2js/dictionary_types_test.dart
+++ b/tests/compiler/dart2js/dictionary_types_test.dart
@@ -113,7 +113,8 @@
});
await compileAndTest("Union.dart", (types, getType, compiler) {
Expect.equals(getType('nullOrInt'), types.uint31Type.nullable());
- Expect.isTrue(getType('aString').containsOnlyString(compiler.world));
+ Expect
+ .isTrue(getType('aString').containsOnlyString(compiler.closedWorld));
Expect.equals(getType('doubleOrNull'), types.doubleType.nullable());
});
await compileAndTest("ValueType.dart", (types, getType, compiler) {
diff --git a/tests/compiler/dart2js/exit_code_test.dart b/tests/compiler/dart2js/exit_code_test.dart
index e60072e..1ca76fc 100644
--- a/tests/compiler/dart2js/exit_code_test.dart
+++ b/tests/compiler/dart2js/exit_code_test.dart
@@ -152,7 +152,7 @@
TestResolver(TestCompiler compiler, ConstantCompiler constantCompiler)
: this.compiler = compiler,
- super(compiler.resolution, constantCompiler, compiler.world,
+ super(compiler.resolution, constantCompiler, compiler.openWorld,
compiler.measurer);
void computeClassMembers(ClassElement element) {
diff --git a/tests/compiler/dart2js/expect_annotations_test.dart b/tests/compiler/dart2js/expect_annotations_test.dart
index 1d1a235..10ee78c 100644
--- a/tests/compiler/dart2js/expect_annotations_test.dart
+++ b/tests/compiler/dart2js/expect_annotations_test.dart
@@ -103,8 +103,8 @@
TypeMask jsStringType = compiler.commonMasks.stringType;
TypeMask jsIntType = compiler.commonMasks.intType;
- TypeMask coreStringType =
- new TypeMask.subtype(compiler.coreClasses.stringClass, compiler.world);
+ TypeMask coreStringType = new TypeMask.subtype(
+ compiler.coreClasses.stringClass, compiler.closedWorld);
test('method');
test('methodAssumeDynamic', expectAssumeDynamic: true);
diff --git a/tests/compiler/dart2js/field_type_simple_inferer_test.dart b/tests/compiler/dart2js/field_type_simple_inferer_test.dart
index 59ae877..03d7de3 100644
--- a/tests/compiler/dart2js/field_type_simple_inferer_test.dart
+++ b/tests/compiler/dart2js/field_type_simple_inferer_test.dart
@@ -522,7 +522,7 @@
runTest(TEST_15, {
'f': (types) {
ClassElement cls = types.compiler.backend.helpers.jsIndexableClass;
- return new TypeMask.nonNullSubtype(cls, types.compiler.world);
+ return new TypeMask.nonNullSubtype(cls, types.compiler.closedWorld);
}
});
runTest(TEST_16, {'f': subclassOfInterceptor});
diff --git a/tests/compiler/dart2js/gvn_dynamic_field_get_test.dart b/tests/compiler/dart2js/gvn_dynamic_field_get_test.dart
index cf9deec..eb58e74 100644
--- a/tests/compiler/dart2js/gvn_dynamic_field_get_test.dart
+++ b/tests/compiler/dart2js/gvn_dynamic_field_get_test.dart
@@ -36,6 +36,7 @@
var element = cls.lookupLocalMember(name);
Expect.isNotNull(element);
Selector selector = new Selector.getter(new PublicName(name));
- Expect.isFalse(compiler.world.hasAnyUserDefinedGetter(selector, null));
+ Expect.isFalse(
+ compiler.closedWorld.hasAnyUserDefinedGetter(selector, null));
}));
}
diff --git a/tests/compiler/dart2js/jsinterop/world_test.dart b/tests/compiler/dart2js/jsinterop/world_test.dart
index 185e092..e994791 100644
--- a/tests/compiler/dart2js/jsinterop/world_test.dart
+++ b/tests/compiler/dart2js/jsinterop/world_test.dart
@@ -86,7 +86,7 @@
return cls;
}
- ClassWorld world = env.compiler.world;
+ ClosedWorld world = env.compiler.closedWorld;
JavaScriptBackend backend = env.compiler.backend;
ClassElement Object_ = registerClass(env.compiler.coreClasses.objectClass);
ClassElement Interceptor =
diff --git a/tests/compiler/dart2js/kernel/expressions_test.dart b/tests/compiler/dart2js/kernel/expressions_test.dart
new file mode 100644
index 0000000..7074c4c
--- /dev/null
+++ b/tests/compiler/dart2js/kernel/expressions_test.dart
@@ -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 'package:test/test.dart';
+
+import 'helper.dart' show check;
+
+main() {
+ group('string literals', () {
+ test('juxtaposition', () {
+ return check('main() { return "abc" "def"; }');
+ });
+ test('literal interpolation', () {
+ return check('main() { return "abc\${1}def"; }');
+ });
+ test('complex interpolation', () {
+ String code = '''
+foo() => 1;
+main() => "abc\${foo()}"
+ "\${foo()}def";''';
+ return check(code);
+ });
+ });
+}
diff --git a/tests/compiler/dart2js/kernel/impact_test.dart b/tests/compiler/dart2js/kernel/impact_test.dart
index 9581e13..2716d53 100644
--- a/tests/compiler/dart2js/kernel/impact_test.dart
+++ b/tests/compiler/dart2js/kernel/impact_test.dart
@@ -6,18 +6,22 @@
import 'dart:async';
import 'package:async_helper/async_helper.dart';
-import 'package:compiler/src/common.dart';
import 'package:compiler/src/commandline_options.dart';
+import 'package:compiler/src/common.dart';
+import 'package:compiler/src/common/names.dart';
import 'package:compiler/src/common/resolution.dart';
import 'package:compiler/src/compiler.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/feature.dart';
+import 'package:compiler/src/universe/use.dart';
import '../memory_compiler.dart';
import '../serialization/test_helper.dart';
const Map<String, String> SOURCE = const <String, String>{
- 'main.dart': '''
+ 'main.dart': r'''
import 'helper.dart';
main() {
@@ -28,6 +32,9 @@
testInt();
testDouble();
testString();
+ testStringInterpolation();
+ testStringInterpolationConst();
+ testStringJuxtaposition();
testSymbol();
testEmptyListLiteral();
testEmptyListLiteralDynamic();
@@ -50,12 +57,22 @@
testIfThenElse();
testTopLevelInvoke();
testTopLevelInvokeTyped();
+ testTopLevelFunctionTyped();
+ testTopLevelFunctionGet();
testTopLevelField();
testTopLevelFieldTyped();
testDynamicInvoke(null);
testDynamicGet(null);
testDynamicSet(null);
+ testLocalWithoutInitializer();
testLocalWithInitializer();
+ testLocalWithInitializerTyped();
+ testLocalFunction();
+ testLocalFunctionTyped();
+ testLocalFunctionInvoke();
+ testLocalFunctionGet();
+ testClosure();
+ testClosureInvoke();
testInvokeIndex(null);
testInvokeIndexSet(null);
testAssert();
@@ -64,6 +81,10 @@
testFactoryInvokeGeneric();
testFactoryInvokeGenericRaw();
testFactoryInvokeGenericDynamic();
+ testRedirectingFactoryInvoke();
+ testRedirectingFactoryInvokeGeneric();
+ testRedirectingFactoryInvokeGenericRaw();
+ testRedirectingFactoryInvokeGenericDynamic();
}
testEmpty() {}
@@ -73,6 +94,11 @@
testInt() => 42;
testDouble() => 37.5;
testString() => 'foo';
+testStringInterpolation() => '${0}';
+testStringInterpolationConst() {
+ const b = '${0}';
+}
+testStringJuxtaposition() => 'a' 'b';
testSymbol() => #main;
testEmptyListLiteral() => [];
testEmptyListLiteralDynamic() => <dynamic>[];
@@ -132,6 +158,19 @@
topLevelFunction3Typed(true, b: [13], c: {'14': true});
topLevelFunction3Typed(false, c: {'16': false}, b: [17]);
}
+
+topLevelFunctionTyped1(void a(num b)) {}
+topLevelFunctionTyped2(void a(num b, [String c])) {}
+topLevelFunctionTyped3(void a(num b, {String c, int d})) {}
+topLevelFunctionTyped4(void a(num b, {String d, int c})) {}
+testTopLevelFunctionTyped() {
+ topLevelFunctionTyped1(null);
+ topLevelFunctionTyped2(null);
+ topLevelFunctionTyped3(null);
+ topLevelFunctionTyped4(null);
+}
+testTopLevelFunctionGet() => topLevelFunction1;
+
var topLevelField;
testTopLevelField() => topLevelField;
int topLevelFieldTyped;
@@ -149,9 +188,35 @@
}
testDynamicGet(o) => o.foo;
testDynamicSet(o) => o.foo = 42;
+testLocalWithoutInitializer() {
+ var l;
+}
testLocalWithInitializer() {
var l = 42;
}
+testLocalWithInitializerTyped() {
+ int l = 42;
+}
+testLocalFunction() {
+ localFunction() {}
+}
+testLocalFunctionTyped() {
+ int localFunction(String a) => 42;
+}
+testLocalFunctionInvoke() {
+ localFunction() {}
+ localFunction();
+}
+testLocalFunctionGet() {
+ localFunction() {}
+ localFunction;
+}
+testClosure() {
+ () {};
+}
+testClosureInvoke() {
+ () {} ();
+}
testInvokeIndex(o) => o[42];
testInvokeIndexSet(o) => o[42] = null;
testAssert() {
@@ -172,13 +237,29 @@
testFactoryInvokeGenericDynamic() {
new GenericClass<dynamic, dynamic>.fact();
}
+testRedirectingFactoryInvoke() {
+ new Class.redirect();
+}
+testRedirectingFactoryInvokeGeneric() {
+ new GenericClass<int, String>.redirect();
+}
+testRedirectingFactoryInvokeGenericRaw() {
+ new GenericClass.redirect();
+}
+testRedirectingFactoryInvokeGenericDynamic() {
+ new GenericClass<dynamic, dynamic>.redirect();
+}
''',
'helper.dart': '''
class Class {
+ Class.generative();
factory Class.fact() => null;
+ factory Class.redirect() = Class.generative;
}
class GenericClass<X, Y> {
+ GenericClass.generative();
factory GenericClass.fact() => null;
+ factory GenericClass.redirect() = GenericClass.generative;
}
''',
};
@@ -213,7 +294,37 @@
void checkElement(Compiler compiler, AstElement element) {
ResolutionImpact astImpact = compiler.resolution.getResolutionImpact(element);
+ astImpact = laxImpact(element, astImpact);
ResolutionImpact kernelImpact = build(compiler, element.resolvedAst);
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) {
+ ResolutionWorldImpactBuilder builder =
+ new ResolutionWorldImpactBuilder('Lax impact of ${element}');
+ impact.staticUses.forEach(builder.registerStaticUse);
+ impact.dynamicUses.forEach(builder.registerDynamicUse);
+ impact.typeUses.forEach(builder.registerTypeUse);
+ 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.
+ builder.registerFeature(Feature.STRING_INTERPOLATION);
+ builder.registerFeature(Feature.STRING_JUXTAPOSITION);
+ break;
+ default:
+ }
+ }
+ impact.nativeData.forEach(builder.registerNativeData);
+ return builder;
+}
diff --git a/tests/compiler/dart2js/kernel/literals_test.dart b/tests/compiler/dart2js/kernel/literals_test.dart
index bf84989..4bdf271 100644
--- a/tests/compiler/dart2js/kernel/literals_test.dart
+++ b/tests/compiler/dart2js/kernel/literals_test.dart
@@ -16,7 +16,7 @@
test('compile function that returns a literal map', () {
return check('main() { return {"a": 1, "b": 2, "c": 3}; }');
});
- test('compile function that returns a literal map', () {
+ test('compile function that returns a const map', () {
return check('main() { return const {"a": 1, "b": 2, "c": 3}; }');
});
}
diff --git a/tests/compiler/dart2js/kernel/loops_test.dart b/tests/compiler/dart2js/kernel/loops_test.dart
new file mode 100644
index 0000000..6535e95
--- /dev/null
+++ b/tests/compiler/dart2js/kernel/loops_test.dart
@@ -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.
+
+import 'package:test/test.dart';
+
+import 'helper.dart' show check;
+
+main() {
+ test('for-loop', () {
+ String code = '''
+main() {
+ var a = 0;
+ for (var i = 0; i < 10; i++) {
+ a += i;
+ }
+ return a;
+}''';
+ return check(code);
+ });
+
+ test('while-loop', () {
+ String code = '''
+main() {
+ var a = 0;
+ while (a < 100) {
+ a *= 2;
+ }
+ return a;
+}''';
+ return check(code);
+ });
+}
diff --git a/tests/compiler/dart2js/kernel/visitor_test.dart b/tests/compiler/dart2js/kernel/visitor_test.dart
new file mode 100644
index 0000000..1edd591
--- /dev/null
+++ b/tests/compiler/dart2js/kernel/visitor_test.dart
@@ -0,0 +1,66 @@
+// 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 that the dart2js copy of [KernelVisitor] generates the expected IR as
+/// defined by kernel spec-mode test files.
+
+import 'dart:io';
+import 'package:compiler/src/compiler.dart' show Compiler;
+import 'package:compiler/src/js_backend/backend.dart' show JavaScriptBackend;
+import 'package:compiler/src/commandline_options.dart' show Flags;
+import 'package:kernel/ast.dart';
+import 'package:kernel/text/ast_to_text.dart';
+import 'package:kernel/transformations/mixin_full_resolution.dart';
+import 'package:path/path.dart' as pathlib;
+import 'package:test/test.dart';
+
+import '../memory_compiler.dart';
+
+const String TESTCASE_DIR = 'third_party/pkg/kernel/testcases/';
+
+const List<String> SKIP_TESTS = const <String>[];
+
+main(List<String> arguments) {
+ Directory directory = new Directory('${TESTCASE_DIR}/input');
+ for (FileSystemEntity file in directory.listSync()) {
+ if (file is File && file.path.endsWith('.dart')) {
+ String name = pathlib.basenameWithoutExtension(file.path);
+ bool selected = arguments.contains(name);
+ if (!selected) {
+ if (arguments.isNotEmpty) continue;
+ if (SKIP_TESTS.contains(name)) continue;
+ }
+
+ test(name, () async {
+ var result = await runCompiler(
+ entryPoint: file.absolute.uri,
+ options: [Flags.analyzeOnly, Flags.useKernel]);
+ Compiler compiler = result.compiler;
+ JavaScriptBackend backend = compiler.backend;
+ StringBuffer buffer = new StringBuffer();
+ Program program = backend.kernelTask.program;
+ new MixinFullResolution().transform(program);
+ new Printer(buffer).writeLibraryFile(
+ backend.kernelTask.program.mainMethod.enclosingLibrary);
+ String actual = buffer.toString();
+ String expected =
+ new File('${TESTCASE_DIR}/spec-mode/$name.baseline.txt')
+ .readAsStringSync();
+ if (selected) {
+ String input =
+ new File('${TESTCASE_DIR}/input/$name.dart').readAsStringSync();
+ print('============================================================');
+ print(name);
+ print('--input-----------------------------------------------------');
+ print(input);
+ print('--expected--------------------------------------------------');
+ print(expected);
+ print('--actual----------------------------------------------------');
+ print(actual);
+ }
+ expect(actual, equals(expected));
+ });
+ }
+ }
+}
diff --git a/tests/compiler/dart2js/map_tracer_test.dart b/tests/compiler/dart2js/map_tracer_test.dart
index 1f8e806..6c4af67 100644
--- a/tests/compiler/dart2js/map_tracer_test.dart
+++ b/tests/compiler/dart2js/map_tracer_test.dart
@@ -211,7 +211,7 @@
Uri uri = new Uri(scheme: 'source');
var compiler = compilerFor(generateTest(allocation), uri,
expectedErrors: 0, expectedWarnings: 1);
- var classWorld = compiler.world;
+ var classWorld = compiler.openWorld.closeWorld();
asyncTest(() => compiler.run(uri).then((_) {
var keyType, valueType;
var commonMasks = compiler.commonMasks;
diff --git a/tests/compiler/dart2js/patch_test.dart b/tests/compiler/dart2js/patch_test.dart
index f981843..3990949 100644
--- a/tests/compiler/dart2js/patch_test.dart
+++ b/tests/compiler/dart2js/patch_test.dart
@@ -920,8 +920,7 @@
""",
runCompiler: true,
analyzeOnly: true);
- World world = compiler.world;
- world.populate();
+ ClosedWorld world = compiler.openWorld.closeWorld();
ClassElement cls = ensure(
compiler, "A", compiler.commonElements.coreLibrary.find,
@@ -943,7 +942,7 @@
TypeMask typeMask = new TypeMask.exact(cls, world);
FunctionElement method = cls.implementation.lookupLocalMember('method');
method.computeType(compiler.resolution);
- Expect.isTrue(selector.applies(method, world));
+ Expect.isTrue(selector.applies(method, world.backend));
Expect.isTrue(typeMask.canHit(method, selector, world));
// Check that the declaration method in the declaration class is a target
@@ -953,7 +952,7 @@
typeMask = new TypeMask.exact(cls, world);
method = cls.lookupLocalMember('clear');
method.computeType(compiler.resolution);
- Expect.isTrue(selector.applies(method, world));
+ Expect.isTrue(selector.applies(method, world.backend));
Expect.isTrue(typeMask.canHit(method, selector, world));
// Check that the declaration method in the declaration class is a target
@@ -961,7 +960,7 @@
cls = ensure(compiler, "B", compiler.commonElements.coreLibrary.find);
cls.ensureResolved(compiler.resolution);
typeMask = new TypeMask.exact(cls, world);
- Expect.isTrue(selector.applies(method, world));
+ Expect.isTrue(selector.applies(method, world.backend));
Expect.isTrue(typeMask.canHit(method, selector, world));
}
diff --git a/tests/compiler/dart2js/related_types.dart b/tests/compiler/dart2js/related_types.dart
index 7d56a65..09b28ea 100644
--- a/tests/compiler/dart2js/related_types.dart
+++ b/tests/compiler/dart2js/related_types.dart
@@ -35,6 +35,7 @@
/// Check all loaded libraries in [compiler] for unrelated types.
void checkRelatedTypes(Compiler compiler) {
+ compiler.openWorld.closeWorld();
for (LibraryElement library in compiler.libraryLoader.libraries) {
checkLibraryElement(compiler, library);
}
@@ -76,7 +77,7 @@
: this.resolvedAst = resolvedAst,
super(resolvedAst.elements);
- ClassWorld get world => compiler.world;
+ ClosedWorld get world => compiler.closedWorld;
CoreClasses get coreClasses => compiler.coreClasses;
diff --git a/tests/compiler/dart2js/related_types_test.dart b/tests/compiler/dart2js/related_types_test.dart
index f5209b2..38449bc 100644
--- a/tests/compiler/dart2js/related_types_test.dart
+++ b/tests/compiler/dart2js/related_types_test.dart
@@ -267,6 +267,7 @@
Expect.isFalse(
collector.hasRegularMessages, "Unexpected analysis messages.");
Compiler compiler = result.compiler;
+ compiler.openWorld.closeWorld();
void checkMember(MemberElement member) {
if (!member.name.startsWith('test_')) return;
diff --git a/tests/compiler/dart2js/serialization/model_test_helper.dart b/tests/compiler/dart2js/serialization/model_test_helper.dart
index 6952d35..90cde97 100644
--- a/tests/compiler/dart2js/serialization/model_test_helper.dart
+++ b/tests/compiler/dart2js/serialization/model_test_helper.dart
@@ -73,7 +73,7 @@
compilerNormal.resolution.retainCachesForTesting = true;
await compilerNormal.run(entryPoint);
compilerNormal.phase = Compiler.PHASE_DONE_RESOLVING;
- compilerNormal.world.populate();
+ compilerNormal.openWorld.closeWorld();
compilerNormal.backend.onResolutionComplete();
compilerNormal.deferredLoadTask
.onResolutionComplete(compilerNormal.mainFunction);
@@ -89,7 +89,7 @@
compilerDeserialized.resolution.retainCachesForTesting = true;
await compilerDeserialized.run(entryPoint);
compilerDeserialized.phase = Compiler.PHASE_DONE_RESOLVING;
- compilerDeserialized.world.populate();
+ compilerDeserialized.openWorld.closeWorld();
compilerDeserialized.backend.onResolutionComplete();
compilerDeserialized.deferredLoadTask
.onResolutionComplete(compilerDeserialized.mainFunction);
@@ -132,9 +132,9 @@
checkClassHierarchyNodes(
compilerNormal,
compilerDeserialized,
- compilerNormal.world
+ compilerNormal.closedWorld
.getClassHierarchyNode(compilerNormal.coreClasses.objectClass),
- compilerDeserialized.world.getClassHierarchyNode(
+ compilerDeserialized.closedWorld.getClassHierarchyNode(
compilerDeserialized.coreClasses.objectClass),
verbose: verbose);
@@ -271,8 +271,8 @@
ClassElement class2,
{bool verbose: false}) {
checkSets(
- compiler1.world.mixinUsesOf(class1),
- compiler2.world.mixinUsesOf(class2),
+ compiler1.closedWorld.mixinUsesOf(class1),
+ compiler2.closedWorld.mixinUsesOf(class2),
"Mixin uses of $class1 vs $class2",
areElementsEquivalent,
verbose: verbose);
@@ -312,9 +312,9 @@
if (child.isInstantiated) {
print('Missing subclass ${child.cls} of ${node1.cls} '
'in ${node2.directSubclasses}');
- print(compiler1.world
+ print(compiler1.closedWorld
.dump(verbose ? compiler1.coreClasses.objectClass : node1.cls));
- print(compiler2.world
+ print(compiler2.closedWorld
.dump(verbose ? compiler2.coreClasses.objectClass : node2.cls));
}
Expect.isFalse(
diff --git a/tests/compiler/dart2js/serialization/test_helper.dart b/tests/compiler/dart2js/serialization/test_helper.dart
index db97fc4..f081bbd 100644
--- a/tests/compiler/dart2js/serialization/test_helper.dart
+++ b/tests/compiler/dart2js/serialization/test_helper.dart
@@ -240,7 +240,8 @@
Set remaining = computeSetDifference(set1, set2, common, unfound,
sameElement: sameElement, checkElements: onSameElement);
if (unfound.isNotEmpty || remaining.isNotEmpty) {
- String message = "Set mismatch for `$property` on $object1 vs $object2: \n"
+ String message = "Set mismatch for `$property` on\n"
+ "$object1\n vs\n$object2:\n"
"Common:\n ${common.join('\n ')}\n"
"Unfound:\n ${unfound.join('\n ')}\n"
"Extra: \n ${remaining.join('\n ')}";
diff --git a/tests/compiler/dart2js/simple_inferrer_closure_test.dart b/tests/compiler/dart2js/simple_inferrer_closure_test.dart
index 1ca210e..5a12baa 100644
--- a/tests/compiler/dart2js/simple_inferrer_closure_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_closure_test.dart
@@ -154,6 +154,6 @@
var cls = findElement(compiler, 'A');
checkReturnInClass(
- 'A', 'foo', new TypeMask.nonNullExact(cls, compiler.world));
+ 'A', 'foo', new TypeMask.nonNullExact(cls, compiler.closedWorld));
}));
}
diff --git a/tests/compiler/dart2js/simple_inferrer_const_closure_default_test.dart b/tests/compiler/dart2js/simple_inferrer_const_closure_default_test.dart
index 33fdc43..0a97f95 100644
--- a/tests/compiler/dart2js/simple_inferrer_const_closure_default_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_const_closure_default_test.dart
@@ -7,8 +7,6 @@
import 'compiler_helper.dart';
import 'type_mask_test_helper.dart';
-
-
const String TEST = """
// [defaultFn_i] is called only via [foo_i]'s default value with a small integer.
@@ -40,45 +38,70 @@
}
""";
-
void main() {
Uri uri = new Uri(scheme: 'source');
var compiler = compilerFor(TEST, uri);
asyncTest(() => compiler.run(uri).then((_) {
- var typesInferrer = compiler.globalInference.typesInferrer;
+ var typesInferrer = compiler.globalInference.typesInferrer;
- checkArgument(String functionName, type) {
- var functionElement = findElement(compiler, functionName);
- var signature = functionElement.functionSignature;
- var element = signature.requiredParameterCount > 0
- ? signature.requiredParameters.first
- : signature.optionalParameters.first;
- Expect.equals(type,
- simplify(typesInferrer.getTypeOfElement(element), compiler),
- functionName);
- }
+ checkArgument(String functionName, type) {
+ var functionElement = findElement(compiler, functionName);
+ var signature = functionElement.functionSignature;
+ var element = signature.requiredParameterCount > 0
+ ? signature.requiredParameters.first
+ : signature.optionalParameters.first;
+ Expect.equals(
+ type,
+ simplify(typesInferrer.getTypeOfElement(element), compiler),
+ functionName);
+ }
- checkOptionalArgument(String functionName, type) {
- var functionElement = findElement(compiler, functionName);
- var signature = functionElement.functionSignature;
- var element = signature.optionalParameters.first;
- Expect.equals(type,
- simplify(typesInferrer.getTypeOfElement(element), compiler),
- functionName);
- }
+ checkOptionalArgument(String functionName, type) {
+ var functionElement = findElement(compiler, functionName);
+ var signature = functionElement.functionSignature;
+ var element = signature.optionalParameters.first;
+ Expect.equals(
+ type,
+ simplify(typesInferrer.getTypeOfElement(element), compiler),
+ functionName);
+ }
- checkArgument('foo1', compiler.commonMasks.functionType); /// 01: ok
- checkArgument('foo2', compiler.commonMasks.functionType); /// 02: ok
- checkArgument('foo3', compiler.commonMasks.functionType); /// 03: ok
- checkArgument('foo4', compiler.commonMasks.functionType); /// 04: ok
- checkArgument('foo5', compiler.commonMasks.dynamicType); /// 05: ok
- checkArgument('foo6', compiler.commonMasks.dynamicType); /// 06: ok
+ checkArgument('foo1', compiler.commonMasks.functionType);
- checkArgument('defaultFn1', compiler.commonMasks.uint31Type); /// 07: ok
- checkArgument('defaultFn2', compiler.commonMasks.uint31Type); /// 08: ok
- checkArgument('defaultFn3', compiler.commonMasks.uint31Type); /// 09: ok
- checkArgument('defaultFn4', compiler.commonMasks.uint31Type); /// 10: ok
- checkArgument('defaultFn5', compiler.commonMasks.uint31Type); /// 11: ok
- checkArgument('defaultFn6', compiler.commonMasks.uint31Type); /// 12: ok
- }));
+ /// 01: ok
+ checkArgument('foo2', compiler.commonMasks.functionType);
+
+ /// 02: ok
+ checkArgument('foo3', compiler.commonMasks.functionType);
+
+ /// 03: ok
+ checkArgument('foo4', compiler.commonMasks.functionType);
+
+ /// 04: ok
+ checkArgument('foo5', compiler.commonMasks.dynamicType);
+
+ /// 05: ok
+ checkArgument('foo6', compiler.commonMasks.dynamicType);
+
+ /// 06: ok
+
+ checkArgument('defaultFn1', compiler.commonMasks.uint31Type);
+
+ /// 07: ok
+ checkArgument('defaultFn2', compiler.commonMasks.uint31Type);
+
+ /// 08: ok
+ checkArgument('defaultFn3', compiler.commonMasks.uint31Type);
+
+ /// 09: ok
+ checkArgument('defaultFn4', compiler.commonMasks.uint31Type);
+
+ /// 10: ok
+ checkArgument('defaultFn5', compiler.commonMasks.uint31Type);
+
+ /// 11: ok
+ checkArgument('defaultFn6', compiler.commonMasks.uint31Type);
+
+ /// 12: ok
+ }));
}
diff --git a/tests/compiler/dart2js/simple_inferrer_test.dart b/tests/compiler/dart2js/simple_inferrer_test.dart
index 70270da..ccb07a8 100644
--- a/tests/compiler/dart2js/simple_inferrer_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_test.dart
@@ -729,7 +729,7 @@
asyncTest(() => compiler.run(uri).then((_) {
var commonMasks = compiler.commonMasks;
var typesInferrer = compiler.globalInference.typesInferrer;
- var world = compiler.world;
+ var world = compiler.closedWorld;
checkReturn(String name, type) {
var element = findElement(compiler, name);
@@ -761,7 +761,7 @@
checkReturn('returnEmpty1', const TypeMask.nonNullEmpty());
checkReturn('returnEmpty2', const TypeMask.nonNullEmpty());
TypeMask intType = new TypeMask.nonNullSubtype(
- compiler.coreClasses.intClass, compiler.world);
+ compiler.coreClasses.intClass, compiler.closedWorld);
checkReturn('testIsCheck1', intType);
checkReturn('testIsCheck2', intType);
checkReturn('testIsCheck3', intType.nullable());
@@ -796,7 +796,7 @@
checkReturn(
'returnAsString',
new TypeMask.subtype(
- compiler.coreClasses.stringClass, compiler.world));
+ compiler.coreClasses.stringClass, compiler.closedWorld));
checkReturn('returnIntAsNum', commonMasks.uint31Type);
checkReturn('returnAsTypedef', commonMasks.functionType.nullable());
checkReturn('returnTopLevelGetter', commonMasks.uint31Type);
@@ -806,7 +806,7 @@
'testSwitch1',
simplify(
commonMasks.intType
- .union(commonMasks.doubleType, compiler.world)
+ .union(commonMasks.doubleType, compiler.closedWorld)
.nullable(),
compiler));
checkReturn('testSwitch2', commonMasks.uint31Type);
diff --git a/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart b/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart
index f17308b..28c8fde 100644
--- a/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart
+++ b/tests/compiler/dart2js/simple_inferrer_try_catch_test.dart
@@ -186,7 +186,7 @@
checkReturn(
'returnInt6',
new TypeMask.nonNullSubtype(
- compiler.coreClasses.intClass, compiler.world));
+ compiler.coreClasses.intClass, compiler.closedWorld));
var subclassOfInterceptor =
findTypeMask(compiler, 'Interceptor', 'nonNullSubclass');
diff --git a/tests/compiler/dart2js/subtypeset_test.dart b/tests/compiler/dart2js/subtypeset_test.dart
index 38bac61..1f0fd7f 100644
--- a/tests/compiler/dart2js/subtypeset_test.dart
+++ b/tests/compiler/dart2js/subtypeset_test.dart
@@ -47,7 +47,7 @@
""",
useMockCompiler: false)
.then((env) {
- World world = env.compiler.world;
+ ClosedWorld world = env.compiler.closedWorld;
ClassElement A = env.getElement("A");
ClassElement B = env.getElement("B");
diff --git a/tests/compiler/dart2js/trust_type_annotations_test.dart b/tests/compiler/dart2js/trust_type_annotations_test.dart
index 6e86bc0..c140fed 100644
--- a/tests/compiler/dart2js/trust_type_annotations_test.dart
+++ b/tests/compiler/dart2js/trust_type_annotations_test.dart
@@ -58,17 +58,18 @@
var element = classA.lookupMember(name);
var mask = typesInferrer.getReturnTypeOfElement(element);
Expect.isTrue(type.containsMask(
- typesInferrer.getReturnTypeOfElement(element), compiler.world));
+ typesInferrer.getReturnTypeOfElement(element),
+ compiler.closedWorld));
}
checkType(String name, type) {
var element = classA.lookupMember(name);
Expect.isTrue(type.containsMask(
- typesInferrer.getTypeOfElement(element), compiler.world));
+ typesInferrer.getTypeOfElement(element), compiler.closedWorld));
}
- var intMask =
- new TypeMask.subtype(compiler.coreClasses.intClass, compiler.world);
+ var intMask = new TypeMask.subtype(
+ compiler.coreClasses.intClass, compiler.closedWorld);
checkReturn('foo', intMask);
checkReturn('faa', intMask);
diff --git a/tests/compiler/dart2js/type_combination_test.dart b/tests/compiler/dart2js/type_combination_test.dart
index 5a32503..f15d471f 100644
--- a/tests/compiler/dart2js/type_combination_test.dart
+++ b/tests/compiler/dart2js/type_combination_test.dart
@@ -100,8 +100,8 @@
}
void testUnion(MockCompiler compiler) {
- RuleSet ruleSet = new RuleSet(
- 'union', (t1, t2) => simplify(t1.union(t2, compiler.world), compiler));
+ RuleSet ruleSet = new RuleSet('union',
+ (t1, t2) => simplify(t1.union(t2, compiler.closedWorld), compiler));
rule(type1, type2, result) => ruleSet.rule(type1, type2, result);
check(type1, type2, predicate) => ruleSet.check(type1, type2, predicate);
@@ -414,7 +414,7 @@
JavaScriptBackend backend = compiler.backend;
BackendHelpers helpers = backend.helpers;
RuleSet ruleSet = new RuleSet(
- 'intersection', (t1, t2) => t1.intersection(t2, compiler.world));
+ 'intersection', (t1, t2) => t1.intersection(t2, compiler.closedWorld));
rule(type1, type2, result) => ruleSet.rule(type1, type2, result);
rule(emptyType, emptyType, emptyType);
@@ -555,9 +555,9 @@
rule(jsIndexable, nonPrimitive1, emptyType);
rule(jsIndexable, nonPrimitive2, emptyType);
rule(jsIndexable, potentialArray,
- new TypeMask.nonNullSubtype(helpers.jsArrayClass, compiler.world));
+ new TypeMask.nonNullSubtype(helpers.jsArrayClass, compiler.closedWorld));
rule(jsIndexable, potentialString,
- new TypeMask.nonNullSubtype(helpers.jsStringClass, compiler.world));
+ new TypeMask.nonNullSubtype(helpers.jsStringClass, compiler.closedWorld));
rule(jsIndexable, jsBooleanOrNull, emptyType);
rule(jsIndexable, jsNumberOrNull, emptyType);
rule(jsIndexable, jsIntegerOrNull, emptyType);
@@ -723,9 +723,9 @@
void testRegressions(MockCompiler compiler) {
TypeMask nonNullPotentialString =
- new TypeMask.nonNullSubtype(patternClass, compiler.world);
+ new TypeMask.nonNullSubtype(patternClass, compiler.closedWorld);
Expect.equals(potentialString,
- jsStringOrNull.union(nonNullPotentialString, compiler.world));
+ jsStringOrNull.union(nonNullPotentialString, compiler.closedWorld));
}
void main() {
@@ -736,7 +736,7 @@
""");
JavaScriptBackend backend = compiler.backend;
BackendHelpers helpers = backend.helpers;
- World world = compiler.world;
+ ClosedWorld world = compiler.openWorld.closeWorld();
helpers.interceptorsLibrary.forEachLocalMember((element) {
if (element.isClass) {
element.ensureResolved(compiler.resolution);
@@ -753,7 +753,7 @@
compiler.enqueuer.resolution, compiler.globalDependencies);
backend.registerInstantiatedType(patternImplClass.rawType,
compiler.enqueuer.resolution, compiler.globalDependencies);
- compiler.world.populate();
+ compiler.openWorld.closeWorld();
// Grab hold of a supertype for String so we can produce potential
// string types.
diff --git a/tests/compiler/dart2js/type_mask2_test.dart b/tests/compiler/dart2js/type_mask2_test.dart
index 648cf76..78791cb 100644
--- a/tests/compiler/dart2js/type_mask2_test.dart
+++ b/tests/compiler/dart2js/type_mask2_test.dart
@@ -10,7 +10,7 @@
import 'type_test_helper.dart';
import 'package:compiler/src/elements/elements.dart' show Element, ClassElement;
import 'package:compiler/src/types/types.dart';
-import 'package:compiler/src/world.dart' show ClassWorld;
+import 'package:compiler/src/world.dart' show ClosedWorld;
isCheckedMode() {
try {
@@ -29,14 +29,14 @@
});
}
-checkMasks(ClassWorld classWorld, List<ClassElement> allClasses,
+checkMasks(ClosedWorld closedWorld, List<ClassElement> allClasses,
List<FlatTypeMask> masks,
{FlatTypeMask result,
List<FlatTypeMask> disjointMasks,
FlatTypeMask flattened,
List<ClassElement> containedClasses}) {
List<FlatTypeMask> disjoint = <FlatTypeMask>[];
- UnionTypeMask.unionOfHelper(masks, disjoint, classWorld);
+ UnionTypeMask.unionOfHelper(masks, disjoint, closedWorld);
Expect.listEquals(disjointMasks, disjoint,
'Unexpected disjoint masks: $disjoint, expected $disjointMasks.');
if (flattened == null) {
@@ -45,19 +45,19 @@
// reliably tested.
if (isCheckedMode()) {
Expect.throws(
- () => UnionTypeMask.flatten(disjoint, classWorld),
+ () => UnionTypeMask.flatten(disjoint, closedWorld),
(e) => e is AssertionError,
'Expect assertion failure on flattening of $disjoint.');
}
} else {
- TypeMask flattenResult = UnionTypeMask.flatten(disjoint, classWorld);
+ TypeMask flattenResult = UnionTypeMask.flatten(disjoint, closedWorld);
Expect.equals(
flattened,
flattenResult,
'Unexpected flattening of $disjoint: '
'$flattenResult, expected $flattened.');
}
- var union = UnionTypeMask.unionOf(masks, classWorld);
+ var union = UnionTypeMask.unionOf(masks, closedWorld);
if (result == null) {
Expect.isTrue(union is UnionTypeMask,
'Expected union of $masks to be a union-type: $union.');
@@ -73,10 +73,10 @@
if (containedClasses != null) {
for (ClassElement cls in allClasses) {
if (containedClasses.contains(cls)) {
- Expect.isTrue(union.contains(cls, classWorld),
+ Expect.isTrue(union.contains(cls, closedWorld),
'Expected $union to contain $cls.');
} else {
- Expect.isFalse(union.contains(cls, classWorld),
+ Expect.isFalse(union.contains(cls, closedWorld),
'$union not expected to contain $cls.');
}
}
@@ -104,7 +104,7 @@
""",
useMockCompiler: false);
- ClassWorld classWorld = env.compiler.world;
+ ClosedWorld closedWorld = env.compiler.closedWorld;
ClassElement Object_ = env.getElement("Object");
ClassElement A = env.getElement("A");
@@ -120,7 +120,7 @@
List<FlatTypeMask> disjointMasks,
FlatTypeMask flattened,
List<ClassElement> containedClasses}) {
- return checkMasks(classWorld, allClasses, masks,
+ return checkMasks(closedWorld, allClasses, masks,
result: result,
disjointMasks: disjointMasks,
flattened: flattened,
@@ -128,15 +128,15 @@
}
TypeMask empty = const TypeMask.nonNullEmpty();
- TypeMask subclassObject = new TypeMask.nonNullSubclass(Object_, classWorld);
- TypeMask exactA = new TypeMask.nonNullExact(A, classWorld);
- TypeMask subclassA = new TypeMask.nonNullSubclass(A, classWorld);
- TypeMask subtypeA = new TypeMask.nonNullSubtype(A, classWorld);
- TypeMask exactB = new TypeMask.nonNullExact(B, classWorld);
- TypeMask subclassB = new TypeMask.nonNullSubclass(B, classWorld);
- TypeMask exactC = new TypeMask.nonNullExact(C, classWorld);
- TypeMask exactD = new TypeMask.nonNullExact(D, classWorld);
- TypeMask exactE = new TypeMask.nonNullExact(E, classWorld);
+ TypeMask subclassObject = new TypeMask.nonNullSubclass(Object_, closedWorld);
+ TypeMask exactA = new TypeMask.nonNullExact(A, closedWorld);
+ TypeMask subclassA = new TypeMask.nonNullSubclass(A, closedWorld);
+ TypeMask subtypeA = new TypeMask.nonNullSubtype(A, closedWorld);
+ TypeMask exactB = new TypeMask.nonNullExact(B, closedWorld);
+ TypeMask subclassB = new TypeMask.nonNullSubclass(B, closedWorld);
+ TypeMask exactC = new TypeMask.nonNullExact(C, closedWorld);
+ TypeMask exactD = new TypeMask.nonNullExact(D, closedWorld);
+ TypeMask exactE = new TypeMask.nonNullExact(E, closedWorld);
check([], result: empty, disjointMasks: [], containedClasses: []);
@@ -213,7 +213,7 @@
}
""",
useMockCompiler: false);
- var classWorld = env.compiler.world;
+ var closedWorld = env.compiler.closedWorld;
var backend = env.compiler.backend;
ClassElement Object_ = env.getElement("Object");
@@ -222,23 +222,23 @@
List<ClassElement> allClasses = <ClassElement>[Object_, String_];
- Expect.isFalse(classWorld.isDirectlyInstantiated(Object_));
- Expect.isTrue(classWorld.isIndirectlyInstantiated(Object_));
- Expect.isTrue(classWorld.isInstantiated(Object_));
+ Expect.isFalse(closedWorld.isDirectlyInstantiated(Object_));
+ Expect.isTrue(closedWorld.isIndirectlyInstantiated(Object_));
+ Expect.isTrue(closedWorld.isInstantiated(Object_));
- Expect.isFalse(classWorld.isDirectlyInstantiated(String_));
- Expect.isFalse(classWorld.isIndirectlyInstantiated(String_));
- Expect.isFalse(classWorld.isInstantiated(String_));
+ Expect.isFalse(closedWorld.isDirectlyInstantiated(String_));
+ Expect.isFalse(closedWorld.isIndirectlyInstantiated(String_));
+ Expect.isFalse(closedWorld.isInstantiated(String_));
- Expect.isTrue(classWorld.isDirectlyInstantiated(JSString));
- Expect.isFalse(classWorld.isIndirectlyInstantiated(JSString));
- Expect.isTrue(classWorld.isInstantiated(JSString));
+ Expect.isTrue(closedWorld.isDirectlyInstantiated(JSString));
+ Expect.isFalse(closedWorld.isIndirectlyInstantiated(JSString));
+ Expect.isTrue(closedWorld.isInstantiated(JSString));
- TypeMask subtypeString = new TypeMask.nonNullSubtype(String_, classWorld);
- TypeMask exactJSString = new TypeMask.nonNullExact(JSString, classWorld);
- TypeMask subtypeJSString = new TypeMask.nonNullSubtype(JSString, classWorld);
+ TypeMask subtypeString = new TypeMask.nonNullSubtype(String_, closedWorld);
+ TypeMask exactJSString = new TypeMask.nonNullExact(JSString, closedWorld);
+ TypeMask subtypeJSString = new TypeMask.nonNullSubtype(JSString, closedWorld);
TypeMask subclassJSString =
- new TypeMask.nonNullSubclass(JSString, classWorld);
+ new TypeMask.nonNullSubclass(JSString, closedWorld);
Expect.equals(exactJSString, subtypeString);
Expect.equals(exactJSString, subtypeJSString);
diff --git a/tests/compiler/dart2js/type_mask_disjoint_test.dart b/tests/compiler/dart2js/type_mask_disjoint_test.dart
index f27ac57..7c643a5 100644
--- a/tests/compiler/dart2js/type_mask_disjoint_test.dart
+++ b/tests/compiler/dart2js/type_mask_disjoint_test.dart
@@ -36,7 +36,7 @@
Uri uri = new Uri(scheme: 'source');
var compiler = compilerFor(CODE, uri);
-var world = compiler.world;
+var world = compiler.closedWorld;
main() {
asyncTest(() => compiler.run(uri).then((_) {
diff --git a/tests/compiler/dart2js/type_mask_test.dart b/tests/compiler/dart2js/type_mask_test.dart
index 29a89ce..00508d1 100644
--- a/tests/compiler/dart2js/type_mask_test.dart
+++ b/tests/compiler/dart2js/type_mask_test.dart
@@ -21,7 +21,7 @@
main() {
Uri uri = new Uri(scheme: 'source');
var compiler = compilerFor(CODE, uri);
- var classWorld = compiler.world;
+ var classWorld = compiler.openWorld.closeWorld();
asyncTest(() => compiler.run(uri).then((_) {
var classA = findElement(compiler, 'A');
diff --git a/tests/compiler/dart2js/type_mask_test_helper.dart b/tests/compiler/dart2js/type_mask_test_helper.dart
index 0d2d41d..a6c8604 100644
--- a/tests/compiler/dart2js/type_mask_test_helper.dart
+++ b/tests/compiler/dart2js/type_mask_test_helper.dart
@@ -11,7 +11,7 @@
if (mask is ForwardingTypeMask) {
return simplify(mask.forwardTo, compiler);
} else if (mask is UnionTypeMask) {
- return UnionTypeMask.flatten(mask.disjointMasks, compiler.world);
+ return UnionTypeMask.flatten(mask.disjointMasks, compiler.closedWorld);
} else {
return mask;
}
diff --git a/tests/compiler/dart2js/union_type_test.dart b/tests/compiler/dart2js/union_type_test.dart
index 2d18f18..336ce10 100644
--- a/tests/compiler/dart2js/union_type_test.dart
+++ b/tests/compiler/dart2js/union_type_test.dart
@@ -22,8 +22,7 @@
}
""",
useMockCompiler: false);
- World world = env.compiler.world;
- world.populate();
+ ClosedWorld world = env.compiler.openWorld.closeWorld();
FlatTypeMask mask1 = new FlatTypeMask.exact(env.getElement('A'));
FlatTypeMask mask2 = new FlatTypeMask.exact(env.getElement('B'));
UnionTypeMask union1 = mask1.nonNullable().union(mask2, world);
diff --git a/tests/compiler/dart2js/world_test.dart b/tests/compiler/dart2js/world_test.dart
index b80f0c0..c68e05a 100644
--- a/tests/compiler/dart2js/world_test.dart
+++ b/tests/compiler/dart2js/world_test.dart
@@ -10,7 +10,7 @@
import 'package:compiler/src/common.dart';
import 'package:compiler/src/elements/elements.dart' show Element, ClassElement;
import 'package:compiler/src/universe/class_set.dart';
-import 'package:compiler/src/world.dart' show ClassWorld;
+import 'package:compiler/src/world.dart' show ClosedWorld;
void main() {
asyncTest(() async {
@@ -44,7 +44,7 @@
}
""",
useMockCompiler: false);
- ClassWorld classWorld = env.compiler.world;
+ ClosedWorld closedWorld = env.compiler.closedWorld;
ClassElement Object_ = env.getElement("Object");
ClassElement A = env.getElement("A");
@@ -64,7 +64,7 @@
foundClasses.contains(expectedClass),
"Expect $expectedClass in '$property' on $cls. "
"Found:\n ${foundClasses.join('\n ')}\n"
- "${env.compiler.world.dump(cls)}");
+ "${env.compiler.closedWorld.dump(cls)}");
}
if (exact) {
Expect.equals(
@@ -73,7 +73,7 @@
"Unexpected classes "
"${foundClasses.where((c) => !expectedClasses.contains(c))} "
"in '$property' on $cls.\n"
- "${env.compiler.world.dump(cls)}");
+ "${env.compiler.closedWorld.dump(cls)}");
}
}
@@ -99,38 +99,38 @@
expectedClasses.length,
count,
"Unexpected class count in '$property' on $cls.\n"
- "${env.compiler.world.dump(cls)}");
+ "${env.compiler.closedWorld.dump(cls)}");
}
}
void testSubclasses(ClassElement cls, List<ClassElement> expectedClasses,
{bool exact: true}) {
- check('subclassesOf', cls, classWorld.subclassesOf(cls), expectedClasses,
+ check('subclassesOf', cls, closedWorld.subclassesOf(cls), expectedClasses,
exact: exact);
}
void testStrictSubclasses(
ClassElement cls, List<ClassElement> expectedClasses,
{bool exact: true}) {
- check('strictSubclassesOf', cls, classWorld.strictSubclassesOf(cls),
+ check('strictSubclassesOf', cls, closedWorld.strictSubclassesOf(cls),
expectedClasses,
exact: exact,
- forEach: classWorld.forEachStrictSubclassOf,
- getCount: classWorld.strictSubclassCount);
+ forEach: closedWorld.forEachStrictSubclassOf,
+ getCount: closedWorld.strictSubclassCount);
}
void testStrictSubtypes(ClassElement cls, List<ClassElement> expectedClasses,
{bool exact: true}) {
- check('strictSubtypesOf', cls, classWorld.strictSubtypesOf(cls),
+ check('strictSubtypesOf', cls, closedWorld.strictSubtypesOf(cls),
expectedClasses,
exact: exact,
- forEach: classWorld.forEachStrictSubtypeOf,
- getCount: classWorld.strictSubtypeCount);
+ forEach: closedWorld.forEachStrictSubtypeOf,
+ getCount: closedWorld.strictSubtypeCount);
}
void testMixinUses(ClassElement cls, List<ClassElement> expectedClasses,
{bool exact: true}) {
- check('mixinUsesOf', cls, classWorld.mixinUsesOf(cls), expectedClasses,
+ check('mixinUsesOf', cls, closedWorld.mixinUsesOf(cls), expectedClasses,
exact: exact);
}
@@ -234,13 +234,13 @@
}
""",
useMockCompiler: false);
- ClassWorld classWorld = env.compiler.world;
+ ClosedWorld closedWorld = env.compiler.closedWorld;
check(String name, {bool hasStrictSubtype, bool hasOnlySubclasses}) {
ClassElement cls = env.getElement(name);
- Expect.equals(hasStrictSubtype, classWorld.hasAnyStrictSubtype(cls),
+ Expect.equals(hasStrictSubtype, closedWorld.hasAnyStrictSubtype(cls),
"Unexpected hasAnyStrictSubtype property on $cls.");
- Expect.equals(hasOnlySubclasses, classWorld.hasOnlySubclasses(cls),
+ Expect.equals(hasOnlySubclasses, closedWorld.hasOnlySubclasses(cls),
"Unexpected hasOnlySubclasses property on $cls.");
}
diff --git a/tests/compiler/dart2js_extra/mirrors_used_warning_test.dart b/tests/compiler/dart2js_extra/mirrors_used_warning_test.dart
index 4a8a649..9a4eeaa 100644
--- a/tests/compiler/dart2js_extra/mirrors_used_warning_test.dart
+++ b/tests/compiler/dart2js_extra/mirrors_used_warning_test.dart
@@ -24,15 +24,12 @@
Expect.equals("foo", new A().foo);
Expect.isTrue(lines.isEmpty);
var barResult = new A().bar;
- Expect.equals("bar", barResult);
-
- /// minif: ok
+ Expect.equals("bar", barResult); /// minif: ok
+
Expect.isTrue(lines.length == 1);
var line = lines.first;
Expect.isTrue(line.contains("Warning") &&
- line.contains("bar") &&
-
- /// minif: continued
+ line.contains("bar") && /// minif: continued
line.contains("minif"));
}
diff --git a/tests/compiler/dart2js_native/dispatch_property_initialization_test.dart b/tests/compiler/dart2js_native/dispatch_property_initialization_test.dart
new file mode 100644
index 0000000..174eaf8
--- /dev/null
+++ b/tests/compiler/dart2js_native/dispatch_property_initialization_test.dart
@@ -0,0 +1,41 @@
+// 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 for initialization of dispatchPropertyName.
+
+import "package:expect/expect.dart";
+import 'dart:_foreign_helper' show JS;
+import 'dart:_js_helper' show Native;
+
+@Native("Foo")
+class Foo {
+ String method(String x) native;
+}
+
+makeFoo() native;
+
+void setup() native r"""
+function Foo() {}
+Foo.prototype.method = function(x) { return 'Foo ' + x; }
+
+self.makeFoo = function() { return new Foo(); }
+""";
+
+
+main() {
+ setup();
+
+ // If the dispatchPropertyName is uninitialized, it will be `undefined` or
+ // `null` instead of the secret string or Symbol. These properties on
+ // `Object.prototype` will be retrieved by the lookup instead of `undefined`
+ // for the dispatch record.
+ JS('', r'self.Object.prototype["undefined"] = {}');
+ JS('', r'self.Object.prototype["null"] = {}');
+ Expect.equals('Foo A', makeFoo().method('A'));
+
+ // Slightly different version that has malformed dispatch records.
+ JS('', r'self.Object.prototype["undefined"] = {p: false}');
+ JS('', r'self.Object.prototype["null"] = {p: false}');
+ Expect.equals('Foo B', makeFoo().method('B'));
+}
diff --git a/tests/compiler/dart2js_native/foreign_test.dart b/tests/compiler/dart2js_native/foreign_test.dart
index dcefa26..e2a4c4e 100644
--- a/tests/compiler/dart2js_native/foreign_test.dart
+++ b/tests/compiler/dart2js_native/foreign_test.dart
@@ -22,7 +22,7 @@
}
foreign11(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) {
- return JS("num", r"# + # + # + # + # + # + # + # + # + # + #",
+ return JS("num|String", r"# + # + # + # + # + # + # + # + # + # + #",
a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11);
}
diff --git a/tests/compiler/dart2js_native/load_elim_refinement_test.dart b/tests/compiler/dart2js_native/load_elim_refinement_test.dart
new file mode 100644
index 0000000..026b142
--- /dev/null
+++ b/tests/compiler/dart2js_native/load_elim_refinement_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2011, 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";
+import 'dart:_foreign_helper' show JS;
+
+class A {
+ int a;
+}
+
+class B extends A {
+ int b;
+}
+
+@NoInline()
+escape(v) { g = v; }
+var g;
+
+main() {
+ g = new A();
+ var a = JS('returns:A;new:true', '(1,#)', new B());
+
+ a.a = 1;
+ if (a is B) {
+ escape(a); // Here we need to escape 'a' not the refinement of a to B.
+ g.a = 2;
+ Expect.equals(2, a.a);
+ }
+}
diff --git a/tests/html/js_dispatch_property_test.dart b/tests/html/js_dispatch_property_test.dart
new file mode 100644
index 0000000..ebcd2af
--- /dev/null
+++ b/tests/html/js_dispatch_property_test.dart
@@ -0,0 +1,27 @@
+// 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 for dart2js initialization of dispatchPropertyName.
+
+import 'package:unittest/unittest.dart';
+import 'package:unittest/html_config.dart';
+
+import 'package:expect/expect.dart' show NoInline, AssumeDynamic;
+
+import 'js_dispatch_property_test_lib.dart';
+
+@NoInline() @AssumeDynamic()
+confuse(x) => x;
+
+main() {
+ useHtmlConfiguration();
+
+ group('group', () {
+ test('test', () {
+ // Force dynamic interceptor dispatch.
+ var a = confuse(create());
+ expect(a.foo('A'), equals('Foo A'));
+ });
+ });
+}
diff --git a/tests/html/js_dispatch_property_test.html b/tests/html/js_dispatch_property_test.html
new file mode 100644
index 0000000..c17424b
--- /dev/null
+++ b/tests/html/js_dispatch_property_test.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<--
+// 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.
+-->
+<html>
+<head>
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <meta name="dart.unittest" content="full-stack-traces">
+ <title> js_type_test </title>
+ <style>
+ .unittest-table { font-family:monospace; border:1px; }
+ .unittest-pass { background: #6b3;}
+ .unittest-fail { background: #d55;}
+ .unittest-error { background: #a11;}
+ </style>
+</head>
+<body>
+ <h1> Running js_type_test </h1>
+ <script type="text/javascript"
+ src="/root_dart/tests/html/js_dispatch_property_test_js.js"></script>
+ <script type="text/javascript"
+ src="/root_dart/tools/testing/dart/test_controller.js"></script>
+ %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/tests/html/js_dispatch_property_test_js.js b/tests/html/js_dispatch_property_test_js.js
new file mode 100644
index 0000000..8f10dcc
--- /dev/null
+++ b/tests/html/js_dispatch_property_test_js.js
@@ -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.
+
+self.create = function() {
+ return {
+ // If the dispatch property name is uninitialized, it will be `undefined` or
+ // `null`, which will match these properties on dispatch record
+ // lookup. These properties map to malformed dispatch records to force an
+ // error.
+
+ 'undefined': {p: false},
+ 'null': {p: false},
+
+ foo: function(x) { return 'Foo ' + x; },
+ };
+}
diff --git a/tests/html/js_dispatch_property_test_lib.dart b/tests/html/js_dispatch_property_test_lib.dart
new file mode 100644
index 0000000..77e371c
--- /dev/null
+++ b/tests/html/js_dispatch_property_test_lib.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+@JS()
+library js_dispatch_property_test_lib;
+
+import 'package:js/js.dart';
+
+@JS()
+external A create();
+
+@JS() @anonymous
+class A {
+ external String foo(String x);
+}
diff --git a/tests/language/async_star_pause_test.dart b/tests/language/async_star_pause_test.dart
new file mode 100644
index 0000000..c21519d
--- /dev/null
+++ b/tests/language/async_star_pause_test.dart
@@ -0,0 +1,32 @@
+// 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.
+
+library async_star_pause_test;
+
+import "package:unittest/unittest.dart";
+import "dart:async";
+
+main() {
+ test("await for pauses stream during body", () async {
+ // Assumes await-for uses streamIterator.
+ var log = [];
+ var s = () async* {
+ for (int i = 0; i < 3; i++) {
+ log.add("$i-");
+ yield i;
+ // Should pause here until next iteration of await-for loop.
+ log.add("$i+");
+ }
+ }();
+ await for (var i in s) {
+ log.add("$i?");
+ await nextMicrotask();
+ log.add("$i!");
+ }
+ expect(log, ["0-", "0?", "0!", "0+",
+ "1-", "1?", "1!", "1+",
+ "2-", "2?", "2!", "2+"]);
+ });
+}
+Future nextMicrotask() => new Future.microtask((){});
diff --git a/tests/language/async_star_test.dart b/tests/language/async_star_test.dart
index c30f50e..fb7d2e4 100644
--- a/tests/language/async_star_test.dart
+++ b/tests/language/async_star_test.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.
-library async_start_test;
+library async_star_test;
import "package:unittest/unittest.dart";
import "dart:async";
diff --git a/tests/language/language.status b/tests/language/language.status
index 001cf0e..de99e84 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -5,9 +5,15 @@
# 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
+# This is OK for now, but we may want to change the semantics to match the test.
+async_star_pause_test: Fail, OK
+
# These tests are skipped in the VM because it has "--supermixin"
# functionality enabled unconditionally. The tests should be removed
# once the same is true for analyzer (#24478) and dart2js (#23773)
diff --git a/tests/language/string_literals_test.dart b/tests/language/string_literals_test.dart
new file mode 100644
index 0000000..4f7cc04
--- /dev/null
+++ b/tests/language/string_literals_test.dart
@@ -0,0 +1,40 @@
+// 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";
+
+main() {
+ var expect = new String.fromCharCodes([
+ 0, 0x0a, 0x0d, 0x7f, 0xff, 0xffff, 0xd800, 0xdc00, 0xdbff, 0xdfff
+ ]);
+ test(string) {
+ Expect.equals(expect, string);
+ }
+
+ // Plain escapes of code points.
+ test("\x00\x0a\x0d\x7f\xff\uffff\u{10000}\u{10ffff}");
+ test("""\x00\x0a\x0d\x7f\xff\uffff\u{10000}\u{10ffff}""");
+ test('\x00\x0a\x0d\x7f\xff\uffff\u{10000}\u{10ffff}');
+ test('''\x00\x0a\x0d\x7f\xff\uffff\u{10000}\u{10ffff}''');
+ // Plain escapes of individual code units.
+ test("\x00\x0a\x0d\x7f\xff\uffff\ud800\udc00\udbff\udfff");
+ test("""\x00\x0a\x0d\x7f\xff\uffff\ud800\udc00\udbff\udfff""");
+ test('\x00\x0a\x0d\x7f\xff\uffff\ud800\udc00\udbff\udfff');
+ test('''\x00\x0a\x0d\x7f\xff\uffff\ud800\udc00\udbff\udfff''');
+ // Insert newline into multiline string.
+ test("""\x00
+\x0d\x7f\xff\uffff\ud800\udc00\udbff\udfff""");
+ test('''\x00
+\x0d\x7f\xff\uffff\ud800\udc00\udbff\udfff''');
+ // Extract code points from multi-character escape string.
+ test("\x00\x0a\x0d\x7f\xff\uffff"
+ "${"\u{10000}"[0]}${"\u{10000}"[1]}"
+ "${"\u{10FFFF}"[0]}${"\u{10FFFF}"[1]}");
+ test("\x00\x0a\x0d\x7f\xff\uffff" +
+ "\ud800" + "\udc00\udbff" + "\udfff");
+ // Single line string over multiple lines with newlines inside interpolation.
+ test("\x00\x0a\x0d\x7f\xff${
+ ""
+ }\uffff\ud800\udc00\udbff\udfff");
+}
diff --git a/tests/language/string_unicode4_negative_test.dart b/tests/language/string_unicode4_negative_test.dart
index b4ee30f..c7bdf60 100644
--- a/tests/language/string_unicode4_negative_test.dart
+++ b/tests/language/string_unicode4_negative_test.dart
@@ -5,10 +5,8 @@
class StringUnicode4NegativeTest {
static testMain() {
- // Unicode escapes must refer to valid Unicode points and not surrogate characters
+ // Unicode escapes must refer to valid Unicode points.
String str = "Foo\u{FFFFFF}";
- str = "Foo\uD800";
- str = "Foo\uDC00";
}
}
diff --git a/tests/language/vm/lazy_deopt_with_exception_test.dart b/tests/language/vm/lazy_deopt_with_exception_test.dart
new file mode 100644
index 0000000..a494366
--- /dev/null
+++ b/tests/language/vm/lazy_deopt_with_exception_test.dart
@@ -0,0 +1,64 @@
+// 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 deoptimization on an optimistically hoisted smi check.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation --enable-inlining-annotations
+
+// Test that lazy deoptimization works if the program returns to a function
+// that is scheduled for lazy deoptimization via an exception.
+
+import 'package:expect/expect.dart';
+
+class C {
+ var x = 42;
+}
+
+
+const NeverInline = "NeverInline";
+
+@NeverInline
+AA(C c, bool b) {
+ if (b) {
+ c.x = 2.5;
+ throw 123;
+ }
+}
+
+@NeverInline
+T1(C c, bool b) {
+ try {
+ AA(c, b);
+ } on dynamic {
+ }
+ return c.x + 1;
+}
+
+
+@NeverInline
+T2(C c, bool b) {
+ try {
+ AA(c, b);
+ } on String {
+ Expect.isTrue(false);
+ } on int catch(e) {
+ Expect.equals(e, 123);
+ Expect.equals(b, true);
+ Expect.equals(c.x, 2.5);
+ }
+ return c.x + 1;
+}
+
+
+main() {
+ var c = new C();
+ for (var i = 0; i < 10000; ++i) {
+ T1(c, false);
+ T2(c, false);
+ }
+ Expect.equals(43, T1(c, false));
+ Expect.equals(43, T2(c, false));
+ Expect.equals(3.5, T1(c, true));
+ Expect.equals(3.5, T2(c, true));
+}
+
+
diff --git a/tests/standalone/io/skipping_dart2js_compilations_test.dart b/tests/standalone/io/skipping_dart2js_compilations_test.dart
index 27d896f..c175383 100644
--- a/tests/standalone/io/skipping_dart2js_compilations_test.dart
+++ b/tests/standalone/io/skipping_dart2js_compilations_test.dart
@@ -165,6 +165,9 @@
}
void main() {
+ // This script is in [sdk]/tests/standalone/io.
+ suite.TestUtils.setDartDirUri(Platform.script.resolve('../../..'));
+
var fs_noTestJs = new FileUtils(createJs: false,
createJsDeps: true,
createDart: true,
diff --git a/tests/standalone/io/socket_invalid_arguments_test.dart b/tests/standalone/io/socket_invalid_arguments_test.dart
index 803e106..4bc34b6 100644
--- a/tests/standalone/io/socket_invalid_arguments_test.dart
+++ b/tests/standalone/io/socket_invalid_arguments_test.dart
@@ -20,12 +20,17 @@
testSocketCreation(host, port) {
asyncStart();
- Socket.connect(host, port)
- .then((socket) => Expect.fail("Shouldn't get connected"))
- .catchError((e) {
- Expect.isTrue(e is ArgumentError || e is SocketException);
- asyncEnd();
- });
+ try {
+ Socket.connect(host, port)
+ .then((socket) => Expect.fail("Shouldn't get connected"))
+ .catchError((e) {
+ Expect.isTrue(e is ArgumentError || e is SocketException);
+ asyncEnd();
+ });
+ } catch (e) {
+ Expect.isTrue(e is ArgumentError || e is SocketException);
+ asyncEnd();
+ }
}
testAdd(buffer) {
@@ -71,6 +76,8 @@
testSocketCreation(123, 123);
testSocketCreation("string", null);
testSocketCreation(null, null);
+ testSocketCreation("localhost", -1);
+ testSocketCreation("localhost", 65536);
testAdd(null);
testAdd(new NotAList());
testAdd(42);
@@ -82,4 +89,6 @@
testServerSocketCreation(123, 123, 123);
testServerSocketCreation("string", null, null);
testServerSocketCreation("string", 123, null);
+ testServerSocketCreation("localhost", -1, 123);
+ testServerSocketCreation("localhost", 65536, 123);
}
diff --git a/tests/standalone/io/test_runner_test.dart b/tests/standalone/io/test_runner_test.dart
index b216562..d4d6076 100644
--- a/tests/standalone/io/test_runner_test.dart
+++ b/tests/standalone/io/test_runner_test.dart
@@ -141,6 +141,8 @@
}
void main(List<String> arguments) {
+ // This script is in [sdk]/tests/standalone/io.
+ TestUtils.setDartDirUri(Platform.script.resolve('../../..'));
// Run the test_runner_test if there are no command-line options.
// Otherwise, run one of the component tests that always pass,
// fail, or timeout.
diff --git a/tests/standalone/package/scenarios/empty_packages_file/empty_packages_file_noimports_test.dart b/tests/standalone/package/scenarios/empty_packages_file/empty_packages_file_noimports_test.dart
index 580bb01..afaeff5 100644
--- a/tests/standalone/package/scenarios/empty_packages_file/empty_packages_file_noimports_test.dart
+++ b/tests/standalone/package/scenarios/empty_packages_file/empty_packages_file_noimports_test.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.
-// PackageRoot=none
// Packages=.packages
// We expect this to not cause any errors. An empty packages file is valid,
diff --git a/tests/standalone/package/scenarios/empty_packages_file/empty_packages_file_option_test.dart b/tests/standalone/package/scenarios/empty_packages_file/empty_packages_file_option_test.dart
index 38fff19..88fa49b 100644
--- a/tests/standalone/package/scenarios/empty_packages_file/empty_packages_file_option_test.dart
+++ b/tests/standalone/package/scenarios/empty_packages_file/empty_packages_file_option_test.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.
-// PackageRoot=none
// Packages=.packages
library empty_packages_file_option_test;
diff --git a/tests/standalone/package/scenarios/invalid/invalid_package_name_test.dart b/tests/standalone/package/scenarios/invalid/invalid_package_name_test.dart
index ef37f27..4c278c9 100644
--- a/tests/standalone/package/scenarios/invalid/invalid_package_name_test.dart
+++ b/tests/standalone/package/scenarios/invalid/invalid_package_name_test.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.
-// PackageRoot=none
// Packages=invalid_package_name.packages
library invalid_package_name_test;
diff --git a/tests/standalone/package/scenarios/invalid/invalid_utf8_test.dart b/tests/standalone/package/scenarios/invalid/invalid_utf8_test.dart
index 0d93b35..2200e96 100644
--- a/tests/standalone/package/scenarios/invalid/invalid_utf8_test.dart
+++ b/tests/standalone/package/scenarios/invalid/invalid_utf8_test.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.
-// PackageRoot=none
// Packages=invalid_utf8.packages
library invalid_utf8_test;
diff --git a/tests/standalone/package/scenarios/invalid/non_existent_packages_file_test.dart b/tests/standalone/package/scenarios/invalid/non_existent_packages_file_test.dart
index 7c333f7..72a9c65 100644
--- a/tests/standalone/package/scenarios/invalid/non_existent_packages_file_test.dart
+++ b/tests/standalone/package/scenarios/invalid/non_existent_packages_file_test.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.
-// PackageRoot=none
// Packages=non_existent.packages
library non_existent_packages_file_test;
diff --git a/tests/standalone/package/scenarios/invalid/same_package_twice_test.dart b/tests/standalone/package/scenarios/invalid/same_package_twice_test.dart
index e539e71..b3eae8d 100644
--- a/tests/standalone/package/scenarios/invalid/same_package_twice_test.dart
+++ b/tests/standalone/package/scenarios/invalid/same_package_twice_test.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.
-// PackageRoot=none
// Packages=same_package_twice.packages
library same_package_twice_test;
diff --git a/tests/standalone/package/scenarios/packages_file_strange_formatting/empty_lines_test.dart b/tests/standalone/package/scenarios/packages_file_strange_formatting/empty_lines_test.dart
index a5ec547..665597a 100644
--- a/tests/standalone/package/scenarios/packages_file_strange_formatting/empty_lines_test.dart
+++ b/tests/standalone/package/scenarios/packages_file_strange_formatting/empty_lines_test.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.
-// PackageRoot=none
// Packages=empty_lines.packages
library empty_lines_test;
diff --git a/tests/standalone/package/scenarios/packages_file_strange_formatting/empty_package_dir_test.dart b/tests/standalone/package/scenarios/packages_file_strange_formatting/empty_package_dir_test.dart
index 5c7eb39..6c65971 100644
--- a/tests/standalone/package/scenarios/packages_file_strange_formatting/empty_package_dir_test.dart
+++ b/tests/standalone/package/scenarios/packages_file_strange_formatting/empty_package_dir_test.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.
-// PackageRoot=none
// Packages=empty_package_dir.packages
// In this test, we give a packages file that associates the package 'foo' with
diff --git a/tests/standalone/package/scenarios/packages_file_strange_formatting/mixed_line_ends_test.dart b/tests/standalone/package/scenarios/packages_file_strange_formatting/mixed_line_ends_test.dart
index 8f4b629..3e9ec48 100644
--- a/tests/standalone/package/scenarios/packages_file_strange_formatting/mixed_line_ends_test.dart
+++ b/tests/standalone/package/scenarios/packages_file_strange_formatting/mixed_line_ends_test.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.
-// PackageRoot=none
// Packages=mixed_line_ends.packages
library mixed_line_ends_test;
diff --git a/tests/standalone/package/scenarios/packages_option_only/packages_option_only_noimports_test.dart b/tests/standalone/package/scenarios/packages_option_only/packages_option_only_noimports_test.dart
index a6a8273..a519877 100644
--- a/tests/standalone/package/scenarios/packages_option_only/packages_option_only_noimports_test.dart
+++ b/tests/standalone/package/scenarios/packages_option_only/packages_option_only_noimports_test.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.
-// PackageRoot=none
// Packages=sub/.packages
library packages_option_only_noimports_test;
diff --git a/tests/standalone/package/scenarios/packages_option_only/packages_option_only_test.dart b/tests/standalone/package/scenarios/packages_option_only/packages_option_only_test.dart
index e873350..47fdcde 100644
--- a/tests/standalone/package/scenarios/packages_option_only/packages_option_only_test.dart
+++ b/tests/standalone/package/scenarios/packages_option_only/packages_option_only_test.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.
-// PackageRoot=none
// Packages=sub/.packages
library packages_option_only_test;
diff --git a/third_party/tcmalloc/BUILD.gn b/third_party/tcmalloc/BUILD.gn
new file mode 100644
index 0000000..e970559
--- /dev/null
+++ b/third_party/tcmalloc/BUILD.gn
@@ -0,0 +1,124 @@
+# 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.
+
+config("internal_config") {
+ visibility = [ ":*" ] # Only targets in this file can depend on this.
+ cflags = [
+ "-Wall",
+ "-Wextra",
+ "-Wno-missing-field-initializers",
+ "-Wno-sign-compare",
+ "-Wno-type-limits",
+ "-Wno-unused-result",
+ "-Wno-unused-parameter",
+ "-Wno-unused-function",
+ "-Wno-vla",
+ "-g3",
+ "-ggdb3",
+ "-fstack-protector",
+ "-Wa,--noexecstack",
+ "-fno-omit-frame-pointer",
+ "-fno-builtin-malloc",
+ "-fno-builtin-free",
+ "-fno-builtin-realloc",
+ "-fno-builtin-calloc",
+ "-fno-builtin-cfree",
+ "-fno-builtin-memalign",
+ "-fno-builtin-posix_memalign",
+ "-fno-builtin-valloc",
+ "-fno-builtin-pvalloc",
+ ]
+ if (is_clang) {
+ cflags += [
+ "-Wno-unused-const-variable",
+ ]
+ }
+}
+
+config("link_config") {
+ visibility = [ ":*" ] # Only targets in this file can depend on this.
+ ldflags = [
+ # Don't let linker rip this symbol out, otherwise the heap&cpu
+ # profilers will not initialize properly on startup.
+ "-Wl,-uIsHeapProfilerRunning,-uProfilerStart",
+ ]
+}
+
+source_set("dynamic_annotations") {
+ configs -= [ "//build/config/compiler:chromium_code" ]
+ configs += [ ":internal_config" ]
+
+ include_dirs = [
+ "include",
+ "gperftools/src/base",
+ "gperftools/src",
+ ]
+
+ sources = [
+ "gperftools/src/base/dynamic_annotations.c",
+ "gperftools/src/base/dynamic_annotations.h",
+ ]
+}
+
+tcmalloc_sources_list = exec_script("../../tools/gypi_to_gn.py",
+ [rebase_path("tcmalloc_sources.gypi")],
+ "scope",
+ ["tcmalloc_sources.gypi"])
+
+
+source_set("tcmalloc") {
+ configs -= [ "//build/config/compiler:chromium_code" ]
+ configs += [ ":internal_config" ]
+
+ public_configs = [":link_config"]
+
+ deps = [
+ ":dynamic_annotations"
+ ]
+
+ include_dirs = [
+ "include",
+ "gperftools/src/base",
+ "gperftools/src",
+ ]
+
+ # Disable the heap checker in tcmalloc.
+ defines = [
+ "ENABLE_EMERGENCY_MALLOC",
+ "NO_HEAP_CHECK",
+ # Disable debug even in a Dart Debug build. It is too slow.
+ "NDEBUG",
+ ]
+
+ # Disable stack sampling for heap profiling in Product builds.
+ if (is_product) {
+ defines += [
+ "NO_TCMALLOC_SAMPLES",
+ ]
+ }
+
+ cflags = [
+ "-Wnon-virtual-dtor",
+ "-Woverloaded-virtual",
+ "-fno-rtti",
+ "-fpermissive",
+ ]
+
+ set_sources_assignment_filter([
+ # No debug allocator.
+ "gperftools/src/debugallocation.cc",
+ # Not needed when using emergency malloc.
+ "gperftools/src/fake_stacktrace_scope.cc",
+ # Not using the cpuprofiler
+ "gperftools/src/base/thread_lister.c",
+ "gperftools/src/base/thread_lister.h",
+ "gperftools/src/profile-handler.cc",
+ "gperftools/src/profile-handler.h",
+ "gperftools/src/profiledata.cc",
+ "gperftools/src/profiledata.h",
+ "gperftools/src/profiler.cc",
+ ])
+
+ sources = tcmalloc_sources_list.sources
+}
diff --git a/third_party/tcmalloc/tcmalloc_sources.gypi b/third_party/tcmalloc/tcmalloc_sources.gypi
index 6325fb7..d8c4d98 100644
--- a/third_party/tcmalloc/tcmalloc_sources.gypi
+++ b/third_party/tcmalloc/tcmalloc_sources.gypi
@@ -11,8 +11,6 @@
'gperftools/src/common.cc',
'gperftools/src/common.h',
'gperftools/src/config_for_unittests.h',
- 'gperftools/src/config.h',
- 'gperftools/src/config.h.in',
'gperftools/src/debugallocation.cc',
'gperftools/src/emergency_malloc.cc',
'gperftools/src/emergency_malloc_for_stacktrace.cc',
@@ -152,8 +150,6 @@
'gperftools/src/gperftools/malloc_hook.h',
'gperftools/src/gperftools/profiler.h',
'gperftools/src/gperftools/stacktrace.h',
- 'gperftools/src/gperftools/tcmalloc.h',
- 'gperftools/src/gperftools/tcmalloc.h.in',
# gperftools/src/third_party/
'gperftools/src/third_party/valgrind.h',
diff --git a/tools/VERSION b/tools/VERSION
index efeb63c..59e3311 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 1
MINOR 20
PATCH 0
-PRERELEASE 7
+PRERELEASE 8
PRERELEASE_PATCH 0
diff --git a/tools/android_link.py b/tools/android_link.py
index 7854ce4..5de6d45 100755
--- a/tools/android_link.py
+++ b/tools/android_link.py
@@ -132,9 +132,11 @@
crtend_android = os.path.join(android_ndk_lib, 'crtend_android.o')
if link_target == 'target':
+ # We meddle with the android link command line here because gyp does not
+ # allow configurations to modify link_settings, or set variables.
+
# Add and remove libraries as listed in configurations_android.gypi
- libs_to_rm = ['-lrt', '-lpthread', '-lnss3', '-lnssutil3', '-lsmime3',
- '-lplds4', '-lplc4', '-lnspr4',]
+ libs_to_rm = ['-lrt', '-lpthread',]
libs_to_add = ['-lstlport_static', android_libgcc, '-lc', '-ldl',
'-lstdc++', '-lm',]
@@ -142,9 +144,13 @@
if link_type == 'executable':
libs_to_add.extend(['-llog', '-lz', crtend_android])
+ # Filter out -l libs and add the right Android ones.
link_args = [i for i in link_args if i not in libs_to_rm]
link_args.extend(libs_to_add)
+ # Filter out tcmalloc.
+ link_args = [i for i in link_args if "tcmalloc" not in i]
+
link_args.insert(0, android_linker)
else:
link_args.extend(['-ldl', '-lrt'])
diff --git a/tools/clang/scripts/update.py b/tools/clang/scripts/update.py
new file mode 100755
index 0000000..55b64ee
--- /dev/null
+++ b/tools/clang/scripts/update.py
@@ -0,0 +1,771 @@
+#!/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.
+
+"""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."""
+
+import argparse
+import contextlib
+import cStringIO
+import glob
+import os
+import pipes
+import re
+import shutil
+import subprocess
+import stat
+import sys
+import tarfile
+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
+# 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'
+
+use_head_revision = 'LLVM_FORCE_HEAD_REVISION' in os.environ
+if use_head_revision:
+ LLVM_WIN_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)
+
+# Path constants. (All of these should be absolute paths.)
+THIS_DIR = os.path.abspath(os.path.dirname(__file__))
+CHROMIUM_DIR = os.path.abspath(os.path.join(THIS_DIR, '..', '..', '..'))
+THIRD_PARTY_DIR = os.path.join(CHROMIUM_DIR, 'third_party')
+LLVM_DIR = os.path.join(THIRD_PARTY_DIR, 'llvm')
+LLVM_BOOTSTRAP_DIR = os.path.join(THIRD_PARTY_DIR, 'llvm-bootstrap')
+LLVM_BOOTSTRAP_INSTALL_DIR = os.path.join(THIRD_PARTY_DIR,
+ 'llvm-bootstrap-install')
+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')
+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')
+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')
+BINUTILS_DIR = os.path.join(THIRD_PARTY_DIR, 'binutils')
+VERSION = '3.8.0'
+
+# URL for pre-built binaries.
+CDS_URL = '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']
+
+
+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
+ 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.'
+
+
+def ReadStampFile():
+ """Return the contents of the stamp file, or '' if it doesn't exist."""
+ try:
+ with open(STAMP_FILE, 'r') as f:
+ return f.read()
+ except IOError:
+ return ''
+
+
+def WriteStampFile(s):
+ """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:
+ f.write(s)
+
+
+def GetSvnRevision(svn_repo):
+ """Returns current revision of the svn repo at svn_repo."""
+ svn_info = subprocess.check_output('svn info ' + svn_repo, shell=True)
+ m = re.search(r'Revision: (\d+)', svn_info)
+ return m.group(1)
+
+
+def RmTree(dir):
+ """Delete dir."""
+ def ChmodAndRetry(func, path, _):
+ # Subversion can leave read-only files around.
+ if not os.access(path, os.W_OK):
+ os.chmod(path, stat.S_IWUSR)
+ return func(path)
+ raise
+
+ shutil.rmtree(dir, onerror=ChmodAndRetry)
+
+
+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
+ shell with the msvc tools for that architecture."""
+
+ if msvc_arch and sys.platform == 'win32':
+ command = GetVSVersion().SetupScript(msvc_arch) + ['&&'] + command
+
+ # https://docs.python.org/2/library/subprocess.html:
+ # "On Unix with shell=True [...] if args is a sequence, the first item
+ # specifies the command string, and any additional items will be treated as
+ # additional arguments to the shell itself. That is to say, Popen does the
+ # equivalent of:
+ # Popen(['/bin/sh', '-c', args[0], args[1], ...])"
+ #
+ # We want to pass additional arguments to command[0], not to the shell,
+ # so manually join everything into a single string.
+ # Annoyingly, for "svn co url c:\path", pipes.quote() thinks that it should
+ # quote c:\path but svn can't handle quoted paths on Windows. Since on
+ # Windows follow-on args are passed to args[0] instead of the shell, don't
+ # do the single-string transformation there.
+ if sys.platform != 'win32':
+ command = ' '.join([pipes.quote(c) for c in command])
+ print 'Running', command
+ if subprocess.call(command, env=env, shell=True) == 0:
+ return True
+ print 'Failed.'
+ if fail_hard:
+ sys.exit(1)
+ return False
+
+
+def CopyFile(src, dst):
+ """Copy a file from src to dst."""
+ shutil.copy(src, dst)
+ print "Copying %s to %s" % (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)
+ for root, _, files in os.walk(src):
+ for f in files:
+ if filename_filter and not re.match(filename_filter, f):
+ continue
+ CopyFile(os.path.join(root, f), dst)
+
+
+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)
+
+ command = ['svn', 'checkout', '--force', url + '@' + LLVM_WIN_REVISION, dir]
+ if RunCommand(command, fail_hard=False):
+ return
+
+ if os.path.isdir(dir):
+ print "Removing %s." % (dir)
+ RmTree(dir)
+
+ print "Retrying."
+ 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():
+ shutil.rmtree(CHROME_TOOLS_SHIM_DIR, ignore_errors=True)
+
+
+def CreateChromeToolsShim():
+ """Hooks the Chrome tools into the LLVM build.
+
+ Several Chrome tools have dependencies on LLVM/Clang libraries. The LLVM build
+ detects implicit tools in the tools subdirectory, so this helper install a
+ shim CMakeLists.txt that forwards to the real directory for the Chrome tools.
+
+ Note that the shim directory name intentionally has no - or _. The implicit
+ tool detection logic munges them in a weird way."""
+ assert not any(i in os.path.basename(CHROME_TOOLS_SHIM_DIR) for i in '-_')
+ os.mkdir(CHROME_TOOLS_SHIM_DIR)
+ with file(os.path.join(CHROME_TOOLS_SHIM_DIR, 'CMakeLists.txt'), 'w') as f:
+ f.write('# Automatically generated by tools/clang/scripts/update.py. ' +
+ 'Do not edit.\n')
+ f.write('# Since tools/clang is located in another directory, use the \n')
+ f.write('# two arg version to specify where build artifacts go. CMake\n')
+ f.write('# disallows reuse of the same binary dir for multiple source\n')
+ f.write('# dirs, so the build artifacts need to go into a subdirectory.\n')
+ f.write('# dirs, so the build artifacts need to go into a subdirectory.\n')
+ f.write('if (CHROMIUM_TOOLS_SRC)\n')
+ f.write(' add_subdirectory(${CHROMIUM_TOOLS_SRC} ' +
+ '${CMAKE_CURRENT_BINARY_DIR}/a)\n')
+ f.write('endif (CHROMIUM_TOOLS_SRC)\n')
+
+
+def AddCMakeToPath():
+ """Download CMake and add it to PATH."""
+ if sys.platform == 'win32':
+ zip_name = 'cmake-3.2.2-win32-x86.zip'
+ cmake_dir = os.path.join(LLVM_BUILD_TOOLS_DIR,
+ 'cmake-3.2.2-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')
+ 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)
+ os.environ['PATH'] = cmake_dir + os.pathsep + os.environ.get('PATH', '')
+
+vs_version = None
+def GetVSVersion():
+ global vs_version
+ if vs_version:
+ return vs_version
+
+ # Try using the toolchain in depot_tools.
+ # This sets environment variables used by SelectVisualStudioVersion below.
+ sys.path.append(os.path.join(CHROMIUM_DIR, 'build'))
+ import vs_toolchain
+ vs_toolchain.SetEnvironmentAndGetRuntimeDllDirs()
+
+ # Use gyp to find the MSVS installation, either in depot_tools as per above,
+ # 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')
+ return vs_version
+
+
+def UpdateClang(args):
+ print 'Updating Clang to %s...' % PACKAGE_VERSION
+ if ReadStampFile() == PACKAGE_VERSION:
+ print 'Already up to date.'
+ 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
+
+ # 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'
+
+ # 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
+
+ AddCMakeToPath()
+
+ RevertPreviouslyPatchedFiles()
+ DeleteChromeToolsShim()
+
+ Checkout('LLVM', LLVM_REPO_URL + '/llvm/trunk', LLVM_DIR)
+ Checkout('Clang', LLVM_REPO_URL + '/cfe/trunk', CLANG_DIR)
+ if sys.platform == 'win32':
+ 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()
+
+ cc, cxx = None, None
+ cflags = cxxflags = ldflags = []
+
+ # 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 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'
+
+ base_cmake_args = ['-GNinja',
+ '-DCMAKE_BUILD_TYPE=Release',
+ '-DLLVM_ENABLE_ASSERTIONS=ON',
+ '-DLLVM_ENABLE_THREADS=OFF',
+ ]
+
+ if args.bootstrap:
+ print 'Building bootstrap compiler'
+ if not os.path.exists(LLVM_BOOTSTRAP_DIR):
+ os.makedirs(LLVM_BOOTSTRAP_DIR)
+ os.chdir(LLVM_BOOTSTRAP_DIR)
+ bootstrap_args = base_cmake_args + [
+ '-DLLVM_TARGETS_TO_BUILD=host',
+ '-DCMAKE_INSTALL_PREFIX=' + LLVM_BOOTSTRAP_INSTALL_DIR,
+ '-DCMAKE_C_FLAGS=' + ' '.join(cflags),
+ '-DCMAKE_CXX_FLAGS=' + ' '.join(cxxflags),
+ ]
+ if cc is not None: bootstrap_args.append('-DCMAKE_C_COMPILER=' + cc)
+ if cxx is not None: bootstrap_args.append('-DCMAKE_CXX_COMPILER=' + cxx)
+ RunCommand(['cmake'] + bootstrap_args + [LLVM_DIR], msvc_arch='x64')
+ RunCommand(['ninja'], msvc_arch='x64')
+ if args.run_tests:
+ RunCommand(['ninja', 'check-all'], msvc_arch='x64')
+ RunCommand(['ninja', 'install'], msvc_arch='x64')
+
+ if sys.platform == 'win32':
+ cc = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'clang-cl.exe')
+ cxx = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'clang-cl.exe')
+ # CMake has a hard time with backslashes in compiler paths:
+ # https://stackoverflow.com/questions/13050827
+ cc = cc.replace('\\', '/')
+ cxx = cxx.replace('\\', '/')
+ else:
+ cc = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'clang')
+ cxx = os.path.join(LLVM_BOOTSTRAP_INSTALL_DIR, 'bin', 'clang++')
+ 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']
+
+ # 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')))
+
+ 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')])
+
+ 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]
+
+ 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
+
+ # 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.
+ if use_head_revision:
+ cflags += ['-DLLVM_FORCE_HEAD_REVISION']
+ cxxflags += ['-DLLVM_FORCE_HEAD_REVISION']
+
+ CreateChromeToolsShim()
+
+ deployment_env = None
+ if deployment_target:
+ deployment_env = os.environ.copy()
+ deployment_env['MACOSX_DEPLOYMENT_TARGET'] = deployment_target
+
+ cmake_args = base_cmake_args + [
+ '-DLLVM_BINUTILS_INCDIR=' + binutils_incdir,
+ '-DCMAKE_C_FLAGS=' + ' '.join(cflags),
+ '-DCMAKE_CXX_FLAGS=' + ' '.join(cxxflags),
+ '-DCMAKE_EXE_LINKER_FLAGS=' + ' '.join(ldflags),
+ '-DCMAKE_SHARED_LINKER_FLAGS=' + ' '.join(ldflags),
+ '-DCMAKE_MODULE_LINKER_FLAGS=' + ' '.join(ldflags),
+ '-DCMAKE_INSTALL_PREFIX=' + LLVM_BUILD_DIR,
+ '-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)
+ os.chdir(LLVM_BUILD_DIR)
+ RunCommand(['cmake'] + cmake_args + [LLVM_DIR],
+ msvc_arch='x64', env=deployment_env)
+ RunCommand(['ninja'], msvc_arch='x64')
+
+ if args.tools:
+ # If any Chromium tools were built, install those now.
+ 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.
+ # 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)
+ os.chdir(COMPILER_RT_BUILD_DIR)
+ # TODO(thakis): Add this once compiler-rt can build with clang-cl (see
+ # above).
+ #if args.bootstrap and sys.platform == 'win32':
+ # The bootstrap compiler produces 64-bit binaries by default.
+ #cflags += ['-m32']
+ #cxxflags += ['-m32']
+ compiler_rt_args = base_cmake_args + [
+ '-DCMAKE_C_FLAGS=' + ' '.join(cflags),
+ '-DCMAKE_CXX_FLAGS=' + ' '.join(cxxflags)]
+ 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)
+ RunCommand(['ninja', 'compiler-rt'], msvc_arch='x86')
+
+ # TODO(hans): Make this (and the .gypi and .isolate files) version number
+ # independent.
+ if sys.platform == 'win32':
+ platform = 'windows'
+ elif sys.platform == 'darwin':
+ platform = 'darwin'
+ 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_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$')
+
+ 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
+ # of the fallback compiler.
+ sanitizer_include_dir = os.path.join(LLVM_BUILD_DIR, 'lib', 'clang',
+ VERSION, 'include', 'sanitizer')
+ 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)
+ for _, _, files in os.walk(sanitizer_include_dir):
+ for f in files:
+ CopyFile(os.path.join(sanitizer_include_dir, f),
+ aux_sanitizer_include_dir)
+
+ # Run tests.
+ if args.run_tests or use_head_revision:
+ os.chdir(LLVM_BUILD_DIR)
+ RunCommand(GetVSVersion().SetupScript('x64') +
+ ['&&', 'ninja', 'cr-check-all'])
+ if args.run_tests:
+ os.chdir(LLVM_BUILD_DIR)
+ RunCommand(GetVSVersion().SetupScript('x64') +
+ ['&&', 'ninja', 'check-all'])
+
+ WriteStampFile(PACKAGE_VERSION)
+ print 'Clang update was successful.'
+ return 0
+
+
+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.')
+ parser.add_argument('--if-needed', action='store_true',
+ 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('--print-revision', action='store_true',
+ help='print current clang revision and exit.')
+ parser.add_argument('--print-clang-version', action='store_true',
+ help='print current clang version (e.g. x.y.z) and exit.')
+ parser.add_argument('--run-tests', action='store_true',
+ help='run tests after building; only for local builds')
+ 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')
+
+ args = parser.parse_args()
+
+ if args.if_needed:
+ is_clang_required = False
+ # clang is always used on Mac and Linux.
+ if sys.platform == 'darwin' or sys.platform.startswith('linux'):
+ is_clang_required = True
+ # clang requested via $GYP_DEFINES.
+ 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.
+ # 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
+ if not is_clang_required:
+ return 0
+ if re.search(r'\b(make_clang_dir)=', os.environ.get('GYP_DEFINES', '')):
+ print 'Skipping Clang update (make_clang_dir= was set in GYP_DEFINES).'
+ return 0
+
+ global LLVM_WIN_REVISION, PACKAGE_VERSION
+ if args.print_revision:
+ if use_head_revision:
+ print GetSvnRevision(LLVM_DIR)
+ else:
+ print PACKAGE_VERSION
+ return 0
+
+ if args.print_clang_version:
+ sys.stdout.write(VERSION)
+ return 0
+
+ # Don't buffer stdout, so that print statements are immediately flushed.
+ # Do this only after --print-revision has been handled, else we'll get
+ # an error message when this script is run from gn for some reason.
+ sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
+
+ 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'
+
+ args.force_local_build = True
+ # Skip local patches when using HEAD: they probably don't apply anymore.
+ args.with_patches = False
+
+ return UpdateClang(args)
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/tools/clang/scripts/update.sh b/tools/clang/scripts/update.sh
new file mode 100755
index 0000000..d85deae
--- /dev/null
+++ b/tools/clang/scripts/update.sh
@@ -0,0 +1,724 @@
+#!/usr/bin/env 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 script will check out llvm and clang into third_party/llvm and build it.
+
+# Do NOT CHANGE this if you don't know what you're doing -- see
+# https://code.google.com/p/chromium/wiki/UpdatingClang
+# Reverting problematic clang rolls is safe, though.
+CLANG_REVISION=241602
+
+# This is incremented when pushing a new build of Clang at the same revision.
+CLANG_SUB_REVISION=3
+
+PACKAGE_VERSION="${CLANG_REVISION}-${CLANG_SUB_REVISION}"
+
+THIS_DIR="$(dirname "${0}")"
+LLVM_DIR="${THIS_DIR}/../../../third_party/llvm"
+LLVM_BUILD_DIR="${LLVM_DIR}/../llvm-build/Release+Asserts"
+COMPILER_RT_BUILD_DIR="${LLVM_DIR}/../llvm-build/compiler-rt"
+LLVM_BOOTSTRAP_DIR="${LLVM_DIR}/../llvm-bootstrap"
+LLVM_BOOTSTRAP_INSTALL_DIR="${LLVM_DIR}/../llvm-bootstrap-install"
+CLANG_DIR="${LLVM_DIR}/tools/clang"
+COMPILER_RT_DIR="${LLVM_DIR}/compiler-rt"
+LIBCXX_DIR="${LLVM_DIR}/projects/libcxx"
+LIBCXXABI_DIR="${LLVM_DIR}/projects/libcxxabi"
+ANDROID_NDK_DIR="${THIS_DIR}/../../../third_party/android_tools/ndk"
+STAMP_FILE="${LLVM_DIR}/../llvm-build/cr_build_revision"
+CHROMIUM_TOOLS_DIR="${THIS_DIR}/.."
+BINUTILS_DIR="${THIS_DIR}/../../../third_party/binutils"
+
+ABS_CHROMIUM_TOOLS_DIR="${PWD}/${CHROMIUM_TOOLS_DIR}"
+ABS_LIBCXX_DIR="${PWD}/${LIBCXX_DIR}"
+ABS_LIBCXXABI_DIR="${PWD}/${LIBCXXABI_DIR}"
+ABS_LLVM_DIR="${PWD}/${LLVM_DIR}"
+ABS_LLVM_BUILD_DIR="${PWD}/${LLVM_BUILD_DIR}"
+ABS_COMPILER_RT_DIR="${PWD}/${COMPILER_RT_DIR}"
+ABS_BINUTILS_DIR="${PWD}/${BINUTILS_DIR}"
+
+# ${A:-a} returns $A if it's set, a else.
+LLVM_REPO_URL=${LLVM_URL:-https://llvm.org/svn/llvm-project}
+
+CDS_URL=https://commondatastorage.googleapis.com/chromium-browser-clang
+
+if [[ -z "$GYP_DEFINES" ]]; then
+ GYP_DEFINES=
+fi
+if [[ -z "$GYP_GENERATORS" ]]; then
+ GYP_GENERATORS=
+fi
+if [[ -z "$LLVM_DOWNLOAD_GOLD_PLUGIN" ]]; then
+ LLVM_DOWNLOAD_GOLD_PLUGIN=
+fi
+
+
+# Die if any command dies, error on undefined variable expansions.
+set -eu
+
+
+if [[ -n ${LLVM_FORCE_HEAD_REVISION:-''} ]]; then
+ # Use a real revision number rather than HEAD to make sure that the stamp file
+ # logic works.
+ CLANG_REVISION=$(svn info "$LLVM_REPO_URL" \
+ | grep 'Revision:' | awk '{ printf $2; }')
+ PACKAGE_VERSION="${CLANG_REVISION}-0"
+fi
+
+OS="$(uname -s)"
+
+# Parse command line options.
+if_needed=
+force_local_build=
+run_tests=
+bootstrap=
+with_android=yes
+chrome_tools="plugins;blink_gc_plugin"
+gcc_toolchain=
+with_patches=yes
+
+if [[ "${OS}" = "Darwin" ]]; then
+ with_android=
+fi
+
+while [[ $# > 0 ]]; do
+ case $1 in
+ --bootstrap)
+ bootstrap=yes
+ ;;
+ --if-needed)
+ if_needed=yes
+ ;;
+ --force-local-build)
+ force_local_build=yes
+ ;;
+ --print-revision)
+ if [[ -n ${LLVM_FORCE_HEAD_REVISION:-''} ]]; then
+ svn info "$LLVM_DIR" | grep 'Revision:' | awk '{ printf $2; }'
+ else
+ echo $PACKAGE_VERSION
+ fi
+ exit 0
+ ;;
+ --run-tests)
+ run_tests=yes
+ ;;
+ --without-android)
+ with_android=
+ ;;
+ --without-patches)
+ with_patches=
+ ;;
+ --with-chrome-tools)
+ shift
+ if [[ $# == 0 ]]; then
+ echo "--with-chrome-tools requires an argument."
+ exit 1
+ fi
+ chrome_tools=$1
+ ;;
+ --gcc-toolchain)
+ shift
+ if [[ $# == 0 ]]; then
+ echo "--gcc-toolchain requires an argument."
+ exit 1
+ fi
+ if [[ -x "$1/bin/gcc" ]]; then
+ gcc_toolchain=$1
+ else
+ echo "Invalid --gcc-toolchain: '$1'."
+ echo "'$1/bin/gcc' does not appear to be valid."
+ exit 1
+ fi
+ ;;
+
+ --help)
+ echo "usage: $0 [--force-local-build] [--if-needed] [--run-tests] "
+ echo "--bootstrap: First build clang with CC, then with itself."
+ echo "--force-local-build: Don't try to download prebuilt binaries."
+ echo "--if-needed: Download clang only if the script thinks it is needed."
+ echo "--run-tests: Run tests after building. Only for local builds."
+ echo "--print-revision: Print current clang revision and exit."
+ echo "--without-android: Don't build ASan Android runtime library."
+ echo "--with-chrome-tools: Select which chrome tools to build." \
+ "Defaults to plugins;blink_gc_plugin."
+ echo " Example: --with-chrome-tools plugins;empty-string"
+ echo "--gcc-toolchain: Set the prefix for which GCC version should"
+ echo " be used for building. For example, to use gcc in"
+ echo " /opt/foo/bin/gcc, use '--gcc-toolchain '/opt/foo"
+ echo "--without-patches: Don't apply local patches."
+ echo
+ exit 1
+ ;;
+ *)
+ echo "Unknown argument: '$1'."
+ echo "Use --help for help."
+ exit 1
+ ;;
+ esac
+ shift
+done
+
+if [[ -n ${LLVM_FORCE_HEAD_REVISION:-''} ]]; then
+ force_local_build=yes
+
+ # Skip local patches when using HEAD: they probably don't apply anymore.
+ with_patches=
+
+ if ! [[ "$GYP_DEFINES" =~ .*OS=android.* ]]; then
+ # Only build the Android ASan rt when targetting Android.
+ with_android=
+ fi
+
+ LLVM_BUILD_TOOLS_DIR="${ABS_LLVM_DIR}/../llvm-build-tools"
+
+ if [[ "${OS}" == "Linux" ]] && [[ -z "${gcc_toolchain}" ]]; then
+ if [[ $(gcc -dumpversion) < "4.7.0" ]]; then
+ # We need a newer GCC version.
+ if [[ ! -e "${LLVM_BUILD_TOOLS_DIR}/gcc482" ]]; then
+ echo "Downloading pre-built GCC 4.8.2..."
+ mkdir -p "${LLVM_BUILD_TOOLS_DIR}"
+ curl --fail -L "${CDS_URL}/tools/gcc482.tgz" | \
+ tar zxf - -C "${LLVM_BUILD_TOOLS_DIR}"
+ echo Done
+ fi
+ gcc_toolchain="${LLVM_BUILD_TOOLS_DIR}/gcc482"
+ else
+ # Always set gcc_toolchain; llvm-symbolizer needs the bundled libstdc++.
+ gcc_toolchain="$(dirname $(dirname $(which gcc)))"
+ fi
+ fi
+
+ if [[ "${OS}" == "Linux" || "${OS}" == "Darwin" ]]; then
+ if [[ $(cmake --version | grep -Eo '[0-9.]+') < "3.0" ]]; then
+ # We need a newer CMake version.
+ if [[ ! -e "${LLVM_BUILD_TOOLS_DIR}/cmake310" ]]; then
+ echo "Downloading pre-built CMake 3.10..."
+ mkdir -p "${LLVM_BUILD_TOOLS_DIR}"
+ curl --fail -L "${CDS_URL}/tools/cmake310_${OS}.tgz" | \
+ tar zxf - -C "${LLVM_BUILD_TOOLS_DIR}"
+ echo Done
+ fi
+ export PATH="${LLVM_BUILD_TOOLS_DIR}/cmake310/bin:${PATH}"
+ fi
+ fi
+
+ echo "LLVM_FORCE_HEAD_REVISION was set; using r${CLANG_REVISION}"
+fi
+
+if [[ -n "$if_needed" ]]; then
+ if [[ "${OS}" == "Darwin" ]]; then
+ # clang is always used on Mac.
+ true
+ elif [[ "${OS}" == "Linux" ]]; then
+ # clang is also aways used on Linux.
+ true
+ elif [[ "$GYP_DEFINES" =~ .*(clang|tsan|asan|lsan|msan)=1.* ]]; then
+ # clang requested via $GYP_DEFINES.
+ true
+ elif [[ -d "${LLVM_BUILD_DIR}" ]]; then
+ # clang previously downloaded, keep it up-to-date.
+ # If you don't want this, delete third_party/llvm-build on your machine.
+ true
+ else
+ # clang wasn't needed, not doing anything.
+ exit 0
+ fi
+fi
+
+
+# Check if there's anything to be done, exit early if not.
+if [[ -f "${STAMP_FILE}" ]]; then
+ PREVIOUSLY_BUILT_REVISON=$(cat "${STAMP_FILE}")
+ if [[ -z "$force_local_build" ]] && \
+ [[ "${PREVIOUSLY_BUILT_REVISON}" = \
+ "${PACKAGE_VERSION}" ]]; then
+ echo "Clang already at ${PACKAGE_VERSION}"
+ exit 0
+ fi
+fi
+# To always force a new build if someone interrupts their build half way.
+rm -f "${STAMP_FILE}"
+
+
+if [[ -z "$force_local_build" ]]; then
+ # 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.
+ CDS_FILE="clang-${PACKAGE_VERSION}.tgz"
+ CDS_OUT_DIR=$(mktemp -d -t clang_download.XXXXXX)
+ CDS_OUTPUT="${CDS_OUT_DIR}/${CDS_FILE}"
+ if [ "${OS}" = "Linux" ]; then
+ CDS_FULL_URL="${CDS_URL}/Linux_x64/${CDS_FILE}"
+ elif [ "${OS}" = "Darwin" ]; then
+ CDS_FULL_URL="${CDS_URL}/Mac/${CDS_FILE}"
+ fi
+ echo Trying to download prebuilt clang
+ if which curl > /dev/null; then
+ curl -L --fail "${CDS_FULL_URL}" -o "${CDS_OUTPUT}" || \
+ rm -rf "${CDS_OUT_DIR}"
+ elif which wget > /dev/null; then
+ wget "${CDS_FULL_URL}" -O "${CDS_OUTPUT}" || rm -rf "${CDS_OUT_DIR}"
+ else
+ echo "Neither curl nor wget found. Please install one of these."
+ exit 1
+ fi
+ if [ -f "${CDS_OUTPUT}" ]; then
+ rm -rf "${LLVM_BUILD_DIR}"
+ mkdir -p "${LLVM_BUILD_DIR}"
+ tar -xzf "${CDS_OUTPUT}" -C "${LLVM_BUILD_DIR}"
+ echo clang "${PACKAGE_VERSION}" unpacked
+ echo "${PACKAGE_VERSION}" > "${STAMP_FILE}"
+ rm -rf "${CDS_OUT_DIR}"
+ # Download the gold plugin if requested to by an environment variable.
+ # This is used by the CFI ClusterFuzz bot.
+ if [[ -n "${LLVM_DOWNLOAD_GOLD_PLUGIN}" ]]; then
+ ${THIS_DIR}/../../../build/download_gold_plugin.py
+ fi
+ exit 0
+ else
+ echo Did not find prebuilt clang "${PACKAGE_VERSION}", building
+ fi
+fi
+
+if [[ -n "${with_android}" ]] && ! [[ -d "${ANDROID_NDK_DIR}" ]]; then
+ echo "Android NDK not found at ${ANDROID_NDK_DIR}"
+ echo "The Android NDK is needed to build a Clang whose -fsanitize=address"
+ echo "works on Android. See "
+ echo "http://code.google.com/p/chromium/wiki/AndroidBuildInstructions for how"
+ echo "to install the NDK, or pass --without-android."
+ exit 1
+fi
+
+# Check that cmake and ninja are available.
+if ! which cmake > /dev/null; then
+ echo "CMake needed to build clang; please install"
+ exit 1
+fi
+if ! which ninja > /dev/null; then
+ echo "ninja needed to build clang, please install"
+ exit 1
+fi
+
+echo Reverting previously patched files
+for i in \
+ "${CLANG_DIR}/test/Index/crash-recovery-modules.m" \
+ "${CLANG_DIR}/unittests/libclang/LibclangTest.cpp" \
+ "${COMPILER_RT_DIR}/lib/asan/asan_rtl.cc" \
+ "${COMPILER_RT_DIR}/test/asan/TestCases/Linux/new_array_cookie_test.cc" \
+ "${LLVM_DIR}/test/DebugInfo/gmlt.ll" \
+ "${LLVM_DIR}/lib/CodeGen/SpillPlacement.cpp" \
+ "${LLVM_DIR}/lib/CodeGen/SpillPlacement.h" \
+ "${LLVM_DIR}/lib/Transforms/Instrumentation/MemorySanitizer.cpp" \
+ "${CLANG_DIR}/test/Driver/env.c" \
+ "${CLANG_DIR}/lib/Frontend/InitPreprocessor.cpp" \
+ "${CLANG_DIR}/test/Frontend/exceptions.c" \
+ "${CLANG_DIR}/test/Preprocessor/predefined-exceptions.m" \
+ "${LLVM_DIR}/test/Bindings/Go/go.test" \
+ "${CLANG_DIR}/lib/Parse/ParseExpr.cpp" \
+ "${CLANG_DIR}/lib/Parse/ParseTemplate.cpp" \
+ "${CLANG_DIR}/lib/Sema/SemaDeclCXX.cpp" \
+ "${CLANG_DIR}/lib/Sema/SemaExprCXX.cpp" \
+ "${CLANG_DIR}/test/SemaCXX/default2.cpp" \
+ "${CLANG_DIR}/test/SemaCXX/typo-correction-delayed.cpp" \
+ "${COMPILER_RT_DIR}/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc" \
+ "${COMPILER_RT_DIR}/test/tsan/signal_segv_handler.cc" \
+ "${COMPILER_RT_DIR}/lib/sanitizer_common/sanitizer_coverage_libcdep.cc" \
+ "${COMPILER_RT_DIR}/cmake/config-ix.cmake" \
+ "${COMPILER_RT_DIR}/CMakeLists.txt" \
+ "${COMPILER_RT_DIR}/lib/ubsan/ubsan_platform.h" \
+ ; do
+ if [[ -e "${i}" ]]; then
+ rm -f "${i}" # For unversioned files.
+ svn revert "${i}"
+ fi;
+done
+
+echo Remove the Clang tools shim dir
+CHROME_TOOLS_SHIM_DIR=${ABS_LLVM_DIR}/tools/chrometools
+rm -rfv ${CHROME_TOOLS_SHIM_DIR}
+
+echo Getting LLVM r"${CLANG_REVISION}" in "${LLVM_DIR}"
+if ! svn co --force "${LLVM_REPO_URL}/llvm/trunk@${CLANG_REVISION}" \
+ "${LLVM_DIR}"; then
+ echo Checkout failed, retrying
+ rm -rf "${LLVM_DIR}"
+ svn co --force "${LLVM_REPO_URL}/llvm/trunk@${CLANG_REVISION}" "${LLVM_DIR}"
+fi
+
+echo Getting clang r"${CLANG_REVISION}" in "${CLANG_DIR}"
+svn co --force "${LLVM_REPO_URL}/cfe/trunk@${CLANG_REVISION}" "${CLANG_DIR}"
+
+# We have moved from building compiler-rt in the LLVM tree, to a separate
+# directory. Nuke any previous checkout to avoid building it.
+rm -rf "${LLVM_DIR}/projects/compiler-rt"
+
+echo Getting compiler-rt r"${CLANG_REVISION}" in "${COMPILER_RT_DIR}"
+svn co --force "${LLVM_REPO_URL}/compiler-rt/trunk@${CLANG_REVISION}" \
+ "${COMPILER_RT_DIR}"
+
+# clang needs a libc++ checkout, else -stdlib=libc++ won't find includes
+# (i.e. this is needed for bootstrap builds).
+if [ "${OS}" = "Darwin" ]; then
+ echo Getting libc++ r"${CLANG_REVISION}" in "${LIBCXX_DIR}"
+ svn co --force "${LLVM_REPO_URL}/libcxx/trunk@${CLANG_REVISION}" \
+ "${LIBCXX_DIR}"
+fi
+
+# 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).
+if [ "${OS}" = "Darwin" ]; then
+ echo Getting libc++abi r"${CLANG_REVISION}" in "${LIBCXXABI_DIR}"
+ svn co --force "${LLVM_REPO_URL}/libcxxabi/trunk@${CLANG_REVISION}" \
+ "${LIBCXXABI_DIR}"
+fi
+
+if [[ -n "$with_patches" ]]; then
+
+ # Apply patch for tests failing with --disable-pthreads (llvm.org/PR11974)
+ pushd "${CLANG_DIR}"
+ cat << 'EOF' |
+--- 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;
+EOF
+patch -p0
+popd
+
+pushd "${CLANG_DIR}"
+cat << 'EOF' |
+--- 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() {"
+EOF
+ patch -p0
+ popd
+
+ # This Go bindings test doesn't work after the bootstrap build on Linux. (PR21552)
+ pushd "${LLVM_DIR}"
+ cat << 'EOF' |
+--- 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
+EOF
+ patch -p0
+ popd
+
+ # The UBSan run-time, which is now bundled with the ASan run-time, doesn't work
+ # on Mac OS X 10.8 (PR23539).
+ pushd "${COMPILER_RT_DIR}"
+ cat << 'EOF' |
+Index: CMakeLists.txt
+===================================================================
+--- 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()
+EOF
+ patch -p0
+ popd
+
+fi
+
+# Echo all commands.
+set -x
+
+# Set default values for CC and CXX if they're not set in the environment.
+CC=${CC:-cc}
+CXX=${CXX:-c++}
+
+if [[ -n "${gcc_toolchain}" ]]; then
+ # Use the specified gcc installation for building.
+ CC="$gcc_toolchain/bin/gcc"
+ CXX="$gcc_toolchain/bin/g++"
+ # Set LD_LIBRARY_PATH to make auxiliary targets (tablegen, bootstrap compiler,
+ # etc.) find the .so.
+ export LD_LIBRARY_PATH="$(dirname $(${CXX} -print-file-name=libstdc++.so.6))"
+fi
+
+CFLAGS=""
+CXXFLAGS=""
+LDFLAGS=""
+
+# 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 [ "${OS}" = "Darwin" ]; then
+ # 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 $(xcrun --show-sdk-path)"
+ CXXFLAGS="-stdlib=libc++ -nostdinc++ -I${ABS_LIBCXX_DIR}/include ${CFLAGS}"
+
+ if [[ -n "${bootstrap}" ]]; then
+ deployment_target=10.6
+ fi
+fi
+
+# Build bootstrap clang if requested.
+if [[ -n "${bootstrap}" ]]; then
+ ABS_INSTALL_DIR="${PWD}/${LLVM_BOOTSTRAP_INSTALL_DIR}"
+ echo "Building bootstrap compiler"
+ mkdir -p "${LLVM_BOOTSTRAP_DIR}"
+ pushd "${LLVM_BOOTSTRAP_DIR}"
+
+ cmake -GNinja \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DLLVM_ENABLE_ASSERTIONS=ON \
+ -DLLVM_TARGETS_TO_BUILD=host \
+ -DLLVM_ENABLE_THREADS=OFF \
+ -DCMAKE_INSTALL_PREFIX="${ABS_INSTALL_DIR}" \
+ -DCMAKE_C_COMPILER="${CC}" \
+ -DCMAKE_CXX_COMPILER="${CXX}" \
+ -DCMAKE_C_FLAGS="${CFLAGS}" \
+ -DCMAKE_CXX_FLAGS="${CXXFLAGS}" \
+ ../llvm
+
+ ninja
+ if [[ -n "${run_tests}" ]]; then
+ ninja check-all
+ fi
+
+ ninja install
+ if [[ -n "${gcc_toolchain}" ]]; then
+ # Copy that gcc's stdlibc++.so.6 to the build dir, so the bootstrap
+ # compiler can start.
+ cp -v "$(${CXX} -print-file-name=libstdc++.so.6)" \
+ "${ABS_INSTALL_DIR}/lib/"
+ fi
+
+ popd
+ CC="${ABS_INSTALL_DIR}/bin/clang"
+ CXX="${ABS_INSTALL_DIR}/bin/clang++"
+
+ if [[ -n "${gcc_toolchain}" ]]; then
+ # Tell the bootstrap compiler to use a specific gcc prefix to search
+ # for standard library headers and shared object file.
+ CFLAGS="--gcc-toolchain=${gcc_toolchain}"
+ CXXFLAGS="--gcc-toolchain=${gcc_toolchain}"
+ fi
+
+ echo "Building final compiler"
+fi
+
+# Build clang (in a separate directory).
+# The clang bots have this path hardcoded in built/scripts/slave/compile.py,
+# so if you change it you also need to change these links.
+mkdir -p "${LLVM_BUILD_DIR}"
+pushd "${LLVM_BUILD_DIR}"
+
+# Build libc++.dylib while some bots are still on OS X 10.6.
+if [ "${OS}" = "Darwin" ]; then
+ rm -rf libcxxbuild
+ LIBCXXFLAGS="-O3 -std=c++11 -fstrict-aliasing"
+
+ # libcxx and libcxxabi both have a file stdexcept.cpp, so put their .o files
+ # into different subdirectories.
+ mkdir -p libcxxbuild/libcxx
+ pushd libcxxbuild/libcxx
+ ${CXX:-c++} -c ${CXXFLAGS} ${LIBCXXFLAGS} "${ABS_LIBCXX_DIR}"/src/*.cpp
+ popd
+
+ mkdir -p libcxxbuild/libcxxabi
+ pushd libcxxbuild/libcxxabi
+ ${CXX:-c++} -c ${CXXFLAGS} ${LIBCXXFLAGS} "${ABS_LIBCXXABI_DIR}"/src/*.cpp -I"${ABS_LIBCXXABI_DIR}/include"
+ popd
+
+ pushd libcxxbuild
+ ${CC:-cc} libcxx/*.o 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,${ABS_LIBCXX_DIR}/lib/libc++unexp.exp \
+ -Wl,-force_symbols_not_weak_list,${ABS_LIBCXX_DIR}/lib/notweak.exp \
+ -Wl,-force_symbols_weak_list,${ABS_LIBCXX_DIR}/lib/weak.exp
+ ln -sf libc++.1.dylib libc++.dylib
+ popd
+ LDFLAGS+="-stdlib=libc++ -L${PWD}/libcxxbuild"
+
+ if [[ -n "${bootstrap}" ]]; then
+ # 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)
+ rm -rf "${ABS_LIBCXX_DIR}"
+ rm -rf "${ABS_LIBCXXABI_DIR}"
+ CXXFLAGS="-stdlib=libc++ -nostdinc++ -I${ABS_INSTALL_DIR}/include/c++/v1 ${CFLAGS}"
+ fi
+fi
+
+# Find the binutils include dir for the gold plugin.
+BINUTILS_INCDIR=""
+if [ "${OS}" = "Linux" ]; then
+ BINUTILS_INCDIR="${ABS_BINUTILS_DIR}/Linux_x64/Release/include"
+fi
+
+
+# If building at head, define a macro that plugins can use for #ifdefing
+# out code that builds at head, but not at CLANG_REVISION or vice versa.
+if [[ -n ${LLVM_FORCE_HEAD_REVISION:-''} ]]; then
+ CFLAGS="${CFLAGS} -DLLVM_FORCE_HEAD_REVISION"
+ CXXFLAGS="${CXXFLAGS} -DLLVM_FORCE_HEAD_REVISION"
+fi
+
+# Hook the Chromium tools into the LLVM build. Several Chromium tools have
+# dependencies on LLVM/Clang libraries. The LLVM build detects implicit tools
+# in the tools subdirectory, so install a shim CMakeLists.txt that forwards to
+# the real directory for the Chromium tools.
+# Note that the shim directory name intentionally has no _ or _. The implicit
+# tool detection logic munges them in a weird way.
+mkdir -v ${CHROME_TOOLS_SHIM_DIR}
+cat > ${CHROME_TOOLS_SHIM_DIR}/CMakeLists.txt << EOF
+# Since tools/clang isn't actually a subdirectory, use the two argument version
+# to specify where build artifacts go. CMake doesn't allow reusing the same
+# binary dir for multiple source dirs, so the build artifacts have to go into a
+# subdirectory...
+add_subdirectory(\${CHROMIUM_TOOLS_SRC} \${CMAKE_CURRENT_BINARY_DIR}/a)
+EOF
+rm -fv CMakeCache.txt
+MACOSX_DEPLOYMENT_TARGET=${deployment_target} cmake -GNinja \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DLLVM_ENABLE_ASSERTIONS=ON \
+ -DLLVM_ENABLE_THREADS=OFF \
+ -DLLVM_BINUTILS_INCDIR="${BINUTILS_INCDIR}" \
+ -DCMAKE_C_COMPILER="${CC}" \
+ -DCMAKE_CXX_COMPILER="${CXX}" \
+ -DCMAKE_C_FLAGS="${CFLAGS}" \
+ -DCMAKE_CXX_FLAGS="${CXXFLAGS}" \
+ -DCMAKE_EXE_LINKER_FLAGS="${LDFLAGS}" \
+ -DCMAKE_SHARED_LINKER_FLAGS="${LDFLAGS}" \
+ -DCMAKE_MODULE_LINKER_FLAGS="${LDFLAGS}" \
+ -DCMAKE_INSTALL_PREFIX="${ABS_LLVM_BUILD_DIR}" \
+ -DCHROMIUM_TOOLS_SRC="${ABS_CHROMIUM_TOOLS_DIR}" \
+ -DCHROMIUM_TOOLS="${chrome_tools}" \
+ "${ABS_LLVM_DIR}"
+env
+
+if [[ -n "${gcc_toolchain}" ]]; then
+ # Copy in the right stdlibc++.so.6 so clang can start.
+ mkdir -p lib
+ cp -v "$(${CXX} ${CXXFLAGS} -print-file-name=libstdc++.so.6)" lib/
+fi
+
+ninja
+# If any Chromium tools were built, install those now.
+if [[ -n "${chrome_tools}" ]]; then
+ ninja cr-install
+fi
+
+STRIP_FLAGS=
+if [ "${OS}" = "Darwin" ]; then
+ # See http://crbug.com/256342
+ STRIP_FLAGS=-x
+
+ cp libcxxbuild/libc++.1.dylib bin/
+fi
+strip ${STRIP_FLAGS} bin/clang
+popd
+
+# Build compiler-rt out-of-tree.
+mkdir -p "${COMPILER_RT_BUILD_DIR}"
+pushd "${COMPILER_RT_BUILD_DIR}"
+
+rm -fv CMakeCache.txt
+MACOSX_DEPLOYMENT_TARGET=${deployment_target} cmake -GNinja \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DLLVM_ENABLE_ASSERTIONS=ON \
+ -DLLVM_ENABLE_THREADS=OFF \
+ -DCMAKE_C_COMPILER="${CC}" \
+ -DCMAKE_CXX_COMPILER="${CXX}" \
+ -DLLVM_CONFIG_PATH="${ABS_LLVM_BUILD_DIR}/bin/llvm-config" \
+ "${ABS_COMPILER_RT_DIR}"
+
+ninja
+
+# Copy selected output to the main tree.
+# Darwin doesn't support cp --parents, so pipe through tar instead.
+CLANG_VERSION=$("${ABS_LLVM_BUILD_DIR}/bin/clang" --version | \
+ sed -ne 's/clang version \([0-9]\.[0-9]\.[0-9]\).*/\1/p')
+ABS_LLVM_CLANG_LIB_DIR="${ABS_LLVM_BUILD_DIR}/lib/clang/${CLANG_VERSION}"
+tar -c *blacklist.txt | tar -C ${ABS_LLVM_CLANG_LIB_DIR} -xv
+tar -c include/sanitizer | tar -C ${ABS_LLVM_CLANG_LIB_DIR} -xv
+if [[ "${OS}" = "Darwin" ]]; then
+ tar -c lib/darwin | tar -C ${ABS_LLVM_CLANG_LIB_DIR} -xv
+else
+ tar -c lib/linux | tar -C ${ABS_LLVM_CLANG_LIB_DIR} -xv
+fi
+
+popd
+
+if [[ -n "${with_android}" ]]; then
+ # Make a standalone Android toolchain.
+ ${ANDROID_NDK_DIR}/build/tools/make-standalone-toolchain.sh \
+ --platform=android-19 \
+ --install-dir="${LLVM_BUILD_DIR}/android-toolchain" \
+ --system=linux-x86_64 \
+ --stl=stlport \
+ --toolchain=arm-linux-androideabi-4.9
+
+ # Android NDK r9d copies a broken unwind.h into the toolchain, see
+ # http://crbug.com/357890
+ rm -v "${LLVM_BUILD_DIR}"/android-toolchain/include/c++/*/unwind.h
+
+ # Build ASan runtime for Android in a separate build tree.
+ mkdir -p ${LLVM_BUILD_DIR}/android
+ pushd ${LLVM_BUILD_DIR}/android
+ rm -fv CMakeCache.txt
+ MACOSX_DEPLOYMENT_TARGET=${deployment_target} cmake -GNinja \
+ -DCMAKE_BUILD_TYPE=Release \
+ -DLLVM_ENABLE_ASSERTIONS=ON \
+ -DLLVM_ENABLE_THREADS=OFF \
+ -DCMAKE_C_COMPILER=${PWD}/../bin/clang \
+ -DCMAKE_CXX_COMPILER=${PWD}/../bin/clang++ \
+ -DLLVM_CONFIG_PATH=${PWD}/../bin/llvm-config \
+ -DCMAKE_C_FLAGS="--target=arm-linux-androideabi --sysroot=${PWD}/../android-toolchain/sysroot -B${PWD}/../android-toolchain" \
+ -DCMAKE_CXX_FLAGS="--target=arm-linux-androideabi --sysroot=${PWD}/../android-toolchain/sysroot -B${PWD}/../android-toolchain" \
+ -DANDROID=1 \
+ "${ABS_COMPILER_RT_DIR}"
+ ninja libclang_rt.asan-arm-android.so
+
+ # And copy it into the main build tree.
+ cp "$(find -name libclang_rt.asan-arm-android.so)" "${ABS_LLVM_CLANG_LIB_DIR}/lib/linux/"
+ popd
+fi
+
+if [[ -n "$run_tests" || -n "${LLVM_FORCE_HEAD_REVISION:-''}" ]]; then
+ # Run Chrome tool tests.
+ ninja -C "${LLVM_BUILD_DIR}" cr-check-all
+fi
+if [[ -n "$run_tests" ]]; then
+ # Run the LLVM and Clang tests.
+ ninja -C "${LLVM_BUILD_DIR}" check-all
+fi
+
+# After everything is done, log success for this revision.
+echo "${PACKAGE_VERSION}" > "${STAMP_FILE}"
diff --git a/tools/dartium/buildbot_annotated_steps.py b/tools/dartium/buildbot_annotated_steps.py
index f8eeb23..aeaed2f 100755
--- a/tools/dartium/buildbot_annotated_steps.py
+++ b/tools/dartium/buildbot_annotated_steps.py
@@ -53,6 +53,10 @@
print '@@@STEP_FAILURE@@@'
return status
+def ClearTemp():
+ if platform.system() == 'Windows':
+ shutil.rmtree('C:\\Users\\chrome-bot\\AppData\\Local\\Temp',
+ ignore_errors=True)
def Test(info, component, suite, checked, test_filter=None):
"""Test a particular component (e.g., dartium or content_shell(drt)).
@@ -70,6 +74,7 @@
info.name,
info.version,
component, checked)
+ ClearTemp()
return status
@@ -97,11 +102,10 @@
if info.mode == 'Release' or platform.system() != 'Darwin':
result = Test(info, 'drt', 'layout', 'unchecked') or result
result = Test(info, 'drt', 'layout', 'checked') or result
-
# Run dartium tests
result = Test(info, 'dartium', 'core', 'unchecked') or result
result = Test(info, 'dartium', 'core', 'checked') or result
-
+
# Run ContentShell tests
# NOTE: We don't run ContentShell tests on dartium-*-inc builders to keep
# cycle times down.
diff --git a/tools/deps/dartium.deps/DEPS b/tools/deps/dartium.deps/DEPS
index 43d002d..2083c3a 100644
--- a/tools/deps/dartium.deps/DEPS
+++ b/tools/deps/dartium.deps/DEPS
@@ -9,7 +9,7 @@
vars.update({
"dartium_chromium_commit": "a8ead7ec922730667be7112de7ec40abbfd5f5aa",
- "dartium_webkit_commit": "1a294dcc3d47ae5e5ce58777df2e1b701b2b2b60",
+ "dartium_webkit_commit": "b32a113c16f0a46b0dd747f80f0ec78e8db3512b",
"chromium_base_revision": "338390",
# We use mirrors of all github repos to guarantee reproducibility and
@@ -40,7 +40,7 @@
"http_parser_rev" : "@8b179e36aba985208e4c5fb15cfddd386b6370a4",
"http_throttle_rev" : "@a81f08be942cdd608883c7b67795c12226abc235",
"json_rpc_2_rev": "@a38eefd116d910199de205f962af92fed87c164c",
- "kernel_rev": "@9677d68402ea15d0eca6430d64f631bb3e505499",
+ "kernel_rev": "@449803b82e850a41148e636db1a6e4a848284aed",
"logging_rev": "@85d83e002670545e9039ad3985f0018ab640e597",
"matcher_tag": "@0.12.0",
"mime_rev": "@75890811d4af5af080351ba8a2853ad4c8df98dd",
diff --git a/tools/gn.py b/tools/gn.py
new file mode 100755
index 0000000..22f3530
--- /dev/null
+++ b/tools/gn.py
@@ -0,0 +1,161 @@
+#!/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 subprocess
+import sys
+import os
+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 to_command_line(gn_args):
+ def merge(key, value):
+ if type(value) is bool:
+ return '%s=%s' % (key, 'true' if value else 'false')
+ 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']:
+ return 'x86'
+ if arch in ['x64', 'arm64', 'simarm64', 'simdbc64']:
+ return 'x64'
+
+def target_cpu_for_arch(arch, os):
+ if arch in ['ia32', 'simarm', 'simarmv6', 'simarmv5te', 'simmips']:
+ return 'x86'
+ if arch in ['simarm64']:
+ return 'x64'
+ if arch == 'mips':
+ return 'mipsel'
+ if arch == 'simdbc':
+ return 'arm' if os == 'android' else 'x86'
+ if arch == 'simdbc64':
+ return 'arm64' if os == 'android' else 'x64'
+ return arch
+
+def to_gn_args(args):
+ gn_args = {}
+
+ if args.os == 'host':
+ gn_args['target_os'] = HOST_OS
+ else:
+ gn_args['target_os'] = args.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)
+
+ # 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.
+ gn_args['dart_host_pub_exe'] = os.path.join(
+ DART_ROOT, 'tools', 'sdks', HOST_OS, 'dart-sdk', 'bin', 'pub')
+
+ # For Fuchsia support, the default is to not compile in the root
+ # certificates.
+ gn_args['dart_use_fallback_root_certificates'] = True
+
+ gn_args['dart_zlib_path'] = "//runtime/bin/zlib"
+
+ gn_args['dart_use_tcmalloc'] = gn_args['target_os'] == 'linux'
+
+ 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'
+
+ # 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']
+
+ if args.target_sysroot:
+ gn_args['target_sysroot'] = args.target_sysroot
+
+ if args.toolchain_prefix:
+ gn_args['toolchain_prefix'] = args.toolchain_prefix
+
+ goma_dir = os.environ.get('GOMA_DIR')
+ goma_home_dir = os.path.join(os.getenv('HOME', ''), 'goma')
+ if args.goma and goma_dir:
+ gn_args['use_goma'] = True
+ gn_args['goma_dir'] = goma_dir
+ elif args.goma and os.path.exists(goma_home_dir):
+ gn_args['use_goma'] = True
+ gn_args['goma_dir'] = goma_home_dir
+ else:
+ gn_args['use_goma'] = False
+ gn_args['goma_dir'] = None
+
+ return gn_args
+
+def parse_args(args):
+ args = args[1:]
+ parser = argparse.ArgumentParser(description='A script run` gn gen`.')
+
+ parser.add_argument('--mode', '-m',
+ type=str,
+ choices=['debug', 'release', 'product'],
+ default='debug')
+ parser.add_argument('--os',
+ type=str,
+ choices=['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'],
+ default='x64')
+
+ parser.add_argument('--goma', default=True, action='store_true')
+ parser.add_argument('--no-goma', dest='goma', action='store_false')
+
+ 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)
+
+ return parser.parse_args(args)
+
+def main(argv):
+ args = parse_args(argv)
+
+ if sys.platform.startswith(('cygwin', 'win')):
+ subdir = 'win'
+ elif sys.platform == 'darwin':
+ subdir = 'mac'
+ elif sys.platform.startswith('linux'):
+ subdir = 'linux64'
+ else:
+ raise Error('Unknown platform: ' + sys.platform)
+
+ 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)
+
+if __name__ == '__main__':
+ sys.exit(main(sys.argv))
diff --git a/tools/test.dart b/tools/test.dart
index 76e4928..c66489e 100755
--- a/tools/test.dart
+++ b/tools/test.dart
@@ -56,7 +56,7 @@
}
void main(List<String> arguments) {
- // This script is in [dart]/tools.
+ // This script is in [sdk]/tools.
TestUtils.setDartDirUri(Platform.script.resolve('..'));
_deleteTemporaryDartDirectories().then((_) {
var optionsParser = new TestOptionsParser();
diff --git a/tools/testing/dart/test_options.dart b/tools/testing/dart/test_options.dart
index 917e236..936bb39 100644
--- a/tools/testing/dart/test_options.dart
+++ b/tools/testing/dart/test_options.dart
@@ -808,6 +808,40 @@
configuration['selectors'] = selectorMap;
}
+ // Put observatory_ui in a configuration with its own packages override.
+ // Only one value in the configuration map is mutable:
+ selectors = configuration['selectors'];
+ if (selectors.containsKey('observatory_ui')) {
+ if (selectors.length == 1) {
+ configuration['packages'] = TestUtils.dartDirUri
+ .resolve('runtime/observatory/.packages').toFilePath();
+ } else {
+ // Make a new configuration whose selectors map only contains
+ // observatory_ui, and remove the key from the original selectors.
+ // The only mutable value in the map is the selectors, so a
+ // shallow copy is safe.
+ var observatoryConfiguration = new Map.from(configuration);
+ observatoryConfiguration['selectors'] =
+ {'observatory_ui': selectors['observatory_ui']};
+ selectors.remove('observatory_ui');
+
+ // Set the packages flag.
+ observatoryConfiguration['packages'] = TestUtils.dartDirUri
+ .resolve('runtime/observatory/.packages').toFilePath();
+
+ // Return the expansions of both configurations. Neither will reach
+ // this line in the recursive call to _expandConfigurations.
+ return _expandConfigurations(configuration)
+ ..addAll(_expandConfigurations(observatoryConfiguration));
+ }
+ }
+ // Set the default package spec explicitly.
+ if (configuration['package_root'] == null &&
+ configuration['packages'] == null) {
+ configuration['packages'] =
+ TestUtils.dartDirUri.resolve('.packages').toFilePath();
+ }
+
// Expand the architectures.
if (configuration['arch'].contains(',')) {
return _expandHelper('arch', configuration);
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index f5707b8..cf6a1a0 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -302,7 +302,8 @@
if (configuration['hot_reload'] || configuration['hot_reload_rollback']) {
// Handle reload special cases.
- if (expectations.contains(Expectation.COMPILETIME_ERROR)) {
+ if (expectations.contains(Expectation.COMPILETIME_ERROR) ||
+ testCase.hasCompileError || testCase.expectCompileError) {
// Running a test that expects a compilation error with hot reloading
// is redundant with a regular run of the test.
return;
@@ -970,15 +971,17 @@
}
}
}
- if (configuration['package_root'] != null) {
- packageRoot = new Path(configuration['package_root']);
- optionsFromFile['packageRoot'] = packageRoot.toNativePath();
+ if (optionsFromFile['packageRoot'] == null &&
+ optionsFromFile['packages'] == null) {
+ if (configuration['package_root'] != null) {
+ packageRoot = new Path(configuration['package_root']);
+ optionsFromFile['packageRoot'] = packageRoot.toNativePath();
+ }
+ if (configuration['packages'] != null) {
+ Path packages = new Path(configuration['packages']);
+ optionsFromFile['packages'] = packages.toNativePath();
+ }
}
- if (configuration['packages'] != null) {
- Path packages = new Path(configuration['packages']);
- optionsFromFile['packages'] = packages.toNativePath();
- }
-
if (new CompilerConfiguration(configuration).hasCompiler &&
expectCompileError(info)) {
// If a compile-time error is expected, and we're testing a
@@ -1585,9 +1588,12 @@
String packagesArgument(String packageRootFromFile,
String packagesFromFile) {
- if (packagesFromFile != null) {
+ if (packageRootFromFile == 'none' ||
+ packagesFromFile == 'none') {
+ return null;
+ } else if (packagesFromFile != null) {
return '--packages=$packagesFromFile';
- } else if (packageRootFromFile != null && packageRootFromFile != 'none') {
+ } else if (packageRootFromFile != null) {
return '--package-root=$packageRootFromFile';
} else {
return null;
@@ -1712,26 +1718,30 @@
matches = packageRootRegExp.allMatches(contents);
for (var match in matches) {
- if (packageRoot != null) {
+ if (packageRoot != null || packages != null) {
throw new Exception(
- 'More than one "// PackageRoot=" line in test $filePath');
+ 'More than one "// Package... line in test $filePath');
}
packageRoot = match[1];
if (packageRoot != 'none') {
- // PackageRoot=none means that no package-root option should be given.
+ // PackageRoot=none means that no packages or package-root option
+ // should be given. Any other value overrides package-root and
+ // removes any packages option. Don't use with // Packages=.
packageRoot = '${filePath.directoryPath.join(new Path(packageRoot))}';
}
}
matches = packagesRegExp.allMatches(contents);
for (var match in matches) {
- if (packages != null) {
+ if (packages != null || packageRoot != null) {
throw new Exception(
- 'More than one "// Packages=" line in test $filePath');
+ 'More than one "// Package..." line in test $filePath');
}
packages = match[1];
if (packages != 'none') {
- // Packages=none means that no packages option should be given.
+ // Packages=none means that no packages or package-root option
+ // should be given. Any other value overrides packages and removes
+ // any package-root option. Don't use with // PackageRoot=.
packages = '${filePath.directoryPath.join(new Path(packages))}';
}
}
diff --git a/utils/analysis_server/analysis_server.gyp b/utils/analysis_server/analysis_server.gyp
index 8126e95..c238888 100644
--- a/utils/analysis_server/analysis_server.gyp
+++ b/utils/analysis_server/analysis_server.gyp
@@ -24,6 +24,7 @@
],
'action': [
'<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
+ '--packages=../../.packages',
'--snapshot=<(SHARED_INTERMEDIATE_DIR)/analysis_server.dart.snapshot',
'../../pkg/analysis_server/bin/server.dart',
],
diff --git a/utils/compiler/compiler.gyp b/utils/compiler/compiler.gyp
index 201a4bb..63c4dae 100644
--- a/utils/compiler/compiler.gyp
+++ b/utils/compiler/compiler.gyp
@@ -31,6 +31,7 @@
],
'action': [
'<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
+ '--packages=../../.packages',
'create_snapshot.dart',
'--output_dir=<(SHARED_INTERMEDIATE_DIR)',
'--dart2js_main=pkg/compiler/lib/src/dart2js.dart',
diff --git a/utils/compiler/create_snapshot.dart b/utils/compiler/create_snapshot.dart
index 2b5b869..c2ca95e 100644
--- a/utils/compiler/create_snapshot.dart
+++ b/utils/compiler/create_snapshot.dart
@@ -63,7 +63,8 @@
Future createSnapshot(var dart_file) {
return Process.run(Platform.executable,
- ["--snapshot=$dart_file.snapshot",
+ ["--packages=../../.packages",
+ "--snapshot=$dart_file.snapshot",
dart_file])
.then((result) {
if (result.exitCode != 0) {
diff --git a/utils/dartanalyzer/dartanalyzer.gyp b/utils/dartanalyzer/dartanalyzer.gyp
index 3b65740..daf226c 100644
--- a/utils/dartanalyzer/dartanalyzer.gyp
+++ b/utils/dartanalyzer/dartanalyzer.gyp
@@ -24,6 +24,7 @@
],
'action': [
'<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
+ '--packages=../../.packages',
'--snapshot=<(SHARED_INTERMEDIATE_DIR)/dartanalyzer.dart.snapshot',
'../../pkg/analyzer_cli/bin/analyzer.dart',
],
@@ -40,6 +41,7 @@
],
'action': [
'<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
+ '--packages=../../.packages',
'../../pkg/analyzer/tool/summary/build_sdk_summaries.dart',
'build-spec',
'<(SHARED_INTERMEDIATE_DIR)/spec.sum',
@@ -57,6 +59,7 @@
],
'action': [
'<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
+ '--packages=../../.packages',
'../../pkg/analyzer/tool/summary/build_sdk_summaries.dart',
'build-strong',
'<(SHARED_INTERMEDIATE_DIR)/strong.sum',
diff --git a/utils/dartdevc/dartdevc.gyp b/utils/dartdevc/dartdevc.gyp
index 4bf98f0..167327e 100644
--- a/utils/dartdevc/dartdevc.gyp
+++ b/utils/dartdevc/dartdevc.gyp
@@ -24,6 +24,7 @@
],
'action': [
'<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
+ '--packages=../../.packages',
'--snapshot=<(SHARED_INTERMEDIATE_DIR)/dartdevc.dart.snapshot',
'../../pkg/dev_compiler/bin/dartdevc.dart'
],
diff --git a/utils/dartdoc/dartdoc.gyp b/utils/dartdoc/dartdoc.gyp
index d855cfe..dc5e414 100644
--- a/utils/dartdoc/dartdoc.gyp
+++ b/utils/dartdoc/dartdoc.gyp
@@ -23,6 +23,7 @@
],
'action': [
'<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
+ '--packages=../../.packages',
'--snapshot=<(SHARED_INTERMEDIATE_DIR)/dartdoc.dart.snapshot',
'../../third_party/pkg/dartdoc/bin/dartdoc.dart',
],
diff --git a/utils/dartfmt/dartfmt.gyp b/utils/dartfmt/dartfmt.gyp
index 826d31a..a59ef9a 100644
--- a/utils/dartfmt/dartfmt.gyp
+++ b/utils/dartfmt/dartfmt.gyp
@@ -23,6 +23,7 @@
],
'action': [
'<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
+ '--packages=../../.packages',
'--snapshot=<(SHARED_INTERMEDIATE_DIR)/dartfmt.dart.snapshot',
'../../third_party/pkg_tested/dart_style/bin/format.dart',
],
diff --git a/utils/pub/pub.gyp b/utils/pub/pub.gyp
index 13f2f5e..b568c0c 100644
--- a/utils/pub/pub.gyp
+++ b/utils/pub/pub.gyp
@@ -26,6 +26,7 @@
],
'action': [
'<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
+ '--packages=../../.packages',
'--snapshot=<(SHARED_INTERMEDIATE_DIR)/pub.dart.snapshot',
'../../third_party/pkg/pub/bin/pub.dart',
]