[cfe] Fixes to part with parts
Before this CL we could both crash and add wrong metadata to "part"
nodes when a part defined other parts.
This CL fixes it by
a) Not resetting a counter so *every* part in a part will be out of
bounds when trying to reference it; and
b) Check if a part directive is in bounds and ignore it if it isn't
(an error should already have been issued).
Change-Id: I3d31f2577b2120df6461c9cc1002131dbee9dbbc
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/106641
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
diff --git a/pkg/front_end/lib/src/fasta/source/diet_listener.dart b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
index cf3c27f..c556487 100644
--- a/pkg/front_end/lib/src/fasta/source/diet_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
@@ -496,8 +496,14 @@
Token metadata = pop();
Library libraryNode = library.target;
- LibraryPart part = libraryNode.parts[partDirectiveIndex++];
- parseMetadata(library, metadata, part);
+ if (libraryNode.parts.length > partDirectiveIndex) {
+ // If partDirectiveIndex >= libraryNode.parts.length we are in a case of
+ // on part having other parts. An error has already been issued.
+ // Don't try to parse metadata into other parts that have nothing to do
+ // with the one this keyword is talking about.
+ LibraryPart part = libraryNode.parts[partDirectiveIndex++];
+ parseMetadata(library, metadata, part);
+ }
}
@override
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index c420708..3040e27 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -289,7 +289,6 @@
Token tokens = await tokenize(part);
if (tokens != null) {
listener.uri = part.fileUri;
- listener.partDirectiveIndex = 0;
parser.parseUnit(tokens);
}
}
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index 65cb2ec..7e5143d 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -2,9 +2,6 @@
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE.md file.
-# Not sorted --- these crashes should be fixed ASAP!
-PartTwice/part_wrapped_script: Crash
-
AbstractClassInstantiation/example: Fail
AbstractClassMember/part_wrapped_script5: Fail
AbstractClassMember/part_wrapped_script6: Fail
@@ -413,6 +410,7 @@
PartOfUseUri/example: Fail
PartOrphan/analyzerCode: Fail # Analyzer can't handle this situation
PartOrphan/part_wrapped_script: Fail # Already using 'part of' in the (now) part.
+PartTwice/part_wrapped_script: Fail # Using 'part' in the (now) part.
PatchClassTypeVariablesMismatch/analyzerCode: Fail
PatchClassTypeVariablesMismatch/example: Fail
PatchDeclarationMismatch/analyzerCode: Fail
diff --git a/pkg/front_end/testcases/having_part_with_part_and_annotation.dart.legacy.expect b/pkg/front_end/testcases/having_part_with_part_and_annotation.dart.legacy.expect
index 176c13c..929cc78 100644
--- a/pkg/front_end/testcases/having_part_with_part_and_annotation.dart.legacy.expect
+++ b/pkg/front_end/testcases/having_part_with_part_and_annotation.dart.legacy.expect
@@ -12,7 +12,6 @@
import "dart:core" as core;
@self::Foo
-@self::Bar
part having_part_with_part_and_annotation_lib1.dart;
static const field core::int Foo = 42;
static const field core::int Bar = 43 /* from org-dartlang-testcase:///having_part_with_part_and_annotation_lib1.dart */;
diff --git a/pkg/front_end/testcases/having_part_with_part_and_annotation.dart.legacy.transformed.expect b/pkg/front_end/testcases/having_part_with_part_and_annotation.dart.legacy.transformed.expect
index 176c13c..929cc78 100644
--- a/pkg/front_end/testcases/having_part_with_part_and_annotation.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/having_part_with_part_and_annotation.dart.legacy.transformed.expect
@@ -12,7 +12,6 @@
import "dart:core" as core;
@self::Foo
-@self::Bar
part having_part_with_part_and_annotation_lib1.dart;
static const field core::int Foo = 42;
static const field core::int Bar = 43 /* from org-dartlang-testcase:///having_part_with_part_and_annotation_lib1.dart */;
diff --git a/pkg/front_end/testcases/having_part_with_part_and_annotation.dart.strong.expect b/pkg/front_end/testcases/having_part_with_part_and_annotation.dart.strong.expect
index 176c13c..929cc78 100644
--- a/pkg/front_end/testcases/having_part_with_part_and_annotation.dart.strong.expect
+++ b/pkg/front_end/testcases/having_part_with_part_and_annotation.dart.strong.expect
@@ -12,7 +12,6 @@
import "dart:core" as core;
@self::Foo
-@self::Bar
part having_part_with_part_and_annotation_lib1.dart;
static const field core::int Foo = 42;
static const field core::int Bar = 43 /* from org-dartlang-testcase:///having_part_with_part_and_annotation_lib1.dart */;
diff --git a/pkg/front_end/testcases/having_part_with_part_and_annotation.dart.strong.transformed.expect b/pkg/front_end/testcases/having_part_with_part_and_annotation.dart.strong.transformed.expect
index 176c13c..929cc78 100644
--- a/pkg/front_end/testcases/having_part_with_part_and_annotation.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/having_part_with_part_and_annotation.dart.strong.transformed.expect
@@ -12,7 +12,6 @@
import "dart:core" as core;
@self::Foo
-@self::Bar
part having_part_with_part_and_annotation_lib1.dart;
static const field core::int Foo = 42;
static const field core::int Bar = 43 /* from org-dartlang-testcase:///having_part_with_part_and_annotation_lib1.dart */;
diff --git a/pkg/front_end/testcases/having_part_with_parts_and_annotation.dart.legacy.expect b/pkg/front_end/testcases/having_part_with_parts_and_annotation.dart.legacy.expect
new file mode 100644
index 0000000..a33aba1
--- /dev/null
+++ b/pkg/front_end/testcases/having_part_with_parts_and_annotation.dart.legacy.expect
@@ -0,0 +1,27 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/having_part_with_parts_and_annotation_lib1.dart:4:6: Error: A file that's a part of a library can't have parts itself.
+// Try moving the 'part' declaration to the containing library.
+// part 'having_part_with_parts_and_annotation_lib2.dart';
+// ^
+// pkg/front_end/testcases/having_part_with_parts_and_annotation.dart: Context: This is the containing library.
+//
+// pkg/front_end/testcases/having_part_with_parts_and_annotation_lib1.dart:6:6: Error: A file that's a part of a library can't have parts itself.
+// Try moving the 'part' declaration to the containing library.
+// part 'having_part_with_parts_and_annotation_lib2.dart';
+// ^
+// pkg/front_end/testcases/having_part_with_parts_and_annotation.dart: Context: This is the containing library.
+//
+import self as self;
+import "dart:core" as core;
+
+@self::Foo
+part having_part_with_parts_and_annotation_lib1.dart;
+static const field core::int Foo = 42;
+static const field core::int Bar = 43 /* from org-dartlang-testcase:///having_part_with_parts_and_annotation_lib1.dart */;
+static const field core::int Baz = 44 /* from org-dartlang-testcase:///having_part_with_parts_and_annotation_lib1.dart */;
+static method fromMain() → void {}
+static method main() → dynamic {}
+static method /* from org-dartlang-testcase:///having_part_with_parts_and_annotation_lib1.dart */ fromLib1() → void {}
diff --git a/pkg/front_end/testcases/having_part_with_parts_and_annotation.dart.legacy.transformed.expect b/pkg/front_end/testcases/having_part_with_parts_and_annotation.dart.legacy.transformed.expect
new file mode 100644
index 0000000..a33aba1
--- /dev/null
+++ b/pkg/front_end/testcases/having_part_with_parts_and_annotation.dart.legacy.transformed.expect
@@ -0,0 +1,27 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/having_part_with_parts_and_annotation_lib1.dart:4:6: Error: A file that's a part of a library can't have parts itself.
+// Try moving the 'part' declaration to the containing library.
+// part 'having_part_with_parts_and_annotation_lib2.dart';
+// ^
+// pkg/front_end/testcases/having_part_with_parts_and_annotation.dart: Context: This is the containing library.
+//
+// pkg/front_end/testcases/having_part_with_parts_and_annotation_lib1.dart:6:6: Error: A file that's a part of a library can't have parts itself.
+// Try moving the 'part' declaration to the containing library.
+// part 'having_part_with_parts_and_annotation_lib2.dart';
+// ^
+// pkg/front_end/testcases/having_part_with_parts_and_annotation.dart: Context: This is the containing library.
+//
+import self as self;
+import "dart:core" as core;
+
+@self::Foo
+part having_part_with_parts_and_annotation_lib1.dart;
+static const field core::int Foo = 42;
+static const field core::int Bar = 43 /* from org-dartlang-testcase:///having_part_with_parts_and_annotation_lib1.dart */;
+static const field core::int Baz = 44 /* from org-dartlang-testcase:///having_part_with_parts_and_annotation_lib1.dart */;
+static method fromMain() → void {}
+static method main() → dynamic {}
+static method /* from org-dartlang-testcase:///having_part_with_parts_and_annotation_lib1.dart */ fromLib1() → void {}
diff --git a/pkg/front_end/testcases/having_part_with_parts_and_annotation.dart.strong.expect b/pkg/front_end/testcases/having_part_with_parts_and_annotation.dart.strong.expect
new file mode 100644
index 0000000..a33aba1
--- /dev/null
+++ b/pkg/front_end/testcases/having_part_with_parts_and_annotation.dart.strong.expect
@@ -0,0 +1,27 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/having_part_with_parts_and_annotation_lib1.dart:4:6: Error: A file that's a part of a library can't have parts itself.
+// Try moving the 'part' declaration to the containing library.
+// part 'having_part_with_parts_and_annotation_lib2.dart';
+// ^
+// pkg/front_end/testcases/having_part_with_parts_and_annotation.dart: Context: This is the containing library.
+//
+// pkg/front_end/testcases/having_part_with_parts_and_annotation_lib1.dart:6:6: Error: A file that's a part of a library can't have parts itself.
+// Try moving the 'part' declaration to the containing library.
+// part 'having_part_with_parts_and_annotation_lib2.dart';
+// ^
+// pkg/front_end/testcases/having_part_with_parts_and_annotation.dart: Context: This is the containing library.
+//
+import self as self;
+import "dart:core" as core;
+
+@self::Foo
+part having_part_with_parts_and_annotation_lib1.dart;
+static const field core::int Foo = 42;
+static const field core::int Bar = 43 /* from org-dartlang-testcase:///having_part_with_parts_and_annotation_lib1.dart */;
+static const field core::int Baz = 44 /* from org-dartlang-testcase:///having_part_with_parts_and_annotation_lib1.dart */;
+static method fromMain() → void {}
+static method main() → dynamic {}
+static method /* from org-dartlang-testcase:///having_part_with_parts_and_annotation_lib1.dart */ fromLib1() → void {}
diff --git a/pkg/front_end/testcases/having_part_with_parts_and_annotation.dart.strong.transformed.expect b/pkg/front_end/testcases/having_part_with_parts_and_annotation.dart.strong.transformed.expect
new file mode 100644
index 0000000..a33aba1
--- /dev/null
+++ b/pkg/front_end/testcases/having_part_with_parts_and_annotation.dart.strong.transformed.expect
@@ -0,0 +1,27 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/having_part_with_parts_and_annotation_lib1.dart:4:6: Error: A file that's a part of a library can't have parts itself.
+// Try moving the 'part' declaration to the containing library.
+// part 'having_part_with_parts_and_annotation_lib2.dart';
+// ^
+// pkg/front_end/testcases/having_part_with_parts_and_annotation.dart: Context: This is the containing library.
+//
+// pkg/front_end/testcases/having_part_with_parts_and_annotation_lib1.dart:6:6: Error: A file that's a part of a library can't have parts itself.
+// Try moving the 'part' declaration to the containing library.
+// part 'having_part_with_parts_and_annotation_lib2.dart';
+// ^
+// pkg/front_end/testcases/having_part_with_parts_and_annotation.dart: Context: This is the containing library.
+//
+import self as self;
+import "dart:core" as core;
+
+@self::Foo
+part having_part_with_parts_and_annotation_lib1.dart;
+static const field core::int Foo = 42;
+static const field core::int Bar = 43 /* from org-dartlang-testcase:///having_part_with_parts_and_annotation_lib1.dart */;
+static const field core::int Baz = 44 /* from org-dartlang-testcase:///having_part_with_parts_and_annotation_lib1.dart */;
+static method fromMain() → void {}
+static method main() → dynamic {}
+static method /* from org-dartlang-testcase:///having_part_with_parts_and_annotation_lib1.dart */ fromLib1() → void {}
diff --git a/pkg/front_end/testcases/legacy.status b/pkg/front_end/testcases/legacy.status
index 2a0d665..b1b1917 100644
--- a/pkg/front_end/testcases/legacy.status
+++ b/pkg/front_end/testcases/legacy.status
@@ -16,7 +16,6 @@
external_import: RuntimeError # Expected -- test uses import which doesn't exist.
fallthrough: Fail # Missing FallThroughError.
function_type_recovery: Fail
-having_part_with_parts_and_annotation: Crash
incomplete_field_formal_parameter: Fail # Fasta doesn't recover well
inference/bug31436: RuntimeError # Test exercises Dart 2.0 semantics
inference/constructors_too_many_positional_arguments: Fail
diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status
index 44b9c0b..79ac736 100644
--- a/pkg/front_end/testcases/strong.status
+++ b/pkg/front_end/testcases/strong.status
@@ -24,7 +24,6 @@
expressions: RuntimeError
external_import: RuntimeError # The native extension to import doesn't exist. This is ok.
fallthrough: ExpectationFileMismatch
-having_part_with_parts_and_annotation: Crash
incomplete_field_formal_parameter: RuntimeError
inference/abstract_class_instantiation: InstrumentationMismatch # Issue #30040
inference/conflicting_fields: TypeCheckError
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index b43ed5f..8508fee 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -105,7 +105,7 @@
future_or_test: TextSerializationFailure # Was: Pass
hello: TextSerializationFailure # Was: Pass
having_part_with_part_and_annotation: TextSerializationFailure
-having_part_with_parts_and_annotation: Crash
+having_part_with_parts_and_annotation: TextSerializationFailure
illegal_named_function_expression: TextSerializationFailure # Was: Pass
illegal_named_function_expression_scope: TextSerializationFailure # Was: Pass
implicit_const_with_static_fields: TextSerializationFailure # Was: Pass