Skip to content

Commit

Permalink
Version 3.3.0-201.0.dev
Browse files Browse the repository at this point in the history
Merge eeb3ecb into dev
  • Loading branch information
Dart CI committed Dec 7, 2023
2 parents be8a95b + eeb3ecb commit 4b22e64
Show file tree
Hide file tree
Showing 126 changed files with 2,512 additions and 2,232 deletions.
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,20 @@

[#51896]: https://github.com/dart-lang/sdk/issues/51896

#### `dart:js_interop`

- **Breaking Change in the representation of JS types** [#52687][]: JS types
like `JSAny` were previously represented using a custom erasure of
`@staticInterop` types that were compiler-specific. They are now represented
as extension types where their representation types are compiler-specific.
This means that user-defined `@staticInterop` types that implemented `JSAny`
or `JSObject` can no longer do so and need to use
`JSObject.fromInteropObject`. Going forward, it's recommended to use extension
types to define interop APIs. Those extension types can still implement JS
types.

[#52687]: https://github.com/dart-lang/sdk/issues/52687

#### `dart:typed_data`

- **BREAKING CHANGE** (https://github.com/dart-lang/sdk/issues/53218) The
Expand Down Expand Up @@ -62,6 +76,15 @@
Dart classes. This information provides little value and keeping it imposes an
unnecessary maintenance cost.

#### Production JavaScript compiler (dart2js)

- **Breaking Change** [#54201][]:
The `Invocation` that is passed to `noSuchMethod` will no longer have a
minified `memberName`, even when dart2js is invoked with `--minify`.
See [#54201][] for more details.

[#54201]: https://github.com/dart-lang/sdk/issues/54201

#### Linter

- Removed the `iterable_contains_unrelated_type` and
Expand Down
33 changes: 0 additions & 33 deletions pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9123,39 +9123,6 @@ Message _withArgumentsJsInteropStaticInteropWithInstanceMembers(String name) {
arguments: {'name': name});
}

// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<Message Function(String name, String name2)>
templateJsInteropStaticInteropWithInvalidJsTypesSupertype =
const Template<Message Function(String name, String name2)>(
"JsInteropStaticInteropWithInvalidJsTypesSupertype",
problemMessageTemplate:
r"""`@staticInterop` class '#name' cannot have '#name2' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes.""",
correctionMessageTemplate:
r"""Try subtyping `JSObject` or `JSAny` instead, or try casting an object of type '#name' to '#name2' when needed.""",
withArguments:
_withArgumentsJsInteropStaticInteropWithInvalidJsTypesSupertype);

// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Message Function(String name, String name2)>
codeJsInteropStaticInteropWithInvalidJsTypesSupertype =
const Code<Message Function(String name, String name2)>(
"JsInteropStaticInteropWithInvalidJsTypesSupertype",
);

// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
Message _withArgumentsJsInteropStaticInteropWithInvalidJsTypesSupertype(
String name, String name2) {
if (name.isEmpty) throw 'No name provided';
name = demangleMixinApplicationName(name);
if (name2.isEmpty) throw 'No name provided';
name2 = demangleMixinApplicationName(name2);
return new Message(codeJsInteropStaticInteropWithInvalidJsTypesSupertype,
problemMessage:
"""`@staticInterop` class '${name}' cannot have '${name2}' as a supertype. `JSObject` and `JSAny` are the only valid supertypes from `dart:js_interop` for `@staticInterop` classes.""",
correctionMessage: """Try subtyping `JSObject` or `JSAny` instead, or try casting an object of type '${name}' to '${name2}' when needed.""",
arguments: {'name': name, 'name2': name2});
}

// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<Message Function(String name, String name2)>
templateJsInteropStaticInteropWithNonStaticSupertype =
Expand Down
47 changes: 7 additions & 40 deletions pkg/_js_interop_checks/lib/js_interop_checks.dart
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import 'package:_fe_analyzer_shared/src/messages/codes.dart'
templateJsInteropNonStaticWithStaticInteropSupertype,
templateJsInteropStaticInteropNoJSAnnotation,
templateJsInteropStaticInteropWithInstanceMembers,
templateJsInteropStaticInteropWithInvalidJsTypesSupertype,
templateJsInteropStaticInteropWithNonStaticSupertype,
templateJsInteropObjectLiteralConstructorPositionalParameters,
templateJsInteropNativeClassInAnnotation,
Expand Down Expand Up @@ -227,13 +226,17 @@ class JsInteropChecks extends RecursiveVisitor {
report(templateJsInteropStaticInteropNoJSAnnotation
.withArguments(node.name));
}
if (superclass != null) {
_checkSuperclassOfStaticInteropClass(node, superclass);
if (superclass != null && !hasStaticInteropAnnotation(superclass)) {
report(templateJsInteropStaticInteropWithNonStaticSupertype
.withArguments(node.name, superclass.name));
}
// Validate that superinterfaces are all valid supertypes as well. Note
// that mixins are already disallowed and therefore are not checked here.
for (final supertype in node.implementedTypes) {
_checkSuperclassOfStaticInteropClass(node, supertype.classNode);
if (!hasStaticInteropAnnotation(supertype.classNode)) {
report(templateJsInteropStaticInteropWithNonStaticSupertype
.withArguments(node.name, supertype.classNode.name));
}
}
} else {
// For classes, `dart:js_interop`'s `@JS` can only be used with
Expand Down Expand Up @@ -819,39 +822,6 @@ class JsInteropChecks extends RecursiveVisitor {
}
}

/// Reports an error if @staticInterop classes extends or implements a
/// non-@staticInterop type or an invalid dart:_js_types type.
void _checkSuperclassOfStaticInteropClass(Class node, Class superclass) {
void report(Message message) => _reporter.report(
message, node.fileOffset, node.name.length, node.fileUri);
if (!hasStaticInteropAnnotation(superclass)) {
report(templateJsInteropStaticInteropWithNonStaticSupertype.withArguments(
node.name, superclass.name));
} else {
// dart:_js_types @staticInterop types are special. They are custom-erased
// to different types at runtime. User @staticInterop types are always
// erased to JavaScriptObject. As such, this means that we should only
// allow users to subtype dart:_js_types types that erase to a
// T >: JavaScriptObject. Currently, this is only JSObject and JSAny.
// TODO(srujzs): This error should be temporary. In the future, once we
// have extension types that can implement concrete classes, we can move
// all the dart:_js_types that aren't JSObject and JSAny to extension
// types. Then, this error becomes redundant. This would also allow us to
// idiomatically add type parameters to JSArray and JSPromise.
final superclassUri = superclass.enclosingLibrary.importUri;
// Make an exception for some internal libraries.
final allowList = {'_js_types', '_js_helper'};
if (superclassUri.isScheme('dart') &&
superclassUri.path == '_js_types' &&
!allowList.contains(node.enclosingLibrary.importUri.path) &&
superclass.name != 'JSAny' &&
superclass.name != 'JSObject') {
report(templateJsInteropStaticInteropWithInvalidJsTypesSupertype
.withArguments(node.name, superclass.name));
}
}
}

/// If [procedure] is a generated procedure that represents a relevant
/// tear-off, return the torn-off member.
///
Expand Down Expand Up @@ -944,9 +914,6 @@ class JsInteropChecks extends RecursiveVisitor {
.isInteropExtensionType(type.extensionTypeDeclaration)) {
return true;
}
// Extension types where the representation type is allowed are okay.
// TODO(srujzs): Once the CFE pre-computes the concrete type, don't
// recurse.
return _isAllowedExternalType(type.extensionTypeErasure);
}
return false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ class ExportCreator extends Transformer {
final Procedure _functionToJS;
final Procedure _getProperty;
final Procedure _globalContext;
final Class _jsAny;
final Class _jsObject;
final ExtensionTypeDeclaration _jsAny;
final ExtensionTypeDeclaration _jsObject;
final Procedure _setProperty;
final Procedure _stringToJS;
final StaticInteropMockValidator _staticInteropMockValidator;
Expand All @@ -51,9 +51,9 @@ class ExportCreator extends Transformer {
_globalContext = _typeEnvironment.coreTypes.index
.getTopLevelProcedure('dart:js_interop', 'get:globalContext'),
_jsAny = _typeEnvironment.coreTypes.index
.getClass('dart:_js_types', 'JSAny'),
.getExtensionType('dart:js_interop', 'JSAny'),
_jsObject = _typeEnvironment.coreTypes.index
.getClass('dart:_js_types', 'JSObject'),
.getExtensionType('dart:js_interop', 'JSObject'),
_setProperty = _typeEnvironment.coreTypes.index.getTopLevelProcedure(
'dart:js_interop_unsafe', 'JSObjectUnsafeUtilExtension|[]='),
_stringToJS = _typeEnvironment.coreTypes.index.getTopLevelProcedure(
Expand Down Expand Up @@ -175,7 +175,7 @@ class ExportCreator extends Transformer {
Expression asJSObject(Expression object, [bool nullable = false]) =>
AsExpression(
object,
InterfaceType(_jsObject,
ExtensionType(_jsObject,
nullable ? Nullability.nullable : Nullability.nonNullable))
..fileOffset = node.fileOffset;

Expand All @@ -192,7 +192,7 @@ class ExportCreator extends Transformer {
jsObject,
toJSString(methodName),
ListLiteral(args,
typeArgument: InterfaceType(_jsAny, Nullability.nullable))
typeArgument: ExtensionType(_jsAny, Nullability.nullable))
], types: [
returnType
]))
Expand All @@ -211,7 +211,7 @@ class ExportCreator extends Transformer {
getObjectProperty(),
'create',
[asJSObject(proto ?? NullLiteral(), true)],
InterfaceType(_jsObject, Nullability.nonNullable));
ExtensionType(_jsObject, Nullability.nonNullable));
}

var exportMap =
Expand All @@ -230,7 +230,7 @@ class ExportCreator extends Transformer {

var jsExporter = VariableDeclaration('#jsExporter',
initializer: getLiteral(proto),
type: InterfaceType(_jsObject, Nullability.nonNullable),
type: ExtensionType(_jsObject, Nullability.nonNullable),
isSynthesized: true)
..fileOffset = node.fileOffset
..parent = node.parent;
Expand Down Expand Up @@ -295,7 +295,7 @@ class ExportCreator extends Transformer {
// statements for each export name.
var getSetMap = VariableDeclaration('#${exportName}Mapping',
initializer: getLiteral(),
type: InterfaceType(_jsObject, Nullability.nonNullable),
type: ExtensionType(_jsObject, Nullability.nonNullable),
isSynthesized: true)
..fileOffset = node.fileOffset
..parent = node.parent;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -786,23 +786,27 @@ class ExtensionIndex {
///
/// This currently allows the interface type to be:
/// - all package:js classes
/// - dart:js_types types
/// - dart:js_interop types
/// - @Native types that implement JavaScriptObject
/// - extension types that wrap any of the above
bool isInteropExtensionType(ExtensionTypeDeclaration extensionType) {
final reference = extensionType.reference;
if (_interopExtensionTypeIndex.containsKey(reference)) {
return _interopExtensionTypeIndex[reference]!;
}
DartType repType = extensionType.declaredRepresentationType;
if (repType is ExtensionType) {
repType = repType.extensionTypeErasure;
// Check if this is an dart:js_interop JS type or recursively an extension
// type on one.
DartType repType = ExtensionType(extensionType, Nullability.nonNullable);
while (repType is ExtensionType) {
final declaration = repType.extensionTypeDeclaration;
if (declaration.enclosingLibrary.importUri.toString() ==
'dart:js_interop') {
return true;
}
repType = declaration.declaredRepresentationType;
}
if (repType is InterfaceType) {
final cls = repType.classNode;
// TODO(srujzs): Note that dart:_js_types types currently use a custom
// lowering of @staticInterop. Once
// https://github.com/dart-lang/sdk/issues/52687 is handled, we should
// modify this if-check to handle the new representation.
final javaScriptObject = _coreTypes.index
.tryGetClass('dart:_interceptors', 'JavaScriptObject');
if (hasStaticInteropAnnotation(cls) ||
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,112 +13,11 @@ import 'package:kernel/src/constant_replacer.dart';
import 'package:kernel/src/replacement_visitor.dart';

/// Erasure function for `@staticInterop` types for the JS compilers.
///
/// `dart:_js_types` are implemented currently using `@staticInterop`, but they
/// are erased to different types at runtime. Non-`dart:_js_types`
/// `@staticInterop` types are erased to `JavaScriptObject`.
InterfaceType eraseStaticInteropTypesForJSCompilers(
CoreTypes coreTypes, InterfaceType staticInteropType) {
if (staticInteropType.classNode.enclosingLibrary.importUri ==
Uri.parse('dart:_js_types')) {
final className = staticInteropType.classNode.name;
Class erasedClass;
var typeArguments = staticInteropType.typeArguments;
// TODO(srujzs): Switch to a switch expression once they're working in the
// SDK.
switch (className) {
case 'JSAny':
erasedClass = coreTypes.objectClass;
break;
case 'JSObject':
erasedClass =
coreTypes.index.getClass('dart:_interceptors', 'JSObject');
break;
case 'JSFunction':
erasedClass = coreTypes.functionClass;
break;
case 'JSExportedDartFunction':
erasedClass = coreTypes.functionClass;
break;
case 'JSArray':
erasedClass = coreTypes.listClass;
typeArguments = [coreTypes.objectNullableRawType];
break;
case 'JSBoxedDartObject':
erasedClass =
coreTypes.index.getClass('dart:_interceptors', 'JSObject');
break;
case 'JSArrayBuffer':
erasedClass = coreTypes.index.getClass('dart:typed_data', 'ByteBuffer');
break;
case 'JSDataView':
erasedClass = coreTypes.index.getClass('dart:typed_data', 'ByteData');
break;
case 'JSTypedArray':
erasedClass = coreTypes.index.getClass('dart:typed_data', 'TypedData');
break;
case 'JSInt8Array':
erasedClass = coreTypes.index.getClass('dart:typed_data', 'Int8List');
break;
case 'JSUint8Array':
erasedClass = coreTypes.index.getClass('dart:typed_data', 'Uint8List');
break;
case 'JSUint8ClampedArray':
erasedClass =
coreTypes.index.getClass('dart:typed_data', 'Uint8ClampedList');
break;
case 'JSInt16Array':
erasedClass = coreTypes.index.getClass('dart:typed_data', 'Int16List');
break;
case 'JSUint16Array':
erasedClass = coreTypes.index.getClass('dart:typed_data', 'Uint16List');
break;
case 'JSInt32Array':
erasedClass = coreTypes.index.getClass('dart:typed_data', 'Int32List');
break;
case 'JSUint32Array':
erasedClass = coreTypes.index.getClass('dart:typed_data', 'Uint32List');
break;
case 'JSFloat32Array':
erasedClass =
coreTypes.index.getClass('dart:typed_data', 'Float32List');
break;
case 'JSFloat64Array':
erasedClass =
coreTypes.index.getClass('dart:typed_data', 'Float64List');
break;
case 'JSNumber':
erasedClass = coreTypes.doubleClass;
break;
case 'JSBoolean':
erasedClass = coreTypes.boolClass;
break;
case 'JSString':
erasedClass = coreTypes.stringClass;
break;
case 'JSPromise':
erasedClass =
coreTypes.index.getClass('dart:_interceptors', 'JSObject');
break;
case 'JSSymbol':
erasedClass =
coreTypes.index.getClass('dart:_interceptors', 'JavaScriptSymbol');
break;
case 'JSBigInt':
erasedClass =
coreTypes.index.getClass('dart:_interceptors', 'JavaScriptBigInt');
break;
default:
throw 'Unimplemented `dart:_js_types`: $className';
}
return InterfaceType(
erasedClass, staticInteropType.declaredNullability, typeArguments);
} else {
return InterfaceType(
CoreTypes coreTypes, InterfaceType staticInteropType) =>
InterfaceType(
coreTypes.index.getClass('dart:_interceptors', 'JavaScriptObject'),
staticInteropType.declaredNullability);
}
}

class _TypeSubstitutor extends ReplacementVisitor {
final InterfaceType Function(InterfaceType staticInteropType)
Expand Down
2 changes: 1 addition & 1 deletion pkg/analysis_server/lib/src/cider/rename.dart
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ class CanRenameResponse {
}

FlutterWidgetState? _findFlutterStateClass(Element element, String newName) {
if (Flutter.instance.isStatefulWidgetDeclaration(element)) {
if (Flutter.isStatefulWidgetDeclaration(element)) {
var oldStateName = '${element.displayName}State';
var library = element.library!;
var state =
Expand Down
Loading

0 comments on commit 4b22e64

Please sign in to comment.