diff --git a/.github/workflows/scorecards-analysis.yml b/.github/workflows/scorecards-analysis.yml index f5b802d86241..23df05cd3c7d 100644 --- a/.github/workflows/scorecards-analysis.yml +++ b/.github/workflows/scorecards-analysis.yml @@ -44,7 +44,7 @@ jobs: # Upload the results as artifacts (optional). - name: "Upload artifact" - uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b + uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 with: name: SARIF file path: results.sarif @@ -52,6 +52,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@48ab28a6f5dbc2a99bf1e0131198dd8f1df78169 + uses: github/codeql-action/upload-sarif@b6a472f63d85b9c78a3ac5e89422239fc15e9b3c with: sarif_file: results.sarif diff --git a/.github/workflows/third-party-deps-scan.yml b/.github/workflows/third-party-deps-scan.yml index bc36b23fa342..17425809d3fe 100644 --- a/.github/workflows/third-party-deps-scan.yml +++ b/.github/workflows/third-party-deps-scan.yml @@ -32,7 +32,7 @@ jobs: - name: "extract deps, find commit hash, pass to osv-scanner" run: python .github/extract_deps.py --output osv-lockfile-${{github.sha}}.json - name: "upload osv-scanner deps" - uses: actions/upload-artifact@6f51ac03b9356f520e9adb1b1b7802705f340c2b + uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 with: # use github.ref in name to avoid duplicated artifacts name: osv-lockfile-${{github.sha}} diff --git a/CHANGELOG.md b/CHANGELOG.md index 01e0d697c74c..e2730fc58fa3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +## 3.8.0 + ## 3.7.0 ### Language diff --git a/DEPS b/DEPS index 9a8e623fe1b5..9a81cc03eb1e 100644 --- a/DEPS +++ b/DEPS @@ -71,9 +71,9 @@ vars = { # self-service update these by following the go/dart-engprod/browsers.md # instructions. d8, the V8 shell, is always checked out. "checkout_javascript_engines": False, - "d8_tag": "version:13.3.255", - "jsshell_tag": "version:133.0", - "jsc_tag": "version:287397", + "d8_tag": "version:13.4.32", + "jsshell_tag": "version:134.0", + "jsc_tag": "version:288804", # https://chrome-infra-packages.appspot.com/p/fuchsia/third_party/clang "clang_version": "git_revision:684052173971868aab0e6b62d7770a6299e84141", @@ -85,7 +85,7 @@ vars = { "download_reclient": True, # Update from https://chrome-infra-packages.appspot.com/p/fuchsia/sdk/core - "fuchsia_sdk_version": "version:26.20241231.3.1", + "fuchsia_sdk_version": "version:26.20250106.5.1", "download_fuchsia_deps": False, # Ninja, runs the build based on files generated by GN. @@ -97,7 +97,7 @@ vars = { ### /third_party/ dependencies # Prefer to use hashes of binaryen that have been reviewed & rolled into g3. - "binaryen_rev" : "87f9dac127b387715d8d96ac7ec8fd469d8c2dab", + "binaryen_rev" : "3f6831c0bd147ae1ae0ab1d9187d37bce7cca38b", "boringssl_rev": "822902749a5956bba09c7e9e451104e8a74f02c5", "browser-compat-data_tag": "ac8cae697014da1ff7124fba33b0b4245cc6cd1b", # v1.0.22 "cpu_features_rev": "936b9ab5515dead115606559502e3864958f7f6e", @@ -131,7 +131,7 @@ vars = { # EOL comment after a dependency to disable this and pin it at its current # revision. "core_rev": "7a71ad6b9170e09d5cbe39f3fccdee648659f1e7", - "dartdoc_rev": "c7f11603effa88ddacabfd555993f322fca8b3fe", + "dartdoc_rev": "e1295863b11c54680bf178ec9c2662a33b0e24be", "ecosystem_rev": "efe4ee4af6ac2e4c90aa525fae213b65c97295a9", "flute_rev": "e4ea0459a7debae5e9592c85141707b01fac86c9", "glob_rev": "eee18d1a577d5f965f6afbbd251798e065dced43", @@ -141,35 +141,20 @@ vars = { "markdown_rev": "19aaded4300d24bedcbf52ade792b203ddf030b0", "material_color_utilities_rev": "799b6ba2f3f1c28c67cc7e0b4f18e0c7d7f3c03e", # dart-native-interop-team@ is rolling breaking changes manually while the assets features are in experimental. - "native_rev": "14368a80bae9e3f381a2e59c91405338d82451ee", # disable tools/rev_sdk_deps.dart - "package_config_rev": "07097d7ae60d40b34ce8daabdce318ecc168b7d1", - "pool_rev": "bf27900420ba382b6e5c0484ab3c79daad703dcd", + "native_rev": "f179ec2693179e48ff1fce827914fd1711c1a941", # disable tools/rev_sdk_deps.dart "protobuf_rev": "b7dd58cdbd879beee4c3fbf8ee80fce8e97bad26", "pub_rev": "58de642dc1d07601f6eb2b4ecd94555c0210106b", # disable tools/rev_sdk_deps.dart - "pub_semver_rev": "960f91309e325ae037e5f1434acb77b83a12d91e", - "shelf_rev": "2b5b683e78f5cc84e479a43297fd7b5489d7db02", - "source_maps_rev": "e5e9d343302acf7df2145316ae4e56026c550989", - "source_span_rev": "e6a34591b7f7880c7ca0fcb95b858ccf7f8be304", - "sse_rev": "b573a1e9a61f5f3e2198becfa3f4f2e8decd1e90", - "stack_trace_rev": "5fe4cfea7f0d8e67b7d5738d2e1c64a18b5ba450", - "stream_channel_rev": "31a3aba8a78a78b266fbf7474f19cd4ba9ca562e", - "string_scanner_rev": "69212690d491603a511904a7a84cd502f34bf7a9", + "shelf_rev": "bf799519cda2898a7c5af06dcfdd5fe6443afd79", "sync_http_rev": "47e6b264a209d0d806cfe9cdad8b6c69ce231986", "tar_rev": "5a1ea943e70cdf3fa5e1102cdbb9418bd9b4b81a", - "term_glyph_rev": "52677db71a2c6b6d0018ebbe5ed7552dbae1248f", "test_rev": "f364fc8291d668d85c702a5b9f9a4f2e5c1ade0e", - "test_descriptor_rev": "92fa0c551267b38e4b27c9f74976ae4cd96d8b1e", - "test_reflective_loader_rev": "9e35c9e00b8b6299e9295c0f29617af39276717d", - "tools_rev": "b412ba4550bb634caf3c1064b7ebb671cd5e9247", + "tools_rev": "3bdef2043af9244b804adc08896bf96d51bb49ba", "vector_math_rev": "bd4b574b2a457a3955d223694f1a979a0c0f38c9", - "watcher_rev": "7f3b3a3ea49ba7e21fff240ce8ee616d62d32956", "web_rev": "af5de5e8548060c0795713ee7129ba6d5ff9f1b2", "web_socket_channel_rev": "a937243563e8ee75d11fb23610297d4f6e5cb2b9", "webdev_rev": "e72f365a4408dce73bc023e624adc6a9a72dd7a2", "webdriver_rev": "d83d6a3cbaab152ff9b99b29382d1f48b5d5ba23", "webkit_inspection_protocol_rev": "effa75205516757795683d527c3dea9546eb0c32", - "yaml_rev": "0406507fb719b0c8787896475734747fa35f2b78", - "yaml_edit_rev": "fbdc70acc164af187772e013a2e1364cd05b88dc", # Windows deps "crashpad_rev": "d256de317164c0eb362bdd9cbb4d259fe6d086f3", @@ -180,9 +165,9 @@ vars = { # meant to be downloaded by users for local testing. You can self-service # update these by following the go/dart-engprod/browsers.md instructions. "download_chrome": False, - "chrome_tag": "132.0.6834.57", + "chrome_tag": "132.0.6834.83", "download_firefox": False, - "firefox_tag": "133.0.3", + "firefox_tag": "134.0", # Emscripten is used in dart2wasm tests. "download_emscripten": False, @@ -382,54 +367,24 @@ deps = { }, Var("dart_root") + "/third_party/pkg/native": Var("dart_git") + "native.git" + "@" + Var("native_rev"), - Var("dart_root") + "/third_party/pkg/package_config": - Var("dart_git") + "package_config.git" + - "@" + Var("package_config_rev"), - Var("dart_root") + "/third_party/pkg/pool": - Var("dart_git") + "pool.git" + "@" + Var("pool_rev"), Var("dart_root") + "/third_party/pkg/protobuf": Var("dart_git") + "protobuf.git" + "@" + Var("protobuf_rev"), - Var("dart_root") + "/third_party/pkg/pub_semver": - Var("dart_git") + "pub_semver.git" + "@" + Var("pub_semver_rev"), Var("dart_root") + "/third_party/pkg/pub": Var("dart_git") + "pub.git" + "@" + Var("pub_rev"), Var("dart_root") + "/third_party/pkg/shelf": Var("dart_git") + "shelf.git" + "@" + Var("shelf_rev"), - Var("dart_root") + "/third_party/pkg/source_maps": - Var("dart_git") + "source_maps.git" + "@" + Var("source_maps_rev"), - Var("dart_root") + "/third_party/pkg/source_span": - Var("dart_git") + "source_span.git" + "@" + Var("source_span_rev"), - Var("dart_root") + "/third_party/pkg/sse": - Var("dart_git") + "sse.git" + "@" + Var("sse_rev"), - Var("dart_root") + "/third_party/pkg/stack_trace": - Var("dart_git") + "stack_trace.git" + "@" + Var("stack_trace_rev"), - Var("dart_root") + "/third_party/pkg/stream_channel": - Var("dart_git") + "stream_channel.git" + - "@" + Var("stream_channel_rev"), - Var("dart_root") + "/third_party/pkg/string_scanner": - Var("dart_git") + "string_scanner.git" + - "@" + Var("string_scanner_rev"), Var("dart_root") + "/third_party/pkg/sync_http": Var("dart_git") + "sync_http.git" + "@" + Var("sync_http_rev"), Var("dart_root") + "/third_party/pkg/tar": Var("dart_git") + "external/github.com/simolus3/tar.git" + "@" + Var("tar_rev"), - Var("dart_root") + "/third_party/pkg/term_glyph": - Var("dart_git") + "term_glyph.git" + "@" + Var("term_glyph_rev"), Var("dart_root") + "/third_party/pkg/test": Var("dart_git") + "test.git" + "@" + Var("test_rev"), - Var("dart_root") + "/third_party/pkg/test_descriptor": - Var("dart_git") + "test_descriptor.git" + "@" + Var("test_descriptor_rev"), - Var("dart_root") + "/third_party/pkg/test_reflective_loader": - Var("dart_git") + "test_reflective_loader.git" + - "@" + Var("test_reflective_loader_rev"), Var("dart_root") + "/third_party/pkg/tools": Var("dart_git") + "tools.git" + "@" + Var("tools_rev"), Var("dart_root") + "/third_party/pkg/vector_math": Var("dart_git") + "external/github.com/google/vector_math.dart.git" + "@" + Var("vector_math_rev"), - Var("dart_root") + "/third_party/pkg/watcher": - Var("dart_git") + "watcher.git" + "@" + Var("watcher_rev"), Var("dart_root") + "/third_party/pkg/webdev": Var("dart_git") + "webdev.git" + "@" + Var("webdev_rev"), Var("dart_root") + "/third_party/pkg/webdriver": @@ -443,10 +398,6 @@ deps = { Var("dart_root") + "/third_party/pkg/web_socket_channel": Var("dart_git") + "web_socket_channel.git" + "@" + Var("web_socket_channel_rev"), - Var("dart_root") + "/third_party/pkg/yaml_edit": - Var("dart_git") + "yaml_edit.git" + "@" + Var("yaml_edit_rev"), - Var("dart_root") + "/third_party/pkg/yaml": - Var("dart_git") + "yaml.git" + "@" + Var("yaml_rev"), Var("dart_root") + "/buildtools/sysroot/linux": { "packages": [ @@ -610,7 +561,7 @@ deps = { "packages": [ { "package": "chromium/fuchsia/test-scripts", - "version": "r9Dc5VRF6sE3pJH20k2d1Yko3xSlwljH_nuw7O8vcb4C", + "version": "3SIihrAqX5c1w3ep7-s9Yi4qLUITve0PUVs6COrU-eIC", } ], "condition": 'download_fuchsia_deps', diff --git a/OWNERS b/OWNERS index f3846d0267ba..f524dea43030 100644 --- a/OWNERS +++ b/OWNERS @@ -10,6 +10,8 @@ vsm@google.com #{LAST_RESORT_SUGGESTION} # DEPS per-file DEPS=file:/tools/OWNERS_ENG +# Updates fuchsia components only. +per-file DEPS=file:/tools/OWNERS_FUCHSIA # Changelog, AUTHORS, and .git* do not require approval. per-file CHANGELOG.md,AUTHORS,WATCHLISTS,.gitattributes,.gitconfig,.gitignore,sdk.code-workspace=* diff --git a/pkg/_fe_analyzer_shared/lib/src/experiments/flags.dart b/pkg/_fe_analyzer_shared/lib/src/experiments/flags.dart index f32c1ced7d9f..9419dd2f7ff4 100644 --- a/pkg/_fe_analyzer_shared/lib/src/experiments/flags.dart +++ b/pkg/_fe_analyzer_shared/lib/src/experiments/flags.dart @@ -6,7 +6,7 @@ // // Instead modify 'tools/experimental_features.yaml' and run // 'dart pkg/front_end/tool/cfe.dart generate-experimental-flags' to update. -const Version defaultLanguageVersion = const Version(3, 7); +const Version defaultLanguageVersion = const Version(3, 8); /// Enum for experimental flags shared between the CFE and the analyzer. enum ExperimentalFlag { diff --git a/pkg/_fe_analyzer_shared/test/mini_ast.dart b/pkg/_fe_analyzer_shared/test/mini_ast.dart index e9b5c314d4f3..a0f57e0c5722 100644 --- a/pkg/_fe_analyzer_shared/test/mini_ast.dart +++ b/pkg/_fe_analyzer_shared/test/mini_ast.dart @@ -34,9 +34,8 @@ import 'package:_fe_analyzer_shared/src/type_inference/variable_bindings.dart'; import 'package:_fe_analyzer_shared/src/types/shared_type.dart'; import 'package:test/test.dart'; -import 'type_inference/type_constraint_gatherer_test.dart'; - import 'mini_ir.dart'; +import 'mini_type_constraint_gatherer.dart'; import 'mini_types.dart'; final RegExp _locationRegExp = diff --git a/pkg/_fe_analyzer_shared/test/mini_type_constraint_gatherer.dart b/pkg/_fe_analyzer_shared/test/mini_type_constraint_gatherer.dart new file mode 100644 index 000000000000..ef5dba028c55 --- /dev/null +++ b/pkg/_fe_analyzer_shared/test/mini_type_constraint_gatherer.dart @@ -0,0 +1,112 @@ +// Copyright (c) 2025, 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:_fe_analyzer_shared/src/type_inference/type_analyzer_operations.dart'; +import 'package:_fe_analyzer_shared/src/type_inference/type_constraint.dart'; +import 'package:_fe_analyzer_shared/src/types/shared_type.dart'; + +import 'mini_ast.dart'; +import 'mini_types.dart'; + +class TypeConstraintGatherer extends TypeConstraintGenerator + with + TypeConstraintGeneratorMixin { + @override + final Set typeParametersToConstrain = {}; + + @override + final bool enableDiscrepantObliviousnessOfNullabilitySuffixOfFutureOr; + + @override + final MiniAstOperations typeAnalyzerOperations = MiniAstOperations(); + + final constraints = []; + + TypeConstraintGatherer(Set typeVariablesBeingConstrained, + {this.enableDiscrepantObliviousnessOfNullabilitySuffixOfFutureOr = false}) + : super(inferenceUsingBoundsIsEnabled: false) { + for (var typeVariableName in typeVariablesBeingConstrained) { + typeParametersToConstrain + .add(TypeRegistry.addTypeParameter(typeVariableName)); + } + } + + @override + TypeConstraintGeneratorState get currentState => + TypeConstraintGeneratorState(constraints.length); + + @override + void addLowerConstraintForParameter(TypeParameter typeParameter, Type lower, + {required Node? astNodeForTesting}) { + constraints.add('$lower <: $typeParameter'); + } + + @override + void addUpperConstraintForParameter(TypeParameter typeParameter, Type upper, + {required Node? astNodeForTesting}) { + constraints.add('$typeParameter <: $upper'); + } + + @override + Map> + computeConstraints() { + // TODO(cstefantsova): implement computeConstraints + throw UnimplementedError(); + } + + @override + void eliminateTypeParametersInGeneratedConstraints( + Object eliminator, TypeConstraintGeneratorState eliminationStartState, + {required Node? astNodeForTesting}) { + // TODO(paulberry): implement eliminateTypeParametersInGeneratedConstraints + } + + @override + List? getTypeArgumentsAsInstanceOf(Type type, String typeDeclaration) { + // We just have a few cases hardcoded here to make the tests work. + // TODO(paulberry): if this gets too unwieldy, replace it with a more + // general implementation. + switch ((type, typeDeclaration)) { + case (PrimaryType(name: 'List', :var args), 'Iterable'): + // List inherits from Iterable + return args; + case (PrimaryType(name: 'MyListOfInt'), 'List'): + // MyListOfInt inherits from List + return [Type('int')]; + case (PrimaryType(name: 'Future'), 'int'): + case (PrimaryType(name: 'int'), 'String'): + case (PrimaryType(name: 'List'), 'Future'): + case (PrimaryType(name: 'String'), 'int'): + case (PrimaryType(name: 'Future'), 'String'): + // Unrelated types + return null; + default: + throw UnimplementedError( + 'getTypeArgumentsAsInstanceOf($type, $typeDeclaration)'); + } + } + + @override + ( + Type, + Type, { + List typeParametersToEliminate + }) instantiateFunctionTypesAndProvideFreshTypeParameters( + SharedFunctionTypeStructure + p, + SharedFunctionTypeStructure + q, + {required bool leftSchema}) { + // TODO(paulberry): implement instantiateFunctionTypesAndProvideEliminator + throw UnimplementedError(); + } + + @override + void restoreState(TypeConstraintGeneratorState state) { + constraints.length = state.count; + } +} diff --git a/pkg/_fe_analyzer_shared/test/type_inference/type_constraint_gatherer_test.dart b/pkg/_fe_analyzer_shared/test/type_inference/type_constraint_gatherer_test.dart index 57d600a96d7d..983c521795f6 100644 --- a/pkg/_fe_analyzer_shared/test/type_inference/type_constraint_gatherer_test.dart +++ b/pkg/_fe_analyzer_shared/test/type_inference/type_constraint_gatherer_test.dart @@ -3,12 +3,11 @@ // BSD-style license that can be found in the LICENSE file. import 'package:_fe_analyzer_shared/src/type_inference/type_analyzer_operations.dart'; -import 'package:_fe_analyzer_shared/src/type_inference/type_constraint.dart'; -import 'package:_fe_analyzer_shared/src/types/shared_type.dart'; import 'package:checks/checks.dart'; import 'package:test/scaffolding.dart'; import '../mini_ast.dart'; +import '../mini_type_constraint_gatherer.dart'; import '../mini_types.dart'; main() { @@ -31,7 +30,7 @@ main() { Type('void Function()'), Type('void Function()'), leftSchema: false, astNodeForTesting: Node.placeholder())) .equals(true); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); group('Matching functions with positional parameters:', () { @@ -41,7 +40,7 @@ main() { Type('void Function(int, String)'), Type('void Function(T, U)'), leftSchema: false, astNodeForTesting: Node.placeholder())) .equals(true); - check(tcg._constraints).unorderedEquals(['T <: int', 'U <: String']); + check(tcg.constraints).unorderedEquals(['T <: int', 'U <: String']); }); test('Some optional on LHS', () { @@ -52,7 +51,7 @@ main() { leftSchema: false, astNodeForTesting: Node.placeholder())) .equals(true); - check(tcg._constraints).unorderedEquals(['T <: int', 'U <: String']); + check(tcg.constraints).unorderedEquals(['T <: int', 'U <: String']); }); }); @@ -63,7 +62,7 @@ main() { Type('int Function(int)'), Type('String Function(int)'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isFalse(); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); test('Non-matching due to parameter types', () { @@ -72,7 +71,7 @@ main() { Type('void Function(int)'), Type('void Function(String)'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isFalse(); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); test('Non-matching due to optional parameters on RHS', () { @@ -81,7 +80,7 @@ main() { Type('void Function()'), Type('void Function([int])'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isFalse(); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); test('Non-matching due to more parameters being required on LHS', () { @@ -90,7 +89,7 @@ main() { Type('void Function(int)'), Type('void Function([int])'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isFalse(); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); }); @@ -103,7 +102,7 @@ main() { leftSchema: false, astNodeForTesting: Node.placeholder())) .equals(true); - check(tcg._constraints).unorderedEquals(['T <: int', 'U <: String']); + check(tcg.constraints).unorderedEquals(['T <: int', 'U <: String']); }); test('Some optional on LHS', () { @@ -114,7 +113,7 @@ main() { leftSchema: false, astNodeForTesting: Node.placeholder())) .equals(true); - check(tcg._constraints).unorderedEquals(['T <: int', 'U <: String']); + check(tcg.constraints).unorderedEquals(['T <: int', 'U <: String']); }); test('Optional named parameter on LHS', () { @@ -125,7 +124,7 @@ main() { leftSchema: false, astNodeForTesting: Node.placeholder())) .equals(true); - check(tcg._constraints).unorderedEquals(['T <: int']); + check(tcg.constraints).unorderedEquals(['T <: int']); }); test('Extra optional named parameter on LHS', () { @@ -136,7 +135,7 @@ main() { leftSchema: false, astNodeForTesting: Node.placeholder())) .equals(true); - check(tcg._constraints).unorderedEquals(['T <: int']); + check(tcg.constraints).unorderedEquals(['T <: int']); }); }); @@ -147,7 +146,7 @@ main() { Type('int Function({int x})'), Type('String Function({int x})'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isFalse(); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); test('Non-matching due to named parameter types', () { @@ -158,7 +157,7 @@ main() { leftSchema: false, astNodeForTesting: Node.placeholder())) .isFalse(); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); test('Non-matching due to required named parameter on LHS', () { @@ -169,7 +168,7 @@ main() { leftSchema: false, astNodeForTesting: Node.placeholder())) .isFalse(); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); test('Non-matching due to optional named parameter on RHS', () { @@ -178,7 +177,7 @@ main() { Type('void Function()'), Type('void Function({int x})'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isFalse(); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); test('Non-matching due to named parameter on RHS, with decoys on LHS', @@ -190,7 +189,7 @@ main() { leftSchema: false, astNodeForTesting: Node.placeholder())) .isFalse(); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); }); @@ -202,7 +201,7 @@ main() { leftSchema: false, astNodeForTesting: Node.placeholder())) .equals(true); - check(tcg._constraints).unorderedEquals(['T <: int', 'U <: String']); + check(tcg.constraints).unorderedEquals(['T <: int', 'U <: String']); }); group('Non-matching functions with named and positional parameters:', () { @@ -216,7 +215,7 @@ main() { leftSchema: false, astNodeForTesting: Node.placeholder())) .isFalse(); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); test('Non-matching due to positional parameter length mismatch', () { @@ -227,7 +226,7 @@ main() { leftSchema: false, astNodeForTesting: Node.placeholder())) .isFalse(); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); }); }); @@ -239,7 +238,7 @@ main() { Type('()'), Type('()'), leftSchema: false, astNodeForTesting: Node.placeholder())) .equals(true); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); group('Matching records:', () { @@ -249,7 +248,7 @@ main() { Type('(int, String)'), Type('(T, U)'), leftSchema: true, astNodeForTesting: Node.placeholder())) .equals(true); - check(tcg._constraints).unorderedEquals(['int <: T', 'String <: U']); + check(tcg.constraints).unorderedEquals(['int <: T', 'String <: U']); }); test('With named parameters', () { @@ -258,7 +257,7 @@ main() { Type('(int, {String foo})'), Type('(T, {U foo})'), leftSchema: true, astNodeForTesting: Node.placeholder())) .equals(true); - check(tcg._constraints).unorderedEquals(['int <: T', 'String <: U']); + check(tcg.constraints).unorderedEquals(['int <: T', 'String <: U']); }); }); @@ -269,7 +268,7 @@ main() { Type('(int,)'), Type('(String,)'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isFalse(); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); test('Non-matching due to parameter numbers', () { @@ -278,7 +277,7 @@ main() { Type('()'), Type('(int,)'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isFalse(); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); test('Non-matching due to more parameters on LHS', () { @@ -287,7 +286,7 @@ main() { Type('(int,)'), Type('()'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isFalse(); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); }); @@ -298,7 +297,7 @@ main() { Type('({int x, String y})'), Type('({int x, String y})'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isTrue(); - check(tcg._constraints).unorderedEquals([]); + check(tcg.constraints).unorderedEquals([]); }); test('Type parameters in RHS', () { @@ -307,7 +306,7 @@ main() { Type('({int x, String y})'), Type('({T x, U y})'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isTrue(); - check(tcg._constraints).unorderedEquals(['int <: T', 'String <: U']); + check(tcg.constraints).unorderedEquals(['int <: T', 'String <: U']); }); test('Type parameters in LHS', () { @@ -316,7 +315,7 @@ main() { Type('({T x, U y})'), Type('({int x, String y})'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isTrue(); - check(tcg._constraints).unorderedEquals(['T <: int', 'U <: String']); + check(tcg.constraints).unorderedEquals(['T <: int', 'U <: String']); }); }); @@ -327,7 +326,7 @@ main() { Type('({int x, String y})'), Type('({int x, String y})'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isTrue(); - check(tcg._constraints).unorderedEquals([]); + check(tcg.constraints).unorderedEquals([]); }); test('Type parameters in RHS', () { @@ -336,7 +335,7 @@ main() { Type('({int x, String y})'), Type('({T x, U y})'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isTrue(); - check(tcg._constraints).unorderedEquals(['int <: T', 'String <: U']); + check(tcg.constraints).unorderedEquals(['int <: T', 'String <: U']); }); test('Type parameters in LHS', () { @@ -345,7 +344,7 @@ main() { Type('({T x, U y})'), Type('({int x, String y})'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isTrue(); - check(tcg._constraints).unorderedEquals(['T <: int', 'U <: String']); + check(tcg.constraints).unorderedEquals(['T <: int', 'U <: String']); }); }); @@ -358,7 +357,7 @@ main() { leftSchema: false, astNodeForTesting: Node.placeholder())) .isFalse(); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); test('Non-matching due to named parameter numbers', () { @@ -367,7 +366,7 @@ main() { Type('({T x, U y, num z})'), Type('({int x, String y})'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isFalse(); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); test('Non-matching due to named parameter names', () { @@ -376,7 +375,7 @@ main() { Type('(num, {T x, U y})'), Type('(num, {int x, String x2})'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isFalse(); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); }); }); @@ -389,7 +388,7 @@ main() { Type('FutureOr'), Type('FutureOr'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isTrue(); - check(tcg._constraints).deepEquals(['T <: int']); + check(tcg.constraints).deepEquals(['T <: int']); }); test('FutureOr does not match FutureOr because arguments fail to match', @@ -400,7 +399,7 @@ main() { Type('FutureOr'), Type('FutureOr'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isFalse(); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); test('Future matches FutureOr favoring Future branch', () { @@ -416,7 +415,7 @@ main() { Type('Future'), Type('FutureOr'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isTrue(); - check(tcg._constraints).deepEquals(['int <: T']); + check(tcg.constraints).deepEquals(['int <: T']); }); test('Future matches FutureOr preferring to generate constraints', () { @@ -432,7 +431,7 @@ main() { Type('Future<_>'), Type('FutureOr'), leftSchema: true, astNodeForTesting: Node.placeholder())) .isTrue(); - check(tcg._constraints).deepEquals(['Future<_> <: T']); + check(tcg.constraints).deepEquals(['Future<_> <: T']); }); test('Type matches FutureOr favoring the Future branch', () { @@ -448,7 +447,7 @@ main() { Type('T'), Type('FutureOr'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isTrue(); - check(tcg._constraints).deepEquals(['T <: Future']); + check(tcg.constraints).deepEquals(['T <: Future']); }); test('Testing FutureOr as the lower bound of the constraint', () { @@ -457,7 +456,7 @@ main() { Type('FutureOr'), Type('dynamic'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isTrue(); - check(tcg._constraints).deepEquals(['T <: dynamic']); + check(tcg.constraints).deepEquals(['T <: dynamic']); }); test('FutureOr does not match Future in general', () { @@ -469,7 +468,7 @@ main() { Type('FutureOr<(T,)>'), Type('Future<(int,)>'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isFalse(); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); test('Testing nested FutureOr as the lower bound of the constraint', () { @@ -478,7 +477,7 @@ main() { Type('FutureOr>'), Type('FutureOr'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isTrue(); - check(tcg._constraints).deepEquals(['T <: dynamic', 'T <: dynamic']); + check(tcg.constraints).deepEquals(['T <: dynamic', 'T <: dynamic']); }); test('Future matches FutureOr with no constraints', () { @@ -489,7 +488,7 @@ main() { Type('Future'), Type('FutureOr'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isTrue(); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); test('Type matches FutureOr favoring the branch that matches', () { @@ -501,7 +500,7 @@ main() { Type('List'), Type('FutureOr>'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isTrue(); - check(tcg._constraints).deepEquals(['T <: int']); + check(tcg.constraints).deepEquals(['T <: int']); }); group('Nullable FutureOr on RHS:', () { @@ -511,7 +510,7 @@ main() { Type('FutureOr'), Type('FutureOr?'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isFalse(); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); test('Matches, according to CFE discrepancy', () { @@ -521,7 +520,7 @@ main() { Type('FutureOr'), Type('FutureOr?'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isTrue(); - check(tcg._constraints).deepEquals(['T <: int']); + check(tcg.constraints).deepEquals(['T <: int']); }); }); @@ -532,7 +531,7 @@ main() { Type('FutureOr?'), Type('FutureOr'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isFalse(); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); test('Matches, according to CFE discrepancy', () { @@ -542,7 +541,7 @@ main() { Type('FutureOr?'), Type('FutureOr'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isTrue(); - check(tcg._constraints).deepEquals(['T <: int']); + check(tcg.constraints).deepEquals(['T <: int']); }); }); }); @@ -555,7 +554,7 @@ main() { Type('T?'), Type('Null'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isTrue(); - check(tcg._constraints).deepEquals(['T <: Null']); + check(tcg.constraints).deepEquals(['T <: Null']); }); test('Nullable does not match Nullable because base types fail to match', @@ -566,7 +565,7 @@ main() { Type('int?'), Type('String?'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isFalse(); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); test('Nullable does not match non-nullable', () { @@ -576,7 +575,7 @@ main() { Type('(int, T)?'), Type('(int, String)'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isFalse(); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); test('Both LHS and RHS nullable, matching', () { @@ -585,7 +584,7 @@ main() { Type('T?'), Type('int?'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isTrue(); - check(tcg._constraints).deepEquals(['T <: int']); + check(tcg.constraints).deepEquals(['T <: int']); }); test('Both LHS and RHS nullable, not matching', () { @@ -594,7 +593,7 @@ main() { Type('(T, int)?'), Type('(int, String)?'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isFalse(); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); }); @@ -612,7 +611,7 @@ main() { Type('Null'), Type('T?'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isTrue(); - check(tcg._constraints).deepEquals(['Null <: T']); + check(tcg.constraints).deepEquals(['Null <: T']); }); test('Type matches Nullable favoring the non-Null branch', () { @@ -628,7 +627,7 @@ main() { Type('T'), Type('int?'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isTrue(); - check(tcg._constraints).deepEquals(['T <: int']); + check(tcg.constraints).deepEquals(['T <: int']); }); test('Null matches Nullable with no constraints', () { @@ -639,7 +638,7 @@ main() { Type('Null'), Type('int?'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isTrue(); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); test('Dynamic matches Object?', () { @@ -648,7 +647,7 @@ main() { Type('dynamic'), Type('Object?'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isTrue(); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); test('void matches Object?', () { @@ -657,7 +656,7 @@ main() { Type('void'), Type('Object?'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isTrue(); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); test('LHS not nullable, matches with no constraints', () { @@ -666,7 +665,7 @@ main() { Type('int'), Type('int?'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isTrue(); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); }); @@ -678,7 +677,7 @@ main() { Type('Map'), Type('Map'), leftSchema: false, astNodeForTesting: Node.placeholder())) .equals(true); - check(tcg._constraints).unorderedEquals(['T <: int', 'U <: String']); + check(tcg.constraints).unorderedEquals(['T <: int', 'U <: String']); }); test('Covariant, not matching', () { @@ -687,7 +686,7 @@ main() { Type('Map'), Type('Map'), leftSchema: false, astNodeForTesting: Node.placeholder())) .equals(false); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); test('Contravariant, matching', () { @@ -698,7 +697,7 @@ main() { Type('Contravariant'), Type('Contravariant'), leftSchema: false, astNodeForTesting: Node.placeholder())) .equals(true); - check(tcg._constraints).unorderedEquals(['int <: T', 'String <: U']); + check(tcg.constraints).unorderedEquals(['int <: T', 'String <: U']); }); test('Contravariant, not matching', () { @@ -711,7 +710,7 @@ main() { leftSchema: false, astNodeForTesting: Node.placeholder())) .equals(false); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); test('Invariant, matching', () { @@ -722,7 +721,7 @@ main() { Type('Invariant'), Type('Invariant'), leftSchema: false, astNodeForTesting: Node.placeholder())) .equals(true); - check(tcg._constraints).unorderedEquals( + check(tcg.constraints).unorderedEquals( ['T <: int', 'U <: String', 'int <: T', 'String <: U']); }); @@ -734,7 +733,7 @@ main() { Type('Invariant'), Type('Invariant'), leftSchema: false, astNodeForTesting: Node.placeholder())) .equals(false); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); test('Unrelated, matchable', () { @@ -747,7 +746,7 @@ main() { Type('Unrelated'), Type('Unrelated'), leftSchema: false, astNodeForTesting: Node.placeholder())) .equals(true); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); test('Unrelated, not matchable', () { @@ -760,7 +759,7 @@ main() { Type('Unrelated'), Type('Unrelated'), leftSchema: false, astNodeForTesting: Node.placeholder())) .equals(true); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); }); @@ -771,7 +770,7 @@ main() { Type('List'), Type('Iterable'), leftSchema: false, astNodeForTesting: Node.placeholder())) .equals(true); - check(tcg._constraints).deepEquals(['T <: int']); + check(tcg.constraints).deepEquals(['T <: int']); }); test('Change in type args', () { @@ -780,7 +779,7 @@ main() { Type('MyListOfInt'), Type('List'), leftSchema: false, astNodeForTesting: Node.placeholder())) .equals(true); - check(tcg._constraints).deepEquals(['int <: T']); + check(tcg.constraints).deepEquals(['int <: T']); }); test('LHS nullable', () { @@ -793,7 +792,7 @@ main() { Type('List?'), Type('Iterable'), leftSchema: false, astNodeForTesting: Node.placeholder())) .equals(false); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); test('RHS nullable', () { @@ -806,7 +805,7 @@ main() { Type('List'), Type('Iterable?'), leftSchema: false, astNodeForTesting: Node.placeholder())) .equals(false); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); }); @@ -816,7 +815,7 @@ main() { Type('void Function()'), Type('int'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isNull(); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); test('Non-interface type on RHS', () { @@ -825,7 +824,7 @@ main() { Type('int'), Type('void Function()'), leftSchema: false, astNodeForTesting: Node.placeholder())) .isNull(); - check(tcg._constraints).isEmpty(); + check(tcg.constraints).isEmpty(); }); }); @@ -839,7 +838,7 @@ main() { leftSchema: false, astNodeForTesting: Node.placeholder())) .isTrue(); - check(tcg._constraints).unorderedEquals(['String <: T']); + check(tcg.constraints).unorderedEquals(['String <: T']); }); test('Promoted parameter on LHS', () { @@ -853,109 +852,7 @@ main() { leftSchema: false, astNodeForTesting: Node.placeholder())) .isTrue(); - check(tcg._constraints).unorderedEquals(['num <: T']); + check(tcg.constraints).unorderedEquals(['num <: T']); }); }); } - -class TypeConstraintGatherer extends TypeConstraintGenerator - with - TypeConstraintGeneratorMixin { - @override - final Set typeParametersToConstrain = {}; - - @override - final bool enableDiscrepantObliviousnessOfNullabilitySuffixOfFutureOr; - - @override - final MiniAstOperations typeAnalyzerOperations = MiniAstOperations(); - - final _constraints = []; - - TypeConstraintGatherer(Set typeVariablesBeingConstrained, - {this.enableDiscrepantObliviousnessOfNullabilitySuffixOfFutureOr = false}) - : super(inferenceUsingBoundsIsEnabled: false) { - for (var typeVariableName in typeVariablesBeingConstrained) { - typeParametersToConstrain - .add(TypeRegistry.addTypeParameter(typeVariableName)); - } - } - - @override - TypeConstraintGeneratorState get currentState => - TypeConstraintGeneratorState(_constraints.length); - - @override - List? getTypeArgumentsAsInstanceOf(Type type, String typeDeclaration) { - // We just have a few cases hardcoded here to make the tests work. - // TODO(paulberry): if this gets too unwieldy, replace it with a more - // general implementation. - switch ((type, typeDeclaration)) { - case (PrimaryType(name: 'List', :var args), 'Iterable'): - // List inherits from Iterable - return args; - case (PrimaryType(name: 'MyListOfInt'), 'List'): - // MyListOfInt inherits from List - return [Type('int')]; - case (PrimaryType(name: 'Future'), 'int'): - case (PrimaryType(name: 'int'), 'String'): - case (PrimaryType(name: 'List'), 'Future'): - case (PrimaryType(name: 'String'), 'int'): - case (PrimaryType(name: 'Future'), 'String'): - // Unrelated types - return null; - default: - throw UnimplementedError( - 'getTypeArgumentsAsInstanceOf($type, $typeDeclaration)'); - } - } - - @override - void restoreState(TypeConstraintGeneratorState state) { - _constraints.length = state.count; - } - - @override - void addUpperConstraintForParameter(TypeParameter typeParameter, Type upper, - {required Node? astNodeForTesting}) { - _constraints.add('$typeParameter <: $upper'); - } - - @override - void addLowerConstraintForParameter(TypeParameter typeParameter, Type lower, - {required Node? astNodeForTesting}) { - _constraints.add('$lower <: $typeParameter'); - } - - @override - void eliminateTypeParametersInGeneratedConstraints( - Object eliminator, TypeConstraintGeneratorState eliminationStartState, - {required Node? astNodeForTesting}) { - // TODO(paulberry): implement eliminateTypeParametersInGeneratedConstraints - } - - @override - ( - Type, - Type, { - List typeParametersToEliminate - }) instantiateFunctionTypesAndProvideFreshTypeParameters( - SharedFunctionTypeStructure - p, - SharedFunctionTypeStructure - q, - {required bool leftSchema}) { - // TODO(paulberry): implement instantiateFunctionTypesAndProvideEliminator - throw UnimplementedError(); - } - - @override - Map> - computeConstraints() { - // TODO(cstefantsova): implement computeConstraints - throw UnimplementedError(); - } -} diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html index 563e10953851..e7247a6e73f7 100644 --- a/pkg/analysis_server/doc/api.html +++ b/pkg/analysis_server/doc/api.html @@ -110,7 +110,7 @@

Analysis Server API Specification

Version - 1.38.0 + 1.39.0

This document contains a specification of the API provided by the @@ -245,6 +245,10 @@

Enumerations

ignoring the item or treating it with some default/fallback handling.

Changelog

+

1.39.0

+
    +
  • Added a new lspCapabilities field to the setClientCapabilities parameters to allow clients to provide their LSP capabilities. These capabilities can indicate that a client can support lsp.handle requests in the server-to-client direction.
  • +

1.38.0