Version 2.19.0-18.0.dev
Merge commit '210af2940f89ffc3ddf8c929cb2f0e8dbd8fd399' into 'dev'
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 02ba848..d26be9c 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,7 +4,7 @@
### Libraries
-### `dart:developer`
+#### `dart:developer`
#### `dart:developer`
@@ -19,6 +19,16 @@
- Deprecated `UserTag.MAX_USER_TAGS` in favor of `UserTag.maxUserTags`.
+#### `dart:mirrors`
+
+- **Breaking change** [#34233][]: The APIs [`MirrorsUsed`][] and [`Comment`][]
+ have been removed. `MirrorsUsed` was experimental and deprecated; `Comment`
+ was previously used internally in dart2js. Both are no longer functional.
+
+[#34233]: https://github.com/dart-lang/sdk/issues/34233
+[`MirrorsUsed`]: https://api.dart.dev/stable/dart-mirrors/MirrorsUsed-class.html
+[`Comment`]: https://api.dart.dev/stable/dart-mirrors/Comment-class.html
+
### Tools
#### Linter
diff --git a/pkg/analysis_server/lib/src/services/correction/organize_imports.dart b/pkg/analysis_server/lib/src/services/correction/organize_imports.dart
index 30ace8f..8206e04 100644
--- a/pkg/analysis_server/lib/src/services/correction/organize_imports.dart
+++ b/pkg/analysis_server/lib/src/services/correction/organize_imports.dart
@@ -72,24 +72,25 @@
var lineInfo = unit.lineInfo;
var hasLibraryDirective = false;
var directives = <_DirectiveInfo>[];
- // Track the end offset of any library-level comment/annotations that should
- // remain at the top of the file regardless of whether it was attached to a
- // directive that's moved/removed.
- // Code up to this offset will be excluded from the comment/docs/annotation
- // text for the computed DirectiveInfo and also its range for replacement
- // in the document.
- int? libraryDocsAndAnnotationsEndOffset;
for (var directive in unit.directives) {
if (directive is LibraryDirective) {
hasLibraryDirective = true;
}
if (directive is UriBasedDirective) {
+ // Track the end offset of any library-level comment/annotations that should
+ // remain at the top of the file regardless of whether it was attached to a
+ // directive that's moved/removed.
+ // Code up to this offset will be excluded from the comment/docs/annotation
+ // text for the computed DirectiveInfo and also its range for replacement
+ // in the document.
+ int? libraryDocsAndAnnotationsEndOffset;
var priority = _getDirectivePriority(directive);
if (priority != null) {
var offset = directive.offset;
var end = directive.end;
- final isPseudoLibraryDirective = directive == unit.directives.first;
+ final isPseudoLibraryDirective =
+ !hasLibraryDirective && directive == unit.directives.first;
Annotation? lastLibraryAnnotation;
if (isPseudoLibraryDirective) {
// Find the last library-level annotation that does not come
@@ -99,10 +100,17 @@
lastLibraryAnnotation = directive.metadata
.takeWhile(_isLibraryTargetAnnotation)
.lastOrNull;
- if (lastLibraryAnnotation != null) {
- libraryDocsAndAnnotationsEndOffset =
- lineInfo.getOffsetOfLineAfter(lastLibraryAnnotation.end);
- // In the case of a blank line after the last library annotation
+
+ // If there is no annotation, use the end of the doc text (since the
+ // doc text is considered library-level here).
+ libraryDocsAndAnnotationsEndOffset = lastLibraryAnnotation?.end ??
+ directive.documentationComment?.end;
+
+ // Fix up the offset to be after the line end.
+ if (libraryDocsAndAnnotationsEndOffset != null) {
+ libraryDocsAndAnnotationsEndOffset = lineInfo
+ .getOffsetOfLineAfter(libraryDocsAndAnnotationsEndOffset);
+ // In the case of a blank line after the annotation/doc text
// we should include that in the library part. Otherwise it will
// be included in the top of the following directive and may
// result in an extra blank line in the annotation block if it
@@ -124,84 +132,25 @@
final leadingToken =
lastLibraryAnnotation == null ? directive.beginToken : null;
final leadingComment = leadingToken != null
- ? getLeadingComment(unit, leadingToken, lineInfo)
+ ? getLeadingComment(unit, leadingToken, lineInfo,
+ isPseudoLibraryDirective: isPseudoLibraryDirective)
: null;
final trailingComment = getTrailingComment(unit, directive, lineInfo);
- /// Computes the offset to use for the start of directive-specific
- /// code below taking into account code already included by
- /// [libraryDocsAndAnnotationsEndOffset].
- final clampedOffset = libraryDocsAndAnnotationsEndOffset == null
- ? (int offset) => offset
- : (int offset) =>
- math.max(libraryDocsAndAnnotationsEndOffset!, offset);
-
- String? leadingCommentText;
if (leadingComment != null && leadingToken != null) {
- offset = clampedOffset(leadingComment.offset);
- leadingCommentText = code.substring(
- offset,
- clampedOffset(leadingToken.offset),
- );
+ offset = libraryDocsAndAnnotationsEndOffset != null
+ ? math.max(
+ libraryDocsAndAnnotationsEndOffset, leadingComment.offset)
+ : leadingComment.offset;
}
- String? trailingCommentText;
if (trailingComment != null) {
- trailingCommentText =
- code.substring(directive.end, trailingComment.end);
end = trailingComment.end;
}
- String? documentationText;
- var documentationComment = directive.documentationComment;
- if (documentationComment != null) {
- documentationText = code.substring(
- clampedOffset(documentationComment.offset),
- clampedOffset(documentationComment.end),
- );
- }
- String? annotationText;
- String? postAnnotationCommentText;
- var beginToken = directive.metadata.beginToken;
- var endToken = directive.metadata.endToken;
- if (beginToken != null && endToken != null) {
- var annotationOffset = clampedOffset(beginToken.offset);
- var annotationEnd = clampedOffset(endToken.end);
- if (annotationOffset != annotationEnd) {
- annotationText = code.substring(
- annotationOffset,
- annotationEnd,
- );
- }
- // Capture text between the end of the annotation and the directive
- // text as there may be end-of line or line comments between.
- // If not, this will capture the newline between the two, as it
- // cannot be assumed there is a newline after annotationText because
- // of the possibility of comments.
- if (annotationEnd <
- directive.firstTokenAfterCommentAndMetadata.offset) {
- postAnnotationCommentText = code.substring(annotationEnd,
- directive.firstTokenAfterCommentAndMetadata.offset);
- }
- }
- var text = code.substring(
- directive.firstTokenAfterCommentAndMetadata.offset,
- directive.end);
- var uriContent = directive.uri.stringValue ?? '';
+ offset = libraryDocsAndAnnotationsEndOffset ?? offset;
+ final text = code.substring(offset, end);
+ final uriContent = directive.uri.stringValue ?? '';
directives.add(
- _DirectiveInfo(
- directive,
- priority,
- leadingCommentText,
- documentationText,
- annotationText,
- postAnnotationCommentText,
- uriContent,
- trailingCommentText,
- isPseudoLibraryDirective
- ? (libraryDocsAndAnnotationsEndOffset ?? offset)
- : offset,
- end,
- text,
- ),
+ _DirectiveInfo(directive, priority, uriContent, offset, end, text),
);
}
}
@@ -213,24 +162,12 @@
var firstDirectiveOffset = directives.first.offset;
var lastDirectiveEnd = directives.last.end;
- // Without a library directive, the library comment is the comment of the
- // first directive.
- _DirectiveInfo? libraryDocumentationDirective;
- if (!hasLibraryDirective && directives.isNotEmpty) {
- libraryDocumentationDirective = directives.first;
- }
-
// sort
directives.sort();
// append directives with grouping
String directivesCode;
{
var sb = StringBuffer();
- if (libraryDocumentationDirective != null &&
- libraryDocumentationDirective.documentationText != null) {
- sb.write(libraryDocumentationDirective.documentationText);
- sb.write(endOfLine);
- }
_DirectivePriority? currentPriority;
for (var directiveInfo in directives) {
if (!hasUnresolvedIdentifierError) {
@@ -245,24 +182,7 @@
}
currentPriority = directiveInfo.priority;
}
- if (directiveInfo.leadingCommentText != null) {
- sb.write(directiveInfo.leadingCommentText);
- }
- if (directiveInfo != libraryDocumentationDirective &&
- directiveInfo.documentationText != null) {
- sb.write(directiveInfo.documentationText);
- sb.write(endOfLine);
- }
- if (directiveInfo.annotationText != null) {
- sb.write(directiveInfo.annotationText);
- }
- if (directiveInfo.postAnnotationCommentText != null) {
- sb.write(directiveInfo.postAnnotationCommentText);
- }
sb.write(directiveInfo.text);
- if (directiveInfo.trailingCommentText != null) {
- sb.write(directiveInfo.trailingCommentText);
- }
sb.write(endOfLine);
}
directivesCode = sb.toString();
@@ -286,14 +206,16 @@
/// Gets the first comment token considered to be the leading comment for this
/// token.
///
- /// Leading comments for the first directive in a file are considered library
- /// comments and not returned unless they contain blank lines, in which case
- /// only the last part of the comment will be returned (unless it is a
- /// language directive comment, in which case it will also be skipped) or an
- /// '// ignore:' comment which should always be treated as attached to the
- /// import.
+ /// Leading comments for the first directive in a file with no library
+ /// directive (indicated with [isPseudoLibraryDirective]) are considered
+ /// library comments and not included unless they contain blank lines, in
+ /// which case only the last part of the comment will be returned (unless it
+ /// is a language directive comment, in which case it will also be skipped),
+ /// or an '// ignore:' comment which should always be treated as attached to
+ /// the import.
static Token? getLeadingComment(
- CompilationUnit unit, Token beginToken, LineInfo lineInfo) {
+ CompilationUnit unit, Token beginToken, LineInfo lineInfo,
+ {required bool isPseudoLibraryDirective}) {
if (beginToken.precedingComments == null) {
return null;
}
@@ -301,8 +223,9 @@
Token? firstComment = beginToken.precedingComments;
var comment = firstComment;
var nextComment = comment?.next;
- // Don't connect comments that have a blank line between them
- while (comment != null && nextComment != null) {
+ // Don't connect comments that have a blank line between them if this is
+ // a psuedo-library directive.
+ while (isPseudoLibraryDirective && comment != null && nextComment != null) {
var currentLine = lineInfo.getLocation(comment.offset).lineNumber;
var nextLine = lineInfo.getLocation(nextComment.offset).lineNumber;
if (nextLine - currentLine > 1) {
@@ -400,12 +323,7 @@
class _DirectiveInfo implements Comparable<_DirectiveInfo> {
final UriBasedDirective directive;
final _DirectivePriority priority;
- final String? leadingCommentText;
- final String? documentationText;
- final String? annotationText;
- final String? postAnnotationCommentText;
final String uri;
- final String? trailingCommentText;
/// The offset of the first token, usually the keyword but may include leading comments.
final int offset;
@@ -419,12 +337,7 @@
_DirectiveInfo(
this.directive,
this.priority,
- this.leadingCommentText,
- this.documentationText,
- this.annotationText,
- this.postAnnotationCommentText,
this.uri,
- this.trailingCommentText,
this.offset,
this.end,
this.text,
diff --git a/pkg/analysis_server/test/abstract_single_unit.dart b/pkg/analysis_server/test/abstract_single_unit.dart
index 0177328..5a0daa7 100644
--- a/pkg/analysis_server/test/abstract_single_unit.dart
+++ b/pkg/analysis_server/test/abstract_single_unit.dart
@@ -32,16 +32,12 @@
@override
void addSource(String path, String content) {
- if (useLineEndingsForPlatform) {
- content = normalizeNewlinesForPlatform(content);
- }
+ content = normalizeSource(content);
super.addSource(path, content);
}
void addTestSource(String code) {
- if (useLineEndingsForPlatform) {
- code = normalizeNewlinesForPlatform(code);
- }
+ code = normalizeSource(code);
testCode = code;
addSource(testFile, code);
}
@@ -58,12 +54,15 @@
@override
File newFile(String path, String content) {
- if (useLineEndingsForPlatform) {
- content = normalizeNewlinesForPlatform(content);
- }
+ content = normalizeSource(content);
return super.newFile(path, content);
}
+ /// Convenient function to normalize newlines in [code] for the current
+ /// platform if [useLineEndingsForPlatform] is `true`.
+ String normalizeSource(String code) =>
+ useLineEndingsForPlatform ? normalizeNewlinesForPlatform(code) : code;
+
Future<void> resolveFile2(String path) async {
var result =
await (await session).getResolvedUnit(path) as ResolvedUnitResult;
diff --git a/pkg/analysis_server/test/services/correction/organize_directives_test.dart b/pkg/analysis_server/test/services/correction/organize_directives_test.dart
index 686b25d..3d59aee 100644
--- a/pkg/analysis_server/test/services/correction/organize_directives_test.dart
+++ b/pkg/analysis_server/test/services/correction/organize_directives_test.dart
@@ -561,19 +561,25 @@
''');
}
- Future<void>
- test_sort_imports_dontConnectFirstCommentsWithBlankLinesBetween() async {
+ Future<void> test_sort_imports_blankLinesInImportComments() async {
+ // Only the blank line in the first import is treated specially and split.
await _computeUnitAndErrors(r'''
-// Copyright...
+// Import 1 comment 1
-// Some comment related to the line below
+// Import 1 comment 2
import 'package:b/a.dart';
+// Import 2 comment 1
+
+// Import 2 comment 2
import 'package:a/b.dart';''');
_assertOrganize(r'''
-// Copyright...
+// Import 1 comment 1
+// Import 2 comment 1
+
+// Import 2 comment 2
import 'package:a/b.dart';
-// Some comment related to the line below
+// Import 1 comment 2
import 'package:b/a.dart';''');
}
@@ -658,7 +664,8 @@
''');
}
- Future<void> test_sort_imports_with_library_keepPrecedingComments() async {
+ Future<void>
+ test_sort_imports_with_library_blankLineInImportComments() async {
await _computeUnitAndErrors(r'''
/// Copyright...
library lib;
@@ -677,11 +684,11 @@
/// Copyright...
library lib;
-// Test comment
-
// Comment for a
import 'package:a/b.dart';
+// Test comment
+
// We are keeping this because ... l1
// We are keeping this because ... l2
// We are keeping this because ... l3
diff --git a/pkg/analysis_server/test/services/refactoring/abstract_refactoring.dart b/pkg/analysis_server/test/services/refactoring/abstract_refactoring.dart
index 4fa30e3..010d536 100644
--- a/pkg/analysis_server/test/services/refactoring/abstract_refactoring.dart
+++ b/pkg/analysis_server/test/services/refactoring/abstract_refactoring.dart
@@ -7,7 +7,6 @@
import 'package:analysis_server/src/services/search/search_engine.dart';
import 'package:analysis_server/src/services/search/search_engine_internal.dart';
import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/test_utilities/platform.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart'
show RefactoringProblemSeverity, SourceChange, SourceEdit;
import 'package:test/test.dart';
@@ -39,9 +38,7 @@
/// Asserts that [refactoringChange] contains a [FileEdit] for the file
/// with the given [path], and it results the [expectedCode].
void assertFileChangeResult(String path, String expectedCode) {
- if (useLineEndingsForPlatform) {
- expectedCode = normalizeNewlinesForPlatform(expectedCode);
- }
+ expectedCode = normalizeSource(expectedCode);
// prepare FileEdit
var fileEdit = refactoringChange.getFileEdit(convertPath(path));
if (fileEdit == null) {
@@ -120,9 +117,7 @@
/// Asserts that [refactoringChange] contains a [FileEdit] for [testFile], and
/// it results the [expectedCode].
void assertTestChangeResult(String expectedCode) {
- if (useLineEndingsForPlatform) {
- expectedCode = normalizeNewlinesForPlatform(expectedCode);
- }
+ expectedCode = normalizeSource(expectedCode);
// prepare FileEdit
var fileEdit = refactoringChange.getFileEdit(testFile);
if (fileEdit == null) {
diff --git a/pkg/analysis_server/test/src/services/correction/assist/assist_processor.dart b/pkg/analysis_server/test/src/services/correction/assist/assist_processor.dart
index 96a9ead..cd65f80 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/assist_processor.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/assist_processor.dart
@@ -37,9 +37,7 @@
@override
void addTestSource(String code) {
- if (useLineEndingsForPlatform) {
- code = normalizeNewlinesForPlatform(code);
- }
+ code = normalizeSource(code);
final eol = code.contains('\r\n') ? '\r\n' : '\n';
var offset = code.indexOf('/*caret*/');
if (offset >= 0) {
@@ -122,9 +120,7 @@
/// given [snippet] which produces the [expected] code when applied to [testCode].
Future<void> assertHasAssistAt(String snippet, String expected,
{int length = 0}) async {
- if (useLineEndingsForPlatform) {
- expected = normalizeNewlinesForPlatform(expected);
- }
+ expected = normalizeSource(expected);
_offset = findOffset(snippet);
_length = length;
var assist = await _assertHasAssist();
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_center_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_center_test.dart
index f8ac287..7ad2c40 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_center_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_center_test.dart
@@ -142,7 +142,10 @@
var assist = await assertHasAssist(expected);
- expect(assist.selection!.offset, expected.indexOf('child: '));
+ expect(
+ assist.selection!.offset,
+ normalizeSource(expected).indexOf('child: '),
+ );
expect(assist.selectionLength, 0);
}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_generic_test.dart b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_generic_test.dart
index 3f9c655..e6dfe49 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_generic_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/flutter_wrap_generic_test.dart
@@ -53,7 +53,7 @@
var editGroup = assist.linkedEditGroups.first;
expect(editGroup.length, 'widget'.length);
var pos = editGroup.positions.single;
- expect(pos.offset, expected.indexOf('widget('));
+ expect(pos.offset, normalizeSource(expected).indexOf('widget('));
}
Future<void> test_minimal() async {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart b/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
index c0f1f6e..111c333 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
@@ -11,7 +11,6 @@
import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/error/lint_codes.dart';
import 'package:analyzer/src/services/available_declarations.dart';
-import 'package:analyzer/src/test_utilities/platform.dart';
import 'package:analyzer_plugin/protocol/protocol_common.dart'
hide AnalysisError;
import 'package:analyzer_plugin/utilities/change_builder/change_workspace.dart';
@@ -162,9 +161,7 @@
var fileEdits = fix.change.edits;
expect(fileEdits, hasLength(1));
- if (useLineEndingsForPlatform) {
- expected = normalizeNewlinesForPlatform(expected);
- }
+ expected = normalizeSource(expected);
var fileContent = testCode;
resultCode = SourceEdit.applySequence(fileContent, fileEdits[0].edits);
@@ -256,9 +253,7 @@
int? expectedNumberOfFixesForKind,
String? matchFixMessage,
bool allowFixAllFixes = false}) async {
- if (useLineEndingsForPlatform) {
- expected = normalizeNewlinesForPlatform(expected);
- }
+ expected = normalizeSource(expected);
var error = await _findErrorToFix(
errorFilter: errorFilter,
length: length,
@@ -285,9 +280,7 @@
Future<void> assertHasFixAllFix(ErrorCode errorCode, String expected,
{String? target}) async {
- if (useLineEndingsForPlatform) {
- expected = normalizeNewlinesForPlatform(expected);
- }
+ expected = normalizeSource(expected);
var error = await _findErrorToFixOfType(errorCode);
var fix = await _assertHasFixAllFix(error);
change = fix.change;
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index 2dec46a..17ed8d6 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -1135,11 +1135,9 @@
R? visitConstructorElement(ConstructorElement element);
- @Deprecated('Override visitExportElement2() instead')
+ @Deprecated('Override visitLibraryExportElement() instead')
R? visitExportElement(ExportElement element);
- R? visitExportElement2(LibraryExportElement element);
-
R? visitExtensionElement(ExtensionElement element);
R? visitFieldElement(FieldElement element);
@@ -1150,17 +1148,19 @@
R? visitGenericFunctionTypeElement(GenericFunctionTypeElement element);
- @Deprecated('Override visitImportElement2() instead')
+ @Deprecated('Override visitLibraryImportElement() instead')
R? visitImportElement(ImportElement element);
- R? visitImportElement2(LibraryImportElement element);
-
R? visitLabelElement(LabelElement element);
R? visitLibraryAugmentationElement(LibraryAugmentationElement element);
R? visitLibraryElement(LibraryElement element);
+ R? visitLibraryExportElement(LibraryExportElement element);
+
+ R? visitLibraryImportElement(LibraryImportElement element);
+
R? visitLocalVariableElement(LocalVariableElement element);
R? visitMethodElement(MethodElement element);
diff --git a/pkg/analyzer/lib/dart/element/visitor.dart b/pkg/analyzer/lib/dart/element/visitor.dart
index 7beaa7c..2ec106e 100644
--- a/pkg/analyzer/lib/dart/element/visitor.dart
+++ b/pkg/analyzer/lib/dart/element/visitor.dart
@@ -104,14 +104,11 @@
R? visitExecutableElement(ExecutableElement element) => visitElement(element);
- @Deprecated('Override visitExportElement2() instead')
+ @Deprecated('Override visitLibraryExportElement() instead')
@override
R? visitExportElement(ExportElement element) => visitElement(element);
@override
- R? visitExportElement2(LibraryExportElement element) => visitElement(element);
-
- @override
R? visitExtensionElement(ExtensionElement element) => visitElement(element);
@override
@@ -130,14 +127,11 @@
R? visitGenericFunctionTypeElement(GenericFunctionTypeElement element) =>
visitElement(element);
- @Deprecated('Override visitImportElement2() instead')
+ @Deprecated('Override visitLibraryImportElement() instead')
@override
R? visitImportElement(ImportElement element) => visitElement(element);
@override
- R? visitImportElement2(LibraryImportElement element) => visitElement(element);
-
- @override
R? visitLabelElement(LabelElement element) => visitElement(element);
@override
@@ -147,6 +141,14 @@
@override
R? visitLibraryElement(LibraryElement element) => visitElement(element);
+ @override
+ R? visitLibraryExportElement(LibraryExportElement element) =>
+ visitElement(element);
+
+ @override
+ R? visitLibraryImportElement(LibraryImportElement element) =>
+ visitElement(element);
+
R? visitLocalElement(LocalElement element) {
if (element is LocalVariableElement) {
return visitVariableElement(element);
@@ -244,7 +246,7 @@
return null;
}
- @Deprecated('Override visitExportElement2() instead')
+ @Deprecated('Override visitLibraryExportElement() instead')
@override
R? visitExportElement(ExportElement element) {
element.visitChildren(this);
@@ -252,12 +254,6 @@
}
@override
- R? visitExportElement2(LibraryExportElement element) {
- element.visitChildren(this);
- return null;
- }
-
- @override
R? visitExtensionElement(ExtensionElement element) {
element.visitChildren(this);
return null;
@@ -287,7 +283,7 @@
return null;
}
- @Deprecated('Override visitImportElement2() instead')
+ @Deprecated('Override visitLibraryImportElement() instead')
@override
R? visitImportElement(ImportElement element) {
element.visitChildren(this);
@@ -295,12 +291,6 @@
}
@override
- R? visitImportElement2(LibraryImportElement element) {
- element.visitChildren(this);
- return null;
- }
-
- @override
R? visitLabelElement(LabelElement element) {
element.visitChildren(this);
return null;
@@ -319,6 +309,18 @@
}
@override
+ R? visitLibraryExportElement(LibraryExportElement element) {
+ element.visitChildren(this);
+ return null;
+ }
+
+ @override
+ R? visitLibraryImportElement(LibraryImportElement element) {
+ element.visitChildren(this);
+ return null;
+ }
+
+ @override
R? visitLocalVariableElement(LocalVariableElement element) {
element.visitChildren(this);
return null;
@@ -407,14 +409,11 @@
@override
R? visitConstructorElement(ConstructorElement element) => null;
- @Deprecated('Override visitExportElement2() instead')
+ @Deprecated('Override visitLibraryExportElement() instead')
@override
R? visitExportElement(ExportElement element) => null;
@override
- R? visitExportElement2(LibraryExportElement element) => null;
-
- @override
R? visitExtensionElement(ExtensionElement element) => null;
@override
@@ -431,14 +430,11 @@
R? visitGenericFunctionTypeElement(GenericFunctionTypeElement element) =>
null;
- @Deprecated('Override visitImportElement2() instead')
+ @Deprecated('Override visitLibraryImportElement() instead')
@override
R? visitImportElement(ImportElement element) => null;
@override
- R? visitImportElement2(LibraryImportElement element) => null;
-
- @override
R? visitLabelElement(LabelElement element) => null;
@override
@@ -449,6 +445,12 @@
R? visitLibraryElement(LibraryElement element) => null;
@override
+ R? visitLibraryExportElement(LibraryExportElement element) => null;
+
+ @override
+ R? visitLibraryImportElement(LibraryImportElement element) => null;
+
+ @override
R? visitLocalVariableElement(LocalVariableElement element) => null;
@override
@@ -508,14 +510,11 @@
@override
R? visitConstructorElement(ConstructorElement element) => _throw(element);
- @Deprecated('Override visitExportElement2() instead')
+ @Deprecated('Override visitLibraryExportElement() instead')
@override
R? visitExportElement(ExportElement element) => _throw(element);
@override
- R? visitExportElement2(LibraryExportElement element) => _throw(element);
-
- @override
R? visitExtensionElement(ExtensionElement element) => _throw(element);
@override
@@ -532,14 +531,11 @@
R? visitGenericFunctionTypeElement(GenericFunctionTypeElement element) =>
_throw(element);
- @Deprecated('Override visitImportElement2() instead')
+ @Deprecated('Override visitLibraryImportElement() instead')
@override
R? visitImportElement(ImportElement element) => _throw(element);
@override
- R? visitImportElement2(LibraryImportElement element) => _throw(element);
-
- @override
R? visitLabelElement(LabelElement element) => _throw(element);
@override
@@ -550,6 +546,12 @@
R? visitLibraryElement(LibraryElement element) => _throw(element);
@override
+ R? visitLibraryExportElement(LibraryExportElement element) => _throw(element);
+
+ @override
+ R? visitLibraryImportElement(LibraryImportElement element) => _throw(element);
+
+ @override
R? visitLocalVariableElement(LocalVariableElement element) => _throw(element);
@override
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
index b2e4b1f..15ea65d 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -530,23 +530,12 @@
/// Parse and resolve all files in [_library].
Map<FileState, CompilationUnitImpl> _parseAndResolve() {
- // Parse all files.
- final libraryFile = _library.file;
- final libraryUnit = _parse(libraryFile);
- final units = <FileState, CompilationUnitImpl>{
- libraryFile: libraryUnit,
- };
- for (final part in _library.parts) {
- if (part is PartWithFile) {
- final partFile = part.includedPart?.file;
- if (partFile != null) {
- units[partFile] = _parse(partFile);
- }
- }
- }
-
- // Resolve URIs in directives to corresponding sources.
- _resolveDirectives(units, libraryUnit);
+ final units = <FileState, CompilationUnitImpl>{};
+ _resolveDirectives(
+ containerKind: _library,
+ containerElement: _libraryElement,
+ units: units,
+ );
units.forEach((file, unit) {
_resolveFile(file, unit);
@@ -561,132 +550,160 @@
required AugmentationImportDirectiveImpl directive,
required AugmentationImportElement element,
required AugmentationImportState state,
- // TODO(scheglov) wrong value, wrong name
- required ErrorReporter libraryErrorReporter,
+ required ErrorReporter errorReporter,
required Set<AugmentationFileKind> seenAugmentations,
+ required Map<FileState, CompilationUnitImpl> units,
}) {
directive.element = element;
- final primaryUriState = state.uri;
- if (primaryUriState is DirectiveUriWithString) {
- directive.uriContent = primaryUriState.relativeUriStr;
- directive.uriSource = primaryUriState.source;
+ final uriState = state.uri;
+ if (uriState is DirectiveUriWithString) {
+ directive.uriContent = uriState.relativeUriStr;
+ directive.uriSource = uriState.source;
}
+ final AugmentationFileKind? importedAugmentationKind;
if (state is AugmentationImportWithUri) {
if (state.importedSource == null) {
// TODO(scheglov) When do we have a valid URI here and in imports?
final errorCode = state.uri.isValid
? CompileTimeErrorCode.URI_DOES_NOT_EXIST
: CompileTimeErrorCode.INVALID_URI;
- libraryErrorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
errorCode,
directive.uri,
[state.uri.relativeUriStr],
);
+ return;
} else if (state is AugmentationImportWithFile) {
- final importedAugmentation = state.importedAugmentation;
+ importedAugmentationKind = state.importedAugmentation;
if (!state.importedFile.exists) {
final errorCode = isGeneratedSource(state.importedSource)
? CompileTimeErrorCode.URI_HAS_NOT_BEEN_GENERATED
: CompileTimeErrorCode.URI_DOES_NOT_EXIST;
- libraryErrorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
errorCode,
directive.uri,
[state.importedFile.uriStr],
);
- } else if (importedAugmentation == null) {
- libraryErrorReporter.reportErrorForNode(
+ return;
+ } else if (importedAugmentationKind == null) {
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.IMPORT_OF_NOT_AUGMENTATION,
directive.uri,
[state.importedFile.uriStr],
);
- } else if (!seenAugmentations.add(importedAugmentation)) {
- libraryErrorReporter.reportErrorForNode(
+ return;
+ } else if (!seenAugmentations.add(importedAugmentationKind)) {
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.DUPLICATE_AUGMENTATION_IMPORT,
directive.uri,
[state.importedFile.uriStr],
);
+ return;
}
+ } else {
+ return;
}
} else {
- libraryErrorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.URI_WITH_INTERPOLATION,
directive.uri,
);
+ return;
}
- }
- void _resolveDirectives(
- Map<FileState, CompilationUnitImpl> units,
- CompilationUnitImpl libraryUnit,
- ) {
- libraryUnit.element = _libraryElement.definingCompilationUnit;
+ final augmentationFile = importedAugmentationKind.file;
+ final augmentationUnit = _parse(augmentationFile);
+ units[augmentationFile] = augmentationUnit;
- ErrorReporter libraryErrorReporter = _getErrorReporter(_library.file);
+ final importedAugmentation = element.importedAugmentation!;
+ directive.uriSource = importedAugmentation.source;
+ augmentationUnit.element = importedAugmentation.definingCompilationUnit;
- var augmentationImportIndex = 0;
- var libraryImportIndex = 0;
- var libraryExportIndex = 0;
-
- LibraryIdentifier? libraryNameNode;
- final seenAugmentations = <AugmentationFileKind>{};
- var seenPartSources = <Source>{};
- var directivesToResolve = <DirectiveImpl>[];
- final partIndexes = _PartDirectiveIndexes();
- for (Directive directive in libraryUnit.directives) {
- if (directive is LibraryDirectiveImpl) {
- libraryNameNode = directive.name;
- directivesToResolve.add(directive);
- } else if (directive is AugmentationImportDirectiveImpl) {
- final index = augmentationImportIndex++;
- _resolveAugmentationImportDirective(
- directive: directive,
- // TODO(scheglov) Not only in the library.
- element: _libraryElement.augmentationImports[index],
- // TODO(scheglov) Not only in the library.
- state: _library.augmentationImports[index],
- // TODO(scheglov) Not only in the library.
- libraryErrorReporter: libraryErrorReporter,
- seenAugmentations: seenAugmentations,
- );
- } else if (directive is ImportDirectiveImpl) {
- _resolveLibraryImportDirective(
- directive: directive,
- importElement: _libraryElement.libraryImports[libraryImportIndex],
- importState: _library.libraryImports[libraryImportIndex],
- libraryErrorReporter: libraryErrorReporter,
- );
- libraryImportIndex++;
- } else if (directive is ExportDirectiveImpl) {
- _resolveLibraryExportDirective(
- directive: directive,
- exportElement: _libraryElement.libraryExports[libraryExportIndex],
- exportState: _library.libraryExports[libraryExportIndex],
- libraryErrorReporter: libraryErrorReporter,
- );
- libraryExportIndex++;
- } else if (directive is PartDirectiveImpl) {
- _resolvePartDirective(
- directive: directive,
- partIndexes: partIndexes,
- libraryErrorReporter: libraryErrorReporter,
- libraryNameNode: libraryNameNode,
- units: units,
- directivesToResolve: directivesToResolve,
- seenPartSources: seenPartSources,
- );
+ for (final directive in augmentationUnit.directives) {
+ if (directive is AugmentationImportDirectiveImpl) {
+ directive.element = importedAugmentation;
}
}
- // TODO(brianwilkerson) Report the error
- // ResolverErrorCode.MISSING_LIBRARY_DIRECTIVE_WITH_PART
+ _resolveDirectives(
+ containerKind: importedAugmentationKind,
+ containerElement: importedAugmentation,
+ units: units,
+ );
+ }
- //
- // Resolve the relevant directives to the library element.
- //
- for (var directive in directivesToResolve) {
- directive.element = _libraryElement;
+ /// Parses the file of [containerKind], and resolves directives.
+ /// Recursively parses augmentations and parts.
+ void _resolveDirectives({
+ required LibraryOrAugmentationFileKind containerKind,
+ required LibraryOrAugmentationElement containerElement,
+ required Map<FileState, CompilationUnitImpl> units,
+ }) {
+ final containerFile = containerKind.file;
+ final containerUnit = _parse(containerFile);
+ containerUnit.element = containerElement.definingCompilationUnit;
+ units[containerFile] = containerUnit;
+
+ final containerErrorReporter = _getErrorReporter(containerFile);
+
+ var augmentationImportIndex = 0;
+ var libraryExportIndex = 0;
+ var libraryImportIndex = 0;
+ var partIndex = 0;
+
+ LibraryIdentifier? libraryNameNode;
+ final seenAugmentations = <AugmentationFileKind>{};
+ final seenPartSources = <Source>{};
+ for (Directive directive in containerUnit.directives) {
+ if (directive is AugmentationImportDirectiveImpl) {
+ final index = augmentationImportIndex++;
+ _resolveAugmentationImportDirective(
+ directive: directive,
+ element: containerElement.augmentationImports[index],
+ state: containerKind.augmentationImports[index],
+ errorReporter: containerErrorReporter,
+ seenAugmentations: seenAugmentations,
+ units: units,
+ );
+ } else if (directive is ExportDirectiveImpl) {
+ final index = libraryExportIndex++;
+ _resolveLibraryExportDirective(
+ directive: directive,
+ exportElement: containerElement.libraryExports[index],
+ exportState: containerKind.libraryExports[index],
+ errorReporter: containerErrorReporter,
+ );
+ } else if (directive is ImportDirectiveImpl) {
+ final index = libraryImportIndex++;
+ _resolveLibraryImportDirective(
+ directive: directive,
+ importElement: containerElement.libraryImports[index],
+ importState: containerKind.libraryImports[index],
+ errorReporter: containerErrorReporter,
+ );
+ } else if (directive is LibraryAugmentationDirectiveImpl) {
+ // TODO(scheglov) test
+ directive.element = containerElement;
+ } else if (directive is LibraryDirectiveImpl) {
+ directive.element = containerElement;
+ libraryNameNode = directive.name;
+ } else if (directive is PartDirectiveImpl) {
+ if (containerKind is LibraryFileKind &&
+ containerElement is LibraryElementImpl) {
+ final index = partIndex++;
+ _resolvePartDirective(
+ directive: directive,
+ partState: containerKind.parts[index],
+ partElement: containerElement.parts2[index],
+ errorReporter: containerErrorReporter,
+ libraryNameNode: libraryNameNode,
+ units: units,
+ seenPartSources: seenPartSources,
+ );
+ }
+ }
}
}
@@ -732,7 +749,7 @@
required ExportDirectiveImpl directive,
required LibraryExportElement exportElement,
required LibraryExportState exportState,
- required ErrorReporter libraryErrorReporter,
+ required ErrorReporter errorReporter,
}) {
directive.element = exportElement;
_resolveNamespaceDirective(
@@ -746,7 +763,7 @@
if (exportState is LibraryExportWithUri) {
final selectedUriStr = exportState.selectedUri.relativeUriStr;
if (selectedUriStr.startsWith('dart-ext:')) {
- libraryErrorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.USE_OF_NATIVE_EXTENSION,
directive.uri,
);
@@ -754,7 +771,7 @@
final errorCode = exportState.selectedUri.isValid
? CompileTimeErrorCode.URI_DOES_NOT_EXIST
: CompileTimeErrorCode.INVALID_URI;
- libraryErrorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
errorCode,
directive.uri,
[selectedUriStr],
@@ -764,20 +781,20 @@
final errorCode = isGeneratedSource(exportState.exportedSource)
? CompileTimeErrorCode.URI_HAS_NOT_BEEN_GENERATED
: CompileTimeErrorCode.URI_DOES_NOT_EXIST;
- libraryErrorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
errorCode,
directive.uri,
[selectedUriStr],
);
} else if (exportState.exportedLibrarySource == null) {
- libraryErrorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY,
directive.uri,
[selectedUriStr],
);
}
} else {
- libraryErrorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.URI_WITH_INTERPOLATION,
directive.uri,
);
@@ -788,7 +805,7 @@
required ImportDirectiveImpl directive,
required LibraryImportElement importElement,
required LibraryImportState importState,
- required ErrorReporter libraryErrorReporter,
+ required ErrorReporter errorReporter,
}) {
directive.element = importElement;
directive.prefix?.staticElement = importElement.prefix?.element;
@@ -803,7 +820,7 @@
if (importState is LibraryImportWithUri) {
final selectedUriStr = importState.selectedUri.relativeUriStr;
if (selectedUriStr.startsWith('dart-ext:')) {
- libraryErrorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.USE_OF_NATIVE_EXTENSION,
directive.uri,
);
@@ -811,7 +828,7 @@
final errorCode = importState.selectedUri.isValid
? CompileTimeErrorCode.URI_DOES_NOT_EXIST
: CompileTimeErrorCode.INVALID_URI;
- libraryErrorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
errorCode,
directive.uri,
[selectedUriStr],
@@ -821,20 +838,20 @@
final errorCode = isGeneratedSource(importState.importedSource)
? CompileTimeErrorCode.URI_HAS_NOT_BEEN_GENERATED
: CompileTimeErrorCode.URI_DOES_NOT_EXIST;
- libraryErrorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
errorCode,
directive.uri,
[selectedUriStr],
);
} else if (importState.importedLibrarySource == null) {
- libraryErrorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY,
directive.uri,
[selectedUriStr],
);
}
} else {
- libraryErrorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.URI_WITH_INTERPOLATION,
directive.uri,
);
@@ -868,25 +885,20 @@
void _resolvePartDirective({
required PartDirectiveImpl directive,
- required _PartDirectiveIndexes partIndexes,
- required ErrorReporter libraryErrorReporter,
+ required PartState partState,
+ required PartElement partElement,
+ required ErrorReporter errorReporter,
required LibraryIdentifier? libraryNameNode,
required Map<FileState, CompilationUnitImpl> units,
- required List<DirectiveImpl> directivesToResolve,
required Set<Source> seenPartSources,
}) {
StringLiteral partUri = directive.uri;
- final index = partIndexes.directive++;
-
- final partState = _library.parts[index];
directive.uriSource = partState.includedSource;
-
- final partElement = _libraryElement.parts2[index];
directive.element = partElement;
if (partState is! PartWithUri) {
- libraryErrorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.URI_WITH_INTERPOLATION,
directive.uri,
);
@@ -897,7 +909,7 @@
final errorCode = partState.uri.isValid
? CompileTimeErrorCode.URI_DOES_NOT_EXIST
: CompileTimeErrorCode.INVALID_URI;
- libraryErrorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
errorCode,
directive.uri,
[partState.uri.relativeUriStr],
@@ -909,7 +921,7 @@
if (includedKind is! PartFileKind) {
if (includedFile.exists) {
- libraryErrorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.PART_OF_NON_PART,
partUri,
[partUri.toSource()],
@@ -918,7 +930,7 @@
final errorCode = isGeneratedSource(includedFile.source)
? CompileTimeErrorCode.URI_HAS_NOT_BEEN_GENERATED
: CompileTimeErrorCode.URI_DOES_NOT_EXIST;
- libraryErrorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
errorCode,
directive.uri,
[partUri.toSource()],
@@ -931,13 +943,13 @@
if (!includedKind.libraries.contains(_library)) {
final name = includedKind.unlinked.name;
if (libraryNameNode == null) {
- libraryErrorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.PART_OF_UNNAMED_LIBRARY,
partUri,
[name],
);
} else {
- libraryErrorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.PART_OF_DIFFERENT_LIBRARY,
partUri,
[libraryNameNode.name, name],
@@ -946,7 +958,7 @@
return;
}
} else if (includedKind.library != _library) {
- libraryErrorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.PART_OF_DIFFERENT_LIBRARY,
partUri,
[_library.file.uriStr, includedFile.uriStr],
@@ -954,7 +966,9 @@
return;
}
- var partUnit = units[includedFile]!;
+ final partUnit = _parse(includedFile);
+ units[includedFile] = partUnit;
+
final partElementUri = partElement.uri;
if (partElementUri is DirectiveUriWithUnit) {
partUnit.element = partElementUri.unit;
@@ -965,7 +979,7 @@
for (final directive in partUnit.directives) {
if (directive is PartOfDirectiveImpl) {
- directivesToResolve.add(directive);
+ directive.element = _libraryElement;
}
}
@@ -973,7 +987,7 @@
// Validate that the part source is unique in the library.
//
if (!seenPartSources.add(partSource)) {
- libraryErrorReporter.reportErrorForNode(
+ errorReporter.reportErrorForNode(
CompileTimeErrorCode.DUPLICATE_PART, partUri, [partSource.uri]);
}
}
@@ -1075,8 +1089,3 @@
UnitAnalysisResult(this.file, this.unit, this.errors);
}
-
-class _PartDirectiveIndexes {
- int directive = 0;
- int element = 0;
-}
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index b0018c9..e8b91a4 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -3812,6 +3812,7 @@
..addToken('exportKeyword', exportKeyword)
..addNode('uri', uri)
..addNodeList('combinators', combinators)
+ ..addNodeList('configurations', configurations)
..addToken('semicolon', semicolon);
@override
@@ -6471,6 +6472,7 @@
..addToken('asKeyword', asKeyword)
..addNode('prefix', prefix)
..addNodeList('combinators', combinators)
+ ..addNodeList('configurations', configurations)
..addToken('semicolon', semicolon);
@override
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 4a90b77..2f13dee 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -4434,7 +4434,7 @@
@override
T? accept<T>(ElementVisitor<T> visitor) {
- return visitor.visitExportElement2(this);
+ return visitor.visitLibraryExportElement(this);
}
@override
@@ -4502,7 +4502,7 @@
@override
T? accept<T>(ElementVisitor<T> visitor) {
- return visitor.visitImportElement2(this);
+ return visitor.visitLibraryImportElement(this);
}
@override
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index bc8a8d3..634506e 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -266,6 +266,10 @@
}
}
+ void visitLibraryAugmentationDirective(LibraryAugmentationDirective node) {
+ _resolveAnnotations(node.metadata);
+ }
+
void visitLibraryDirective(LibraryDirective node) {
_resolveAnnotations(node.metadata);
}
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index d7408ef..9a01970 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -1891,6 +1891,13 @@
}
@override
+ void visitLibraryAugmentationDirective(LibraryAugmentationDirective node) {
+ checkUnreachableNode(node);
+ node.visitChildren(this);
+ elementResolver.visitLibraryAugmentationDirective(node);
+ }
+
+ @override
void visitLibraryDirective(LibraryDirective node) {
checkUnreachableNode(node);
node.visitChildren(this);
diff --git a/pkg/analyzer/test/src/dart/resolution/augmentation_import_test.dart b/pkg/analyzer/test/src/dart/resolution/augmentation_import_test.dart
index 1457bd4..8cfd850 100644
--- a/pkg/analyzer/test/src/dart/resolution/augmentation_import_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/augmentation_import_test.dart
@@ -2,6 +2,7 @@
// 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 'package:analyzer/src/error/codes.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'context_collection_resolution.dart';
@@ -15,12 +16,181 @@
@reflectiveTest
class AugmentationImportDirectiveResolutionTest
extends PubPackageResolutionTest {
- test_augmentation() async {
+ test_inAugmentation_augmentation() async {
+ newFile('$testPackageLibPath/a.dart', r'''
+import augment 'b.dart';
+''');
+
+ final b = newFile('$testPackageLibPath/b.dart', r'''
+library augment 'a.dart';
+import augment 'c.dart';
+''');
+
+ newFile('$testPackageLibPath/c.dart', r'''
+library augment 'b.dart';
+''');
+
+ await resolveFile2(b.path);
+ assertNoErrorsInResult();
+
+ final node = findNode.augmentationImportDirective('c.dart');
+ assertResolvedNodeText(node, r'''
+AugmentationImportDirective
+ importKeyword: import
+ augmentKeyword: augment
+ uri: SimpleStringLiteral
+ literal: 'c.dart'
+ semicolon: ;
+ element: AugmentationImportElement
+ uri: DirectiveUriWithAugmentation
+ uri: package:test/c.dart
+ uriContent: c.dart
+ uriElement: package:test/a.dart::@augmentation::package:test/c.dart
+ uriSource: package:test/c.dart
+''');
+ }
+
+ test_inAugmentation_augmentation_duplicate() async {
+ newFile('$testPackageLibPath/a.dart', r'''
+import augment 'b.dart';
+''');
+
+ final b = newFile('$testPackageLibPath/b.dart', r'''
+library augment 'a.dart';
+import augment 'c.dart';
+import augment 'c.dart' /*2*/;
+''');
+
+ newFile('$testPackageLibPath/c.dart', r'''
+library augment 'b.dart';
+''');
+
+ await resolveFile2(b.path);
+ assertErrorsInResult([
+ error(CompileTimeErrorCode.DUPLICATE_AUGMENTATION_IMPORT, 66, 8),
+ ]);
+
+ final node = findNode.augmentationImportDirective('/*2*/');
+ assertResolvedNodeText(node, r'''
+AugmentationImportDirective
+ importKeyword: import
+ augmentKeyword: augment
+ uri: SimpleStringLiteral
+ literal: 'c.dart'
+ semicolon: ;
+ element: AugmentationImportElement
+ uri: DirectiveUriWithAugmentation
+ uri: package:test/c.dart
+ uriContent: c.dart
+ uriElement: package:test/a.dart::@augmentation::package:test/c.dart
+ uriSource: package:test/c.dart
+''');
+ }
+
+ test_inAugmentation_notAugmentation_invalidUri() async {
+ newFile('$testPackageLibPath/a.dart', r'''
+import augment 'b.dart';
+''');
+
+ final b = newFile('$testPackageLibPath/b.dart', r'''
+library augment 'a.dart';
+import augment 'da:';
+''');
+
+ await resolveFile2(b.path);
+ assertErrorsInResult([
+ error(CompileTimeErrorCode.INVALID_URI, 41, 5),
+ ]);
+
+ final node = findNode.augmentationImportDirective('da:');
+ assertResolvedNodeText(node, r'''
+AugmentationImportDirective
+ importKeyword: import
+ augmentKeyword: augment
+ uri: SimpleStringLiteral
+ literal: 'da:'
+ semicolon: ;
+ element: AugmentationImportElement
+ uri: DirectiveUriWithRelativeUri
+ relativeUri: da:
+ uriContent: da:
+ uriElement: <null>
+ uriSource: <null>
+''');
+ }
+
+ test_inAugmentation_notAugmentation_library() async {
+ newFile('$testPackageLibPath/a.dart', r'''
+import augment 'b.dart';
+''');
+
+ final b = newFile('$testPackageLibPath/b.dart', r'''
+library augment 'a.dart';
+import augment 'c.dart';
+''');
+
+ newFile('$testPackageLibPath/c.dart', '');
+
+ await resolveFile2(b.path);
+ assertErrorsInResult([
+ error(CompileTimeErrorCode.IMPORT_OF_NOT_AUGMENTATION, 41, 8),
+ ]);
+
+ final node = findNode.augmentationImportDirective('c.dart');
+ assertResolvedNodeText(node, r'''
+AugmentationImportDirective
+ importKeyword: import
+ augmentKeyword: augment
+ uri: SimpleStringLiteral
+ literal: 'c.dart'
+ semicolon: ;
+ element: AugmentationImportElement
+ uri: DirectiveUriWithSource
+ source: package:test/c.dart
+ uriContent: c.dart
+ uriElement: <null>
+ uriSource: package:test/c.dart
+''');
+ }
+
+ test_inAugmentation_notAugmentation_uriDoesNotExist() async {
+ newFile('$testPackageLibPath/a.dart', r'''
+import augment 'b.dart';
+''');
+
+ final b = newFile('$testPackageLibPath/b.dart', r'''
+library augment 'a.dart';
+import augment 'c.dart';
+''');
+
+ await resolveFile2(b.path);
+ assertErrorsInResult([
+ error(CompileTimeErrorCode.URI_DOES_NOT_EXIST, 41, 8),
+ ]);
+
+ final node = findNode.augmentationImportDirective('c.dart');
+ assertResolvedNodeText(node, r'''
+AugmentationImportDirective
+ importKeyword: import
+ augmentKeyword: augment
+ uri: SimpleStringLiteral
+ literal: 'c.dart'
+ semicolon: ;
+ element: AugmentationImportElement
+ uri: DirectiveUriWithSource
+ source: package:test/c.dart
+ uriContent: c.dart
+ uriElement: <null>
+ uriSource: package:test/c.dart
+''');
+ }
+
+ test_inLibrary_augmentation() async {
newFile('$testPackageLibPath/a.dart', r'''
library augment 'test.dart';
''');
- await resolveTestCode(r'''
+ await assertNoErrorsInCode(r'''
import augment 'a.dart';
''');
@@ -41,12 +211,43 @@
''');
}
- test_library() async {
+ test_inLibrary_augmentation_duplicate() async {
+ newFile('$testPackageLibPath/a.dart', r'''
+library augment 'test.dart';
+''');
+
+ await assertErrorsInCode(r'''
+import augment 'a.dart';
+import augment /*2*/ 'a.dart';
+''', [
+ error(CompileTimeErrorCode.DUPLICATE_AUGMENTATION_IMPORT, 46, 8),
+ ]);
+
+ final node = findNode.augmentationImportDirective('/*2*/');
+ assertResolvedNodeText(node, r'''
+AugmentationImportDirective
+ importKeyword: import
+ augmentKeyword: augment
+ uri: SimpleStringLiteral
+ literal: 'a.dart'
+ semicolon: ;
+ element: AugmentationImportElement
+ uri: DirectiveUriWithAugmentation
+ uri: package:test/a.dart
+ uriContent: a.dart
+ uriElement: self::@augmentation::package:test/a.dart
+ uriSource: package:test/a.dart
+''');
+ }
+
+ test_inLibrary_notAugmentation_library() async {
newFile('$testPackageLibPath/a.dart', '');
- await resolveTestCode(r'''
+ await assertErrorsInCode(r'''
import augment 'a.dart';
-''');
+''', [
+ error(CompileTimeErrorCode.IMPORT_OF_NOT_AUGMENTATION, 15, 8),
+ ]);
final node = findNode.augmentationImportDirective('a.dart');
assertResolvedNodeText(node, r'''
@@ -65,14 +266,16 @@
''');
}
- test_partOfName() async {
+ test_inLibrary_notAugmentation_partOfName() async {
newFile('$testPackageLibPath/a.dart', r'''
part of my.lib;
''');
- await resolveTestCode(r'''
+ await assertErrorsInCode(r'''
import augment 'a.dart';
-''');
+''', [
+ error(CompileTimeErrorCode.IMPORT_OF_NOT_AUGMENTATION, 15, 8),
+ ]);
final node = findNode.augmentationImportDirective('a.dart');
assertResolvedNodeText(node, r'''
@@ -91,14 +294,16 @@
''');
}
- test_partOfUri() async {
+ test_inLibrary_notAugmentation_partOfUri() async {
newFile('$testPackageLibPath/a.dart', r'''
part of 'test.dart';
''');
- await resolveTestCode(r'''
+ await assertErrorsInCode(r'''
import augment 'a.dart';
-''');
+''', [
+ error(CompileTimeErrorCode.IMPORT_OF_NOT_AUGMENTATION, 15, 8),
+ ]);
final node = findNode.augmentationImportDirective('a.dart');
assertResolvedNodeText(node, r'''
diff --git a/pkg/analyzer/test/src/dart/resolution/export_test.dart b/pkg/analyzer/test/src/dart/resolution/export_test.dart
deleted file mode 100644
index 50965c1..0000000
--- a/pkg/analyzer/test/src/dart/resolution/export_test.dart
+++ /dev/null
@@ -1,115 +0,0 @@
-// Copyright (c) 2019, 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 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import 'context_collection_resolution.dart';
-
-main() {
- defineReflectiveSuite(() {
- defineReflectiveTests(ExportResolutionTest);
- });
-}
-
-@reflectiveTest
-class ExportResolutionTest extends PubPackageResolutionTest {
- test_configurations_default() async {
- newFile('$testPackageLibPath/a.dart', 'class A {}');
- newFile('$testPackageLibPath/a_html.dart', 'class A {}');
- newFile('$testPackageLibPath/a_io.dart', 'class A {}');
-
- declaredVariables = {
- 'dart.library.html': 'false',
- 'dart.library.io': 'false',
- };
-
- await assertNoErrorsInCode(r'''
-export 'a.dart'
- if (dart.library.html) 'a_html.dart'
- if (dart.library.io) 'a_io.dart';
-''');
-
- assertNamespaceDirectiveSelected(
- findNode.export('a.dart'),
- expectedRelativeUri: 'a.dart',
- expectedUri: 'package:test/a.dart',
- );
-
- assertElementLibraryUri(
- result.libraryElement.exportNamespace.get('A'),
- 'package:test/a.dart',
- );
- }
-
- test_configurations_first() async {
- newFile('$testPackageLibPath/a.dart', 'class A {}');
- newFile('$testPackageLibPath/a_html.dart', 'class A {}');
- newFile('$testPackageLibPath/a_io.dart', 'class A {}');
-
- declaredVariables = {
- 'dart.library.html': 'true',
- 'dart.library.io': 'false',
- };
-
- await assertNoErrorsInCode(r'''
-export 'a.dart'
- if (dart.library.html) 'a_html.dart'
- if (dart.library.io) 'a_io.dart';
-''');
-
- assertNamespaceDirectiveSelected(
- findNode.export('a.dart'),
- expectedRelativeUri: 'a_html.dart',
- expectedUri: 'package:test/a_html.dart',
- );
-
- assertElementLibraryUri(
- result.libraryElement.exportNamespace.get('A'),
- 'package:test/a_html.dart',
- );
- }
-
- test_configurations_second() async {
- newFile('$testPackageLibPath/a.dart', 'class A {}');
- newFile('$testPackageLibPath/a_html.dart', 'class A {}');
- newFile('$testPackageLibPath/a_io.dart', 'class A {}');
-
- declaredVariables = {
- 'dart.library.html': 'false',
- 'dart.library.io': 'true',
- };
-
- await assertNoErrorsInCode(r'''
-export 'a.dart'
- if (dart.library.html) 'a_html.dart'
- if (dart.library.io) 'a_io.dart';
-''');
-
- assertNamespaceDirectiveSelected(
- findNode.export('a.dart'),
- expectedRelativeUri: 'a_io.dart',
- expectedUri: 'package:test/a_io.dart',
- );
-
- assertElementLibraryUri(
- result.libraryElement.exportNamespace.get('A'),
- 'package:test/a_io.dart',
- );
- }
-
- /// Test that both getter and setter are in the export namespace.
- test_namespace_getter_setter() async {
- newFile('$testPackageLibPath/a.dart', r'''
-get f => null;
-set f(_) {}
-''');
- await resolveTestCode(r'''
-export 'a.dart';
-''');
- var exportNamespace = result.libraryElement.exportNamespace;
- expect(exportNamespace.get('f'), isNotNull);
- expect(exportNamespace.get('f='), isNotNull);
- }
-}
diff --git a/pkg/analyzer/test/src/dart/resolution/library_export_test.dart b/pkg/analyzer/test/src/dart/resolution/library_export_test.dart
new file mode 100644
index 0000000..d1116c0
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/library_export_test.dart
@@ -0,0 +1,548 @@
+// Copyright (c) 2019, 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 'package:analyzer/src/error/codes.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'context_collection_resolution.dart';
+
+main() {
+ defineReflectiveSuite(() {
+ defineReflectiveTests(ExportDirectiveResolutionTest);
+ });
+}
+
+@reflectiveTest
+class ExportDirectiveResolutionTest extends PubPackageResolutionTest {
+ test_inAugmentation_library() async {
+ newFile('$testPackageLibPath/a.dart', r'''
+import augment 'b.dart';
+''');
+
+ final b = newFile('$testPackageLibPath/b.dart', r'''
+library augment 'a.dart';
+export 'c.dart';
+''');
+
+ newFile('$testPackageLibPath/c.dart', '');
+
+ await resolveFile2(b.path);
+ assertNoErrorsInResult();
+
+ final node = findNode.export('c.dart');
+ assertResolvedNodeText(node, r'''
+ExportDirective
+ exportKeyword: export
+ uri: SimpleStringLiteral
+ literal: 'c.dart'
+ semicolon: ;
+ element: LibraryExportElement
+ uri: DirectiveUriWithLibrary
+ uri: package:test/c.dart
+ selectedSource: package:test/c.dart
+ selectedUriContent: c.dart
+ uriContent: c.dart
+ uriElement: package:test/c.dart
+ uriSource: package:test/c.dart
+''');
+ }
+
+ test_inAugmentation_notLibrary_augmentation() async {
+ newFile('$testPackageLibPath/a.dart', r'''
+import augment 'b.dart';
+''');
+
+ final b = newFile('$testPackageLibPath/b.dart', r'''
+library augment 'a.dart';
+export 'c.dart';
+''');
+
+ newFile('$testPackageLibPath/c.dart', r'''
+library augment 'b.dart';
+''');
+
+ await resolveFile2(b.path);
+ assertErrorsInResult([
+ error(CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY, 33, 8),
+ ]);
+
+ final node = findNode.export('c.dart');
+ assertResolvedNodeText(node, r'''
+ExportDirective
+ exportKeyword: export
+ uri: SimpleStringLiteral
+ literal: 'c.dart'
+ semicolon: ;
+ element: LibraryExportElement
+ uri: DirectiveUriWithSource
+ source: package:test/c.dart
+ selectedSource: package:test/c.dart
+ selectedUriContent: c.dart
+ uriContent: c.dart
+ uriElement: <null>
+ uriSource: package:test/c.dart
+''');
+ }
+
+ test_inAugmentation_notLibrary_partOfName() async {
+ newFile('$testPackageLibPath/a.dart', r'''
+import augment 'b.dart';
+''');
+
+ final b = newFile('$testPackageLibPath/b.dart', r'''
+library augment 'a.dart';
+export 'c.dart';
+''');
+
+ newFile('$testPackageLibPath/c.dart', r'''
+part of my.lib;
+''');
+
+ await resolveFile2(b.path);
+ assertErrorsInResult([
+ error(CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY, 33, 8),
+ ]);
+
+ final node = findNode.export('c.dart');
+ assertResolvedNodeText(node, r'''
+ExportDirective
+ exportKeyword: export
+ uri: SimpleStringLiteral
+ literal: 'c.dart'
+ semicolon: ;
+ element: LibraryExportElement
+ uri: DirectiveUriWithSource
+ source: package:test/c.dart
+ selectedSource: package:test/c.dart
+ selectedUriContent: c.dart
+ uriContent: c.dart
+ uriElement: <null>
+ uriSource: package:test/c.dart
+''');
+ }
+
+ test_inAugmentation_notLibrary_partOfUri() async {
+ newFile('$testPackageLibPath/a.dart', r'''
+import augment 'b.dart';
+''');
+
+ final b = newFile('$testPackageLibPath/b.dart', r'''
+library augment 'a.dart';
+export 'c.dart';
+''');
+
+ newFile('$testPackageLibPath/c.dart', r'''
+part of 'b.dart';
+''');
+
+ await resolveFile2(b.path);
+ assertErrorsInResult([
+ error(CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY, 33, 8),
+ ]);
+
+ final node = findNode.export('c.dart');
+ assertResolvedNodeText(node, r'''
+ExportDirective
+ exportKeyword: export
+ uri: SimpleStringLiteral
+ literal: 'c.dart'
+ semicolon: ;
+ element: LibraryExportElement
+ uri: DirectiveUriWithSource
+ source: package:test/c.dart
+ selectedSource: package:test/c.dart
+ selectedUriContent: c.dart
+ uriContent: c.dart
+ uriElement: <null>
+ uriSource: package:test/c.dart
+''');
+ }
+
+ test_inLibrary_configurations_default() async {
+ newFile('$testPackageLibPath/a.dart', 'class A {}');
+ newFile('$testPackageLibPath/a_html.dart', 'class A {}');
+ newFile('$testPackageLibPath/a_io.dart', 'class A {}');
+
+ declaredVariables = {
+ 'dart.library.html': 'false',
+ 'dart.library.io': 'false',
+ };
+
+ await assertNoErrorsInCode(r'''
+export 'a.dart'
+ if (dart.library.html) 'a_html.dart'
+ if (dart.library.io) 'a_io.dart';
+''');
+
+ final node = findNode.export('a.dart');
+ assertResolvedNodeText(node, r'''
+ExportDirective
+ exportKeyword: export
+ uri: SimpleStringLiteral
+ literal: 'a.dart'
+ configurations
+ Configuration
+ ifKeyword: if
+ leftParenthesis: (
+ name: DottedName
+ components
+ SimpleIdentifier
+ token: dart
+ staticElement: <null>
+ staticType: null
+ SimpleIdentifier
+ token: library
+ staticElement: <null>
+ staticType: null
+ SimpleIdentifier
+ token: html
+ staticElement: <null>
+ staticType: null
+ rightParenthesis: )
+ uri: SimpleStringLiteral
+ literal: 'a_html.dart'
+ Configuration
+ ifKeyword: if
+ leftParenthesis: (
+ name: DottedName
+ components
+ SimpleIdentifier
+ token: dart
+ staticElement: <null>
+ staticType: null
+ SimpleIdentifier
+ token: library
+ staticElement: <null>
+ staticType: null
+ SimpleIdentifier
+ token: io
+ staticElement: <null>
+ staticType: null
+ rightParenthesis: )
+ uri: SimpleStringLiteral
+ literal: 'a_io.dart'
+ semicolon: ;
+ element: LibraryExportElement
+ uri: DirectiveUriWithLibrary
+ uri: package:test/a.dart
+ selectedSource: package:test/a.dart
+ selectedUriContent: a.dart
+ uriContent: a.dart
+ uriElement: package:test/a.dart
+ uriSource: package:test/a.dart
+''');
+ }
+
+ test_inLibrary_configurations_first() async {
+ newFile('$testPackageLibPath/a.dart', 'class A {}');
+ newFile('$testPackageLibPath/a_html.dart', 'class A {}');
+ newFile('$testPackageLibPath/a_io.dart', 'class A {}');
+
+ declaredVariables = {
+ 'dart.library.html': 'true',
+ 'dart.library.io': 'false',
+ };
+
+ await assertNoErrorsInCode(r'''
+export 'a.dart'
+ if (dart.library.html) 'a_html.dart'
+ if (dart.library.io) 'a_io.dart';
+''');
+
+ final node = findNode.export('a.dart');
+ assertResolvedNodeText(node, r'''
+ExportDirective
+ exportKeyword: export
+ uri: SimpleStringLiteral
+ literal: 'a.dart'
+ configurations
+ Configuration
+ ifKeyword: if
+ leftParenthesis: (
+ name: DottedName
+ components
+ SimpleIdentifier
+ token: dart
+ staticElement: <null>
+ staticType: null
+ SimpleIdentifier
+ token: library
+ staticElement: <null>
+ staticType: null
+ SimpleIdentifier
+ token: html
+ staticElement: <null>
+ staticType: null
+ rightParenthesis: )
+ uri: SimpleStringLiteral
+ literal: 'a_html.dart'
+ Configuration
+ ifKeyword: if
+ leftParenthesis: (
+ name: DottedName
+ components
+ SimpleIdentifier
+ token: dart
+ staticElement: <null>
+ staticType: null
+ SimpleIdentifier
+ token: library
+ staticElement: <null>
+ staticType: null
+ SimpleIdentifier
+ token: io
+ staticElement: <null>
+ staticType: null
+ rightParenthesis: )
+ uri: SimpleStringLiteral
+ literal: 'a_io.dart'
+ semicolon: ;
+ element: LibraryExportElement
+ uri: DirectiveUriWithLibrary
+ uri: package:test/a_html.dart
+ selectedSource: package:test/a_html.dart
+ selectedUriContent: a_html.dart
+ uriContent: a.dart
+ uriElement: package:test/a_html.dart
+ uriSource: package:test/a.dart
+''');
+ }
+
+ test_inLibrary_configurations_second() async {
+ newFile('$testPackageLibPath/a.dart', 'class A {}');
+ newFile('$testPackageLibPath/a_html.dart', 'class A {}');
+ newFile('$testPackageLibPath/a_io.dart', 'class A {}');
+
+ declaredVariables = {
+ 'dart.library.html': 'false',
+ 'dart.library.io': 'true',
+ };
+
+ await assertNoErrorsInCode(r'''
+export 'a.dart'
+ if (dart.library.html) 'a_html.dart'
+ if (dart.library.io) 'a_io.dart';
+''');
+
+ final node = findNode.export('a.dart');
+ assertResolvedNodeText(node, r'''
+ExportDirective
+ exportKeyword: export
+ uri: SimpleStringLiteral
+ literal: 'a.dart'
+ configurations
+ Configuration
+ ifKeyword: if
+ leftParenthesis: (
+ name: DottedName
+ components
+ SimpleIdentifier
+ token: dart
+ staticElement: <null>
+ staticType: null
+ SimpleIdentifier
+ token: library
+ staticElement: <null>
+ staticType: null
+ SimpleIdentifier
+ token: html
+ staticElement: <null>
+ staticType: null
+ rightParenthesis: )
+ uri: SimpleStringLiteral
+ literal: 'a_html.dart'
+ Configuration
+ ifKeyword: if
+ leftParenthesis: (
+ name: DottedName
+ components
+ SimpleIdentifier
+ token: dart
+ staticElement: <null>
+ staticType: null
+ SimpleIdentifier
+ token: library
+ staticElement: <null>
+ staticType: null
+ SimpleIdentifier
+ token: io
+ staticElement: <null>
+ staticType: null
+ rightParenthesis: )
+ uri: SimpleStringLiteral
+ literal: 'a_io.dart'
+ semicolon: ;
+ element: LibraryExportElement
+ uri: DirectiveUriWithLibrary
+ uri: package:test/a_io.dart
+ selectedSource: package:test/a_io.dart
+ selectedUriContent: a_io.dart
+ uriContent: a.dart
+ uriElement: package:test/a_io.dart
+ uriSource: package:test/a.dart
+''');
+ }
+
+ /// Test that both getter and setter are in the export namespace.
+ test_inLibrary_namespace_getter_setter() async {
+ newFile('$testPackageLibPath/a.dart', r'''
+get f => null;
+set f(_) {}
+''');
+ await resolveTestCode(r'''
+export 'a.dart';
+''');
+ var exportNamespace = result.libraryElement.exportNamespace;
+ expect(exportNamespace.get('f'), isNotNull);
+ expect(exportNamespace.get('f='), isNotNull);
+ }
+
+ test_inLibrary_noRelativeUriStr() async {
+ await assertErrorsInCode(r'''
+export '${'foo'}.dart';
+''', [
+ error(CompileTimeErrorCode.URI_WITH_INTERPOLATION, 7, 15),
+ ]);
+
+ final node = findNode.export('export');
+ assertResolvedNodeText(node, r'''
+ExportDirective
+ exportKeyword: export
+ uri: StringInterpolation
+ elements
+ InterpolationString
+ contents: '
+ InterpolationExpression
+ leftBracket: ${
+ expression: SimpleStringLiteral
+ literal: 'foo'
+ rightBracket: }
+ InterpolationString
+ contents: .dart'
+ staticType: String
+ stringValue: null
+ semicolon: ;
+ element: LibraryExportElement
+ uri: DirectiveUri
+ selectedSource: <null>
+ selectedUriContent: null
+ uriContent: null
+ uriElement: <null>
+ uriSource: <null>
+''');
+ }
+
+ test_inLibrary_noSource() async {
+ await assertErrorsInCode(r'''
+export 'foo:bar';
+''', [
+ error(CompileTimeErrorCode.URI_DOES_NOT_EXIST, 7, 9),
+ ]);
+
+ final node = findNode.export('export');
+ assertResolvedNodeText(node, r'''
+ExportDirective
+ exportKeyword: export
+ uri: SimpleStringLiteral
+ literal: 'foo:bar'
+ semicolon: ;
+ element: LibraryExportElement
+ uri: DirectiveUriWithRelativeUri
+ relativeUri: foo:bar
+ selectedSource: <null>
+ selectedUriContent: foo:bar
+ uriContent: foo:bar
+ uriElement: <null>
+ uriSource: <null>
+''');
+ }
+
+ test_inLibrary_notLibrary_augmentation() async {
+ newFile('$testPackageLibPath/a.dart', r'''
+library augment 'test.dart';
+''');
+
+ await assertErrorsInCode(r'''
+export 'a.dart';
+''', [
+ error(CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY, 7, 8),
+ ]);
+
+ final node = findNode.export('a.dart');
+ assertResolvedNodeText(node, r'''
+ExportDirective
+ exportKeyword: export
+ uri: SimpleStringLiteral
+ literal: 'a.dart'
+ semicolon: ;
+ element: LibraryExportElement
+ uri: DirectiveUriWithSource
+ source: package:test/a.dart
+ selectedSource: package:test/a.dart
+ selectedUriContent: a.dart
+ uriContent: a.dart
+ uriElement: <null>
+ uriSource: package:test/a.dart
+''');
+ }
+
+ test_inLibrary_notLibrary_partOfName() async {
+ newFile('$testPackageLibPath/a.dart', r'''
+part of my.lib;
+''');
+
+ await assertErrorsInCode(r'''
+export 'a.dart';
+''', [
+ error(CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY, 7, 8),
+ ]);
+
+ final node = findNode.export('a.dart');
+ assertResolvedNodeText(node, r'''
+ExportDirective
+ exportKeyword: export
+ uri: SimpleStringLiteral
+ literal: 'a.dart'
+ semicolon: ;
+ element: LibraryExportElement
+ uri: DirectiveUriWithSource
+ source: package:test/a.dart
+ selectedSource: package:test/a.dart
+ selectedUriContent: a.dart
+ uriContent: a.dart
+ uriElement: <null>
+ uriSource: package:test/a.dart
+''');
+ }
+
+ test_inLibrary_notLibrary_partOfUri() async {
+ newFile('$testPackageLibPath/a.dart', r'''
+part of 'test.dart';
+''');
+
+ await assertErrorsInCode(r'''
+export 'a.dart';
+''', [
+ error(CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY, 7, 8),
+ ]);
+
+ final node = findNode.export('a.dart');
+ assertResolvedNodeText(node, r'''
+ExportDirective
+ exportKeyword: export
+ uri: SimpleStringLiteral
+ literal: 'a.dart'
+ semicolon: ;
+ element: LibraryExportElement
+ uri: DirectiveUriWithSource
+ source: package:test/a.dart
+ selectedSource: package:test/a.dart
+ selectedUriContent: a.dart
+ uriContent: a.dart
+ uriElement: <null>
+ uriSource: package:test/a.dart
+''');
+ }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/library_import_test.dart b/pkg/analyzer/test/src/dart/resolution/library_import_test.dart
index d52aea9..1dbaafc 100644
--- a/pkg/analyzer/test/src/dart/resolution/library_import_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/library_import_test.dart
@@ -2,6 +2,7 @@
// 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 'package:analyzer/src/error/codes.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import 'context_collection_resolution.dart';
@@ -14,7 +15,153 @@
@reflectiveTest
class ImportDirectiveResolutionTest extends PubPackageResolutionTest {
- test_configurations_default() async {
+ test_inAugmentation_library() async {
+ newFile('$testPackageLibPath/a.dart', r'''
+import augment 'b.dart';
+''');
+
+ final b = newFile('$testPackageLibPath/b.dart', r'''
+library augment 'a.dart';
+import 'c.dart';
+''');
+
+ newFile('$testPackageLibPath/c.dart', '');
+
+ await resolveFile2(b.path);
+ assertErrorsInResult([
+ error(HintCode.UNUSED_IMPORT, 33, 8),
+ ]);
+
+ final node = findNode.import('c.dart');
+ assertResolvedNodeText(node, r'''
+ImportDirective
+ importKeyword: import
+ uri: SimpleStringLiteral
+ literal: 'c.dart'
+ semicolon: ;
+ element: LibraryImportElement
+ uri: DirectiveUriWithLibrary
+ uri: package:test/c.dart
+ selectedSource: package:test/c.dart
+ selectedUriContent: c.dart
+ uriContent: c.dart
+ uriElement: package:test/c.dart
+ uriSource: package:test/c.dart
+''');
+ }
+
+ test_inAugmentation_notLibrary_augmentation() async {
+ newFile('$testPackageLibPath/a.dart', r'''
+import augment 'b.dart';
+''');
+
+ final b = newFile('$testPackageLibPath/b.dart', r'''
+library augment 'a.dart';
+import 'c.dart';
+''');
+
+ newFile('$testPackageLibPath/c.dart', r'''
+library augment 'b.dart';
+''');
+
+ await resolveFile2(b.path);
+ assertErrorsInResult([
+ error(CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY, 33, 8),
+ ]);
+
+ final node = findNode.import('c.dart');
+ assertResolvedNodeText(node, r'''
+ImportDirective
+ importKeyword: import
+ uri: SimpleStringLiteral
+ literal: 'c.dart'
+ semicolon: ;
+ element: LibraryImportElement
+ uri: DirectiveUriWithSource
+ source: package:test/c.dart
+ selectedSource: package:test/c.dart
+ selectedUriContent: c.dart
+ uriContent: c.dart
+ uriElement: <null>
+ uriSource: package:test/c.dart
+''');
+ }
+
+ test_inAugmentation_notLibrary_partOfName() async {
+ newFile('$testPackageLibPath/a.dart', r'''
+import augment 'b.dart';
+''');
+
+ final b = newFile('$testPackageLibPath/b.dart', r'''
+library augment 'a.dart';
+import 'c.dart';
+''');
+
+ newFile('$testPackageLibPath/c.dart', r'''
+part of my.lib;
+''');
+
+ await resolveFile2(b.path);
+ assertErrorsInResult([
+ error(CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY, 33, 8),
+ ]);
+
+ final node = findNode.import('c.dart');
+ assertResolvedNodeText(node, r'''
+ImportDirective
+ importKeyword: import
+ uri: SimpleStringLiteral
+ literal: 'c.dart'
+ semicolon: ;
+ element: LibraryImportElement
+ uri: DirectiveUriWithSource
+ source: package:test/c.dart
+ selectedSource: package:test/c.dart
+ selectedUriContent: c.dart
+ uriContent: c.dart
+ uriElement: <null>
+ uriSource: package:test/c.dart
+''');
+ }
+
+ test_inAugmentation_notLibrary_partOfUri() async {
+ newFile('$testPackageLibPath/a.dart', r'''
+import augment 'b.dart';
+''');
+
+ final b = newFile('$testPackageLibPath/b.dart', r'''
+library augment 'a.dart';
+import 'c.dart';
+''');
+
+ newFile('$testPackageLibPath/c.dart', r'''
+part of 'b.dart';
+''');
+
+ await resolveFile2(b.path);
+ assertErrorsInResult([
+ error(CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY, 33, 8),
+ ]);
+
+ final node = findNode.import('c.dart');
+ assertResolvedNodeText(node, r'''
+ImportDirective
+ importKeyword: import
+ uri: SimpleStringLiteral
+ literal: 'c.dart'
+ semicolon: ;
+ element: LibraryImportElement
+ uri: DirectiveUriWithSource
+ source: package:test/c.dart
+ selectedSource: package:test/c.dart
+ selectedUriContent: c.dart
+ uriContent: c.dart
+ uriElement: <null>
+ uriSource: package:test/c.dart
+''');
+ }
+
+ test_inLibrary_configurations_default() async {
newFile('$testPackageLibPath/a.dart', 'class A {}');
newFile('$testPackageLibPath/a_html.dart', 'class A {}');
newFile('$testPackageLibPath/a_io.dart', 'class A {}');
@@ -32,17 +179,95 @@
var a = A();
''');
- assertNamespaceDirectiveSelected(
- findNode.import('a.dart'),
- expectedRelativeUri: 'a.dart',
- expectedUri: 'package:test/a.dart',
- );
-
- var a = findElement.topVar('a');
- assertElementLibraryUri(a.type.element, 'package:test/a.dart');
+ final node = findNode.unit;
+ assertResolvedNodeText(node, r'''
+CompilationUnit
+ directives
+ ImportDirective
+ importKeyword: import
+ uri: SimpleStringLiteral
+ literal: 'a.dart'
+ configurations
+ Configuration
+ ifKeyword: if
+ leftParenthesis: (
+ name: DottedName
+ components
+ SimpleIdentifier
+ token: dart
+ staticElement: <null>
+ staticType: null
+ SimpleIdentifier
+ token: library
+ staticElement: <null>
+ staticType: null
+ SimpleIdentifier
+ token: html
+ staticElement: <null>
+ staticType: null
+ rightParenthesis: )
+ uri: SimpleStringLiteral
+ literal: 'a_html.dart'
+ Configuration
+ ifKeyword: if
+ leftParenthesis: (
+ name: DottedName
+ components
+ SimpleIdentifier
+ token: dart
+ staticElement: <null>
+ staticType: null
+ SimpleIdentifier
+ token: library
+ staticElement: <null>
+ staticType: null
+ SimpleIdentifier
+ token: io
+ staticElement: <null>
+ staticType: null
+ rightParenthesis: )
+ uri: SimpleStringLiteral
+ literal: 'a_io.dart'
+ semicolon: ;
+ element: LibraryImportElement
+ uri: DirectiveUriWithLibrary
+ uri: package:test/a.dart
+ selectedSource: package:test/a.dart
+ selectedUriContent: a.dart
+ uriContent: a.dart
+ uriElement: package:test/a.dart
+ uriSource: package:test/a.dart
+ declarations
+ TopLevelVariableDeclaration
+ variables: VariableDeclarationList
+ keyword: var
+ variables
+ VariableDeclaration
+ name: SimpleIdentifier
+ token: a
+ staticElement: self::@variable::a
+ staticType: null
+ equals: =
+ initializer: InstanceCreationExpression
+ constructorName: ConstructorName
+ type: NamedType
+ name: SimpleIdentifier
+ token: A
+ staticElement: package:test/a.dart::@class::A
+ staticType: null
+ type: A
+ staticElement: package:test/a.dart::@class::A::@constructor::•
+ argumentList: ArgumentList
+ leftParenthesis: (
+ rightParenthesis: )
+ staticType: A
+ declaredElement: self::@variable::a
+ semicolon: ;
+ declaredElement: <null>
+''');
}
- test_configurations_first() async {
+ test_inLibrary_configurations_first() async {
newFile('$testPackageLibPath/a.dart', 'class A {}');
newFile('$testPackageLibPath/a_html.dart', 'class A {}');
newFile('$testPackageLibPath/a_io.dart', 'class A {}');
@@ -60,17 +285,95 @@
var a = A();
''');
- assertNamespaceDirectiveSelected(
- findNode.import('a.dart'),
- expectedRelativeUri: 'a_html.dart',
- expectedUri: 'package:test/a_html.dart',
- );
-
- var a = findElement.topVar('a');
- assertElementLibraryUri(a.type.element, 'package:test/a_html.dart');
+ final node = findNode.unit;
+ assertResolvedNodeText(node, r'''
+CompilationUnit
+ directives
+ ImportDirective
+ importKeyword: import
+ uri: SimpleStringLiteral
+ literal: 'a.dart'
+ configurations
+ Configuration
+ ifKeyword: if
+ leftParenthesis: (
+ name: DottedName
+ components
+ SimpleIdentifier
+ token: dart
+ staticElement: <null>
+ staticType: null
+ SimpleIdentifier
+ token: library
+ staticElement: <null>
+ staticType: null
+ SimpleIdentifier
+ token: html
+ staticElement: <null>
+ staticType: null
+ rightParenthesis: )
+ uri: SimpleStringLiteral
+ literal: 'a_html.dart'
+ Configuration
+ ifKeyword: if
+ leftParenthesis: (
+ name: DottedName
+ components
+ SimpleIdentifier
+ token: dart
+ staticElement: <null>
+ staticType: null
+ SimpleIdentifier
+ token: library
+ staticElement: <null>
+ staticType: null
+ SimpleIdentifier
+ token: io
+ staticElement: <null>
+ staticType: null
+ rightParenthesis: )
+ uri: SimpleStringLiteral
+ literal: 'a_io.dart'
+ semicolon: ;
+ element: LibraryImportElement
+ uri: DirectiveUriWithLibrary
+ uri: package:test/a_html.dart
+ selectedSource: package:test/a_html.dart
+ selectedUriContent: a_html.dart
+ uriContent: a.dart
+ uriElement: package:test/a_html.dart
+ uriSource: package:test/a.dart
+ declarations
+ TopLevelVariableDeclaration
+ variables: VariableDeclarationList
+ keyword: var
+ variables
+ VariableDeclaration
+ name: SimpleIdentifier
+ token: a
+ staticElement: self::@variable::a
+ staticType: null
+ equals: =
+ initializer: InstanceCreationExpression
+ constructorName: ConstructorName
+ type: NamedType
+ name: SimpleIdentifier
+ token: A
+ staticElement: package:test/a_html.dart::@class::A
+ staticType: null
+ type: A
+ staticElement: package:test/a_html.dart::@class::A::@constructor::•
+ argumentList: ArgumentList
+ leftParenthesis: (
+ rightParenthesis: )
+ staticType: A
+ declaredElement: self::@variable::a
+ semicolon: ;
+ declaredElement: <null>
+''');
}
- test_configurations_second() async {
+ test_inLibrary_configurations_second() async {
newFile('$testPackageLibPath/a.dart', 'class A {}');
newFile('$testPackageLibPath/a_html.dart', 'class A {}');
newFile('$testPackageLibPath/a_io.dart', 'class A {}');
@@ -88,13 +391,264 @@
var a = A();
''');
- assertNamespaceDirectiveSelected(
- findNode.import('a.dart'),
- expectedRelativeUri: 'a_io.dart',
- expectedUri: 'package:test/a_io.dart',
- );
+ final node = findNode.unit;
+ assertResolvedNodeText(node, r'''
+CompilationUnit
+ directives
+ ImportDirective
+ importKeyword: import
+ uri: SimpleStringLiteral
+ literal: 'a.dart'
+ configurations
+ Configuration
+ ifKeyword: if
+ leftParenthesis: (
+ name: DottedName
+ components
+ SimpleIdentifier
+ token: dart
+ staticElement: <null>
+ staticType: null
+ SimpleIdentifier
+ token: library
+ staticElement: <null>
+ staticType: null
+ SimpleIdentifier
+ token: html
+ staticElement: <null>
+ staticType: null
+ rightParenthesis: )
+ uri: SimpleStringLiteral
+ literal: 'a_html.dart'
+ Configuration
+ ifKeyword: if
+ leftParenthesis: (
+ name: DottedName
+ components
+ SimpleIdentifier
+ token: dart
+ staticElement: <null>
+ staticType: null
+ SimpleIdentifier
+ token: library
+ staticElement: <null>
+ staticType: null
+ SimpleIdentifier
+ token: io
+ staticElement: <null>
+ staticType: null
+ rightParenthesis: )
+ uri: SimpleStringLiteral
+ literal: 'a_io.dart'
+ semicolon: ;
+ element: LibraryImportElement
+ uri: DirectiveUriWithLibrary
+ uri: package:test/a_io.dart
+ selectedSource: package:test/a_io.dart
+ selectedUriContent: a_io.dart
+ uriContent: a.dart
+ uriElement: package:test/a_io.dart
+ uriSource: package:test/a.dart
+ declarations
+ TopLevelVariableDeclaration
+ variables: VariableDeclarationList
+ keyword: var
+ variables
+ VariableDeclaration
+ name: SimpleIdentifier
+ token: a
+ staticElement: self::@variable::a
+ staticType: null
+ equals: =
+ initializer: InstanceCreationExpression
+ constructorName: ConstructorName
+ type: NamedType
+ name: SimpleIdentifier
+ token: A
+ staticElement: package:test/a_io.dart::@class::A
+ staticType: null
+ type: A
+ staticElement: package:test/a_io.dart::@class::A::@constructor::•
+ argumentList: ArgumentList
+ leftParenthesis: (
+ rightParenthesis: )
+ staticType: A
+ declaredElement: self::@variable::a
+ semicolon: ;
+ declaredElement: <null>
+''');
+ }
- var a = findElement.topVar('a');
- assertElementLibraryUri(a.type.element, 'package:test/a_io.dart');
+ test_inLibrary_library() async {
+ newFile('$testPackageLibPath/a.dart', '');
+
+ await assertNoErrorsInCode(r'''
+// ignore: unused_import
+import 'a.dart';
+''');
+
+ final node = findNode.import('a.dart');
+ assertResolvedNodeText(node, r'''
+ImportDirective
+ importKeyword: import
+ uri: SimpleStringLiteral
+ literal: 'a.dart'
+ semicolon: ;
+ element: LibraryImportElement
+ uri: DirectiveUriWithLibrary
+ uri: package:test/a.dart
+ selectedSource: package:test/a.dart
+ selectedUriContent: a.dart
+ uriContent: a.dart
+ uriElement: package:test/a.dart
+ uriSource: package:test/a.dart
+''');
+ }
+
+ test_inLibrary_noRelativeUriStr() async {
+ await assertErrorsInCode(r'''
+import '${'foo'}.dart';
+''', [
+ error(CompileTimeErrorCode.URI_WITH_INTERPOLATION, 7, 15),
+ ]);
+
+ final node = findNode.import('import');
+ assertResolvedNodeText(node, r'''
+ImportDirective
+ importKeyword: import
+ uri: StringInterpolation
+ elements
+ InterpolationString
+ contents: '
+ InterpolationExpression
+ leftBracket: ${
+ expression: SimpleStringLiteral
+ literal: 'foo'
+ rightBracket: }
+ InterpolationString
+ contents: .dart'
+ staticType: String
+ stringValue: null
+ semicolon: ;
+ element: LibraryImportElement
+ uri: DirectiveUri
+ selectedSource: <null>
+ selectedUriContent: null
+ uriContent: null
+ uriElement: <null>
+ uriSource: <null>
+''');
+ }
+
+ test_inLibrary_noSource() async {
+ await assertErrorsInCode(r'''
+import 'foo:bar';
+''', [
+ error(CompileTimeErrorCode.URI_DOES_NOT_EXIST, 7, 9),
+ ]);
+
+ final node = findNode.import('import');
+ assertResolvedNodeText(node, r'''
+ImportDirective
+ importKeyword: import
+ uri: SimpleStringLiteral
+ literal: 'foo:bar'
+ semicolon: ;
+ element: LibraryImportElement
+ uri: DirectiveUriWithRelativeUri
+ relativeUri: foo:bar
+ selectedSource: <null>
+ selectedUriContent: foo:bar
+ uriContent: foo:bar
+ uriElement: <null>
+ uriSource: <null>
+''');
+ }
+
+ test_inLibrary_notLibrary_augmentation() async {
+ newFile('$testPackageLibPath/a.dart', r'''
+library augment 'test.dart';
+''');
+
+ await assertErrorsInCode(r'''
+import 'a.dart';
+''', [
+ error(CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY, 7, 8),
+ ]);
+
+ final node = findNode.import('a.dart');
+ assertResolvedNodeText(node, r'''
+ImportDirective
+ importKeyword: import
+ uri: SimpleStringLiteral
+ literal: 'a.dart'
+ semicolon: ;
+ element: LibraryImportElement
+ uri: DirectiveUriWithSource
+ source: package:test/a.dart
+ selectedSource: package:test/a.dart
+ selectedUriContent: a.dart
+ uriContent: a.dart
+ uriElement: <null>
+ uriSource: package:test/a.dart
+''');
+ }
+
+ test_inLibrary_notLibrary_partOfName() async {
+ newFile('$testPackageLibPath/a.dart', r'''
+part of my.lib;
+''');
+
+ await assertErrorsInCode(r'''
+import 'a.dart';
+''', [
+ error(CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY, 7, 8),
+ ]);
+
+ final node = findNode.import('a.dart');
+ assertResolvedNodeText(node, r'''
+ImportDirective
+ importKeyword: import
+ uri: SimpleStringLiteral
+ literal: 'a.dart'
+ semicolon: ;
+ element: LibraryImportElement
+ uri: DirectiveUriWithSource
+ source: package:test/a.dart
+ selectedSource: package:test/a.dart
+ selectedUriContent: a.dart
+ uriContent: a.dart
+ uriElement: <null>
+ uriSource: package:test/a.dart
+''');
+ }
+
+ test_inLibrary_notLibrary_partOfUri() async {
+ newFile('$testPackageLibPath/a.dart', r'''
+part of 'test.dart';
+''');
+
+ await assertErrorsInCode(r'''
+import 'a.dart';
+''', [
+ error(CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY, 7, 8),
+ ]);
+
+ final node = findNode.import('a.dart');
+ assertResolvedNodeText(node, r'''
+ImportDirective
+ importKeyword: import
+ uri: SimpleStringLiteral
+ literal: 'a.dart'
+ semicolon: ;
+ element: LibraryImportElement
+ uri: DirectiveUriWithSource
+ source: package:test/a.dart
+ selectedSource: package:test/a.dart
+ selectedUriContent: a.dart
+ uriContent: a.dart
+ uriElement: <null>
+ uriSource: package:test/a.dart
+''');
}
}
diff --git a/pkg/analyzer/test/src/dart/resolution/test_all.dart b/pkg/analyzer/test/src/dart/resolution/test_all.dart
index 6d2bd25..82538d6 100644
--- a/pkg/analyzer/test/src/dart/resolution/test_all.dart
+++ b/pkg/analyzer/test/src/dart/resolution/test_all.dart
@@ -16,7 +16,6 @@
import 'constructor_reference_test.dart' as constructor_reference;
import 'constructor_test.dart' as constructor;
import 'enum_test.dart' as enum_resolution;
-import 'export_test.dart' as export_;
import 'extension_method_test.dart' as extension_method;
import 'extension_override_test.dart' as extension_override;
import 'field_formal_parameter_test.dart' as field_formal_parameter;
@@ -41,6 +40,7 @@
import 'interpolation_string_test.dart' as interpolation_string;
import 'language_version_test.dart' as language_version;
import 'library_element_test.dart' as library_element;
+import 'library_export_test.dart' as library_export;
import 'library_import_prefix_test.dart' as library_import_prefix;
import 'library_import_test.dart' as library_import;
import 'local_function_test.dart' as local_function;
@@ -86,7 +86,6 @@
constructor.main();
constructor_reference.main();
enum_resolution.main();
- export_.main();
extension_method.main();
extension_override.main();
field_formal_parameter.main();
@@ -108,6 +107,7 @@
interpolation_string.main();
language_version.main();
library_element.main();
+ library_export.main();
library_import_prefix.main();
library_import.main();
local_function.main();
diff --git a/pkg/analyzer/test/src/summary/resolved_ast_printer.dart b/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
index 0c26b7e..c41a403 100644
--- a/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
+++ b/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
@@ -267,6 +267,14 @@
}
@override
+ void visitConfiguration(Configuration node) {
+ _writeln('Configuration');
+ _withIndent(() {
+ _writeNamedChildEntities(node);
+ });
+ }
+
+ @override
void visitConstructorDeclaration(ConstructorDeclaration node) {
_writeln('ConstructorDeclaration');
_withIndent(() {
@@ -353,6 +361,14 @@
}
@override
+ void visitDottedName(DottedName node) {
+ _writeln('DottedName');
+ _withIndent(() {
+ _writeNamedChildEntities(node);
+ });
+ }
+
+ @override
void visitDoubleLiteral(DoubleLiteral node) {
_writeln('DoubleLiteral');
_withIndent(() {
@@ -1380,6 +1396,12 @@
final uriStr = _stringOfSource(uri.augmentation.source);
_writelnWithIndent('uri: $uriStr');
});
+ } else if (uri is DirectiveUriWithLibrary) {
+ _writeln('DirectiveUriWithLibrary');
+ _withIndent(() {
+ final uriStr = _stringOfSource(uri.library.source);
+ _writelnWithIndent('uri: $uriStr');
+ });
} else if (uri is DirectiveUriWithUnit) {
_writeln('DirectiveUriWithUnit');
_withIndent(() {
@@ -1438,6 +1460,10 @@
_sink.writeln('<null>');
} else if (element is AugmentationImportElement) {
_writeAugmentationImportElement(element);
+ } else if (element is LibraryExportElement) {
+ _writeLibraryExportElement(element);
+ } else if (element is LibraryImportElement) {
+ _writeLibraryImportElement(element);
} else if (element is PartElement) {
_writePartElement(element);
} else {
@@ -1464,6 +1490,24 @@
}
}
+ void _writeLibraryExportElement(LibraryExportElement element) {
+ _writeln('LibraryExportElement');
+ _withIndent(() {
+ _sink.write(_indent);
+ _sink.write('uri: ');
+ _writeDirectiveUri(element.uri);
+ });
+ }
+
+ void _writeLibraryImportElement(LibraryImportElement element) {
+ _writeln('LibraryImportElement');
+ _withIndent(() {
+ _sink.write(_indent);
+ _sink.write('uri: ');
+ _writeDirectiveUri(element.uri);
+ });
+ }
+
void _writeln(String line) {
_sink.writeln(line);
}
diff --git a/pkg/compiler/README.md b/pkg/compiler/README.md
index a21d663..e574f92 100644
--- a/pkg/compiler/README.md
+++ b/pkg/compiler/README.md
@@ -223,8 +223,7 @@
* `lib/src/common/elements.dart`: provides an interface to lookup basic
elements like the class of `Object`, `int`, `List`, and their corresponding
- interface types, constructors for symbols, annotations such as
- `@MirrorsUsed`, the `identical` function, etc. These are normally restricted
+ interface types, constructors for symbols, annotations such as the `identical` function. These are normally restricted
to elements that are understood directly in Dart.
* `lib/src/js_backend/backend_helpers.dart`: provides a way to lookup internal
@@ -278,10 +277,6 @@
import, export, and part directives and keep crawling. It also triggers the
patch parser to load patch files.
-* `lib/src/mirrors_used.dart`: task that analyzes `@MirrorsUsed` annotations,
- which let the compiler continue to do tree-shaking even when code is used via
- `dart:mirrors`.
-
* Input/output: the compiler is designed to avoid all dependencies on dart:io.
Most data is consumed and emitted via provider APIs.
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types_new.dart b/pkg/compiler/lib/src/js_backend/runtime_types_new.dart
index a0f4161..31de9ed 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types_new.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types_new.dart
@@ -20,6 +20,7 @@
import 'namer.dart';
import 'native_data.dart';
import 'runtime_types_codegen.dart' show RuntimeTypesSubstitutions;
+import 'runtime_types_new_interfaces.dart' as interfaces;
class RecipeEncoding {
final jsAst.Literal recipe;
@@ -28,13 +29,16 @@
const RecipeEncoding(this.recipe, this.typeVariables);
}
-abstract class RecipeEncoder {
+abstract class RecipeEncoder implements interfaces.RecipeEncoder {
/// Returns a [RecipeEncoding] representing the given [recipe] to be
/// evaluated against a type environment with shape [structure].
RecipeEncoding encodeRecipe(ModularEmitter emitter,
TypeEnvironmentStructure environmentStructure, TypeRecipe recipe);
- jsAst.Literal encodeGroundRecipe(ModularEmitter emitter, TypeRecipe recipe);
+ @override
+ // TODO(48820): Remove covariant when ModularEmitter is migrated.
+ jsAst.Literal encodeGroundRecipe(
+ covariant ModularEmitter emitter, TypeRecipe recipe);
/// Returns a [jsAst.Literal] representing [supertypeArgument] to be evaluated
/// against a [FullTypeEnvironmentStructure] representing [declaringType]. Any
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types_new_interfaces.dart b/pkg/compiler/lib/src/js_backend/runtime_types_new_interfaces.dart
new file mode 100644
index 0000000..2b65d05
--- /dev/null
+++ b/pkg/compiler/lib/src/js_backend/runtime_types_new_interfaces.dart
@@ -0,0 +1,7 @@
+import '../js_emitter/code_emitter_task_interfaces.dart';
+import '../js_model/type_recipe.dart';
+import '../js/js.dart' as jsAst;
+
+abstract class RecipeEncoder {
+ jsAst.Literal encodeGroundRecipe(ModularEmitter emitter, TypeRecipe recipe);
+}
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types_resolution.dart b/pkg/compiler/lib/src/js_backend/runtime_types_resolution.dart
index 9791f4a..1ac3892 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types_resolution.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types_resolution.dart
@@ -2,8 +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 file.
-// @dart = 2.10
-
library js_backend.runtime_types_resolution;
import '../common.dart';
@@ -14,19 +12,20 @@
import '../elements/types.dart';
import '../ir/runtime_type_analysis.dart';
import '../kernel/kelements.dart';
-import '../kernel/kernel_world.dart';
+import '../kernel/kernel_world_interfaces.dart';
import '../options.dart';
import '../serialization/serialization.dart';
import '../universe/class_hierarchy.dart';
import '../universe/class_set.dart';
import '../universe/feature.dart';
import '../universe/selector.dart';
-import '../world.dart';
+import '../world_interfaces.dart';
import 'backend_usage.dart';
abstract class RtiNode {
Entity get entity;
- Set<RtiNode> _dependencies;
+
+ Set<RtiNode>? _dependencies;
bool _hasTest = false;
Iterable<RtiNode> get dependencies => _dependencies ?? const [];
@@ -40,17 +39,14 @@
// [entity]!
return false;
}
- _dependencies ??= {};
- return _dependencies.add(node);
+ return (_dependencies ??= {}).add(node);
}
void markTest() {
if (!hasTest) {
_hasTest = true;
- if (_dependencies != null) {
- for (RtiNode node in _dependencies) {
- node.markTest();
- }
+ for (RtiNode node in dependencies) {
+ node.markTest();
}
}
}
@@ -87,11 +83,13 @@
final Entity function;
final ParameterStructure parameterStructure;
final bool isCallTarget;
- final Name instanceName;
+ final Name? instanceName;
final bool isNoSuchMethod;
MethodNode(this.function, this.parameterStructure,
- {this.isCallTarget, this.instanceName, this.isNoSuchMethod = false});
+ {required this.isCallTarget,
+ this.instanceName,
+ this.isNoSuchMethod = false});
@override
Entity get entity => function;
@@ -139,10 +137,10 @@
@override
bool selectorApplies(Selector selector, BuiltWorld world) {
if (property.memberName != selector.memberName) return false;
- if (type is FunctionType &&
- !selector.callStructure
- .signatureApplies(ParameterStructure.fromType(type))) return false;
- return true;
+ final myType = type;
+ return myType is! FunctionType ||
+ selector.callStructure
+ .signatureApplies(ParameterStructure.fromType(myType));
}
@override
@@ -159,7 +157,7 @@
final Map<ClassEntity, ClassNode> _classes = {};
final Map<Entity, MethodNode> _methods = {};
final Map<MemberEntity, CallablePropertyNode> _callableProperties = {};
- Map<Selector, Set<Entity>> _appliedSelectorMap;
+ final Map<Selector, Set<Entity>> _appliedSelectorMap = {};
final Map<Entity, Set<GenericInstantiation>> _instantiationMap = {};
final Map<ClassEntity, Set<InterfaceType>> _classInstantiationMap = {};
@@ -234,7 +232,7 @@
/// needs it in order to generate the check against `A<int>`.
///
Iterable<Entity> getTypeArgumentDependencies(Entity entity) {
- Iterable<RtiNode> dependencies;
+ Iterable<RtiNode>? dependencies;
if (entity is ClassEntity) {
dependencies = _classes[entity]?.dependencies;
} else if (_isProperty(entity)) {
@@ -272,7 +270,7 @@
return _methods.putIfAbsent(function, () {
MethodNode node;
if (function is FunctionEntity) {
- Name instanceName;
+ Name? instanceName;
bool isCallTarget;
bool isNoSuchMethod;
if (function.isInstanceMember) {
@@ -289,7 +287,7 @@
isNoSuchMethod: isNoSuchMethod);
} else {
ParameterStructure parameterStructure = ParameterStructure.fromType(
- _elementEnvironment.getLocalFunctionType(function));
+ _elementEnvironment.getLocalFunctionType(function as Local));
node = MethodNode(function, parameterStructure, isCallTarget: true);
}
return node;
@@ -312,7 +310,7 @@
///
void registerDependencies(RtiNode node, DartType type) {
type.forEachTypeVariable((TypeVariableType typeVariable) {
- Entity typeDeclaration = typeVariable.element.typeDeclaration;
+ final typeDeclaration = typeVariable.element.typeDeclaration!;
if (typeDeclaration is ClassEntity) {
node.addDependency(_getClassNode(typeDeclaration));
} else {
@@ -329,7 +327,7 @@
}
void onTypeVariable(TypeVariableType type) {
- Entity declaration = type.element.typeDeclaration;
+ final declaration = type.element.typeDeclaration!;
if (declaration is ClassEntity) {
node.addDependency(_getClassNode(declaration));
} else {
@@ -362,18 +360,12 @@
//
// TODO(johnniwinther): Make this dependency visible from code, possibly
// using generic methods.
- if (_commonElements.jsArrayClass != null) {
- _getClassNode(_commonElements.jsArrayClass)
- .addDependency(_getClassNode(_commonElements.listClass));
- }
- if (_commonElements.setLiteralClass != null) {
- _getClassNode(_commonElements.setLiteralClass)
- .addDependency(_getClassNode(_commonElements.setClass));
- }
- if (_commonElements.mapLiteralClass != null) {
- _getClassNode(_commonElements.mapLiteralClass)
- .addDependency(_getClassNode(_commonElements.mapClass));
- }
+ _getClassNode(_commonElements.jsArrayClass)
+ .addDependency(_getClassNode(_commonElements.listClass));
+ _getClassNode(_commonElements.setLiteralClass)
+ .addDependency(_getClassNode(_commonElements.setClass));
+ _getClassNode(_commonElements.mapLiteralClass)
+ .addDependency(_getClassNode(_commonElements.mapClass));
void processCheckedType(DartType type) {
var typeWithoutNullability = type.withoutNullability;
@@ -479,7 +471,7 @@
void _propagateTests() {
void processTypeVariableType(TypeVariableType type) {
TypeVariableEntity variable = type.element;
- final typeDeclaration = variable.typeDeclaration;
+ final typeDeclaration = variable.typeDeclaration!;
if (typeDeclaration is ClassEntity) {
_getClassNode(typeDeclaration).markTest();
} else {
@@ -559,7 +551,7 @@
void _addImplicitChecksViaInstantiation(TypeVariableType variable) {
TypeVariableEntity entity = variable.element;
- Entity declaration = entity.typeDeclaration;
+ final declaration = entity.typeDeclaration!;
if (declaration is ClassEntity) {
classInstantiationsOf(declaration).forEach((InterfaceType type) {
_addImplicitCheck(type.typeArguments[entity.index]);
@@ -606,9 +598,8 @@
// set of is-checks.
for (ClassEntity base in _classHierarchy.allSubtypesOf(cls)) {
classInstantiationsOf(base).forEach((InterfaceType subtype) {
- InterfaceType instance = _dartTypes.asInstanceOf(subtype, cls);
- assert(instance != null);
- _addImplicitChecks(instance.typeArguments);
+ final instance = _dartTypes.asInstanceOf(subtype, cls);
+ _addImplicitChecks(instance!.typeArguments);
});
}
});
@@ -621,10 +612,6 @@
_addImplicitChecks(typeArguments);
});
- if (forRtiNeeds) {
- _appliedSelectorMap = {};
- }
-
_world.forEachDynamicTypeArgument(
(Selector selector, Iterable<DartType> typeArguments) {
for (CallableNode node in [
@@ -650,7 +637,7 @@
void Function(InterfaceType) onInterface;
void Function(TypeVariableType) onTypeVariable;
- _DependencyVisitor({this.onInterface, this.onTypeVariable});
+ _DependencyVisitor({required this.onInterface, required this.onTypeVariable});
@override
bool handleInterfaceType(InterfaceType type) {
@@ -824,8 +811,8 @@
classesNeedingTypeArguments,
methodsNeedingSignature,
methodsNeedingTypeArguments,
- null,
- null,
+ const {},
+ const {},
selectorsNeedingTypeArguments,
instantiationsNeedingTypeArguments);
}
@@ -837,8 +824,8 @@
sink.writeClasses(classesNeedingTypeArguments);
sink.writeMembers(methodsNeedingSignature);
sink.writeMembers(methodsNeedingTypeArguments);
- assert(localFunctionsNeedingSignature == null);
- assert(localFunctionsNeedingTypeArguments == null);
+ assert(localFunctionsNeedingSignature.isEmpty);
+ assert(localFunctionsNeedingTypeArguments.isEmpty);
sink.writeList(selectorsNeedingTypeArguments,
(Selector selector) => selector.writeToDataSink(sink));
sink.writeList(instantiationsNeedingTypeArguments, sink.writeInt);
@@ -937,17 +924,18 @@
final Set<Local> localFunctionsUsingTypeVariableLiterals = {};
- Map<Selector, Set<Entity>> selectorsNeedingTypeArgumentsForTesting;
+ Map<Selector, Set<Entity>>? selectorsNeedingTypeArgumentsForTesting;
- Map<Entity, Set<GenericInstantiation>>
+ Map<Entity, Set<GenericInstantiation>>?
_instantiatedEntitiesNeedingTypeArgumentsForTesting;
+
Map<Entity, Set<GenericInstantiation>>
get instantiatedEntitiesNeedingTypeArgumentsForTesting =>
_instantiatedEntitiesNeedingTypeArgumentsForTesting ?? const {};
final Set<GenericInstantiation> _genericInstantiations = {};
- TypeVariableTests typeVariableTestsForTesting;
+ TypeVariableTests? typeVariableTestsForTesting;
RuntimeTypesNeedBuilderImpl(this._elementEnvironment);
@@ -973,7 +961,8 @@
@override
void registerTypeVariableLiteral(TypeVariableType variable) {
- Entity typeDeclaration = variable.element.typeDeclaration;
+ final typeDeclaration = variable.element.typeDeclaration;
+ assert(typeDeclaration != null);
if (typeDeclaration is ClassEntity) {
registerClassUsingTypeVariableLiteral(typeDeclaration);
} else if (typeDeclaration is FunctionEntity) {
@@ -1027,7 +1016,7 @@
} else if (_isProperty(entity)) {
// Do nothing. We just need to visit the dependencies.
} else {
- localFunctionsNeedingTypeArguments.add(entity);
+ localFunctionsNeedingTypeArguments.add(entity as Local);
}
Iterable<Entity> dependencies =
@@ -1042,35 +1031,33 @@
closedWorld.closurizedMembersWithFreeTypeVariables.toSet();
// Check local functions and closurized members.
- void checkClosures({DartType potentialSubtypeOf}) {
+ void checkClosures({required DartType potentialSubtypeOf}) {
bool checkFunctionType(FunctionType functionType) {
- ClassEntity contextClass = DartTypes.getClassContext(functionType);
+ final contextClass = DartTypes.getClassContext(functionType);
if (contextClass != null &&
- (potentialSubtypeOf == null ||
- closedWorld.dartTypes
- .isPotentialSubtype(functionType, potentialSubtypeOf))) {
+ (closedWorld.dartTypes
+ .isPotentialSubtype(functionType, potentialSubtypeOf))) {
potentiallyNeedTypeArguments(contextClass);
return true;
}
return false;
}
- Set<Local> localFunctionsToRemove;
- Set<FunctionEntity> closurizedMembersToRemove;
+ Set<Local>? localFunctionsToRemove;
+ Set<FunctionEntity>? closurizedMembersToRemove;
for (Local function in localFunctions) {
FunctionType functionType =
_elementEnvironment.getLocalFunctionType(function);
- if (potentialSubtypeOf == null ||
- closedWorld.dartTypes
- .isPotentialSubtype(functionType, potentialSubtypeOf,
- // TODO(johnniwinther): Use register generic instantiations
- // instead.
- assumeInstantiations: _genericInstantiations.isNotEmpty)) {
+ if (closedWorld.dartTypes
+ .isPotentialSubtype(functionType, potentialSubtypeOf,
+ // TODO(johnniwinther): Use register generic instantiations
+ // instead.
+ assumeInstantiations: _genericInstantiations.isNotEmpty)) {
if (functionType.typeVariables.isNotEmpty) {
potentiallyNeedTypeArguments(function);
}
functionType.forEachTypeVariable((TypeVariableType typeVariable) {
- Entity typeDeclaration = typeVariable.element.typeDeclaration;
+ final typeDeclaration = typeVariable.element.typeDeclaration!;
if (!processedEntities.contains(typeDeclaration)) {
potentiallyNeedTypeArguments(typeDeclaration);
}
@@ -1110,7 +1097,7 @@
type.forEachTypeVariable((TypeVariableType typeVariable) {
// This handles checks against type variables and function types
// containing type variables.
- Entity typeDeclaration = typeVariable.element.typeDeclaration;
+ final typeDeclaration = typeVariable.element.typeDeclaration!;
potentiallyNeedTypeArguments(typeDeclaration);
});
if (type is FunctionType) {
@@ -1163,11 +1150,11 @@
checkFunction(method, _elementEnvironment.getFunctionType(method));
}
});
- for (KLocalFunction function in closedWorld.genericLocalFunctions) {
+ for (final function in closedWorld.genericLocalFunctions) {
if (closedWorld.annotationsData
// TODO(johnniwinther): Support @pragma on local functions and use
// this here instead of the enclosing member.
- .getParameterCheckPolicy(function.memberContext)
+ .getParameterCheckPolicy((function as KLocalFunction).memberContext)
.isEmitted) {
checkFunction(
function, _elementEnvironment.getLocalFunctionType(function));
@@ -1215,7 +1202,7 @@
throw UnsupportedError('Unexpected type $type');
}
- void addClass(ClassEntity cls) {
+ void addClass(ClassEntity? cls) {
if (cls != null) {
classesDirectlyNeedingRuntimeType.add(cls);
}
@@ -1239,7 +1226,7 @@
Iterable<ClassEntity> receiverClasses =
impliedClasses(runtimeTypeUse.receiverType);
Iterable<ClassEntity> argumentClasses =
- impliedClasses(runtimeTypeUse.argumentType);
+ impliedClasses(runtimeTypeUse.argumentType!);
for (ClassEntity receiverClass in receiverClasses) {
for (ClassEntity argumentClass in argumentClasses) {
@@ -1303,7 +1290,7 @@
FunctionType functionType =
_elementEnvironment.getLocalFunctionType(function);
functionType.forEachTypeVariable((TypeVariableType typeVariable) {
- Entity typeDeclaration = typeVariable.element.typeDeclaration;
+ final typeDeclaration = typeVariable.element.typeDeclaration!;
if (!processedEntities.contains(typeDeclaration)) {
potentiallyNeedTypeArguments(typeDeclaration);
}
@@ -1313,7 +1300,7 @@
for (FunctionEntity function
in closedWorld.closurizedMembersWithFreeTypeVariables) {
methodsNeedingSignature.add(function);
- potentiallyNeedTypeArguments(function.enclosingClass);
+ potentiallyNeedTypeArguments(function.enclosingClass!);
}
}
@@ -1326,8 +1313,7 @@
localFunctionsNeedingTypeArguments.contains(target)) {
selectorsNeedingTypeArguments.add(selector);
if (retainDataForTesting) {
- selectorsNeedingTypeArgumentsForTesting ??= {};
- selectorsNeedingTypeArgumentsForTesting
+ (selectorsNeedingTypeArgumentsForTesting ??= {})
.putIfAbsent(selector, () => {})
.add(target);
} else {
@@ -1352,8 +1338,7 @@
if (retainDataForTesting) {
if (methodsNeedingTypeArguments.contains(target) ||
localFunctionsNeedingTypeArguments.contains(target)) {
- _instantiatedEntitiesNeedingTypeArgumentsForTesting ??= {};
- _instantiatedEntitiesNeedingTypeArgumentsForTesting
+ (_instantiatedEntitiesNeedingTypeArgumentsForTesting ??= {})
.putIfAbsent(target, () => {})
.addAll(instantiations);
}
diff --git a/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
index 0e14253..7a3be27 100644
--- a/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
@@ -234,7 +234,7 @@
code = js(template, fieldName);
}
jsAst.Name getterName = _namer.deriveGetterName(field.accessorName);
- return StubMethod(getterName, code);
+ return StubMethod(getterName, code, element: field.element);
}
/// Generates a setter for the given [field].
@@ -259,7 +259,7 @@
}
jsAst.Name setterName = _namer.deriveSetterName(field.accessorName);
- return StubMethod(setterName, code);
+ return StubMethod(setterName, code, element: field.element);
}
}
diff --git a/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart b/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
index 5932c85..790e988 100644
--- a/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
+++ b/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
@@ -26,6 +26,7 @@
import 'startup_emitter/emitter.dart' as startup_js_emitter;
import 'startup_emitter/fragment_merger.dart';
+import 'code_emitter_task_interfaces.dart' as interfaces;
import 'metadata_collector.dart' show MetadataCollector;
import 'model.dart';
import 'native_emitter.dart' show NativeEmitter;
@@ -155,7 +156,7 @@
///
/// Note that the emission phase is not itself modular but performed on
/// the closed world computed by the codegen enqueuer.
-abstract class ModularEmitter {
+abstract class ModularEmitter implements interfaces.ModularEmitter {
/// Returns the JS prototype of the given class [e].
jsAst.Expression prototypeAccess(ClassEntity e);
diff --git a/pkg/compiler/lib/src/js_emitter/code_emitter_task_interfaces.dart b/pkg/compiler/lib/src/js_emitter/code_emitter_task_interfaces.dart
new file mode 100644
index 0000000..3071fdf
--- /dev/null
+++ b/pkg/compiler/lib/src/js_emitter/code_emitter_task_interfaces.dart
@@ -0,0 +1,5 @@
+// Copyright (c) 2022, 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.
+
+abstract class ModularEmitter {}
diff --git a/pkg/compiler/lib/src/js_emitter/instantiation_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/instantiation_stub_generator.dart
index 9aadb62..6c7af9e 100644
--- a/pkg/compiler/lib/src/js_emitter/instantiation_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/instantiation_stub_generator.dart
@@ -97,7 +97,7 @@
// TODO(sra): .withSourceInformation(sourceInformation);
jsAst.Name name = _namer.invocationName(callSelector);
- return ParameterStubMethod(name, null, function);
+ return ParameterStubMethod(name, null, function, element: functionField);
}
/// Generates a stub for a 'signature' selector. The stub calls the underlying
@@ -120,7 +120,8 @@
// TODO(sra): Generate source information for stub that has no member.
// TODO(sra): .withSourceInformation(sourceInformation);
- return ParameterStubMethod(operatorSignature, null, function);
+ return ParameterStubMethod(operatorSignature, null, function,
+ element: functionField);
}
jsAst.Fun _generateSignatureNewRti(FieldEntity functionField) =>
diff --git a/pkg/compiler/lib/src/js_emitter/metadata_collector.dart b/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
index ae10aaa..76c71d4 100644
--- a/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
+++ b/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
@@ -2,8 +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 file.
-// @dart = 2.10
-
library dart2js.js_emitter.metadata_collector;
import 'package:js_ast/src/precedence.dart' as js_precedence;
@@ -13,10 +11,10 @@
import '../elements/types.dart';
import '../js/js.dart' as jsAst;
-import '../js_backend/runtime_types_new.dart' show RecipeEncoder;
+import '../js_backend/runtime_types_new_interfaces.dart' show RecipeEncoder;
import '../js_model/type_recipe.dart' show TypeExpressionRecipe;
-import 'code_emitter_task.dart' show Emitter;
+import 'code_emitter_task_interfaces.dart' show ModularEmitter;
/// Represents an entry's position in one of the global metadata arrays.
///
@@ -76,17 +74,15 @@
}
class _MetadataList extends jsAst.DeferredExpression {
- jsAst.Expression _value;
+ late final jsAst.Expression _value;
void setExpression(jsAst.Expression value) {
- assert(_value == null);
assert(value.precedenceLevel == this.precedenceLevel);
_value = value;
}
@override
jsAst.Expression get value {
- assert(_value != null);
return _value;
}
@@ -96,7 +92,7 @@
class MetadataCollector implements jsAst.TokenFinalizer {
final DiagnosticReporter reporter;
- final Emitter _emitter;
+ final ModularEmitter _emitter;
final RecipeEncoder _rtiRecipeEncoder;
/// A map used to canonicalize the entries of metadata.
@@ -143,7 +139,7 @@
}
}
- jsAst.Expression reifyType(DartType type, OutputUnit outputUnit) {
+ jsAst.Expression? reifyType(DartType type, OutputUnit outputUnit) {
return _addTypeInOutputUnit(type, outputUnit);
}
@@ -153,19 +149,11 @@
}
jsAst.Expression _addTypeInOutputUnit(DartType type, OutputUnit outputUnit) {
- _typesMap[outputUnit] ??= {};
- BoundMetadataEntry metadataEntry;
-
- if (_typesMap[outputUnit].containsKey(type)) {
- metadataEntry = _typesMap[outputUnit][type].single;
- } else {
- _typesMap[outputUnit].putIfAbsent(type, () {
- metadataEntry =
- BoundMetadataEntry(_computeTypeRepresentationNewRti(type));
- return [metadataEntry];
- });
- }
- return metadataEntry;
+ final typeMap = _typesMap[outputUnit] ??= {};
+ final metadataEntryList = (typeMap[type] ??= [
+ BoundMetadataEntry(_computeTypeRepresentationNewRti(type))
+ ]);
+ return metadataEntryList.single;
}
@override
@@ -194,14 +182,13 @@
entry.finalize(count++);
}
- List<jsAst.Node> values =
- entries.map((BoundMetadataEntry e) => e.entry).toList();
+ final values = entries.map((BoundMetadataEntry e) => e.entry).toList();
return jsAst.ArrayInitializer(values);
}
_typesTokens.forEach((OutputUnit outputUnit, _MetadataList token) {
- Map<DartType, List<BoundMetadataEntry>> typesMap = _typesMap[outputUnit];
+ final typesMap = _typesMap[outputUnit];
if (typesMap != null) {
typesMap.values.forEach(countTokensInTypes);
token.setExpression(finalizeMap(typesMap));
diff --git a/pkg/compiler/lib/src/js_emitter/model.dart b/pkg/compiler/lib/src/js_emitter/model.dart
index a862f48..fd16183 100644
--- a/pkg/compiler/lib/src/js_emitter/model.dart
+++ b/pkg/compiler/lib/src/js_emitter/model.dart
@@ -2,8 +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 file.
-// @dart = 2.10
-
library dart2js.new_js_emitter.model;
import '../common/elements.dart';
@@ -14,7 +12,7 @@
import '../js/js.dart' as js show Expression, Name, Statement, TokenFinalizer;
import '../js/js_debug.dart' as js show nodeToString;
import '../js_backend/runtime_types_codegen.dart';
-import 'js_emitter.dart' show MetadataCollector;
+import 'metadata_collector.dart' show MetadataCollector;
class Program {
final List<Fragment> fragments;
@@ -32,10 +30,8 @@
Program(this.fragments, this.typeToInterceptorMap, this._metadataCollector,
this.finalizers,
- {this.needsNativeSupport, this.outputContainsConstantList}) {
- assert(needsNativeSupport != null);
- assert(outputContainsConstantList != null);
- }
+ {required this.needsNativeSupport,
+ required this.outputContainsConstantList});
void mergeOutputUnitMetadata(OutputUnit target, OutputUnit source) {
_metadataCollector.mergeOutputUnitMetadata(target, source);
@@ -187,8 +183,8 @@
final bool usesNonNullableInitialization;
StaticField(this.element, this.name, this.getterName, this.code,
- {this.isFinal,
- this.isLazy,
+ {required this.isFinal,
+ required this.isLazy,
this.isInitializedByConstant = false,
this.usesNonNullableInitialization = false});
@@ -224,8 +220,8 @@
final ClassTypeData typeData;
final js.Name name;
- Class _superclass;
- Class _mixinClass;
+ Class? superclass;
+ Class? mixinClass;
final List<Method> methods;
final List<Field> fields;
final List<StubMethod> isChecks;
@@ -250,7 +246,7 @@
/// If non-null, this class is used as a base class for closures with a fixed
/// small number of arguments in order to inherit `Function.apply`
/// metadata. The value is the fixed number of arguments.
- final int sharedClosureApplyMetadata;
+ final int? sharedClosureApplyMetadata;
final bool isMixinApplicationWithMembers;
@@ -262,13 +258,13 @@
bool isEager = false;
/// Leaf tags. See [NativeEmitter.prepareNativeClasses].
- List<String> nativeLeafTags;
+ List<String>? nativeLeafTags;
/// Non-leaf tags. See [NativeEmitter.prepareNativeClasses].
- List<String> nativeNonLeafTags;
+ List<String>? nativeNonLeafTags;
/// Native extensions. See [NativeEmitter.prepareNativeClasses].
- List<Class> nativeExtensions;
+ List<Class>? nativeExtensions;
Class(
this.element,
@@ -282,36 +278,18 @@
this.gettersSetters,
this.isChecks,
this.functionTypeIndex,
- {this.hasRtiField,
- this.onlyForRti,
- this.onlyForConstructor,
- this.isDirectlyInstantiated,
- this.isNative,
- this.isClosureBaseClass,
+ {required this.hasRtiField,
+ required this.onlyForRti,
+ required this.onlyForConstructor,
+ required this.isDirectlyInstantiated,
+ required this.isNative,
+ required this.isClosureBaseClass,
this.sharedClosureApplyMetadata,
- this.isMixinApplicationWithMembers}) {
- assert(onlyForRti != null);
- assert(onlyForConstructor != null);
- assert(isDirectlyInstantiated != null);
- assert(isNative != null);
- assert(isClosureBaseClass != null);
- }
+ required this.isMixinApplicationWithMembers});
bool get isSimpleMixinApplication => false;
- Class get superclass => _superclass;
-
- void setSuperclass(Class superclass) {
- _superclass = superclass;
- }
-
- Class get mixinClass => _mixinClass;
-
- void setMixinClass(Class mixinClass) {
- _mixinClass = mixinClass;
- }
-
- js.Name get superclassName => superclass?.name;
+ js.Name? get superclassName => superclass?.name;
@override
String toString() => 'Class(name=${name.key},element=$element)';
@@ -328,10 +306,10 @@
List<StubMethod> gettersSetters,
List<StubMethod> isChecks,
js.Expression functionTypeIndex,
- {bool hasRtiField,
- bool onlyForRti,
- bool onlyForConstructor,
- bool isDirectlyInstantiated})
+ {required bool hasRtiField,
+ required bool onlyForRti,
+ required bool onlyForConstructor,
+ required bool isDirectlyInstantiated})
: super(
element,
typeData,
@@ -424,7 +402,7 @@
abstract class Method {
/// The element should only be used during the transition to the new model.
/// Uses indicate missing information in the model.
- final MemberEntity element;
+ final MemberEntity? element;
/// The name of the method. If the method is a [ParameterStubMethod] for a
/// static function, then the name can be `null`. In that case, only the
@@ -438,7 +416,7 @@
/// A method that corresponds to a method in the original Dart program.
abstract class DartMethod extends Method {
final bool needsTearOff;
- final js.Name tearOffName;
+ final js.Name? tearOffName;
final List<ParameterStubMethod> parameterStubs;
final bool canBeApplied;
final int applyIndex;
@@ -448,7 +426,7 @@
// If the type is encoded in the metadata table this field contains an index
// into the table. Otherwise the type contains type variables in which case
// this field holds a function computing the function signature.
- final js.Expression functionType;
+ final js.Expression? functionType;
// Signature information for this method. [optionalParameterDefaultValues] is
// only required and stored here if the method [canBeApplied]. The count is
@@ -459,24 +437,20 @@
// If this method can be torn off, contains the name of the corresponding
// call method. For example, for the member `foo$1$name` it would be
// `call$1$name` (in unminified mode).
- final js.Name callName;
+ final js.Name? callName;
DartMethod(FunctionEntity element, js.Name name, js.Expression code,
this.parameterStubs, this.callName,
- {this.needsTearOff,
+ {required this.needsTearOff,
this.tearOffName,
- this.canBeApplied,
- this.requiredParameterCount,
+ required this.canBeApplied,
+ required this.requiredParameterCount,
this.optionalParameterDefaultValues,
this.functionType,
- this.applyIndex})
+ required this.applyIndex})
: super(element, name, code) {
- assert(needsTearOff != null);
assert(!needsTearOff || tearOffName != null);
- assert(canBeApplied != null);
- assert(!canBeApplied ||
- (requiredParameterCount != null &&
- optionalParameterDefaultValues != null));
+ assert(!canBeApplied || optionalParameterDefaultValues != null);
}
bool get isStatic;
@@ -487,7 +461,7 @@
/// a method via `super`. If [aliasName] is non-null, the emitter has to
/// ensure that this method is registered on the prototype under both [name]
/// and [aliasName].
- final js.Name aliasName;
+ final js.Name? aliasName;
/// `true` if the tear-off needs to access methods directly rather than rely
/// on JavaScript prototype lookup. This happens when a tear-off getter is
@@ -516,18 +490,18 @@
js.Expression code,
List<ParameterStubMethod> parameterStubs,
js.Name callName, {
- bool needsTearOff,
- js.Name tearOffName,
+ required bool needsTearOff,
+ js.Name? tearOffName,
this.aliasName,
- this.tearOffNeedsDirectAccess,
- bool canBeApplied,
- int requiredParameterCount,
+ required this.tearOffNeedsDirectAccess,
+ required bool canBeApplied,
+ required int requiredParameterCount,
/* List | Map */ optionalParameterDefaultValues,
- this.isClosureCallMethod,
- this.inheritsApplyMetadata,
- this.isIntercepted,
- js.Expression functionType,
- int applyIndex,
+ required this.isClosureCallMethod,
+ required this.inheritsApplyMetadata,
+ required this.isIntercepted,
+ js.Expression? functionType,
+ required int applyIndex,
}) : super(element, name, code, parameterStubs, callName,
needsTearOff: needsTearOff,
tearOffName: tearOffName,
@@ -535,9 +509,7 @@
requiredParameterCount: requiredParameterCount,
optionalParameterDefaultValues: optionalParameterDefaultValues,
functionType: functionType,
- applyIndex: applyIndex) {
- assert(isClosureCallMethod != null);
- }
+ applyIndex: applyIndex);
@override
bool get isStatic => false;
@@ -553,7 +525,7 @@
/// to a method in the original Dart program. Examples are getter and setter
/// stubs and stubs to dispatch calls to methods with optional parameters.
class StubMethod extends Method {
- StubMethod(js.Name name, js.Expression code, {MemberEntity element})
+ StubMethod(js.Name name, js.Expression code, {MemberEntity? element})
: super(element, name, code);
@override
@@ -578,10 +550,10 @@
/// name when it is used this way.
///
/// If a stub's member can not be torn off, the [callName] is `null`.
- js.Name callName;
+ js.Name? callName;
ParameterStubMethod(js.Name name, this.callName, js.Expression code,
- {MemberEntity element})
+ {required MemberEntity element})
: super(name, code, element: element);
@override
@@ -597,13 +569,13 @@
class StaticDartMethod extends DartMethod implements StaticMethod {
StaticDartMethod(FunctionEntity element, js.Name name, js.Expression code,
List<ParameterStubMethod> parameterStubs, js.Name callName,
- {bool needsTearOff,
- js.Name tearOffName,
- bool canBeApplied,
- int requiredParameterCount,
+ {required bool needsTearOff,
+ js.Name? tearOffName,
+ required bool canBeApplied,
+ required int requiredParameterCount,
/* List | Map */ optionalParameterDefaultValues,
- js.Expression functionType,
- int applyIndex})
+ js.Expression? functionType,
+ required int applyIndex})
: super(element, name, code, parameterStubs, callName,
needsTearOff: needsTearOff,
tearOffName: tearOffName,
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
index 542f7d6..112b504 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
@@ -200,7 +200,7 @@
_classes.forEach((ClassEntity cls, Class c) {
ClassEntity superclass = _elementEnvironment.getSuperClass(cls);
if (superclass != null) {
- c.setSuperclass(_classes[superclass]);
+ c.superclass = _classes[superclass];
assert(
c.onlyForConstructor || c.superclass != null,
failedAt(
@@ -211,7 +211,7 @@
if (c.isSimpleMixinApplication || c.isMixinApplicationWithMembers) {
ClassEntity effectiveMixinClass =
_elementEnvironment.getEffectiveMixinClass(cls);
- c.setMixinClass(_classes[effectiveMixinClass]);
+ c.mixinClass = _classes[effectiveMixinClass];
assert(
c.mixinClass != null,
failedAt(
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_merger.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_merger.dart
index f74885d..0c92464 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_merger.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_merger.dart
@@ -2,12 +2,10 @@
// 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.
-// @dart = 2.10
-
import 'dart:collection';
import '../../common/elements.dart' show ElementEnvironment;
import '../../deferred_load/output_unit.dart'
- show ImportDescription, OutputUnit, OutputUnitData, deferredPartFileName;
+ show OutputUnit, OutputUnitData, deferredPartFileName;
import '../../elements/entities.dart';
import '../../js/js.dart' as js;
import '../../options.dart';
@@ -167,8 +165,9 @@
final List<EmittedOutputUnit> emittedOutputUnits = [];
final Set<PreFragment> successors = {};
final Set<PreFragment> predecessors = {};
- FinalizedFragment finalizedFragment;
+ late final FinalizedFragment finalizedFragment;
int size = 0;
+
// TODO(joshualitt): interleave dynamically when it makes sense.
bool shouldInterleave = false;
@@ -275,7 +274,6 @@
Program program,
Map<OutputUnit, CodeFragment> outputUnitMap,
Map<CodeFragment, FinalizedFragment> codeFragmentMap) {
- assert(finalizedFragment == null);
List<CodeFragment> codeFragments = shouldInterleave
? [interleaveEmittedOutputUnits(program)]
: bundleEmittedOutputUnits(program);
@@ -390,7 +388,7 @@
String toString() {
List<String> outputUnitStrings = [];
for (var outputUnit in outputUnits) {
- List<String> importStrings = [];
+ List<String?> importStrings = [];
for (var import in outputUnit.imports) {
importStrings.add(import.name);
}
@@ -462,11 +460,11 @@
List<CodeFragment> codeFragments = [];
for (var outputUnit in outputUnits) {
if (omittedOutputUnits.contains(outputUnit)) continue;
- var codeFragment = outputUnitMap[outputUnit];
+ final codeFragment = outputUnitMap[outputUnit]!;
if (uniqueCodeFragments.add(codeFragment)) {
codeFragments.add(codeFragment);
}
- var finalizedFragment = codeFragmentMap[codeFragment];
+ final finalizedFragment = codeFragmentMap[codeFragment]!;
if (uniqueFinalizedFragments.add(finalizedFragment)) {
finalizedFragments.add(finalizedFragment);
}
@@ -487,16 +485,16 @@
for (int j = i + 1; j < allOutputUnits.length; j++) {
var b = allOutputUnits[j];
if (b.imports.containsAll(aImports)) {
- backEdges[b] ??= {};
+ final backEdge = backEdges[b] ??= {};
// Remove transitive edges from nodes that will reach 'b' from the
// edge we just added.
// Note: Because we add edges in order (starting from the smallest
// sets) we always add transitive edges before the last direct edge.
- backEdges[b].removeWhere((c) => aImports.containsAll(c.imports));
+ backEdge.removeWhere((c) => aImports.containsAll(c.imports));
// Create an edge to denote that 'b' must be loaded before 'a'.
- backEdges[b].add(a);
+ backEdge.add(a);
}
}
}
@@ -525,9 +523,9 @@
// Get a list of direct edges and then attach them to PreFragments.
var allEdges = createDirectEdges(outputUnits);
allEdges.forEach((outputUnit, edges) {
- var predecessor = outputUnitMap[outputUnit];
+ final predecessor = outputUnitMap[outputUnit]!;
for (var edge in edges) {
- var successor = outputUnitMap[edge];
+ final successor = outputUnitMap[edge]!;
predecessor.successors.add(successor);
successor.predecessors.add(predecessor);
}
@@ -576,7 +574,7 @@
/// {a}, {b}, {c}+{a, b}, {b, c}+{a, b, c}.
List<PreFragment> mergeFragments(List<PreFragment> preDeferredFragments) {
var components = separateComponents(preDeferredFragments);
- int desiredNumberOfFragment = _options.mergeFragmentsThreshold;
+ final desiredNumberOfFragment = _options.mergeFragmentsThreshold!;
int idealFragmentSize = (totalSize / desiredNumberOfFragment).ceil();
List<_Partition> partitions = [];
void add(PreFragment next) {
@@ -624,7 +622,7 @@
Map<String, List<OutputUnit>> outputUnitsToLoad = {};
for (var import in outputUnitData.deferredImportDescriptions.keys) {
- var loadId = outputUnitData.importDeferName[import];
+ final loadId = outputUnitData.importDeferName[import]!;
List<OutputUnit> loadList = [];
for (var outputUnit in sortedOutputUnits) {
assert(!outputUnit.isMainOutput);
@@ -659,9 +657,8 @@
outputUnitData.deferredImportDescriptions.keys
.forEach((ImportEntity import) {
var importDeferName = outputUnitData.importDeferName[import];
- List<FinalizedFragment> fragments = fragmentsToLoad[importDeferName];
- ImportDescription description =
- outputUnitData.deferredImportDescriptions[import];
+ final fragments = fragmentsToLoad[importDeferName]!;
+ final description = outputUnitData.deferredImportDescriptions[import]!;
String getName(LibraryEntity library) {
var name = _elementEnvironment.getLibraryName(library);
return name == '' ? '<unnamed>' : name;
diff --git a/pkg/compiler/lib/src/js_model/js_world_builder.dart b/pkg/compiler/lib/src/js_model/js_world_builder.dart
index 673cf82..5433635 100644
--- a/pkg/compiler/lib/src/js_model/js_world_builder.dart
+++ b/pkg/compiler/lib/src/js_model/js_world_builder.dart
@@ -318,8 +318,8 @@
classesNeedingTypeArguments,
methodsNeedingSignature,
methodsNeedingTypeArguments,
- null,
- null,
+ const {},
+ const {},
selectorsNeedingTypeArguments,
rtiNeed.instantiationsNeedingTypeArguments);
}
diff --git a/pkg/compiler/lib/src/kernel/kernel_world.dart b/pkg/compiler/lib/src/kernel/kernel_world.dart
index 8aede80..b60859b 100644
--- a/pkg/compiler/lib/src/kernel/kernel_world.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_world.dart
@@ -23,15 +23,20 @@
import '../world.dart';
import 'element_map.dart';
+import 'kernel_world_interfaces.dart' as interfaces;
/// The immutable result of the [ResolutionWorldBuilder].
-class KClosedWorld implements BuiltWorld {
+class KClosedWorld implements BuiltWorld, interfaces.KClosedWorld {
final KernelToElementMap elementMap;
+ @override
final KElementEnvironment elementEnvironment;
+ @override
final DartTypes dartTypes;
+ @override
final KCommonElements commonElements;
final NativeData nativeData;
final InterceptorData interceptorData;
+ @override
final BackendUsage backendUsage;
final NoSuchMethodData noSuchMethodData;
final Map<ClassEntity, Set<ClassEntity>> mixinUses;
@@ -75,11 +80,13 @@
///
/// A closurized method is considered live if the enclosing class has been
/// instantiated.
+ @override
final Set<FunctionEntity> closurizedMembersWithFreeTypeVariables;
/// Set of (live) local functions (closures).
///
/// A live function is one whose enclosing member function has been enqueued.
+ @override
final Iterable<Local> localFunctions;
@override
@@ -159,6 +166,7 @@
/// Returns `true` if [member] has been marked as used (called, read, etc.) in
/// this world builder.
+ @override
bool isMemberUsed(MemberEntity member) => liveMemberUsage.containsKey(member);
@override
diff --git a/pkg/compiler/lib/src/kernel/kernel_world_interfaces.dart b/pkg/compiler/lib/src/kernel/kernel_world_interfaces.dart
new file mode 100644
index 0000000..6bbd4ad
--- /dev/null
+++ b/pkg/compiler/lib/src/kernel/kernel_world_interfaces.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2022, 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 '../common/elements.dart';
+import '../elements/entities.dart';
+import '../elements/types.dart';
+import '../js_backend/backend_usage.dart';
+import '../world_interfaces.dart';
+
+abstract class KClosedWorld implements BuiltWorld {
+ KElementEnvironment get elementEnvironment;
+
+ KCommonElements get commonElements;
+
+ Iterable<Local> get localFunctions;
+
+ Set<FunctionEntity> get closurizedMembersWithFreeTypeVariables;
+
+ DartTypes get dartTypes;
+
+ BackendUsage get backendUsage;
+
+ bool isMemberUsed(MemberEntity member);
+}
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
index 884cef6..3f9581a 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -27,7 +27,7 @@
import 'world_interfaces.dart' as interfaces;
-export 'world_interfaces.dart' show World;
+export 'world_interfaces.dart' show World, BuiltWorld;
/// The [JClosedWorld] represents the information known about a program when
/// compiling with closed-world semantics.
@@ -228,56 +228,3 @@
/// Registers [interface] as a type argument to `extractTypeArguments`.
void registerExtractTypeArguments(ClassEntity interface);
}
-
-/// A [BuiltWorld] is an immutable result of a [WorldBuilder].
-abstract class BuiltWorld {
- ClassHierarchy get classHierarchy;
-
- /// Calls [f] for each live generic method.
- void forEachGenericMethod(void Function(FunctionEntity) f);
-
- /// All types that are checked either through is, as or checked mode checks.
- Iterable<DartType> get isChecks;
-
- /// All type variables named in recipes.
- Set<TypeVariableType> get namedTypeVariablesNewRti;
-
- /// All directly instantiated types, that is, the types of
- /// [directlyInstantiatedClasses].
- // TODO(johnniwinther): Improve semantic precision.
- Iterable<InterfaceType> get instantiatedTypes;
-
- // TODO(johnniwinther): Clean up these getters.
- /// Methods in instantiated classes that are potentially closurized.
- Iterable<FunctionEntity> get closurizedMembers;
-
- /// Static or top level methods that are closurized.
- Iterable<FunctionEntity> get closurizedStatics;
-
- /// Properties (fields and getters) which can be called as generic functions.
- Map<MemberEntity, DartType> get genericCallableProperties;
-
- /// Type variables used as type literals.
- Iterable<TypeVariableType> get typeVariableTypeLiterals;
-
- /// Live user-defined 'noSuchMethod' implementations.
- Iterable<FunctionEntity> get userNoSuchMethods;
-
- AnnotationsData get annotationsData;
-
- /// Calls [f] for each live generic instance methods.
- void forEachGenericInstanceMethod(void Function(FunctionEntity) f);
-
- /// Live generic local functions.
- Iterable<Local> get genericLocalFunctions;
-
- /// Call [f] for each generic [function] with the type arguments passed
- /// through static calls to [function].
- void forEachStaticTypeArgument(
- void f(Entity function, Set<DartType> typeArguments));
-
- /// Call [f] for each generic [selector] with the type arguments passed
- /// through dynamic calls to [selector].
- void forEachDynamicTypeArgument(
- void f(Selector selector, Set<DartType> typeArguments));
-}
diff --git a/pkg/compiler/lib/src/world_interfaces.dart b/pkg/compiler/lib/src/world_interfaces.dart
index 84c1a9d..6009784 100644
--- a/pkg/compiler/lib/src/world_interfaces.dart
+++ b/pkg/compiler/lib/src/world_interfaces.dart
@@ -16,13 +16,75 @@
abstract class JClosedWorld implements World {
AbstractValueDomain get abstractValueDomain;
+
JCommonElements get commonElements;
+
ClassHierarchy get classHierarchy;
+
DartTypes get dartTypes;
+
NativeData get nativeData;
+
AnnotationsData get annotationsData;
+
bool includesClosureCall(Selector selector, AbstractValue? receiver);
+
Iterable<MemberEntity> locateMembers(
Selector selector, AbstractValue? receiver);
+
bool fieldNeverChanges(MemberEntity element);
}
+
+// TODO(48820): Move back to `world.dart` when migrated.
+/// A [BuiltWorld] is an immutable result of a [WorldBuilder].
+abstract class BuiltWorld {
+ ClassHierarchy get classHierarchy;
+
+ /// Calls [f] for each live generic method.
+ void forEachGenericMethod(void Function(FunctionEntity) f);
+
+ /// All types that are checked either through is, as or checked mode checks.
+ Iterable<DartType> get isChecks;
+
+ /// All type variables named in recipes.
+ Set<TypeVariableType> get namedTypeVariablesNewRti;
+
+ /// All directly instantiated types, that is, the types of
+ /// [directlyInstantiatedClasses].
+ // TODO(johnniwinther): Improve semantic precision.
+ Iterable<InterfaceType> get instantiatedTypes;
+
+ // TODO(johnniwinther): Clean up these getters.
+ /// Methods in instantiated classes that are potentially closurized.
+ Iterable<FunctionEntity> get closurizedMembers;
+
+ /// Static or top level methods that are closurized.
+ Iterable<FunctionEntity> get closurizedStatics;
+
+ /// Properties (fields and getters) which can be called as generic functions.
+ Map<MemberEntity, DartType> get genericCallableProperties;
+
+ /// Type variables used as type literals.
+ Iterable<TypeVariableType> get typeVariableTypeLiterals;
+
+ /// Live user-defined 'noSuchMethod' implementations.
+ Iterable<FunctionEntity> get userNoSuchMethods;
+
+ AnnotationsData get annotationsData;
+
+ /// Calls [f] for each live generic instance methods.
+ void forEachGenericInstanceMethod(void Function(FunctionEntity) f);
+
+ /// Live generic local functions.
+ Iterable<Local> get genericLocalFunctions;
+
+ /// Call [f] for each generic [function] with the type arguments passed
+ /// through static calls to [function].
+ void forEachStaticTypeArgument(
+ void f(Entity function, Set<DartType> typeArguments));
+
+ /// Call [f] for each generic [selector] with the type arguments passed
+ /// through dynamic calls to [selector].
+ void forEachDynamicTypeArgument(
+ void f(Selector selector, Set<DartType> typeArguments));
+}
diff --git a/pkg/dart2js_info/lib/info.dart b/pkg/dart2js_info/lib/info.dart
index cfc7242..1f658a8 100644
--- a/pkg/dart2js_info/lib/info.dart
+++ b/pkg/dart2js_info/lib/info.dart
@@ -125,7 +125,7 @@
/// Major version indicating breaking changes in the format. A new version
/// means that an old deserialization algorithm will not work with the new
/// format.
- final int version = 6;
+ final int version = 7;
/// Minor version indicating non-breaking changes in the format. A change in
/// this version number means that the json parsing in this library from a
diff --git a/pkg/vm_service/CHANGELOG.md b/pkg/vm_service/CHANGELOG.md
index 71f07cb..8145e3e 100644
--- a/pkg/vm_service/CHANGELOG.md
+++ b/pkg/vm_service/CHANGELOG.md
@@ -1,5 +1,9 @@
# Changelog
+## 9.3.0
+- Update to version `3.60` of the spec.
+- Add `gcType` property to `Event`.
+
## 9.2.0
- Update to version `3.59` of the spec.
- Add `abstract` flag to `FuncRef`.
diff --git a/pkg/vm_service/java/version.properties b/pkg/vm_service/java/version.properties
index cf92a35..f0edd09 100644
--- a/pkg/vm_service/java/version.properties
+++ b/pkg/vm_service/java/version.properties
@@ -1 +1 @@
-version=3.59
+version=3.60
diff --git a/pkg/vm_service/lib/src/vm_service.dart b/pkg/vm_service/lib/src/vm_service.dart
index 45dd4ee..3e66f4b 100644
--- a/pkg/vm_service/lib/src/vm_service.dart
+++ b/pkg/vm_service/lib/src/vm_service.dart
@@ -26,7 +26,7 @@
HeapSnapshotObjectNoData,
HeapSnapshotObjectNullData;
-const String vmServiceVersion = '3.59.0';
+const String vmServiceVersion = '3.60.0';
/// @optional
const String optional = 'optional';
@@ -4073,6 +4073,13 @@
@optional
InstanceRef? inspectee;
+ /// The garbage collection (GC) operation performed.
+ ///
+ /// This is provided for the event kinds:
+ /// - GC
+ @optional
+ String? gcType;
+
/// The RPC name of the extension that was added.
///
/// This is provided for the ServiceExtensionAdded event.
@@ -4197,6 +4204,7 @@
this.exception,
this.bytes,
this.inspectee,
+ this.gcType,
this.extensionRPC,
this.extensionKind,
this.extensionData,
@@ -4236,6 +4244,7 @@
bytes = json['bytes'];
inspectee = createServiceObject(json['inspectee'], const ['InstanceRef'])
as InstanceRef?;
+ gcType = json['gcType'];
extensionRPC = json['extensionRPC'];
extensionKind = json['extensionKind'];
extensionData = ExtensionData.parse(json['extensionData']);
@@ -4284,6 +4293,7 @@
_setIfNotNull(json, 'exception', exception?.toJson());
_setIfNotNull(json, 'bytes', bytes);
_setIfNotNull(json, 'inspectee', inspectee?.toJson());
+ _setIfNotNull(json, 'gcType', gcType);
_setIfNotNull(json, 'extensionRPC', extensionRPC);
_setIfNotNull(json, 'extensionKind', extensionKind);
_setIfNotNull(json, 'extensionData', extensionData?.data);
diff --git a/pkg/vm_service/pubspec.yaml b/pkg/vm_service/pubspec.yaml
index e7c8f3b..c82374a 100644
--- a/pkg/vm_service/pubspec.yaml
+++ b/pkg/vm_service/pubspec.yaml
@@ -1,5 +1,5 @@
name: vm_service
-version: 9.2.0
+version: 9.3.0
description: >-
A library to communicate with a service implementing the Dart VM
service protocol.
diff --git a/runtime/observatory/tests/service/get_version_rpc_test.dart b/runtime/observatory/tests/service/get_version_rpc_test.dart
index bf51c64..7572f29 100644
--- a/runtime/observatory/tests/service/get_version_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_version_rpc_test.dart
@@ -12,7 +12,7 @@
final result = await vm.invokeRpcNoUpgrade('getVersion', {});
expect(result['type'], 'Version');
expect(result['major'], 3);
- expect(result['minor'], 59);
+ expect(result['minor'], 60);
expect(result['_privateMajor'], 0);
expect(result['_privateMinor'], 0);
},
diff --git a/runtime/observatory_2/tests/service_2/get_version_rpc_test.dart b/runtime/observatory_2/tests/service_2/get_version_rpc_test.dart
index 4bb45af..d99783f 100644
--- a/runtime/observatory_2/tests/service_2/get_version_rpc_test.dart
+++ b/runtime/observatory_2/tests/service_2/get_version_rpc_test.dart
@@ -12,7 +12,7 @@
final result = await vm.invokeRpcNoUpgrade('getVersion', {});
expect(result['type'], equals('Version'));
expect(result['major'], equals(3));
- expect(result['minor'], equals(59));
+ expect(result['minor'], equals(60));
expect(result['_privateMajor'], equals(0));
expect(result['_privateMinor'], equals(0));
},
diff --git a/runtime/vm/compiler/backend/flow_graph_test.cc b/runtime/vm/compiler/backend/flow_graph_test.cc
index d97244f..ababc2b 100644
--- a/runtime/vm/compiler/backend/flow_graph_test.cc
+++ b/runtime/vm/compiler/backend/flow_graph_test.cc
@@ -9,6 +9,7 @@
#include "platform/text_buffer.h"
#include "platform/utils.h"
#include "vm/compiler/backend/block_builder.h"
+#include "vm/compiler/backend/flow_graph_compiler.h"
#include "vm/compiler/backend/il_printer.h"
#include "vm/compiler/backend/il_test_helper.h"
#include "vm/compiler/backend/type_propagator.h"
@@ -244,4 +245,176 @@
"}\n");
}
+ISOLATE_UNIT_TEST_CASE(FlowGraph_PhiUnboxingHeuristic_Double) {
+ if (!FlowGraphCompiler::SupportsUnboxedDoubles()) {
+ return;
+ }
+
+ const char* kScript = R"(
+ double foo(double sum, int n) {
+ if (sum == null) return 0.0;
+ for (int i = 0; i < n; i++) {
+ sum += 1.0;
+ }
+ return sum;
+ }
+ main() {
+ foo(0.0, 10);
+ }
+ )";
+
+ const auto& root_library = Library::Handle(LoadTestScript(kScript));
+ const auto& function = Function::Handle(GetFunction(root_library, "foo"));
+
+ Invoke(root_library, "main");
+
+ TestPipeline pipeline(function, CompilerPass::kJIT);
+ FlowGraph* flow_graph = pipeline.RunPasses({});
+
+ auto entry = flow_graph->graph_entry()->normal_entry();
+ ILMatcher cursor(flow_graph, entry, /*trace=*/true,
+ ParallelMovesHandling::kSkip);
+
+ RELEASE_ASSERT(cursor.TryMatch({
+ kMatchAndMoveFunctionEntry,
+ }));
+ if (FLAG_sound_null_safety != kNullSafetyOptionStrong) {
+ RELEASE_ASSERT(cursor.TryMatch({
+ kMatchAndMoveBranchFalse,
+ kMatchAndMoveTargetEntry,
+ }));
+ }
+ RELEASE_ASSERT(cursor.TryMatch({
+ kMatchAndMoveUnbox, // outside of loop
+ kMatchAndMoveCheckSmi,
+ kMoveGlob,
+
+ // Loop header
+ kMatchAndMoveJoinEntry,
+ kMatchAndMoveCheckStackOverflow,
+ kMatchAndMoveBranchTrue,
+
+ // Loop body
+ kMatchAndMoveTargetEntry,
+ kMatchAndMoveBinaryDoubleOp,
+ kMatchAndMoveBinarySmiOp,
+ kMatchAndMoveGoto,
+
+ // Loop header, again
+ kMatchAndMoveJoinEntry,
+ kMatchAndMoveCheckStackOverflow,
+ kMatchAndMoveBranchFalse,
+
+ // After loop
+ kMatchAndMoveTargetEntry,
+ kMatchAndMoveBox,
+ kMatchReturn,
+ }));
+}
+
+static void TestPhiUnboxingHeuristicSimd(const char* script) {
+ if (!FlowGraphCompiler::SupportsUnboxedSimd128()) {
+ return;
+ }
+
+ const auto& root_library = Library::Handle(LoadTestScript(script));
+ const auto& function = Function::Handle(GetFunction(root_library, "foo"));
+
+ Invoke(root_library, "main");
+
+ TestPipeline pipeline(function, CompilerPass::kJIT);
+ FlowGraph* flow_graph = pipeline.RunPasses({});
+
+ auto entry = flow_graph->graph_entry()->normal_entry();
+ ILMatcher cursor(flow_graph, entry, /*trace=*/true,
+ ParallelMovesHandling::kSkip);
+
+ RELEASE_ASSERT(cursor.TryMatch({
+ kMatchAndMoveFunctionEntry,
+ }));
+ if (FLAG_sound_null_safety != kNullSafetyOptionStrong) {
+ RELEASE_ASSERT(cursor.TryMatch({
+ kMatchAndMoveBranchFalse,
+ kMatchAndMoveTargetEntry,
+ }));
+ }
+ RELEASE_ASSERT(cursor.TryMatch({
+ kMatchAndMoveUnbox, // outside of loop
+ kMatchAndMoveCheckSmi,
+ kMoveGlob,
+
+ // Loop header
+ kMatchAndMoveJoinEntry,
+ kMatchAndMoveCheckStackOverflow,
+ kMatchAndMoveBranchTrue,
+
+ // Loop body
+ kMatchAndMoveTargetEntry,
+ kMatchAndMoveSimdOp,
+ kMatchAndMoveBinarySmiOp,
+ kMatchAndMoveGoto,
+
+ // Loop header, again
+ kMatchAndMoveJoinEntry,
+ kMatchAndMoveCheckStackOverflow,
+ kMatchAndMoveBranchFalse,
+
+ // After loop
+ kMatchAndMoveTargetEntry,
+ kMatchAndMoveBox,
+ kMatchReturn,
+ }));
+}
+
+ISOLATE_UNIT_TEST_CASE(FlowGraph_PhiUnboxingHeuristic_Float32x4) {
+ const char* kScript = R"(
+ import 'dart:typed_data';
+ Float32x4 foo(Float32x4 sum, int n) {
+ if (sum == null) return Float32x4(0.0, 0.0, 0.0, 0.0);
+ for (int i = 0; i < n; i++) {
+ sum += Float32x4(1.0, 2.0, 3.0, 4.0);
+ }
+ return sum;
+ }
+ main() {
+ foo(Float32x4(0.0, 0.0, 0.0, 0.0), 10);
+ }
+ )";
+ TestPhiUnboxingHeuristicSimd(kScript);
+}
+
+ISOLATE_UNIT_TEST_CASE(FlowGraph_PhiUnboxingHeuristic_Float64x2) {
+ const char* kScript = R"(
+ import 'dart:typed_data';
+ Float64x2 foo(Float64x2 sum, int n) {
+ if (sum == null) return Float64x2(0.0, 0.0);
+ for (int i = 0; i < n; i++) {
+ sum += Float64x2(1.0, 2.0);
+ }
+ return sum;
+ }
+ main() {
+ foo(Float64x2(0.0, 0.0), 10);
+ }
+ )";
+ TestPhiUnboxingHeuristicSimd(kScript);
+}
+
+ISOLATE_UNIT_TEST_CASE(FlowGraph_PhiUnboxingHeuristic_Int32x4) {
+ const char* kScript = R"(
+ import 'dart:typed_data';
+ Int32x4 foo(Int32x4 sum, int n) {
+ if (sum == null) return Int32x4(0, 0, 0, 0);
+ for (int i = 0; i < n; i++) {
+ sum += Int32x4(1, 2, 3, 4);
+ }
+ return sum;
+ }
+ main() {
+ foo(Int32x4(0, 0, 0, 0), 10);
+ }
+ )";
+ TestPhiUnboxingHeuristicSimd(kScript);
+}
+
} // namespace dart
diff --git a/runtime/vm/compiler/backend/redundancy_elimination_test.cc b/runtime/vm/compiler/backend/redundancy_elimination_test.cc
index 1dd76e6..73b64c5 100644
--- a/runtime/vm/compiler/backend/redundancy_elimination_test.cc
+++ b/runtime/vm/compiler/backend/redundancy_elimination_test.cc
@@ -1201,7 +1201,13 @@
RELEASE_ASSERT(cursor.TryMatch({
kMatchAndMoveFunctionEntry,
kMatchAndMoveCheckStackOverflow,
- kMatchAndMoveCheckClass,
+ }));
+ if (FLAG_sound_null_safety != kNullSafetyOptionStrong) {
+ RELEASE_ASSERT(cursor.TryMatch({
+ kMatchAndMoveCheckClass,
+ }));
+ }
+ RELEASE_ASSERT(cursor.TryMatch({
kMatchAndMoveUnbox,
kMatchAndMoveBinaryDoubleOp,
kMatchAndMoveBinaryDoubleOp,
diff --git a/runtime/vm/compiler/backend/type_propagator.cc b/runtime/vm/compiler/backend/type_propagator.cc
index 30e332c..086e3e5 100644
--- a/runtime/vm/compiler/backend/type_propagator.cc
+++ b/runtime/vm/compiler/backend/type_propagator.cc
@@ -768,6 +768,14 @@
cid_ = kSentinelCid;
} else if (type_->IsFunctionType() || type_->IsDartFunctionType()) {
cid_ = kClosureCid;
+ } else if (type_->IsDoubleType()) {
+ cid_ = kDoubleCid; // double's only implementor is _Double.
+ } else if (type_->IsFloat32x4Type()) {
+ cid_ = kFloat32x4Cid; // Float32x4's only implementor is _Float32x4.
+ } else if (type_->IsFloat64x2Type()) {
+ cid_ = kFloat64x2Cid; // Float64x2's only implementor is _Float64x2.
+ } else if (type_->IsInt32x4Type()) {
+ cid_ = kInt32x4Cid; // Int32x4's only implementor is _Int32x4.
} else if (type_->type_class_id() != kIllegalCid) {
const Class& type_class = Class::Handle(type_->type_class());
Thread* thread = Thread::Current();
diff --git a/runtime/vm/service.h b/runtime/vm/service.h
index 38a0bf6..cd32fd0 100644
--- a/runtime/vm/service.h
+++ b/runtime/vm/service.h
@@ -17,7 +17,7 @@
namespace dart {
#define SERVICE_PROTOCOL_MAJOR_VERSION 3
-#define SERVICE_PROTOCOL_MINOR_VERSION 59
+#define SERVICE_PROTOCOL_MINOR_VERSION 60
class Array;
class EmbedderServiceHandler;
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index 622ea1d..d7d7e52 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -1,8 +1,8 @@
-# Dart VM Service Protocol 3.59
+# Dart VM Service Protocol 3.60
> Please post feedback to the [observatory-discuss group][discuss-list]
-This document describes of _version 3.58_ of the Dart VM Service Protocol. This
+This document describes of _version 3.60_ of the Dart VM Service Protocol. This
protocol is used to communicate with a running Dart Virtual Machine.
To use the Service Protocol, start the VM with the *--observe* flag.
@@ -2226,6 +2226,12 @@
// This is provided for the Inspect event.
@Instance inspectee [optional];
+ // The garbage collection (GC) operation performed.
+ //
+ // This is provided for the event kinds:
+ // GC
+ string gcType [optional];
+
// The RPC name of the extension that was added.
//
// This is provided for the ServiceExtensionAdded event.
@@ -4379,5 +4385,6 @@
3.57 | Added optional `libraryFilters` parameter to `getSourceReport` RPC.
3.58 | Added optional `local` parameter to `lookupResolvedPackageUris` RPC.
3.59 | Added `abstract` property to `@Function` and `Function`.
+3.60 | Added `gcType` property to `Event`.
[discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss
diff --git a/runtime/vm/service_event.cc b/runtime/vm/service_event.cc
index 9e4f399..b0e3fcf 100644
--- a/runtime/vm/service_event.cc
+++ b/runtime/vm/service_event.cc
@@ -284,6 +284,7 @@
}
if (gc_stats() != NULL) {
jsobj.AddProperty("reason", Heap::GCReasonToString(gc_stats()->reason_));
+ jsobj.AddProperty("gcType", Heap::GCTypeToString(gc_stats()->type_));
isolate_group()->heap()->PrintToJSONObject(Heap::kNew, &jsobj);
isolate_group()->heap()->PrintToJSONObject(Heap::kOld, &jsobj);
}
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index ec8addd..b4f4f5c 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -154,8 +154,7 @@
}
void throwInvalidReflectionError(String memberName) {
- throw new UnsupportedError("Can't use '$memberName' in reflection "
- "because it is not included in a @MirrorsUsed annotation.");
+ throw new UnsupportedError("Can't use '$memberName' in reflection.");
}
/// Helper used to instrument calls when the compiler is invoked with
diff --git a/sdk/lib/mirrors/mirrors.dart b/sdk/lib/mirrors/mirrors.dart
index 6e19487..963319f 100644
--- a/sdk/lib/mirrors/mirrors.dart
+++ b/sdk/lib/mirrors/mirrors.dart
@@ -120,11 +120,6 @@
/**
* Returns the name of [symbol].
- *
- * The following text is non-normative:
- *
- * Using this method may result in larger output. If possible, use
- * [MirrorsUsed] to specify which symbols must be retained in clear text.
*/
external static String getName(Symbol symbol);
@@ -1196,283 +1191,3 @@
*/
Uri get sourceUri;
}
-
-/**
- * Class used for encoding comments as metadata annotations.
- */
-class Comment {
- /**
- * The comment text as written in the source text.
- */
- final String text;
-
- /**
- * The comment text without the start, end, and padding text.
- *
- * For example, if [text] is [: /** Comment text. */ :] then the [trimmedText]
- * is [: Comment text. :].
- */
- final String trimmedText;
-
- /**
- * Is [:true:] if this comment is a documentation comment.
- *
- * That is, that the comment is either enclosed in [: /** ... */ :] or starts
- * with [: /// :].
- */
- final bool isDocComment;
-
- const Comment(this.text, this.trimmedText, this.isDocComment);
-}
-
-/**
- * Annotation describing how "dart:mirrors" is used (EXPERIMENTAL).
- *
- * When used as metadata on an import of "dart:mirrors" in library *L*, this
- * class describes how "dart:mirrors" is used by library *L* unless overridden.
- * See [override].
- *
- * The following text is non-normative:
- *
- * In some scenarios, for example, when minifying Dart code, or when generating
- * JavaScript code from a Dart program, the size and performance of the output
- * can suffer from use of reflection. In those cases, telling the compiler
- * what is used, can have a significant impact.
- *
- * Example usage:
- *
- * @MirrorsUsed(symbols: 'foo')
- * import 'dart:mirrors';
- *
- * class Foo {
- * noSuchMethod(Invocation invocation) {
- * print(MirrorSystem.getName(invocation.memberName));
- * }
- * }
- *
- * main() {
- * new Foo().foo(); // Prints "foo".
- * new Foo().bar(); // Might print an arbitrary (mangled) name, "bar".
- * }
- *
- * For a detailed description of the parameters to the [MirrorsUsed] constructor
- * see the comments for [symbols], [targets], [metaTargets] and [override].
- *
- * An import of `dart:mirrors` may have multiple [MirrorsUsed] annotations. This
- * is particularly helpful to specify overrides for specific libraries. For
- * example:
- *
- * @MirrorsUsed(targets: 'foo.Bar', override: 'foo')
- * @MirrorsUsed(targets: 'Bar')
- * import 'dart:mirrors';
- *
- * will ensure that the target `Bar` from the current library and from library
- * `foo` is available for reflection. See also [override].
- */
-@Deprecated("No longer has any effect. Will be removed in a later release.")
-class MirrorsUsed {
- // Note: the fields of this class are untyped. This is because the most
- // convenient way to specify symbols today is using a single string. In
- // some cases, a const list of classes might be convenient. Some
- // might prefer to use a const list of symbols.
-
- /**
- * The list of strings passed to new [Symbol], and symbols that might be
- * passed to [MirrorSystem.getName].
- *
- * Combined with the names of [targets], [metaTargets] and their members,
- * this forms the complete list of strings passed to new [Symbol], and
- * symbols that might be passed to [MirrorSystem.getName] by the library to
- * which this metadata applies.
- *
- * The following text is non-normative:
- *
- * Dart2js currently supports the following formats to specify symbols:
- *
- * * A constant [List] of [String] constants representing symbol names,
- * e.g., `const ['foo', 'bar']`.
- * * A single [String] constant whose value is a comma-separated list of
- * symbol names, e.g., `"foo, bar"`.
- *
- * Specifying the `symbols` field turns off the following warnings emitted by
- * dart2js:
- *
- * * Using "MirrorSystem.getName" may result in larger output.
- * * Using "new Symbol" may result in larger output.
- *
- * For example, if you're using [noSuchMethod] to interact with a database,
- * extract all the possible column names and include them in this list.
- * Similarly, if you're using [noSuchMethod] to interact with another
- * language (JavaScript, for example) extract all the identifiers from the
- * API you use and include them in this list.
- *
- * Note that specifying a symbol only ensures that the symbol will be
- * available under that name at runtime. It does not mark targets with
- * that name as available for reflection. See [targets] and [metaTargets]
- * for that purpose.
- */
- final symbols;
-
- /**
- * A list of reflective targets.
- *
- * Combined with [metaTargets], this provides the complete list of reflective
- * targets used by the library to which this metadata applies.
- *
- * The following text is non-normative:
- *
- * For now, there is no formal description of what a reflective target is.
- * Informally, a target is a library, a class, a method or a field.
- *
- * Dart2js currently supports the following formats to specify targets:
- *
- * * A constant [List] containing [String] constants representing (qualified)
- * names of targets and Dart types.
- * * A single [String] constant whose value is a comma-separated list of
- * (qualified) names.
- * * A single Dart type.
- *
- * A (qualified) name is resolved to a target as follows:
- *
- * 1. If the qualified name matches a library name, the matching library is
- * the target.
- * 2. Else, find the longest prefix of the name such that the prefix ends
- * just before a `.` and is a library name.
- * 3. Use that library as current scope. If no matching prefix was found, use
- * the current library, i.e., the library where the [MirrorsUsed]
- * annotation was placed.
- * 4. Split the remaining suffix (the entire name if no library name was
- * found in step 3) into a list of [String] using `.` as a
- * separator.
- * 5. Select all targets in the current scope whose name matches a [String]
- * from the list.
- *
- * For example:
- *
- * library my.library.one;
- *
- * class A {
- * var aField;
- * }
- *
- * library main;
- *
- * @MirrorsUsed(targets: "my.library.one.A.aField")
- * import "dart:mirrors";
- *
- * The [MirrorsUsed] annotation specifies `A` and `aField` from library
- * `my.library.one` as targets. This will mark the class `A` as a reflective
- * target. The target specification for `aField` has no effect, as there is
- * no target in `my.library.one` with that name.
- *
- * Note that everything within a target also is available for reflection.
- * So, if a library is specified as target, all classes in that library
- * become targets for reflection. Likewise, if a class is a target, all
- * its methods and fields become targets for reflection. As a consequence,
- * `aField` in the above example is also a reflective target.
- *
- */
- final targets;
-
- /**
- * A list of classes that when used as metadata indicates a reflective
- * target. See also [targets].
- *
- * The following text is non-normative:
- *
- * The format for specifying the list of classes is the same as used for
- * specifying [targets]. However, as a library cannot be used as a metadata
- * annotation in Dart, adding a library to the list of [metaTargets] has no
- * effect. In particular, adding a library to [metaTargets] does not make
- * the library's classes valid metadata annotations to enable reflection.
- *
- * If an instance of a class specified in [metaTargets] is used as
- * metadata annotation on a library, class, field or method, that library,
- * class, field or method is added to the set of targets for reflection.
- *
- * Example usage:
- *
- * library example;
- * @MirrorsUsed(metaTargets: "example.Reflectable")
- * import "dart:mirrors";
- *
- * class Reflectable {
- * const Reflectable();
- * }
- *
- * class Foo {
- * @Reflectable()
- * reflectableMethod() { ... }
- *
- * nonReflectableMethod() { ... }
- * }
- *
- * In the above example. `reflectableMethod` is marked as reflectable by
- * using the `Reflectable` class, which in turn is specified in the
- * [metaTargets] annotation.
- *
- * The method `nonReflectableMethod` lacks a metadata annotation and thus
- * will not be reflectable at runtime.
- */
- final metaTargets;
-
- /**
- * A list of library names or "*".
- *
- * When used as metadata on an import of "dart:mirrors", this metadata does
- * not apply to the library in which the annotation is used, but instead
- * applies to the other libraries (all libraries if "*" is used).
- *
- * The following text is non-normative:
- *
- * Dart2js currently supports the following formats to specify libraries:
- *
- * * A constant [List] containing [String] constants representing names of
- * libraries.
- * * A single [String] constant whose value is a comma-separated list of
- * library names.
- *
- * Conceptually, a [MirrorsUsed] annotation with [override] has the same
- * effect as placing the annotation directly on the import of `dart:mirrors`
- * in each of the referenced libraries. Thus, if the library had no
- * [MirrorsUsed] annotation before, its unconditional import of
- * `dart:mirrors` is overridden by an annotated import.
- *
- * Note that, like multiple explicit [MirrorsUsed] annotations, using
- * override on a library with an existing [MirrorsUsed] annotation is
- * additive. That is, the overall set of reflective targets is the union
- * of the reflective targets that arise from the original and the
- * overriding [MirrorsUsed] annotations.
- *
- * The use of [override] is only meaningful for libraries that have an
- * import of `dart:mirrors` without annotation because otherwise it would
- * work exactly the same way without the [override] parameter.
- *
- * While the annotation will apply to the given target libraries, the
- * [symbols], [targets] and [metaTargets] are still evaluated in the
- * scope of the annotation. Thus, to select a target from library `foo`,
- * a qualified name has to be used or, if the target is visible in the
- * current scope, its type may be referenced.
- *
- * For example, the following code marks all targets in the library `foo`
- * as reflectable that have a metadata annotation using the `Reflectable`
- * class from the same library.
- *
- * @MirrorsUsed(metaTargets: "foo.Reflectable", override: "foo")
- *
- * However, the following code would require the use of the `Reflectable`
- * class from the current library, instead.
- *
- * @MirrorsUsed(metaTargets: "Reflectable", override: "foo")
- *
- */
- final override;
-
- /**
- * See the documentation for [MirrorsUsed.symbols], [MirrorsUsed.targets],
- * [MirrorsUsed.metaTargets] and [MirrorsUsed.override] for documentation
- * of the parameters.
- */
- const MirrorsUsed(
- {this.symbols, this.targets, this.metaTargets, this.override});
-}
diff --git a/sdk/lib/typed_data/typed_data.dart b/sdk/lib/typed_data/typed_data.dart
index ea6a330..7dce112 100644
--- a/sdk/lib/typed_data/typed_data.dart
+++ b/sdk/lib/typed_data/typed_data.dart
@@ -24,6 +24,9 @@
///
/// Used to process large quantities of binary or numerical data
/// more efficiently using a typed view.
+///
+/// It is a compile-time error for a class to attempt to extend or implement
+/// ByteBuffer.
abstract class ByteBuffer {
/// Returns the length of this byte buffer, in bytes.
int get lengthInBytes;
@@ -340,6 +343,9 @@
}
/// A typed view of a sequence of bytes.
+///
+/// It is a compile-time error for a class to attempt to extend or implement
+/// TypedData.
abstract class TypedData {
/// Returns the number of bytes in the representation of each element in this
/// list.
@@ -377,6 +383,9 @@
/// Describes endianness to be used when accessing or updating a
/// sequence of bytes.
+///
+/// It is a compile-time error for a class to attempt to extend or implement
+/// Endian.
class Endian {
final bool _littleEndian;
const Endian._(this._littleEndian);
@@ -421,6 +430,9 @@
/// bdata.setFloat32(0, 3.04);
/// int huh = bdata.getInt32(0); // 0x40428f5c
/// ```
+///
+/// It is a compile-time error for a class to attempt to extend or implement
+/// ByteData.
abstract class ByteData implements TypedData {
/// Creates a [ByteData] of the specified length (in elements), all of
/// whose bytes are initially zero.
@@ -704,6 +716,9 @@
/// Integers stored in the list are truncated to their low eight bits,
/// interpreted as a signed 8-bit two's complement integer with values in the
/// range -128 to +127.
+///
+/// It is a compile-time error for a class to attempt to extend or implement
+/// Int8List.
abstract class Int8List implements List<int>, _TypedIntList {
/// Creates an [Int8List] of the specified length (in elements), all of
/// whose elements are initially zero.
@@ -814,6 +829,9 @@
/// Integers stored in the list are truncated to their low eight bits,
/// interpreted as an unsigned 8-bit integer with values in the
/// range 0 to 255.
+///
+/// It is a compile-time error for a class to attempt to extend or implement
+/// Uint8List.
abstract class Uint8List implements List<int>, _TypedIntList {
/// Creates a [Uint8List] of the specified length (in elements), all of
/// whose elements are initially zero.
@@ -931,6 +949,9 @@
/// Integers stored in the list are clamped to an unsigned eight bit value.
/// That is, all values below zero are stored as zero
/// and all values above 255 are stored as 255.
+///
+/// It is a compile-time error for a class to attempt to extend or implement
+/// Uint8ClampedList.
abstract class Uint8ClampedList implements List<int>, _TypedIntList {
/// Creates a [Uint8ClampedList] of the specified length (in elements), all of
/// whose elements are initially zero.
@@ -1044,6 +1065,9 @@
/// Integers stored in the list are truncated to their low 16 bits,
/// interpreted as a signed 16-bit two's complement integer with values in the
/// range -32768 to +32767.
+///
+/// It is a compile-time error for a class to attempt to extend or implement
+/// Int16List.
abstract class Int16List implements List<int>, _TypedIntList {
/// Creates an [Int16List] of the specified length (in elements), all of
/// whose elements are initially zero.
@@ -1166,6 +1190,9 @@
/// Integers stored in the list are truncated to their low 16 bits,
/// interpreted as an unsigned 16-bit integer with values in the
/// range 0 to 65535.
+///
+/// It is a compile-time error for a class to attempt to extend or implement
+/// Uint16List.
abstract class Uint16List implements List<int>, _TypedIntList {
/// Creates a [Uint16List] of the specified length (in elements), all
/// of whose elements are initially zero.
@@ -1289,6 +1316,9 @@
/// Integers stored in the list are truncated to their low 32 bits,
/// interpreted as a signed 32-bit two's complement integer with values in the
/// range -2147483648 to 2147483647.
+///
+/// It is a compile-time error for a class to attempt to extend or implement
+/// Int32List.
abstract class Int32List implements List<int>, _TypedIntList {
/// Creates an [Int32List] of the specified length (in elements), all of
/// whose elements are initially zero.
@@ -1411,6 +1441,9 @@
/// Integers stored in the list are truncated to their low 32 bits,
/// interpreted as an unsigned 32-bit integer with values in the
/// range 0 to 4294967295.
+///
+/// It is a compile-time error for a class to attempt to extend or implement
+/// Uint32List.
abstract class Uint32List implements List<int>, _TypedIntList {
/// Creates a [Uint32List] of the specified length (in elements), all
/// of whose elements are initially zero.
@@ -1534,6 +1567,9 @@
/// Integers stored in the list are truncated to their low 64 bits,
/// interpreted as a signed 64-bit two's complement integer with values in the
/// range -9223372036854775808 to +9223372036854775807.
+///
+/// It is a compile-time error for a class to attempt to extend or implement
+/// Int64List.
abstract class Int64List implements List<int>, _TypedIntList {
/// Creates an [Int64List] of the specified length (in elements), all of
/// whose elements are initially zero.
@@ -1656,6 +1692,9 @@
/// Integers stored in the list are truncated to their low 64 bits,
/// interpreted as an unsigned 64-bit integer with values in the
/// range 0 to 18446744073709551615.
+///
+/// It is a compile-time error for a class to attempt to extend or implement
+/// Uint64List.
abstract class Uint64List implements List<int>, _TypedIntList {
/// Creates a [Uint64List] of the specified length (in elements), all
/// of whose elements are initially zero.
@@ -1780,6 +1819,9 @@
/// Double values stored in the list are converted to the nearest
/// single-precision value. Values read are converted to a double
/// value with the same value.
+///
+/// It is a compile-time error for a class to attempt to extend or implement
+/// Float32List.
abstract class Float32List implements List<double>, _TypedFloatList {
/// Creates a [Float32List] of the specified length (in elements), all of
/// whose elements are initially zero.
@@ -1899,6 +1941,9 @@
/// For long lists, this
/// implementation can be considerably more space- and time-efficient than
/// the default [List] implementation.
+///
+/// It is a compile-time error for a class to attempt to extend or implement
+/// Float64List.
abstract class Float64List implements List<double>, _TypedFloatList {
/// Creates a [Float64List] of the specified length (in elements), all of
/// whose elements are initially zero.
@@ -2014,6 +2059,9 @@
///
/// For long lists, this implementation will be considerably more
/// space- and time-efficient than the default [List] implementation.
+///
+/// It is a compile-time error for a class to attempt to extend or implement
+/// Float32x4List.
abstract class Float32x4List implements List<Float32x4>, TypedData {
/// Creates a [Float32x4List] of the specified length (in elements),
/// all of whose elements are initially zero.
@@ -2256,6 +2304,9 @@
///
/// For long lists, this implementation will be considerably more
/// space- and time-efficient than the default [List] implementation.
+///
+/// It is a compile-time error for a class to attempt to extend or implement
+/// Float64x2List.
abstract class Float64x2List implements List<Float64x2>, TypedData {
/// Creates a [Float64x2List] of the specified length (in elements),
/// all of whose elements have all lanes set to zero.
@@ -2376,6 +2427,9 @@
///
/// Float32x4 stores 4 32-bit floating point values in "lanes".
/// The lanes are "x", "y", "z", and "w" respectively.
+///
+/// It is a compile-time error for a class to attempt to extend or implement
+/// Float32x4.
abstract class Float32x4 {
external factory Float32x4(double x, double y, double z, double w);
external factory Float32x4.splat(double v);
@@ -3097,6 +3151,9 @@
///
/// Float64x2 stores 2 64-bit floating point values in "lanes".
/// The lanes are "x" and "y" respectively.
+///
+/// It is a compile-time error for a class to attempt to extend or implement
+/// Float64x2.
abstract class Float64x2 {
external factory Float64x2(double x, double y);
external factory Float64x2.splat(double v);
diff --git a/sdk/lib/typed_data/unmodifiable_typed_data.dart b/sdk/lib/typed_data/unmodifiable_typed_data.dart
index 43aaa84..4647798 100644
--- a/sdk/lib/typed_data/unmodifiable_typed_data.dart
+++ b/sdk/lib/typed_data/unmodifiable_typed_data.dart
@@ -5,6 +5,9 @@
part of dart.typed_data;
/// A read-only view of a [ByteBuffer].
+///
+/// It is a compile-time error for a class to attempt to extend or implement
+/// UnmodifiableByteBufferView.
class UnmodifiableByteBufferView implements ByteBuffer {
final ByteBuffer _data;
@@ -65,6 +68,9 @@
}
/// A read-only view of a [ByteData].
+///
+/// It is a compile-time error for a class to attempt to extend or implement
+/// UnmodifiableByteDataView.
class UnmodifiableByteDataView implements ByteData {
final ByteData _data;
@@ -170,6 +176,9 @@
}
/// View of a [Uint8List] that disallows modification.
+///
+/// It is a compile-time error for a class to attempt to extend or implement
+/// UnmodifiableUint8ListView.
class UnmodifiableUint8ListView extends UnmodifiableListBase<int>
with _UnmodifiableListMixin<int, Uint8List, Uint8List>
implements Uint8List {
@@ -180,6 +189,9 @@
}
/// View of a [Int8List] that disallows modification.
+///
+/// It is a compile-time error for a class to attempt to extend or implement
+/// UnmodifiableInt8ListView.
class UnmodifiableInt8ListView extends UnmodifiableListBase<int>
with _UnmodifiableListMixin<int, Int8List, Int8List>
implements Int8List {
@@ -190,6 +202,9 @@
}
/// View of a [Uint8ClampedList] that disallows modification.
+///
+/// It is a compile-time error for a class to attempt to extend or implement
+/// UnmodifiableUint8ClampedListView.
class UnmodifiableUint8ClampedListView extends UnmodifiableListBase<int>
with _UnmodifiableListMixin<int, Uint8ClampedList, Uint8ClampedList>
implements Uint8ClampedList {
@@ -200,6 +215,9 @@
}
/// View of a [Uint16List] that disallows modification.
+///
+/// It is a compile-time error for a class to attempt to extend or implement
+/// UnmodifiableUint16ListView.
class UnmodifiableUint16ListView extends UnmodifiableListBase<int>
with _UnmodifiableListMixin<int, Uint16List, Uint16List>
implements Uint16List {
@@ -210,6 +228,9 @@
}
/// View of a [Int16List] that disallows modification.
+///
+/// It is a compile-time error for a class to attempt to extend or implement
+/// UnmodifiableInt16ListView.
class UnmodifiableInt16ListView extends UnmodifiableListBase<int>
with _UnmodifiableListMixin<int, Int16List, Int16List>
implements Int16List {
@@ -220,6 +241,9 @@
}
/// View of a [Uint32List] that disallows modification.
+///
+/// It is a compile-time error for a class to attempt to extend or implement
+/// UnmodifiableUint32ListView.
class UnmodifiableUint32ListView extends UnmodifiableListBase<int>
with _UnmodifiableListMixin<int, Uint32List, Uint32List>
implements Uint32List {
@@ -230,6 +254,9 @@
}
/// View of a [Int32List] that disallows modification.
+///
+/// It is a compile-time error for a class to attempt to extend or implement
+/// UnmodifiableInt32ListView.
class UnmodifiableInt32ListView extends UnmodifiableListBase<int>
with _UnmodifiableListMixin<int, Int32List, Int32List>
implements Int32List {
@@ -240,6 +267,9 @@
}
/// View of a [Uint64List] that disallows modification.
+///
+/// It is a compile-time error for a class to attempt to extend or implement
+/// UnmodifiableUint64ListView.
class UnmodifiableUint64ListView extends UnmodifiableListBase<int>
with _UnmodifiableListMixin<int, Uint64List, Uint64List>
implements Uint64List {
@@ -250,6 +280,9 @@
}
/// View of a [Int64List] that disallows modification.
+///
+/// It is a compile-time error for a class to attempt to extend or implement
+/// UnmodifiableInt64ListView.
class UnmodifiableInt64ListView extends UnmodifiableListBase<int>
with _UnmodifiableListMixin<int, Int64List, Int64List>
implements Int64List {
@@ -260,6 +293,9 @@
}
/// View of a [Int32x4List] that disallows modification.
+///
+/// It is a compile-time error for a class to attempt to extend or implement
+/// UnmodifiableInt32x4ListView.
class UnmodifiableInt32x4ListView extends UnmodifiableListBase<Int32x4>
with _UnmodifiableListMixin<Int32x4, Int32x4List, Int32x4List>
implements Int32x4List {
@@ -270,6 +306,9 @@
}
/// View of a [Float32x4List] that disallows modification.
+///
+/// It is a compile-time error for a class to attempt to extend or implement
+/// UnmodifiableFloat32x4ListView.
class UnmodifiableFloat32x4ListView extends UnmodifiableListBase<Float32x4>
with _UnmodifiableListMixin<Float32x4, Float32x4List, Float32x4List>
implements Float32x4List {
@@ -280,6 +319,9 @@
}
/// View of a [Float64x2List] that disallows modification.
+///
+/// It is a compile-time error for a class to attempt to extend or implement
+/// UnmodifiableFloat64x2ListView.
class UnmodifiableFloat64x2ListView extends UnmodifiableListBase<Float64x2>
with _UnmodifiableListMixin<Float64x2, Float64x2List, Float64x2List>
implements Float64x2List {
@@ -290,6 +332,9 @@
}
/// View of a [Float32List] that disallows modification.
+///
+/// It is a compile-time error for a class to attempt to extend or implement
+/// UnmodifiableFloat32ListView.
class UnmodifiableFloat32ListView extends UnmodifiableListBase<double>
with _UnmodifiableListMixin<double, Float32List, Float32List>
implements Float32List {
@@ -300,6 +345,9 @@
}
/// View of a [Float64List] that disallows modification.
+///
+/// It is a compile-time error for a class to attempt to extend or implement
+/// UnmodifiableFloat64ListView.
class UnmodifiableFloat64ListView extends UnmodifiableListBase<double>
with _UnmodifiableListMixin<double, Float64List, Float64List>
implements Float64List {
diff --git a/tools/VERSION b/tools/VERSION
index 02e544a..c27657f 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 19
PATCH 0
-PRERELEASE 17
+PRERELEASE 18
PRERELEASE_PATCH 0
\ No newline at end of file