Skip to content

Commit

Permalink
[cfe] Check name conflicts using fragments
Browse files Browse the repository at this point in the history
Change-Id: I7ffe54bdce190de5b31303fd794947aba3d3b1c3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/393102
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
  • Loading branch information
johnniwinther authored and Commit Queue committed Nov 1, 2024
1 parent 5e6a681 commit e25adcf
Show file tree
Hide file tree
Showing 19 changed files with 378 additions and 134 deletions.
2 changes: 2 additions & 0 deletions pkg/front_end/lib/src/fragment/extension.dart
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ class ExtensionFragment extends DeclarationFragment implements Fragment {
? new FixedExtensionName(name)
: new UnnamedExtensionName();

bool get isUnnamed => extensionName.isUnnamedExtension;

@override
SourceExtensionBuilder get builder {
assert(_builder != null, "Builder has not been computed for $this.");
Expand Down
13 changes: 13 additions & 0 deletions pkg/front_end/lib/src/fragment/field.dart
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,19 @@ class FieldFragment implements Fragment {
: _initializerToken = initializerToken,
_constInitializerToken = constInitializerToken;

// Coverage-ignore(suite): Not run.
bool get hasSetter {
if (modifiers.isFinal) {
if (modifiers.isLate) {
return !modifiers.hasInitializer;
} else {
return false;
}
} else {
return true;
}
}

Token? get initializerToken {
Token? result = _initializerToken;
// Ensure that we don't hold onto the token.
Expand Down
16 changes: 13 additions & 3 deletions pkg/front_end/lib/src/fragment/util.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,23 @@ class ConstructorName {
final int? nameOffset;

/// The name of the constructor including the enclosing declaration name.
///
/// For unnamed constructors the full name is normalized to be the class name,
/// regardless of whether the constructor was declared with 'new'.
///
/// For invalid constructor names, the full name is normalized to use the
/// class name as prefix, regardless of whether the declaration did so.
///
/// This means that not in all cases is the text pointed to by
/// [fullNameOffset] and [fullNameLength] the same as the [fullName].
final String fullName;

/// The offset at which [fullName] occurs.
/// The offset at which the full name occurs.
///
/// This is used in messages to put the `^` at the start of the [fullName].
final int fullNameOffset;

/// The number of characters of [fullName] that occurs at [fullNameOffset].
/// The number of characters of full name that occurs at [fullNameOffset].
///
/// This is used in messages to put the right amount of `^` under the name.
final int fullNameLength;
Expand All @@ -32,5 +41,6 @@ class ConstructorName {
required this.nameOffset,
required this.fullName,
required this.fullNameOffset,
required this.fullNameLength});
required this.fullNameLength})
: assert(name != 'new');
}
22 changes: 15 additions & 7 deletions pkg/front_end/lib/src/source/source_builder_factory.dart
Original file line number Diff line number Diff line change
Expand Up @@ -1871,13 +1871,20 @@ class BuilderFactoryImpl implements BuilderFactory, BuilderFactoryResult {
suffix = identifier.name;
suffixOffset = identifier.nameOffset;
charOffset = qualifier.nameOffset;
fullName = '${prefix}.${suffix}';
String prefixAndSuffix = '${prefix}.${suffix}';
fullNameOffset = qualifier.nameOffset;
// If the there is no space between the prefix and suffix we use the full
// length as the name length. Otherwise the full name has no length.
fullNameLength = fullNameOffset + prefix.length + 1 == suffixOffset
? fullName.length
? prefixAndSuffix.length
: noLength;
if (suffix == "new") {
// Normalize `Class.new` to `Class`.
suffix = '';
fullName = className;
} else {
fullName = '$className.$suffix';
}
} else {
prefix = identifier.name;
suffix = null;
Expand All @@ -1887,16 +1894,17 @@ class BuilderFactoryImpl implements BuilderFactory, BuilderFactoryResult {
fullNameOffset = identifier.nameOffset;
fullNameLength = prefix.length;
}
if (libraryFeatures.constructorTearoffs.isEnabled) {
suffix = suffix == "new" ? "" : suffix;
}

if (prefix == className) {
return new ConstructorName(
name: suffix ?? '',
nameOffset: suffixOffset,
fullName: fullName,
fullNameOffset: fullNameOffset,
fullNameLength: fullNameLength);
} else if (suffix == null) {
// Normalize `foo` in `Class` to `Class.foo`.
fullName = '$className.$prefix';
}
if (suffix == null && !isFactory) {
// This method is called because the syntax indicated that this is a
Expand All @@ -1921,9 +1929,9 @@ class BuilderFactoryImpl implements BuilderFactory, BuilderFactoryResult {
return new ConstructorName(
name: suffix ?? prefix,
nameOffset: suffixOffset,
fullName: suffix ?? prefix,
fullName: fullName,
fullNameOffset: fullNameOffset,
fullNameLength: noLength);
fullNameLength: fullNameLength);
}

void _addNativeGetterFragment(GetterFragment fragment) {
Expand Down
10 changes: 2 additions & 8 deletions pkg/front_end/lib/src/source/source_field_builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -154,14 +154,8 @@ class SourceFieldBuilder extends SourceMemberBuilderImpl
assert(lateIsSetSetterReference == null);
assert(lateGetterReference == null);
assert(lateSetterReference == null);
_fieldEncoding = new RepresentationFieldEncoding(
this,
name,
nameScheme,
fileUri,
nameOffset,
endOffset,
fieldGetterReference);
_fieldEncoding = new RepresentationFieldEncoding(this, name, nameScheme,
fileUri, nameOffset, endOffset, fieldGetterReference);
} else if (isLate &&
libraryBuilder.loader.target.backendTarget.isLateFieldLoweringEnabled(
hasInitializer: hasInitializer,
Expand Down
Loading

0 comments on commit e25adcf

Please sign in to comment.