Version 3.6.0-176.0.dev Merge 298a92d49ba97a3faafcb2a8867587b4e31a4de6 into dev
diff --git a/pkg/dartdev/test/native_assets/test_environment_test.dart b/pkg/dartdev/test/native_assets/test_environment_test.dart new file mode 100644 index 0000000..c2441a8 --- /dev/null +++ b/pkg/dartdev/test/native_assets/test_environment_test.dart
@@ -0,0 +1,39 @@ +// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:io'; + +import 'package:native_assets_cli/native_assets_cli_internal.dart' + show CCompilerConfigImpl; +import 'package:test/test.dart'; + +void main() async { + // Test pkg/test_runner/lib/src/configuration.dart + test('test environment', () async { + printOnFailure(Platform.environment.toString()); + + String unparseKey(String key) => key.replaceAll('.', '__').toUpperCase(); + + final arKey = unparseKey(CCompilerConfigImpl.arConfigKeyFull); + final ccKey = unparseKey(CCompilerConfigImpl.ccConfigKeyFull); + final ldKey = unparseKey(CCompilerConfigImpl.ldConfigKeyFull); + final envScriptKey = unparseKey(CCompilerConfigImpl.envScriptConfigKeyFull); + final envScriptArgsKey = + unparseKey(CCompilerConfigImpl.envScriptArgsConfigKeyFull); + + if (Platform.isLinux || Platform.isWindows) { + expect(Platform.environment[arKey], isNotEmpty); + expect(await File(Platform.environment[arKey]!).exists(), true); + expect(Platform.environment[ccKey], isNotEmpty); + expect(await File(Platform.environment[ccKey]!).exists(), true); + expect(Platform.environment[ldKey], isNotEmpty); + expect(await File(Platform.environment[ldKey]!).exists(), true); + } + if (Platform.isWindows) { + expect(Platform.environment[envScriptKey], isNotEmpty); + expect(await File(Platform.environment[envScriptKey]!).exists(), true); + expect(Platform.environment[envScriptArgsKey], isNotEmpty); + } + }); +}
diff --git a/pkg/dds/lib/src/dds_cli_entrypoint.dart b/pkg/dds/lib/src/dds_cli_entrypoint.dart index ce44c14..665ac27 100644 --- a/pkg/dds/lib/src/dds_cli_entrypoint.dart +++ b/pkg/dds/lib/src/dds_cli_entrypoint.dart
@@ -55,16 +55,21 @@ argResults[DartDevelopmentServiceOptions.vmServiceUriOption], ); + // Prefer IPv4 addresses if we can't determine the address type from the + // VM service host. + final preferredProtocolType = + InternetAddress.tryParse(remoteVmServiceUri.host)?.type ?? + InternetAddressType.IPv4; + // Resolve the address which is potentially provided by the user. late InternetAddress address; final bindAddress = argResults[DartDevelopmentServiceOptions.bindAddressOption]; try { final addresses = await InternetAddress.lookup(bindAddress); - // Prefer IPv4 addresses. for (int i = 0; i < addresses.length; i++) { address = addresses[i]; - if (address.type == InternetAddressType.IPv4) break; + if (address.type == preferredProtocolType) break; } } on SocketException catch (e, st) { writeErrorResponse('Invalid bind address: $bindAddress', st);
diff --git a/pkg/linter/lib/src/rules/use_build_context_synchronously.dart b/pkg/linter/lib/src/rules/use_build_context_synchronously.dart index 663b6b5..1126929 100644 --- a/pkg/linter/lib/src/rules/use_build_context_synchronously.dart +++ b/pkg/linter/lib/src/rules/use_build_context_synchronously.dart
@@ -270,12 +270,14 @@ return switch ((leftGuardState, rightGuardState)) { // Anything on the left followed by async on the right is async. (_, AsyncState.asynchronous) => AsyncState.asynchronous, - // Async on the left followed by anything on the right is async. + // Anything on the left followed by not-mounted on the right is a + // not-mounted check. + (_, AsyncState.notMountedCheck) => AsyncState.notMountedCheck, + // Async on the left followed by anything else on the right is async. (AsyncState.asynchronous, _) => AsyncState.asynchronous, // A mounted guard only applies if both sides are guarded. (AsyncState.mountedCheck, AsyncState.mountedCheck) => AsyncState.mountedCheck, - (_, AsyncState.notMountedCheck) => AsyncState.notMountedCheck, (AsyncState.notMountedCheck, _) => AsyncState.notMountedCheck, // Otherwise it's just uninteresting. (_, _) => null,
diff --git a/pkg/linter/test/rules/use_build_context_synchronously_test.dart b/pkg/linter/test/rules/use_build_context_synchronously_test.dart index accd7a1..8c3e1c7 100644 --- a/pkg/linter/test/rules/use_build_context_synchronously_test.dart +++ b/pkg/linter/test/rules/use_build_context_synchronously_test.dart
@@ -705,6 +705,22 @@ AsyncState.asynchronous); } + test_ifStatement_referenceAfter_asyncOrNotMountedInCondition() async { + await resolveCode(r''' +import 'package:flutter/widgets.dart'; +void foo(BuildContext context) async { + if (await Future.value(true) || !context.mounted) return; + //} else { + context /* ref */; + //} +} +'''); + var body = findNode.ifStatement('if ').parent!; + var reference = findNode.statement('context /* ref */'); + expect(body.asyncStateFor(reference, contextElement), + AsyncState.notMountedCheck); + } + test_ifStatement_referenceAfter_awaitThenExitInElse() async { await resolveCode(r''' import 'package:flutter/widgets.dart';
diff --git a/sdk/lib/_internal/wasm/lib/convert_patch.dart b/sdk/lib/_internal/wasm/lib/convert_patch.dart index a67e3b2..0987af0 100644 --- a/sdk/lib/_internal/wasm/lib/convert_patch.dart +++ b/sdk/lib/_internal/wasm/lib/convert_patch.dart
@@ -245,6 +245,10 @@ int get capacity => array.length; + void clear() { + length = 0; + } + // Pick an initial capacity greater than the first part's size. // The typical use case has two parts, this is the attempt at // guessing the size of the second part without overdoing it. @@ -473,12 +477,15 @@ int partialState = NO_PARTIAL; /** - * Extra data stored while parsing a primitive value. - * May be set during parsing, always set at chunk end if a value is partial. - * - * May contain a string buffer while parsing strings. + * String parts stored while parsing a string. */ - dynamic buffer = null; + late final StringBuffer stringBuffer = StringBuffer(); + + /** + * Number parts stored while parsing a number. + */ + late final _NumberBuffer numberBuffer = + _NumberBuffer(_NumberBuffer.minCapacity); /** * Push the current parse [state] on a stack. @@ -518,9 +525,7 @@ // A partial number might be a valid number if we know it's done. // There is an unnecessary overhead if input is a single number, // but this is assumed to be rare. - _NumberBuffer buffer = this.buffer; - this.buffer = null; - finishChunkNumber(numState, 0, 0, buffer); + finishChunkNumber(numState, 0, 0); } else if (partialType == PARTIAL_STRING) { fail(chunkEnd, "Unterminated string"); } else { @@ -686,8 +691,6 @@ int parsePartialNumber(int position, int state) { int start = position; // Primitive implementation, can be optimized. - _NumberBuffer buffer = this.buffer; - this.buffer = null; int end = chunkEnd; toBailout: { @@ -721,7 +724,7 @@ } else if ((char | 0x20) == CHAR_e) { state = NUM_E; } else { - finishChunkNumber(state, start, position, buffer); + finishChunkNumber(state, start, position); return position; } } @@ -739,7 +742,7 @@ if ((char | 0x20) == CHAR_e) { state = NUM_E; } else { - finishChunkNumber(state, start, position, buffer); + finishChunkNumber(state, start, position); return position; } } @@ -765,12 +768,12 @@ char = getChar(position); digit = char ^ CHAR_0; } - finishChunkNumber(state, start, position, buffer); + finishChunkNumber(state, start, position); return position; } // Bailout code in case the current chunk ends while parsing the numeral. assert(position == end); - continueChunkNumber(state, start, buffer); + continueChunkNumber(state, start); return chunkEnd; } @@ -1289,50 +1292,49 @@ int beginChunkNumber(int state, int start) { int end = chunkEnd; int length = end - start; - var buffer = new _NumberBuffer(length); - copyCharsToList(start, end, buffer.array, 0); - buffer.length = length; - this.buffer = buffer; + numberBuffer.ensureCapacity(length); + copyCharsToList(start, end, numberBuffer.array, 0); + numberBuffer.length = length; this.partialState = PARTIAL_NUMERAL | state; return end; } - void addNumberChunk(_NumberBuffer buffer, int start, int end, int overhead) { + void addNumberChunk(int start, int end, int overhead) { int length = end - start; - int count = buffer.length; + int count = numberBuffer.length; int newCount = count + length; int newCapacity = newCount + overhead; - buffer.ensureCapacity(newCapacity); - copyCharsToList(start, end, buffer.array, count); - buffer.length = newCount; + numberBuffer.ensureCapacity(newCapacity); + copyCharsToList(start, end, numberBuffer.array, count); + numberBuffer.length = newCount; } // Continues an already chunked number across an entire chunk. - int continueChunkNumber(int state, int start, _NumberBuffer buffer) { + int continueChunkNumber(int state, int start) { int end = chunkEnd; - addNumberChunk(buffer, start, end, _NumberBuffer.defaultOverhead); - this.buffer = buffer; + addNumberChunk(start, end, _NumberBuffer.defaultOverhead); this.partialState = PARTIAL_NUMERAL | state; return end; } - int finishChunkNumber(int state, int start, int end, _NumberBuffer buffer) { + void finishChunkNumber(int state, int start, int end) { if (state == NUM_ZERO) { listener.handleNumber(0); - return end; + numberBuffer.clear(); + return; } if (end > start) { - addNumberChunk(buffer, start, end, 0); + addNumberChunk(start, end, 0); } if (state == NUM_DIGIT) { - num value = buffer.parseNum(); + num value = numberBuffer.parseNum(); listener.handleNumber(value); } else if (state == NUM_DOT_DIGIT || state == NUM_E_DIGIT) { - listener.handleNumber(buffer.parseDouble()); + listener.handleNumber(numberBuffer.parseDouble()); } else { fail(chunkEnd, "Unterminated number literal"); } - return end; + numberBuffer.clear(); } int parseNumber(int char, int position) { @@ -1521,23 +1523,21 @@ } void beginString() { - this.buffer = new StringBuffer(); + assert(stringBuffer.isEmpty); } void addSliceToString(int start, int end) { - StringBuffer buffer = this.buffer; - buffer.write(chunk.substringUnchecked(start, end)); + stringBuffer.write(chunk.substringUnchecked(start, end)); } void addCharToString(int charCode) { - StringBuffer buffer = this.buffer; - buffer.writeCharCode(charCode); + stringBuffer.writeCharCode(charCode); } String endString() { - StringBuffer buffer = this.buffer; - this.buffer = null; - return buffer.toString(); + final string = stringBuffer.toString(); + stringBuffer.clear(); + return string; } void copyCharsToList( @@ -1656,25 +1656,23 @@ void beginString() { decoder.reset(); - this.buffer = new StringBuffer(); + stringBuffer.clear(); } void addSliceToString(int start, int end) { - final StringBuffer buffer = this.buffer; - buffer.write(decoder.convertChunked(chunk, start, end)); + stringBuffer.write(decoder.convertChunked(chunk, start, end)); } void addCharToString(int charCode) { - final StringBuffer buffer = this.buffer; - decoder.flush(buffer); - buffer.writeCharCode(charCode); + decoder.flush(stringBuffer); + stringBuffer.writeCharCode(charCode); } String endString() { - final StringBuffer buffer = this.buffer; - decoder.flush(buffer); - this.buffer = null; - return buffer.toString(); + decoder.flush(stringBuffer); + final string = stringBuffer.toString(); + stringBuffer.clear(); + return string; } void copyCharsToList(
diff --git a/tools/VERSION b/tools/VERSION index 1b15b16..81ccca3 100644 --- a/tools/VERSION +++ b/tools/VERSION
@@ -27,5 +27,5 @@ MAJOR 3 MINOR 6 PATCH 0 -PRERELEASE 175 +PRERELEASE 176 PRERELEASE_PATCH 0