Skip to content

Commit 5316613

Browse files
johnniwintherCommit Queue
authored andcommitted
[cfe] Detect Record and Function through builders
The current check using Class doesn't work when compiling the platform and the Class node not yet been built. Change-Id: I3b9e692f761ebdfbfc34bf8334d7dc8ef31230a3 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/412643 Reviewed-by: Chloe Stefantsova <[email protected]> Commit-Queue: Johnni Winther <[email protected]>
1 parent 939699a commit 5316613

File tree

4 files changed

+81
-67
lines changed

4 files changed

+81
-67
lines changed

pkg/front_end/lib/src/builder/library_builder.dart

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
// BSD-style license that can be found in the LICENSE file.
44

55
import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
6-
import 'package:kernel/ast.dart' show Annotatable, Class, Library, Version;
6+
import 'package:kernel/ast.dart' show Annotatable, Library, Version;
77
import 'package:kernel/reference_from_index.dart';
88

99
import '../api_prototype/experimental_flags.dart';
@@ -413,29 +413,22 @@ abstract class LibraryBuilder implements Builder, ProblemReporting {
413413
void recordAccess(
414414
CompilationUnit accessor, int charOffset, int length, Uri fileUri);
415415

416-
/// Returns `true` if [cls] is the 'Function' class defined in [coreLibrary].
417-
static bool isFunction(Class cls, LibraryBuilder coreLibrary) {
418-
return cls.name == 'Function' && _isCoreClass(cls, coreLibrary);
416+
/// Returns `true` if [typeDeclarationBuilder] is the 'Function' class defined
417+
/// in [coreLibrary].
418+
static bool isFunction(TypeDeclarationBuilder? typeDeclarationBuilder,
419+
LibraryBuilder coreLibrary) {
420+
return typeDeclarationBuilder is ClassBuilder &&
421+
typeDeclarationBuilder.name == 'Function' &&
422+
typeDeclarationBuilder.libraryBuilder == coreLibrary;
419423
}
420424

421-
/// Returns `true` if [cls] is the 'Record' class defined in [coreLibrary].
422-
static bool isRecord(Class cls, LibraryBuilder coreLibrary) {
423-
return cls.name == 'Record' && _isCoreClass(cls, coreLibrary);
424-
}
425-
426-
static bool _isCoreClass(Class cls, LibraryBuilder coreLibrary) {
427-
// We use `superclass.parent` here instead of
428-
// `superclass.enclosingLibrary` to handle platform compilation. If
429-
// we are currently compiling the platform, the enclosing library of
430-
// the core class has not yet been set, so the accessing
431-
// `enclosingLibrary` would result in a cast error. We assume that the
432-
// SDK does not contain this error, which we otherwise not find. If we
433-
// are _not_ compiling the platform, the `superclass.parent` has been
434-
// set, if it is a class from `dart:core`.
435-
if (cls.parent == coreLibrary.library) {
436-
return true;
437-
}
438-
return false;
425+
/// Returns `true` if [typeDeclarationBuilder] is the 'Record' class defined
426+
/// in [coreLibrary].
427+
static bool isRecord(TypeDeclarationBuilder? typeDeclarationBuilder,
428+
LibraryBuilder coreLibrary) {
429+
return typeDeclarationBuilder is ClassBuilder &&
430+
typeDeclarationBuilder.name == 'Record' &&
431+
typeDeclarationBuilder.libraryBuilder == coreLibrary;
439432
}
440433
}
441434

pkg/front_end/lib/src/source/source_class_builder.dart

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -409,13 +409,13 @@ class SourceClassBuilder extends ClassBuilderImpl
409409
if (_supertypeBuilder != null) {
410410
_supertypeBuilder = _checkSupertype(_supertypeBuilder!);
411411
}
412-
Supertype? supertype = supertypeBuilder?.buildSupertype(libraryBuilder,
413-
isMixinDeclaration ? TypeUse.mixinOnType : TypeUse.classExtendsType);
414-
if (supertype != null &&
415-
LibraryBuilder.isFunction(supertype.classNode, coreLibrary)) {
416-
supertype = null;
412+
TypeDeclarationBuilder? supertypeDeclaration =
413+
supertypeBuilder?.computeUnaliasedDeclaration(isUsedAsClass: false);
414+
if (LibraryBuilder.isFunction(supertypeDeclaration, coreLibrary)) {
417415
_supertypeBuilder = null;
418416
}
417+
Supertype? supertype = supertypeBuilder?.buildSupertype(libraryBuilder,
418+
isMixinDeclaration ? TypeUse.mixinOnType : TypeUse.classExtendsType);
419419
if (!isMixinDeclaration &&
420420
actualCls.supertype != null &&
421421
// Coverage-ignore(suite): Not run.
@@ -440,14 +440,15 @@ class SourceClassBuilder extends ClassBuilderImpl
440440
if (_mixedInTypeBuilder != null) {
441441
_mixedInTypeBuilder = _checkSupertype(_mixedInTypeBuilder!);
442442
}
443-
Supertype? mixedInType =
444-
_mixedInTypeBuilder?.buildMixedInType(libraryBuilder);
445-
if (mixedInType != null &&
446-
LibraryBuilder.isFunction(mixedInType.classNode, coreLibrary)) {
447-
mixedInType = null;
443+
TypeDeclarationBuilder? mixedInDeclaration =
444+
_mixedInTypeBuilder?.computeUnaliasedDeclaration(isUsedAsClass: false);
445+
if (LibraryBuilder.isFunction(mixedInDeclaration, coreLibrary)) {
448446
_mixedInTypeBuilder = null;
449447
actualCls.isAnonymousMixin = false;
450448
}
449+
Supertype? mixedInType =
450+
_mixedInTypeBuilder?.buildMixedInType(libraryBuilder);
451+
451452
actualCls.isMixinDeclaration = isMixinDeclaration;
452453
actualCls.mixedInType = mixedInType;
453454

@@ -464,12 +465,16 @@ class SourceClassBuilder extends ClassBuilderImpl
464465
if (interfaceBuilders != null) {
465466
for (int i = 0; i < interfaceBuilders.length; ++i) {
466467
interfaceBuilders[i] = _checkSupertype(interfaceBuilders[i]);
468+
TypeDeclarationBuilder? implementedDeclaration = interfaceBuilders[i]
469+
.computeUnaliasedDeclaration(isUsedAsClass: false);
470+
if (LibraryBuilder.isFunction(implementedDeclaration, coreLibrary) &&
471+
// Allow wasm to implement `Function`.
472+
!libraryBuilder.mayImplementRestrictedTypes) {
473+
continue;
474+
}
467475
Supertype? supertype = interfaceBuilders[i]
468476
.buildSupertype(libraryBuilder, TypeUse.classImplementsType);
469477
if (supertype != null) {
470-
if (LibraryBuilder.isFunction(supertype.classNode, coreLibrary)) {
471-
continue;
472-
}
473478
// TODO(ahe): Report an error if supertype is null.
474479
actualCls.implementedTypes.add(supertype);
475480
}

pkg/front_end/lib/src/source/source_extension_type_declaration_builder.dart

Lines changed: 46 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -216,10 +216,33 @@ class SourceExtensionTypeDeclarationBuilder
216216
typeBuilder.declaration is TypeAliasBuilder
217217
? typeBuilder.declaration as TypeAliasBuilder
218218
: null;
219+
219220
DartType interface = typeBuilder.build(
220221
libraryBuilder, TypeUse.extensionTypeImplementsType);
221-
Message? errorMessage;
222-
List<LocatedMessage>? errorContext;
222+
223+
TypeDeclarationBuilder? implementedDeclaration =
224+
typeBuilder.computeUnaliasedDeclaration(isUsedAsClass: false);
225+
if (LibraryBuilder.isFunction(implementedDeclaration, coreLibrary) ||
226+
LibraryBuilder.isRecord(implementedDeclaration, coreLibrary)) {
227+
Message? errorMessage;
228+
List<LocatedMessage>? errorContext;
229+
if (aliasBuilder != null) {
230+
// Coverage-ignore-block(suite): Not run.
231+
errorMessage = templateSuperExtensionTypeIsIllegalAliased
232+
.withArguments(typeBuilder.fullNameForErrors, interface);
233+
errorContext = [
234+
messageTypedefCause.withLocation(
235+
aliasBuilder.fileUri, aliasBuilder.fileOffset, noLength),
236+
];
237+
} else {
238+
errorMessage = templateSuperExtensionTypeIsIllegal
239+
.withArguments(typeBuilder.fullNameForErrors);
240+
}
241+
libraryBuilder.addProblem(errorMessage, typeBuilder.charOffset!,
242+
noLength, typeBuilder.fileUri,
243+
context: errorContext);
244+
continue;
245+
}
223246

224247
if (typeParameters?.isNotEmpty ?? false) {
225248
for (NominalParameterBuilder variable in typeParameters!) {
@@ -228,6 +251,7 @@ class SourceExtensionTypeDeclarationBuilder
228251
sourceLoader: libraryBuilder.loader)
229252
.variance!;
230253
if (!variance.greaterThanOrEqual(variable.variance)) {
254+
Message? errorMessage;
231255
if (variable.parameter.isLegacyCovariant) {
232256
errorMessage =
233257
templateWrongTypeParameterVarianceInSuperinterface
@@ -239,31 +263,33 @@ class SourceExtensionTypeDeclarationBuilder
239263
.withArguments(variable.variance.keyword, variable.name,
240264
variance.keyword, typeBuilder.typeName!.name);
241265
}
266+
libraryBuilder.addProblem(errorMessage, typeBuilder.charOffset!,
267+
noLength, typeBuilder.fileUri);
242268
}
243269
}
244-
if (errorMessage != null) {
245-
libraryBuilder.addProblem(errorMessage, typeBuilder.charOffset!,
246-
noLength, typeBuilder.fileUri,
247-
context: errorContext);
248-
errorMessage = null;
249-
}
250270
}
251271

252272
if (interface is ExtensionType) {
253273
if (interface.nullability == Nullability.nullable) {
254-
errorMessage = templateSuperExtensionTypeIsNullableAliased
274+
Message? errorMessage = templateSuperExtensionTypeIsNullableAliased
255275
.withArguments(typeBuilder.fullNameForErrors, interface);
276+
List<LocatedMessage>? errorContext;
256277
if (aliasBuilder != null) {
257278
errorContext = [
258279
messageTypedefCause.withLocation(
259280
aliasBuilder.fileUri, aliasBuilder.fileOffset, noLength),
260281
];
261282
}
283+
libraryBuilder.addProblem(errorMessage, typeBuilder.charOffset!,
284+
noLength, typeBuilder.fileUri,
285+
context: errorContext);
262286
} else {
263287
extensionTypeDeclaration.implements.add(interface);
264288
}
265289
} else if (interface is InterfaceType) {
266290
if (interface.isPotentiallyNullable) {
291+
Message? errorMessage;
292+
List<LocatedMessage>? errorContext;
267293
if (typeBuilder.nullabilityBuilder.isNullable) {
268294
errorMessage = templateNullableInterfaceError
269295
.withArguments(typeBuilder.fullNameForErrors);
@@ -277,37 +303,29 @@ class SourceExtensionTypeDeclarationBuilder
277303
];
278304
}
279305
}
306+
libraryBuilder.addProblem(errorMessage, typeBuilder.charOffset!,
307+
noLength, typeBuilder.fileUri,
308+
context: errorContext);
280309
} else {
281-
Class cls = interface.classNode;
282-
if (LibraryBuilder.isFunction(cls, coreLibrary) ||
283-
LibraryBuilder.isRecord(cls, coreLibrary)) {
284-
if (aliasBuilder != null) {
285-
// Coverage-ignore-block(suite): Not run.
286-
errorMessage = templateSuperExtensionTypeIsIllegalAliased
287-
.withArguments(typeBuilder.fullNameForErrors, interface);
288-
errorContext = [
289-
messageTypedefCause.withLocation(
290-
aliasBuilder.fileUri, aliasBuilder.fileOffset, noLength),
291-
];
292-
} else {
293-
errorMessage = templateSuperExtensionTypeIsIllegal
294-
.withArguments(typeBuilder.fullNameForErrors);
295-
}
296-
} else {
297-
extensionTypeDeclaration.implements.add(interface);
298-
}
310+
extensionTypeDeclaration.implements.add(interface);
299311
}
300312
} else if (interface is TypeParameterType) {
301-
errorMessage = templateSuperExtensionTypeIsTypeParameter
313+
Message? errorMessage = templateSuperExtensionTypeIsTypeParameter
302314
.withArguments(typeBuilder.fullNameForErrors);
315+
List<LocatedMessage>? errorContext;
303316
if (aliasBuilder != null) {
304317
// Coverage-ignore-block(suite): Not run.
305318
errorContext = [
306319
messageTypedefCause.withLocation(
307320
aliasBuilder.fileUri, aliasBuilder.fileOffset, noLength),
308321
];
309322
}
323+
libraryBuilder.addProblem(errorMessage, typeBuilder.charOffset!,
324+
noLength, typeBuilder.fileUri,
325+
context: errorContext);
310326
} else {
327+
Message? errorMessage;
328+
List<LocatedMessage>? errorContext;
311329
if (aliasBuilder != null) {
312330
errorMessage = templateSuperExtensionTypeIsIllegalAliased
313331
.withArguments(typeBuilder.fullNameForErrors, interface);
@@ -319,8 +337,6 @@ class SourceExtensionTypeDeclarationBuilder
319337
errorMessage = templateSuperExtensionTypeIsIllegal
320338
.withArguments(typeBuilder.fullNameForErrors);
321339
}
322-
}
323-
if (errorMessage != null) {
324340
libraryBuilder.addProblem(errorMessage, typeBuilder.charOffset!,
325341
noLength, typeBuilder.fileUri,
326342
context: errorContext);

pkg/front_end/test/coverage_suite_expected.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -860,7 +860,7 @@ const Map<String, ({int hitCount, int missCount})> _expect = {
860860
),
861861
// 100.0%.
862862
"package:front_end/src/source/source_class_builder.dart": (
863-
hitCount: 1397,
863+
hitCount: 1402,
864864
missCount: 0,
865865
),
866866
// 100.0%.
@@ -886,7 +886,7 @@ const Map<String, ({int hitCount, int missCount})> _expect = {
886886
// 100.0%.
887887
"package:front_end/src/source/source_extension_type_declaration_builder.dart":
888888
(
889-
hitCount: 495,
889+
hitCount: 511,
890890
missCount: 0,
891891
),
892892
// 100.0%.

0 commit comments

Comments
 (0)