Version 2.12.0-130.0.dev Merge commit 'f0ed48196e045f3acbc6e82247eae6b52db11993' into 'dev'
diff --git a/DEPS b/DEPS index be29f0a..e5a3aa1 100644 --- a/DEPS +++ b/DEPS
@@ -82,7 +82,7 @@ "clock_rev" : "a494269254ba978e7ef8f192c5f7fec3fc05b9d3", "collection_rev": "e4bb038ce2d8e66fb15818aa40685c68d53692ab", "convert_rev": "dd3bd28f63be7cb8ab961f38bc73229e4473b555", - "crypto_rev": "f7c48b334b1386bc5ab0f706fbcd6df8496a87fc", + "crypto_rev": "a5ec902dda5a635a35c6b363ec64458cf84c5872", "csslib_rev": "6f77b3dcee957d3e2d5083f666221a220e9ed1f1", "dart2js_info_rev" : "e0acfeb5affdf94c53067e68bd836adf589628fd",
diff --git a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart index 7610ce4..9752d91 100644 --- a/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart +++ b/pkg/_fe_analyzer_shared/lib/src/flow_analysis/flow_analysis.dart
@@ -2566,12 +2566,8 @@ /// The type of the expression on the LHS of `==` or `!=`. final Type _leftOperandType; - /// If the LHS of `==` or `!=` is a variable reference, the variable. - /// Otherwise `null`. - final Variable _leftOperandVariable; - - _EqualityOpContext(ExpressionInfo<Variable, Type> conditionInfo, - this._leftOperandType, this._leftOperandVariable) + _EqualityOpContext( + ExpressionInfo<Variable, Type> conditionInfo, this._leftOperandType) : super(conditionInfo); @override @@ -2606,14 +2602,6 @@ /// corresponding to it. Otherwise `null`. ExpressionInfo<Variable, Type> _expressionInfo; - /// The most recently visited expression which was a variable reference, or - /// `null` if no expression has been visited that was a variable reference. - Expression _expressionWithVariable; - - /// If [_expressionVariable] is not `null`, the variable corresponding to it. - /// Otherwise `null`. - Variable _expressionVariable; - int _functionNestingLevel = 0; final AssignedVariables<Node, Variable> _assignedVariables; @@ -2627,8 +2615,14 @@ @override void asExpression_end(Expression subExpression, Type type) { - Variable variable = _getExpressionVariable(subExpression); - if (variable == null) return; + ExpressionInfo<Variable, Type> subExpressionInfo = + _getExpressionInfo(subExpression); + Variable variable; + if (subExpressionInfo is _VariableReadInfo<Variable, Type>) { + variable = subExpressionInfo._variable; + } else { + return; + } _current = _current.tryPromoteForTypeCast(typeOperations, variable, type); } @@ -2736,10 +2730,8 @@ _EqualityOpContext<Variable, Type> context = _stack.removeLast() as _EqualityOpContext<Variable, Type>; ExpressionInfo<Variable, Type> lhsInfo = context._conditionInfo; - Variable lhsVariable = context._leftOperandVariable; Type leftOperandType = context._leftOperandType; ExpressionInfo<Variable, Type> rhsInfo = _getExpressionInfo(rightOperand); - Variable rhsVariable = _getExpressionVariable(rightOperand); TypeClassification leftOperandTypeClassification = typeOperations.classifyType(leftOperandType); TypeClassification rightOperandTypeClassification = @@ -2757,16 +2749,18 @@ // but weak mode it might produce an "equal" result. We don't want flow // analysis behavior to depend on mode, so we conservatively assume that // either result is possible. - } else if (lhsInfo is _NullInfo<Variable, Type> && rhsVariable != null) { + } else if (lhsInfo is _NullInfo<Variable, Type> && + rhsInfo is _VariableReadInfo<Variable, Type>) { assert( leftOperandTypeClassification == TypeClassification.nullOrEquivalent); ExpressionInfo<Variable, Type> equalityInfo = - _current.tryMarkNonNullable(typeOperations, rhsVariable); + _current.tryMarkNonNullable(typeOperations, rhsInfo._variable); _storeExpressionInfo(wholeExpression, notEqual ? equalityInfo : ExpressionInfo.invert(equalityInfo)); - } else if (rhsInfo is _NullInfo<Variable, Type> && lhsVariable != null) { + } else if (rhsInfo is _NullInfo<Variable, Type> && + lhsInfo is _VariableReadInfo<Variable, Type>) { ExpressionInfo<Variable, Type> equalityInfo = - _current.tryMarkNonNullable(typeOperations, lhsVariable); + _current.tryMarkNonNullable(typeOperations, lhsInfo._variable); _storeExpressionInfo(wholeExpression, notEqual ? equalityInfo : ExpressionInfo.invert(equalityInfo)); } @@ -2775,9 +2769,7 @@ @override void equalityOp_rightBegin(Expression leftOperand, Type leftOperandType) { _stack.add(new _EqualityOpContext<Variable, Type>( - _getExpressionInfo(leftOperand), - leftOperandType, - _getExpressionVariable(leftOperand))); + _getExpressionInfo(leftOperand), leftOperandType)); } @override @@ -2852,9 +2844,6 @@ if (identical(_expressionWithInfo, oldExpression)) { _expressionWithInfo = newExpression; } - if (identical(_expressionWithVariable, oldExpression)) { - _expressionWithVariable = newExpression; - } } @override @@ -2912,12 +2901,12 @@ @override void ifNullExpression_rightBegin( Expression leftHandSide, Type leftHandSideType) { - Variable lhsVariable = _getExpressionVariable(leftHandSide); + ExpressionInfo<Variable, Type> lhsInfo = _getExpressionInfo(leftHandSide); FlowModel<Variable, Type> promoted; _current = _current.split(); - if (lhsVariable != null) { + if (lhsInfo is _VariableReadInfo<Variable, Type>) { ExpressionInfo<Variable, Type> promotionInfo = - _current.tryMarkNonNullable(typeOperations, lhsVariable); + _current.tryMarkNonNullable(typeOperations, lhsInfo._variable); _current = promotionInfo.ifFalse; promoted = promotionInfo.ifTrue; } else { @@ -2970,10 +2959,12 @@ @override void isExpression_end(Expression isExpression, Expression subExpression, bool isNot, Type type) { - Variable subExpressionVariable = _getExpressionVariable(subExpression); - if (subExpressionVariable != null) { - ExpressionInfo<Variable, Type> expressionInfo = _current - .tryPromoteForTypeCheck(typeOperations, subExpressionVariable, type); + ExpressionInfo<Variable, Type> subExpressionInfo = + _getExpressionInfo(subExpression); + if (subExpressionInfo is _VariableReadInfo<Variable, Type>) { + ExpressionInfo<Variable, Type> expressionInfo = + _current.tryPromoteForTypeCheck( + typeOperations, subExpressionInfo._variable, type); _storeExpressionInfo(isExpression, isNot ? ExpressionInfo.invert(expressionInfo) : expressionInfo); } @@ -3063,10 +3054,11 @@ @override void nonNullAssert_end(Expression operand) { - Variable operandVariable = _getExpressionVariable(operand); - if (operandVariable != null) { - _current = - _current.tryMarkNonNullable(typeOperations, operandVariable).ifTrue; + ExpressionInfo<Variable, Type> operandInfo = _getExpressionInfo(operand); + if (operandInfo is _VariableReadInfo<Variable, Type>) { + _current = _current + .tryMarkNonNullable(typeOperations, operandInfo._variable) + .ifTrue; } } @@ -3083,10 +3075,11 @@ _current = _current.split(); _stack.add(new _NullAwareAccessContext<Variable, Type>(_current)); if (target != null) { - Variable targetVariable = _getExpressionVariable(target); - if (targetVariable != null) { - _current = - _current.tryMarkNonNullable(typeOperations, targetVariable).ifTrue; + ExpressionInfo<Variable, Type> targetInfo = _getExpressionInfo(target); + if (targetInfo is _VariableReadInfo<Variable, Type>) { + _current = _current + .tryMarkNonNullable(typeOperations, targetInfo._variable) + .ifTrue; } } } @@ -3233,7 +3226,7 @@ @override Type variableRead(Expression expression, Variable variable) { - _storeExpressionVariable(expression, variable); + _storeExpressionInfo(expression, new _VariableReadInfo(_current, variable)); return _current.infoFor(variable).promotedTypes?.last; } @@ -3280,8 +3273,6 @@ print(' current: $_current'); print(' expressionWithInfo: $_expressionWithInfo'); print(' expressionInfo: $_expressionInfo'); - print(' expressionWithVariable: $_expressionWithVariable'); - print(' expressionVariable: $_expressionVariable'); print(' stack:'); for (_FlowContext stackEntry in _stack.reversed) { print(' $stackEntry'); @@ -3310,19 +3301,6 @@ } } - /// Gets the [Variable] associated with the [expression] (which should be the - /// last expression that was traversed). If there is no [Variable] associated - /// with the [expression], then `null` is returned. - Variable _getExpressionVariable(Expression expression) { - if (identical(expression, _expressionWithVariable)) { - Variable expressionVariable = _expressionVariable; - _expressionVariable = null; - return expressionVariable; - } else { - return null; - } - } - FlowModel<Variable, Type> _join( FlowModel<Variable, Type> first, FlowModel<Variable, Type> second) => FlowModel.join(typeOperations, first, second, _current._emptyVariableMap); @@ -3341,14 +3319,6 @@ _expressionInfo = expressionInfo; _current = expressionInfo.after; } - - /// Associates [expression], which should be the most recently visited - /// expression, with the given [Variable] object. - void _storeExpressionVariable( - Expression expression, Variable expressionVariable) { - _expressionWithVariable = expression; - _expressionVariable = expressionVariable; - } } /// Base class for objects representing constructs in the Dart programming @@ -3467,6 +3437,28 @@ 'afterBodyAndCatches: $_afterBodyAndCatches)'; } +/// [ExpressionInfo] representing an expression that reads the value of a +/// variable. +class _VariableReadInfo<Variable, Type> + implements ExpressionInfo<Variable, Type> { + @override + final FlowModel<Variable, Type> after; + + /// The variable that is being read. + final Variable _variable; + + _VariableReadInfo(this.after, this._variable); + + @override + FlowModel<Variable, Type> get ifFalse => after; + + @override + FlowModel<Variable, Type> get ifTrue => after; + + @override + String toString() => '_VariableReadInfo(after: $after, variable: $_variable)'; +} + /// [_FlowContext] representing a `while` loop (or a C-style `for` loop, which /// is functionally similar). class _WhileContext<Variable, Type>
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart index c0b5988..ba9c66d 100644 --- a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart +++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
@@ -367,6 +367,8 @@ // https://github.com/microsoft/vscode-languageserver-node/issues/673 includeCommitCharacters: server.clientConfiguration.previewCommitCharacters, + completeFunctionCalls: + server.clientConfiguration.completeFunctionCalls, )); results.addAll(setResults); });
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion_resolve.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion_resolve.dart index 4ea03d1..3157a79 100644 --- a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion_resolve.dart +++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion_resolve.dart
@@ -72,8 +72,11 @@ ); } + // If filterText is different to the label, it's because label has parens/args + // appended and we should take the basic label. We cannot use insertText as + // it may include snippets, whereas filterText is always just the pure string. + var requestedName = item.filterText ?? item.label; // The label might be `MyEnum.myValue`, but we import only `MyEnum`. - var requestedName = item.insertText ?? item.label; if (requestedName.contains('.')) { requestedName = requestedName.substring( 0, @@ -173,8 +176,6 @@ insertText: newInsertText, insertTextFormat: item.insertTextFormat, textEdit: TextEdit( - // TODO(dantup): If `clientSupportsSnippets == true` then we should map - // `selection` in to a snippet (see how Dart Code does this). range: toRange(lineInfo, data.rOffset, data.rLength), newText: newInsertText, ),
diff --git a/pkg/analysis_server/lib/src/lsp/mapping.dart b/pkg/analysis_server/lib/src/lsp/mapping.dart index 145b8bf..6f0cd7b 100644 --- a/pkg/analysis_server/lib/src/lsp/mapping.dart +++ b/pkg/analysis_server/lib/src/lsp/mapping.dart
@@ -34,6 +34,7 @@ import 'package:analyzer/src/services/available_declarations.dart'; import 'package:analyzer/src/services/available_declarations.dart' as dec; import 'package:analyzer_plugin/protocol/protocol_common.dart' as plugin; +import 'package:analyzer_plugin/utilities/pair.dart'; import 'package:meta/meta.dart'; const diagnosticTagsForErrorCode = <server.ErrorCode, List<lsp.DiagnosticTag>>{ @@ -223,43 +224,67 @@ int replacementOffset, int replacementLength, { @required bool includeCommitCharacters, + @required bool completeFunctionCalls, }) { - // Build display labels and text to insert. insertText and filterText may - // differ from label (for ex. if the label includes things like (…)). If - // either are missing then label will be used by the client. - String label; - String insertText; - String filterText; + final supportsSnippets = + completionCapabilities?.completionItem?.snippetSupport == true; + + String completion; switch (declaration.kind) { case DeclarationKind.ENUM_CONSTANT: - label = '${declaration.parent.name}.${declaration.name}'; + completion = '${declaration.parent.name}.${declaration.name}'; break; case DeclarationKind.GETTER: case DeclarationKind.FIELD: - label = declaration.parent != null && + completion = declaration.parent != null && declaration.parent.name != null && declaration.parent.name.isNotEmpty ? '${declaration.parent.name}.${declaration.name}' : declaration.name; break; case DeclarationKind.CONSTRUCTOR: - label = declaration.parent.name; + completion = declaration.parent.name; if (declaration.name.isNotEmpty) { - label += '.${declaration.name}'; + completion += '.${declaration.name}'; } - insertText = label; - filterText = label; - label += declaration.parameterNames?.isNotEmpty ?? false ? '(…)' : '()'; - break; - case DeclarationKind.FUNCTION: - label = declaration.name; - insertText = label; - filterText = label; - label += declaration.parameterNames?.isNotEmpty ?? false ? '(…)' : '()'; break; default: - label = declaration.name; + completion = declaration.name; + break; } + // By default, label is the same as the completion text, but may be added to + // later (parens/snippets). + var label = completion; + + // isCallable is used to suffix the label with parens so it's clear the item + // is callable. + final declarationKind = declaration.kind; + final isCallable = declarationKind == DeclarationKind.CONSTRUCTOR || + declarationKind == DeclarationKind.FUNCTION || + declarationKind == DeclarationKind.METHOD; + + if (isCallable) { + label += declaration.parameterNames?.isNotEmpty ?? false ? '(…)' : '()'; + } + + final insertTextInfo = _buildInsertText( + supportsSnippets: supportsSnippets, + includeCommitCharacters: includeCommitCharacters, + completeFunctionCalls: completeFunctionCalls, + isCallable: isCallable, + // For SuggestionSets, we don't have a CompletionKind to check if it's + // an invocation, but since they do not show in show/hide combinators + // we can assume if an item is callable it's probably being used in a context + // that can invoke it. + isInvocation: isCallable, + defaultArgumentListString: declaration.defaultArgumentListString, + defaultArgumentListTextRanges: declaration.defaultArgumentListTextRanges, + completion: completion, + selectionOffset: 0, + selectionLength: 0, + ); + final insertText = insertTextInfo.first; + final insertTextFormat = insertTextInfo.last; final supportsDeprecatedFlag = completionCapabilities?.completionItem?.deprecatedSupport == true; @@ -302,12 +327,15 @@ // 10 -> 999990 // 1 -> 999999 sortText: (1000000 - itemRelevance).toString(), - filterText: filterText != label - ? filterText + filterText: completion != label + ? completion : null, // filterText uses label if not set insertText: insertText != label ? insertText : null, // insertText uses label if not set + insertTextFormat: insertTextFormat != lsp.InsertTextFormat.PlainText + ? insertTextFormat + : null, // Defaults to PlainText if not supplied // data, used for completionItem/resolve. data: lsp.DartCompletionItemResolutionInfo( file: file, @@ -797,8 +825,6 @@ // differ from label (for ex. if the label includes things like (…)). If // either are missing then label will be used by the client. var label = suggestion.displayText ?? suggestion.completion; - var insertText = suggestion.completion; - var filterText = suggestion.completion; // Trim any trailing comma from the (displayed) label. if (label.endsWith(',')) { @@ -841,37 +867,20 @@ : suggestionKindToCompletionItemKind( supportedCompletionItemKinds, suggestion.kind, label); - var insertTextFormat = lsp.InsertTextFormat.PlainText; - - // If the client supports snippets, we can support completeFunctionCalls or - // setting a selection. - if (supportsSnippets) { - // completeFunctionCalls should only work if commit characters are disabled - // otherwise the editor may insert parens that we're also inserting. - if (!includeCommitCharacters && - completeFunctionCalls && - isCallable && - isInvocation) { - insertTextFormat = lsp.InsertTextFormat.Snippet; - final hasRequiredParameters = - (suggestion.defaultArgumentListTextRanges?.length ?? 0) > 0; - final functionCallSuffix = hasRequiredParameters - ? buildSnippetStringWithTabStops( - suggestion.defaultArgumentListString, - suggestion.defaultArgumentListTextRanges, - ) - : '\${0:}'; // No required params still gets a tabstop in the parens. - insertText += '($functionCallSuffix)'; - } else if (suggestion.selectionOffset != 0 && - // We don't need a tabstop if the selection is the end of the string. - suggestion.selectionOffset != suggestion.completion.length) { - insertTextFormat = lsp.InsertTextFormat.Snippet; - insertText = buildSnippetStringWithTabStops( - suggestion.completion, - [suggestion.selectionOffset, suggestion.selectionLength], - ); - } - } + final insertTextInfo = _buildInsertText( + supportsSnippets: supportsSnippets, + includeCommitCharacters: includeCommitCharacters, + completeFunctionCalls: completeFunctionCalls, + isCallable: isCallable, + isInvocation: isInvocation, + defaultArgumentListString: suggestion.defaultArgumentListString, + defaultArgumentListTextRanges: suggestion.defaultArgumentListTextRanges, + completion: suggestion.completion, + selectionOffset: suggestion.selectionOffset, + selectionLength: suggestion.selectionLength, + ); + final insertText = insertTextInfo.first; + final insertTextFormat = insertTextInfo.last; // Because we potentially send thousands of these items, we should minimise // the generated JSON as much as possible - for example using nulls in place @@ -899,8 +908,8 @@ // 10 -> 999990 // 1 -> 999999 sortText: (1000000 - suggestion.relevance).toString(), - filterText: filterText != label - ? filterText + filterText: suggestion.completion != label + ? suggestion.completion : null, // filterText uses label if not set insertText: insertText != label ? insertText @@ -1269,3 +1278,51 @@ return lsp.MarkupContent(kind: format, value: content); } + +Pair<String, lsp.InsertTextFormat> _buildInsertText({ + @required bool supportsSnippets, + @required bool includeCommitCharacters, + @required bool completeFunctionCalls, + @required bool isCallable, + @required bool isInvocation, + @required String defaultArgumentListString, + @required List<int> defaultArgumentListTextRanges, + @required String completion, + @required int selectionOffset, + @required int selectionLength, +}) { + var insertText = completion; + var insertTextFormat = lsp.InsertTextFormat.PlainText; + + // If the client supports snippets, we can support completeFunctionCalls or + // setting a selection. + if (supportsSnippets) { + // completeFunctionCalls should only work if commit characters are disabled + // otherwise the editor may insert parens that we're also inserting. + if (!includeCommitCharacters && + completeFunctionCalls && + isCallable && + isInvocation) { + insertTextFormat = lsp.InsertTextFormat.Snippet; + final hasRequiredParameters = + (defaultArgumentListTextRanges?.length ?? 0) > 0; + final functionCallSuffix = hasRequiredParameters + ? buildSnippetStringWithTabStops( + defaultArgumentListString, + defaultArgumentListTextRanges, + ) + : '\${0:}'; // No required params still gets a tabstop in the parens. + insertText += '($functionCallSuffix)'; + } else if (selectionOffset != 0 && + // We don't need a tabstop if the selection is the end of the string. + selectionOffset != completion.length) { + insertTextFormat = lsp.InsertTextFormat.Snippet; + insertText = buildSnippetStringWithTabStops( + completion, + [selectionOffset, selectionLength], + ); + } + } + + return Pair(insertText, insertTextFormat); +}
diff --git a/pkg/analysis_server/test/lsp/completion_dart_test.dart b/pkg/analysis_server/test/lsp/completion_dart_test.dart index 304bbbb..f71db6c 100644 --- a/pkg/analysis_server/test/lsp/completion_dart_test.dart +++ b/pkg/analysis_server/test/lsp/completion_dart_test.dart
@@ -177,6 +177,43 @@ expect(item.textEdit.newText, equals(item.insertText)); } + Future<void> test_completeFunctionCalls_suggestionSets() async { + final content = ''' + main() { + [[pri]]^ + } + '''; + + final initialAnalysis = waitForAnalysisComplete(); + await provideConfig( + () => initialize( + textDocumentCapabilities: withCompletionItemSnippetSupport( + emptyTextDocumentClientCapabilities), + workspaceCapabilities: withConfigurationSupport( + withApplyEditSupport(emptyWorkspaceClientCapabilities)), + ), + {'completeFunctionCalls': true}, + ); + await openFile(mainFileUri, withoutMarkers(content)); + await initialAnalysis; + final res = await getCompletion(mainFileUri, positionFromMarker(content)); + final item = res.singleWhere((c) => c.label == 'print(…)'); + // Ensure the snippet comes through in the expected format with the expected + // placeholders. + expect(item.insertTextFormat, equals(InsertTextFormat.Snippet)); + expect(item.insertText, equals(r'print(${0:object})')); + expect(item.textEdit, isNull); + + // Ensure the item can be resolved and gets a proper TextEdit. + final resolved = await resolveCompletion(item); + expect(resolved.textEdit, isNotNull); + expect(resolved.textEdit.newText, equals(item.insertText)); + expect( + resolved.textEdit.range, + equals(rangeFromMarkers(content)), + ); + } + Future<void> test_completionKinds_default() async { newFile(join(projectFolderPath, 'file.dart')); newFolder(join(projectFolderPath, 'folder'));
diff --git a/pkg/analyzer/lib/src/dart/analysis/experiments.dart b/pkg/analyzer/lib/src/dart/analysis/experiments.dart index 173a9e6..560bd68 100644 --- a/pkg/analyzer/lib/src/dart/analysis/experiments.dart +++ b/pkg/analyzer/lib/src/dart/analysis/experiments.dart
@@ -44,11 +44,11 @@ static final Version testingSdkLanguageVersion = Version.parse('2.10.0'); /// The latest known language version. - static final Version latestSdkLanguageVersion = Version.parse('2.10.0'); + static final Version latestSdkLanguageVersion = Version.parse('2.12.0'); static final FeatureSet latestWithNullSafety = ExperimentStatus.fromStrings2( sdkLanguageVersion: latestSdkLanguageVersion, - flags: [EnableString.non_nullable], + flags: [], ); /// A map containing information about all known experimental flags.
diff --git a/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart b/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart index 32b5d0f..771dfe8 100644 --- a/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart +++ b/pkg/analyzer/lib/src/dart/analysis/feature_set_provider.dart
@@ -53,6 +53,12 @@ } /// Return the [FeatureSet] for the package that contains the file. + /// + /// Note, that [getLanguageVersion] returns the default language version + /// for libraries in the package, but this method does not restrict the + /// [FeatureSet] of this version. The reason is that we allow libraries to + /// "upgrade" to higher version than the default package language version, + /// and want this to preserve experimental features. FeatureSet getFeatureSet(String path, Uri uri) { if (uri.isScheme('dart')) { var pathSegments = uri.pathSegments;
diff --git a/pkg/analyzer/lib/src/summary2/ast_text_printer.dart b/pkg/analyzer/lib/src/summary2/ast_text_printer.dart index 4c87ce8..4e733f9 100644 --- a/pkg/analyzer/lib/src/summary2/ast_text_printer.dart +++ b/pkg/analyzer/lib/src/summary2/ast_text_printer.dart
@@ -964,6 +964,7 @@ @override void visitVariableDeclarationList(VariableDeclarationList node) { _annotatedNode(node); + _token(node.lateKeyword); _token(node.keyword); node.type?.accept(this); _nodeList(node.variables, node.endToken.next); @@ -1042,6 +1043,7 @@ void _normalFormalParameter(NormalFormalParameter node) { node.documentationComment?.accept(this); _nodeList(node.metadata); + _token(node.requiredKeyword); _token(node.covariantKeyword); }
diff --git a/pkg/analyzer/test/dart/analysis/utilities_test.dart b/pkg/analyzer/test/dart/analysis/utilities_test.dart index 0c2dbf0..da03e22 100644 --- a/pkg/analyzer/test/dart/analysis/utilities_test.dart +++ b/pkg/analyzer/test/dart/analysis/utilities_test.dart
@@ -10,6 +10,7 @@ import 'package:analyzer/file_system/memory_file_system.dart'; import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart'; import 'package:path/path.dart' as p; +import 'package:pub_semver/pub_semver.dart'; import 'package:test/test.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; @@ -91,7 +92,10 @@ String content = ''' int? f() => 1; '''; - var featureSet = FeatureSet.forTesting(sdkVersion: '2.3.0'); + var featureSet = FeatureSet.fromEnableFlags2( + sdkLanguageVersion: Version.parse('2.9.0'), + flags: [], + ); expect(featureSet.isEnabled(Feature.non_nullable), isFalse); ParseStringResult result = _withMemoryFile( content, @@ -179,7 +183,10 @@ String content = ''' int? f() => 1; '''; - var featureSet = FeatureSet.forTesting(sdkVersion: '2.3.0'); + var featureSet = FeatureSet.fromEnableFlags2( + sdkLanguageVersion: Version.parse('2.9.0'), + flags: [], + ); expect(featureSet.isEnabled(Feature.non_nullable), isFalse); ParseStringResult result = parseString( content: content, throwIfDiagnostics: false, featureSet: featureSet);
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart index d054a17..34b6b84 100644 --- a/pkg/analyzer/test/generated/parser_fasta_test.dart +++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -1142,8 +1142,7 @@ expect(thenExpression, isParenthesizedExpression); Expression elseExpression = expression.elseExpression; expect(elseExpression, isSimpleIdentifier); - assertErrors( - errors: [expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 9, 1)]); + assertNoErrors(); } void test_conditionalExpression_precedence_nullableType_as3() { @@ -1158,8 +1157,7 @@ expect(thenExpression, isParenthesizedExpression); Expression elseExpression = expression.elseExpression; expect(elseExpression, isSimpleIdentifier); - assertErrors( - errors: [expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 10, 1)]); + assertNoErrors(); } void test_conditionalExpression_precedence_nullableType_is2() { @@ -1173,8 +1171,7 @@ expect(thenExpression, isParenthesizedExpression); Expression elseExpression = expression.elseExpression; expect(elseExpression, isSimpleIdentifier); - assertErrors( - errors: [expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 11, 1)]); + assertNoErrors(); } void test_conditionalExpression_precedence_nullableType_is3() { @@ -1189,8 +1186,7 @@ expect(thenExpression, isParenthesizedExpression); Expression elseExpression = expression.elseExpression; expect(elseExpression, isSimpleIdentifier); - assertErrors( - errors: [expectedError(ParserErrorCode.EXPERIMENT_NOT_ENABLED, 12, 1)]); + assertNoErrors(); } } @@ -1877,17 +1873,16 @@ implements AbstractParserTestCase { static final List<ErrorCode> NO_ERROR_COMPARISON = <ErrorCode>[]; - final controlFlow = FeatureSet.forTesting( - sdkVersion: '2.0.0', - additionalFeatures: [Feature.control_flow_collections]); + final controlFlow = FeatureSet.latestLanguageVersion(); - final spread = FeatureSet.forTesting( - sdkVersion: '2.0.0', additionalFeatures: [Feature.spread_collections]); + final spread = FeatureSet.latestLanguageVersion(); - final nonNullable = FeatureSet.forTesting( - sdkVersion: '2.2.2', additionalFeatures: [Feature.non_nullable]); + final nonNullable = FeatureSet.latestLanguageVersion(); - final preNonNullable = FeatureSet.forTesting(sdkVersion: '2.2.2'); + final preNonNullable = FeatureSet.fromEnableFlags2( + sdkLanguageVersion: Version.parse('2.9.0'), + flags: [], + ); ParserProxy _parserProxy; @@ -2169,7 +2164,8 @@ @override FormalParameter parseFormalParameter(String code, ParameterKind kind, - {List<ErrorCode> errorCodes = const <ErrorCode>[]}) { + {List<ErrorCode> errorCodes = const <ErrorCode>[], + FeatureSet featureSet}) { String parametersCode; if (kind == ParameterKind.REQUIRED) { parametersCode = '($code)'; @@ -2181,7 +2177,7 @@ fail('$kind'); } FormalParameterList list = parseFormalParameterList(parametersCode, - inFunctionType: false, errorCodes: errorCodes); + inFunctionType: false, errorCodes: errorCodes, featureSet: featureSet); return list.parameters.single; } @@ -2189,8 +2185,9 @@ FormalParameterList parseFormalParameterList(String code, {bool inFunctionType = false, List<ErrorCode> errorCodes = const <ErrorCode>[], - List<ExpectedError> errors}) { - createParser(code); + List<ExpectedError> errors, + FeatureSet featureSet}) { + createParser(code, featureSet: featureSet); FormalParameterList result = _parserProxy.parseFormalParameterList(inFunctionType: inFunctionType); assertErrors(codes: errors != null ? null : errorCodes, errors: errors); @@ -2456,6 +2453,7 @@ void test_functionTyped_named_nullable_disabled() { ParameterKind kind = ParameterKind.NAMED; var defaultParameter = parseFormalParameter('a()? : null', kind, + featureSet: preNonNullable, errorCodes: [ParserErrorCode.EXPERIMENT_NOT_ENABLED]) as DefaultFormalParameter; var functionParameter = @@ -2474,6 +2472,7 @@ void test_functionTyped_positional_nullable_disabled() { ParameterKind kind = ParameterKind.POSITIONAL; var defaultParameter = parseFormalParameter('a()? = null', kind, + featureSet: preNonNullable, errorCodes: [ParserErrorCode.EXPERIMENT_NOT_ENABLED]) as DefaultFormalParameter; var functionParameter = @@ -2492,6 +2491,7 @@ void test_functionTyped_required_nullable_disabled() { ParameterKind kind = ParameterKind.REQUIRED; var functionParameter = parseFormalParameter('a()?', kind, + featureSet: preNonNullable, errorCodes: [ParserErrorCode.EXPERIMENT_NOT_ENABLED]) as FunctionTypedFormalParameter; expect(functionParameter.returnType, isNull); @@ -2676,7 +2676,9 @@ List<ExpectedError> errors, FeatureSet featureSet}) => super.parseCompilationUnit(content, - codes: codes, errors: errors, featureSet: featureSet ?? nonNullable); + codes: codes, + errors: errors, + featureSet: featureSet ?? FeatureSet.latestLanguageVersion()); void test_assignment_complex() { parseCompilationUnit('D? foo(X? x) { X? x1; X? x2 = x + bar(7); }');
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart index 3f1b6d7..340cb84 100644 --- a/pkg/analyzer/test/generated/parser_test.dart +++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -2354,8 +2354,7 @@ createParser('abstract C f;'); ClassMember member = parser.parseClassMember('C'); expectNotNullIfNoErrors(member); - listener.assertErrors( - [expectedError(ParserErrorCode.ABSTRACT_CLASS_MEMBER, 0, 8)]); + assertNoErrors(); } void test_abstractClassMember_getter() { @@ -3342,10 +3341,8 @@ ClassMember member = parser.parseClassMember('C'); expectNotNullIfNoErrors(member); if (usingFastaParser) { - listener.assertErrors([ - expectedError(ParserErrorCode.EXTERNAL_FIELD, 0, 8), - expectedError(CompileTimeErrorCode.CONST_NOT_INITIALIZED, 17, 1) - ]); + listener.assertErrors( + [expectedError(CompileTimeErrorCode.CONST_NOT_INITIALIZED, 17, 1)]); } else { listener.assertErrorsWithCodes([ParserErrorCode.EXTERNAL_FIELD]); } @@ -3355,32 +3352,28 @@ createParser('external final A f;'); ClassMember member = parser.parseClassMember('C'); expectNotNullIfNoErrors(member); - listener - .assertErrors([expectedError(ParserErrorCode.EXTERNAL_FIELD, 0, 8)]); + assertNoErrors(); } void test_externalField_static() { createParser('external static A f;'); ClassMember member = parser.parseClassMember('C'); expectNotNullIfNoErrors(member); - listener - .assertErrors([expectedError(ParserErrorCode.EXTERNAL_FIELD, 0, 8)]); + assertNoErrors(); } void test_externalField_typed() { createParser('external A f;'); ClassMember member = parser.parseClassMember('C'); expectNotNullIfNoErrors(member); - listener - .assertErrors([expectedError(ParserErrorCode.EXTERNAL_FIELD, 0, 8)]); + assertNoErrors(); } void test_externalField_untyped() { createParser('external var f;'); ClassMember member = parser.parseClassMember('C'); expectNotNullIfNoErrors(member); - listener - .assertErrors([expectedError(ParserErrorCode.EXTERNAL_FIELD, 0, 8)]); + assertNoErrors(); } void test_externalGetterWithBody() {
diff --git a/pkg/analyzer/test/src/dart/analysis/feature_set_provider_test.dart b/pkg/analyzer/test/src/dart/analysis/feature_set_provider_test.dart index 37172b1..441fe5b 100644 --- a/pkg/analyzer/test/src/dart/analysis/feature_set_provider_test.dart +++ b/pkg/analyzer/test/src/dart/analysis/feature_set_provider_test.dart
@@ -38,68 +38,36 @@ _createSourceFactory(); } - test_packages_allowedExperiments() { - var packages = Packages( - { - 'aaa': Package( - name: 'aaa', - rootFolder: newFolder('/packages/aaa'), - libFolder: newFolder('/packages/aaa/lib'), - languageVersion: Version(2, 7, 0), - ), - 'bbb': Package( - name: 'bbb', - rootFolder: newFolder('/packages/bbb'), - libFolder: newFolder('/packages/bbb/lib'), - languageVersion: Version(2, 7, 0), - ), - }, - ); - - _createSourceFactory( - packageUriResolver: _createPackageMapUriResolver(packages), + test_getFeatureSet_allowedExperiments() { + var feature_a = ExperimentalFeature( + index: 0, + enableString: 'a', + isEnabledByDefault: false, + isExpired: false, + documentation: 'a', + experimentalReleaseVersion: null, + releaseVersion: null, ); _newSdkExperimentsFile(r''' { "version": 1, "experimentSets": { - "nullSafety": ["non-nullable"] + "with_a": ["a"] }, "sdk": { "default": { - "experimentSet": "nullSafety" + "experimentSet": "with_a" } }, "packages": { "aaa": { - "experimentSet": "nullSafety" + "experimentSet": "with_a" } } } '''); - provider = FeatureSetProvider.build( - sourceFactory: sourceFactory, - resourceProvider: resourceProvider, - packages: packages, - packageDefaultFeatureSet: FeatureSet.latestLanguageVersion(), - nonPackageDefaultLanguageVersion: ExperimentStatus.currentVersion, - nonPackageDefaultFeatureSet: FeatureSet.latestLanguageVersion(), - ); - - _assertNonNullableForPath('/packages/aaa/lib/a.dart', true); - _assertNonNullableForPath('/packages/aaa/bin/b.dart', true); - _assertNonNullableForPath('/packages/aaa/test/c.dart', true); - - _assertNonNullableForPath('/packages/bbb/lib/a.dart', false); - _assertNonNullableForPath('/packages/bbb/bin/b.dart', false); - _assertNonNullableForPath('/packages/bbb/test/c.dart', false); - - _assertNonNullableForPath('/other/file.dart', false); - } - - test_packages_contextExperiments_empty() { var packages = Packages( { 'aaa': Package( @@ -112,13 +80,7 @@ name: 'bbb', rootFolder: newFolder('/packages/bbb'), libFolder: newFolder('/packages/bbb/lib'), - languageVersion: Version(2, 7, 0), - ), - 'ccc': Package( - name: 'ccc', - rootFolder: newFolder('/packages/ccc'), - libFolder: newFolder('/packages/ccc/lib'), - languageVersion: Version(2, 8, 0), + languageVersion: null, ), }, ); @@ -127,28 +89,145 @@ packageUriResolver: _createPackageMapUriResolver(packages), ); - provider = FeatureSetProvider.build( - sourceFactory: sourceFactory, - resourceProvider: resourceProvider, - packages: packages, - packageDefaultFeatureSet: FeatureSet.latestLanguageVersion(), - nonPackageDefaultLanguageVersion: ExperimentStatus.currentVersion, - nonPackageDefaultFeatureSet: FeatureSet.latestLanguageVersion(), + overrideKnownFeatures({'a': feature_a}, () { + provider = FeatureSetProvider.build( + sourceFactory: sourceFactory, + resourceProvider: resourceProvider, + packages: packages, + packageDefaultFeatureSet: FeatureSet.latestLanguageVersion(), + nonPackageDefaultLanguageVersion: ExperimentStatus.currentVersion, + nonPackageDefaultFeatureSet: FeatureSet.latestLanguageVersion(), + ); + + void assertHasFeature(String path, bool expected) { + _assertHasFeatureForPath(path, feature_a, expected); + } + + assertHasFeature('/packages/aaa/lib/a.dart', true); + assertHasFeature('/packages/aaa/bin/b.dart', true); + assertHasFeature('/packages/aaa/test/c.dart', true); + + assertHasFeature('/packages/bbb/lib/a.dart', false); + assertHasFeature('/packages/bbb/bin/b.dart', false); + assertHasFeature('/packages/bbb/test/c.dart', false); + + assertHasFeature('/other/file.dart', false); + }); + } + + test_getFeatureSet_defaultForContext_hasExperiment() { + var feature_a = ExperimentalFeature( + index: 0, + enableString: 'a', + isEnabledByDefault: false, + isExpired: false, + documentation: 'a', + experimentalReleaseVersion: Version.parse('2.12.0'), + releaseVersion: null, ); - _assertNonNullableForPath('/packages/aaa/a.dart', false); - _assertNonNullableForPath('/packages/aaa/lib/b.dart', false); - _assertNonNullableForPath('/packages/aaa/test/c.dart', false); + var packages = Packages( + { + 'aaa': Package( + name: 'aaa', + rootFolder: newFolder('/packages/aaa'), + libFolder: newFolder('/packages/aaa/lib'), + languageVersion: null, + ), + 'bbb': Package( + name: 'bbb', + rootFolder: newFolder('/packages/bbb'), + libFolder: newFolder('/packages/bbb/lib'), + languageVersion: Version(2, 12, 0), + ), + }, + ); - _assertNonNullableForPath('/packages/bbb/a.dart', false); - _assertNonNullableForPath('/packages/bbb/lib/b.dart', false); - _assertNonNullableForPath('/packages/bbb/test/c.dart', false); + _createSourceFactory( + packageUriResolver: _createPackageMapUriResolver(packages), + ); - _assertNonNullableForPath('/packages/ccc/a.dart', false); - _assertNonNullableForPath('/packages/ccc/lib/b.dart', false); - _assertNonNullableForPath('/packages/ccc/test/c.dart', false); + overrideKnownFeatures({'a': feature_a}, () { + provider = FeatureSetProvider.build( + sourceFactory: sourceFactory, + resourceProvider: resourceProvider, + packages: packages, + packageDefaultFeatureSet: FeatureSet.fromEnableFlags2( + sdkLanguageVersion: Version.parse('2.12.0'), + flags: [feature_a.enableString], + ), + nonPackageDefaultLanguageVersion: ExperimentStatus.currentVersion, + nonPackageDefaultFeatureSet: FeatureSet.latestLanguageVersion(), + ); - _assertNonNullableForPath('/other/file.dart', false); + void assertHasFeature(String path, bool expected) { + _assertHasFeatureForPath(path, feature_a, expected); + } + + assertHasFeature('/packages/aaa/a.dart', true); + assertHasFeature('/packages/aaa/lib/b.dart', true); + assertHasFeature('/packages/aaa/test/c.dart', true); + + assertHasFeature('/packages/bbb/a.dart', true); + assertHasFeature('/packages/bbb/lib/b.dart', true); + assertHasFeature('/packages/bbb/test/c.dart', true); + }); + } + + test_getFeatureSet_defaultForContext_noExperiments() { + var feature_a = ExperimentalFeature( + index: 0, + enableString: 'a', + isEnabledByDefault: false, + isExpired: false, + documentation: 'a', + experimentalReleaseVersion: Version.parse('2.12.0'), + releaseVersion: null, + ); + + var packages = Packages( + { + 'aaa': Package( + name: 'aaa', + rootFolder: newFolder('/packages/aaa'), + libFolder: newFolder('/packages/aaa/lib'), + languageVersion: null, + ), + 'bbb': Package( + name: 'bbb', + rootFolder: newFolder('/packages/bbb'), + libFolder: newFolder('/packages/bbb/lib'), + languageVersion: Version(2, 12, 0), + ), + }, + ); + + _createSourceFactory( + packageUriResolver: _createPackageMapUriResolver(packages), + ); + + overrideKnownFeatures({'a': feature_a}, () { + provider = FeatureSetProvider.build( + sourceFactory: sourceFactory, + resourceProvider: resourceProvider, + packages: packages, + packageDefaultFeatureSet: FeatureSet.latestLanguageVersion(), + nonPackageDefaultLanguageVersion: ExperimentStatus.currentVersion, + nonPackageDefaultFeatureSet: FeatureSet.latestLanguageVersion(), + ); + + void assertHasFeature(String path, bool expected) { + _assertHasFeatureForPath(path, feature_a, expected); + } + + assertHasFeature('/packages/aaa/a.dart', false); + assertHasFeature('/packages/aaa/lib/b.dart', false); + assertHasFeature('/packages/aaa/test/c.dart', false); + + assertHasFeature('/packages/bbb/a.dart', false); + assertHasFeature('/packages/bbb/lib/b.dart', false); + assertHasFeature('/packages/bbb/test/c.dart', false); + }); } test_packages_contextExperiments_nested() { @@ -228,38 +307,6 @@ ); } - test_packages_contextExperiments_nonNullable() { - var packages = Packages( - { - 'aaa': Package( - name: 'aaa', - rootFolder: newFolder('/packages/aaa'), - libFolder: newFolder('/packages/aaa/lib'), - languageVersion: null, - ), - }, - ); - - _createSourceFactory( - packageUriResolver: _createPackageMapUriResolver(packages), - ); - - provider = FeatureSetProvider.build( - sourceFactory: sourceFactory, - resourceProvider: resourceProvider, - packages: packages, - packageDefaultFeatureSet: ExperimentStatus.latestWithNullSafety, - nonPackageDefaultLanguageVersion: ExperimentStatus.currentVersion, - nonPackageDefaultFeatureSet: FeatureSet.latestLanguageVersion(), - ); - - _assertNonNullableForPath('/packages/aaa/a.dart', true); - _assertNonNullableForPath('/packages/aaa/lib/b.dart', true); - _assertNonNullableForPath('/packages/aaa/test/c.dart', true); - - _assertNonNullableForPath('/other/file.dart', false); - } - test_sdk_allowedExperiments_default() { var feature_a = ExperimentalFeature( index: 0, @@ -366,9 +413,9 @@ expect(featureSet.isEnabled(Feature.non_nullable), isTrue); } - void _assertNonNullableForPath(String path, bool expected) { + _assertHasFeatureForPath(String path, Feature feature, bool expected) { var featureSet = _getPathFeatureSet(path); - expect(featureSet.isEnabled(Feature.non_nullable), expected); + expect(featureSet.isEnabled(feature), expected); } PackageMapUriResolver _createPackageMapUriResolver(Packages packages) {
diff --git a/pkg/analyzer/test/src/dart/resolver/legacy_type_asserter_test.dart b/pkg/analyzer/test/src/dart/resolver/legacy_type_asserter_test.dart index 28cd25a..75d3b88 100644 --- a/pkg/analyzer/test/src/dart/resolver/legacy_type_asserter_test.dart +++ b/pkg/analyzer/test/src/dart/resolver/legacy_type_asserter_test.dart
@@ -10,6 +10,7 @@ import 'package:analyzer/src/dart/element/type.dart'; import 'package:analyzer/src/dart/resolver/legacy_type_asserter.dart'; import 'package:analyzer/src/generated/testing/ast_test_factory.dart'; +import 'package:pub_semver/pub_semver.dart'; import 'package:test/test.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart'; @@ -140,15 +141,20 @@ CompilationUnit _wrapExpression(Expression e, {bool nonNullable = false}) { return AstTestFactory.compilationUnit9( - declarations: [ - AstTestFactory.functionDeclaration( - null, - null, - null, - AstTestFactory.functionExpression2( - null, AstTestFactory.expressionFunctionBody(e))) - ], - featureSet: FeatureSet.forTesting( - additionalFeatures: nonNullable ? [Feature.non_nullable] : [])); + declarations: [ + AstTestFactory.functionDeclaration( + null, + null, + null, + AstTestFactory.functionExpression2( + null, AstTestFactory.expressionFunctionBody(e))) + ], + featureSet: nonNullable + ? FeatureSet.latestLanguageVersion() + : FeatureSet.fromEnableFlags2( + sdkLanguageVersion: Version.parse('2.9.0'), + flags: [], + ), + ); } }
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart index 1950530..aab0156 100644 --- a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart +++ b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
@@ -34,22 +34,14 @@ class ResynthesizeAst2Test extends AbstractResynthesizeTest with ResynthesizeTestCases { /// The shared SDK bundle, computed once and shared among test invocations. - static _SdkBundle _sdkBundleNullSafe; - - /// The shared SDK bundle, computed once and shared among test invocations. - static _SdkBundle _sdkBundleLegacy; + static _SdkBundle _sdkBundle; _SdkBundle get sdkBundle { - if (featureSet.isEnabled(Feature.non_nullable)) { - if (_sdkBundleNullSafe != null) { - return _sdkBundleNullSafe; - } - } else { - if (_sdkBundleLegacy != null) { - return _sdkBundleLegacy; - } + if (_sdkBundle != null) { + return _sdkBundle; } + var featureSet = FeatureSet.latestLanguageVersion(); var inputLibraries = <LinkInputLibrary>[]; for (var sdkLibrary in sdk.sdkLibraries) { var source = sourceFactory.resolveUri(null, sdkLibrary.shortName); @@ -57,7 +49,7 @@ var unit = parseText(text, featureSet); var inputUnits = <LinkInputUnit>[]; - _addLibraryUnits(source, unit, inputUnits); + _addLibraryUnits(source, unit, inputUnits, featureSet); inputLibraries.add( LinkInputLibrary(source, inputUnits), ); @@ -77,17 +69,10 @@ var sdkLinkResult = link(elementFactory, inputLibraries, true); - if (featureSet.isEnabled(Feature.non_nullable)) { - return _sdkBundleNullSafe = _SdkBundle( - astBytes: sdkLinkResult.astBytes, - resolutionBytes: sdkLinkResult.resolutionBytes, - ); - } else { - return _sdkBundleLegacy = _SdkBundle( - astBytes: sdkLinkResult.astBytes, - resolutionBytes: sdkLinkResult.resolutionBytes, - ); - } + return _sdkBundle = _SdkBundle( + astBytes: sdkLinkResult.astBytes, + resolutionBytes: sdkLinkResult.resolutionBytes, + ); } @override @@ -144,6 +129,7 @@ Source definingSource, CompilationUnit definingUnit, List<LinkInputUnit> units, + FeatureSet featureSet, ) { units.add( LinkInputUnit(null, definingSource, false, definingUnit), @@ -188,7 +174,7 @@ var unit = parseText(text, featureSet); var units = <LinkInputUnit>[]; - _addLibraryUnits(source, unit, units); + _addLibraryUnits(source, unit, units, featureSet); libraries.add( LinkInputLibrary(source, units), );
diff --git a/pkg/compiler/lib/src/inferrer/builder_kernel.dart b/pkg/compiler/lib/src/inferrer/builder_kernel.dart index fdfd67e..55d7ab6 100644 --- a/pkg/compiler/lib/src/inferrer/builder_kernel.dart +++ b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
@@ -1243,15 +1243,15 @@ var commonElements = _elementMap.commonElements; if (commonElements.isUnnamedListConstructor(constructor)) { - // We have `new List.filled(..., null)`. + // We have `new List(...)`. if (arguments.positional.isEmpty && arguments.named.isEmpty) { - // We have `[]`. + // We have `new List()`. return _inferrer.concreteTypes.putIfAbsent( node, () => _types.allocateList(_types.growableListType, node, _analyzedMember, _types.nonNullEmpty(), 0)); } else { - // We have `new List.filled(len, null)`. + // We have `new List(len)`. int length = _findLength(arguments); return _inferrer.concreteTypes.putIfAbsent( node,
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types.dart b/pkg/compiler/lib/src/js_backend/runtime_types.dart index 2998012..c8084d5 100644 --- a/pkg/compiler/lib/src/js_backend/runtime_types.dart +++ b/pkg/compiler/lib/src/js_backend/runtime_types.dart
@@ -994,7 +994,7 @@ /// For instance `A` in: /// /// class A {} - /// main() => <A>[] is List<String>; + /// main() => new List<A>() is List<String>; /// bool typeArgument = false; @@ -1003,7 +1003,7 @@ /// For instance `A` in: /// /// class A {} - /// main() => <String>[] is List<A>; + /// main() => new List<String>() is List<A>; /// bool checkedTypeArgument = false;
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart index e81ca79..7c66c12 100644 --- a/pkg/compiler/lib/src/ssa/builder_kernel.dart +++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -3816,12 +3816,12 @@ return; } - // Recognize `[]` and `List.filled(n, null)`. + // Recognize `List()` and `List(n)`. if (_commonElements.isUnnamedListConstructor(function)) { if (invocation.arguments.named.isEmpty) { int argumentCount = invocation.arguments.positional.length; if (argumentCount == 0) { - // `[]` takes no arguments, `JSArray.list()` takes a sentinel. + // `List()` takes no arguments, `JSArray.list()` takes a sentinel. assert(arguments.length == 0 || arguments.length == 1, '\narguments: $arguments\n'); _handleInvokeLegacyGrowableListFactoryConstructor( @@ -3936,14 +3936,14 @@ stack.add(_setListRuntimeTypeInfoIfNeeded(pop(), type, sourceInformation)); } - /// Handle the legacy `<T>[]` constructor. + /// Handle the legacy `List<T>()` constructor. void _handleInvokeLegacyGrowableListFactoryConstructor( ir.StaticInvocation invocation, ConstructorEntity function, AbstractValue typeMask, List<HInstruction> arguments, SourceInformation sourceInformation) { - // `<T>[]` is essentially the same as `<T>[]`. + // `List<T>()` is essentially the same as `<T>[]`. push(_buildLiteralList(<HInstruction>[])); HInstruction allocation = pop(); var inferredType = globalInferenceResults.typeOfNewList(invocation); @@ -3956,7 +3956,7 @@ _setListRuntimeTypeInfoIfNeeded(allocation, type, sourceInformation)); } - /// Handle the `JSArray<T>.list(length)` and legacy `List<T>.filled(length, null)` + /// Handle the `JSArray<T>.list(length)` and legacy `List<T>(length)` /// constructors. void _handleInvokeLegacyFixedListFactoryConstructor( ir.StaticInvocation invocation,
diff --git a/pkg/dev_compiler/doc/GENERIC_METHOD_COMMENTS.md b/pkg/dev_compiler/doc/GENERIC_METHOD_COMMENTS.md index 8f23657..9050eab 100644 --- a/pkg/dev_compiler/doc/GENERIC_METHOD_COMMENTS.md +++ b/pkg/dev_compiler/doc/GENERIC_METHOD_COMMENTS.md
@@ -139,7 +139,7 @@ ```dart List/*<T>*/ makeList/*<T extends num>*/() { - return <num /*=T*/>[]; + return new List<num /*=T*/>(); } void main() { @@ -174,7 +174,7 @@ var l0 = <dynamic /*=S*/>[x]; // as above, but with a regular constructor. - var l1 = <dynamic /*=S*/>[]; + var l1 = new List<dynamic /*=S*/>(); return l1; } ```
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc index a829957..eddf299 100644 --- a/runtime/lib/mirrors.cc +++ b/runtime/lib/mirrors.cc
@@ -435,11 +435,12 @@ const LibraryPrefix& prefix, const bool is_import, const bool is_deferred) { - const Library& importee = Library::Handle(ns.library()); + const Library& importee = Library::Handle(ns.target()); const Array& show_names = Array::Handle(ns.show_names()); const Array& hide_names = Array::Handle(ns.hide_names()); - Object& metadata = Object::Handle(ns.GetMetadata()); + const Library& owner = Library::Handle(ns.owner()); + Object& metadata = Object::Handle(owner.GetMetadata(ns)); if (metadata.IsError()) { Exceptions::PropagateError(Error::Cast(metadata)); UNREACHABLE();
diff --git a/runtime/observatory/tests/service/service_kernel.status b/runtime/observatory/tests/service/service_kernel.status index 7a297eb..b62a6e9 100644 --- a/runtime/observatory/tests/service/service_kernel.status +++ b/runtime/observatory/tests/service/service_kernel.status
@@ -39,159 +39,159 @@ pause_on_unhandled_async_exceptions2_test: Pass, Slow [ $compiler == dartkp ] -add_breakpoint_rpc_kernel_test: SkipByDesign -async_generator_breakpoint_test: SkipByDesign -async_next_regession_18877_test: Skip, Timeout -async_next_test: Skip, Timeout -async_scope_test: Skip, Timeout -async_single_step_exception_test: Skip, Timeout -async_single_step_into_test: Skip, Timeout -async_single_step_out_test: Skip, Timeout -async_star_single_step_into_test: Skip, Timeout -async_star_step_out_test: Skip, Timeout -async_step_out_test: Skip, Timeout -awaiter_async_stack_contents_2_test: Skip, Timeout -awaiter_async_stack_contents_test: Skip, Timeout -bad_reload_test: SkipByDesign -break_on_activation_test: SkipByDesign -break_on_async_function_test: Skip, Timeout -break_on_default_constructor_test: SkipByDesign -break_on_function_test: Skip, Timeout -breakpoint_async_break_test: SkipByDesign -breakpoint_in_package_parts_class_file_uri_test: SkipByDesign -breakpoint_in_package_parts_class_test: SkipByDesign -breakpoint_in_parts_class_test: SkipByDesign -breakpoint_non_debuggable_library_test: SkipByDesign -breakpoint_on_if_null_1_test: SkipByDesign -breakpoint_on_if_null_2_test: SkipByDesign -breakpoint_on_if_null_3_test: SkipByDesign -breakpoint_on_if_null_4_test: SkipByDesign -breakpoint_partfile_test: SkipByDesign -breakpoint_two_args_checked_test: Skip, Timeout +add_breakpoint_rpc_kernel_test: SkipByDesign # Debugger is disabled in AOT mode. +async_generator_breakpoint_test: SkipByDesign # Debugger is disabled in AOT mode. +async_next_regession_18877_test: SkipByDesign # Debugger is disabled in AOT mode. +async_next_test: SkipByDesign # Debugger is disabled in AOT mode. +async_scope_test: SkipByDesign # Debugger is disabled in AOT mode. +async_single_step_exception_test: SkipByDesign # Debugger is disabled in AOT mode. +async_single_step_into_test: SkipByDesign # Debugger is disabled in AOT mode. +async_single_step_out_test: SkipByDesign # Debugger is disabled in AOT mode. +async_star_single_step_into_test: SkipByDesign # Debugger is disabled in AOT mode. +async_star_step_out_test: SkipByDesign # Debugger is disabled in AOT mode. +async_step_out_test: SkipByDesign # Debugger is disabled in AOT mode. +awaiter_async_stack_contents_2_test: SkipByDesign # Debugger is disabled in AOT mode. +awaiter_async_stack_contents_test: SkipByDesign # Debugger is disabled in AOT mode. +bad_reload_test: SkipByDesign # Hot reload is disabled in AOT mode. +break_on_activation_test: SkipByDesign # Debugger is disabled in AOT mode. +break_on_async_function_test: SkipByDesign # Debugger is disabled in AOT mode. +break_on_default_constructor_test: SkipByDesign # Debugger is disabled in AOT mode. +break_on_function_test: SkipByDesign # Debugger is disabled in AOT mode. +breakpoint_async_break_test: SkipByDesign # Debugger is disabled in AOT mode. +breakpoint_in_package_parts_class_file_uri_test: SkipByDesign # Debugger is disabled in AOT mode. +breakpoint_in_package_parts_class_test: SkipByDesign # Debugger is disabled in AOT mode. +breakpoint_in_parts_class_test: SkipByDesign # Debugger is disabled in AOT mode. +breakpoint_non_debuggable_library_test: SkipByDesign # Debugger is disabled in AOT mode. +breakpoint_on_if_null_1_test: SkipByDesign # Debugger is disabled in AOT mode. +breakpoint_on_if_null_2_test: SkipByDesign # Debugger is disabled in AOT mode. +breakpoint_on_if_null_3_test: SkipByDesign # Debugger is disabled in AOT mode. +breakpoint_on_if_null_4_test: SkipByDesign # Debugger is disabled in AOT mode. +breakpoint_partfile_test: SkipByDesign # Debugger is disabled in AOT mode. +breakpoint_two_args_checked_test: SkipByDesign # Debugger is disabled in AOT mode. breakpoints_with_mixin_test: SkipByDesign # Debugger is disabled in AOT mode. -capture_stdio_test: Skip, Timeout -causal_async_stack_contents_test: Skip, Timeout -causal_async_stack_presence_test: Skip, Timeout -causal_async_star_stack_contents_test: Skip, Timeout -causal_async_star_stack_presence_test: Skip, Timeout -client_resume_approvals_reload_test: SkipByDesign # Compiler is disabled in AOT mode. -code_test: SkipByDesign -column_breakpoint_test: SkipByDesign -complex_reload_test: SkipByDesign -coverage_const_field_async_closure_test: Skip, Timeout -coverage_leaf_function_test: Skip, Timeout -coverage_optimized_function_test: Skip, Timeout -dds_log_history_size_*: Skip, Timeout -debugger_inspect_test: SkipByDesign -debugger_location_second_test: Skip, Timeout -debugger_location_test: Skip, Timeout -debugging_inlined_finally_test: Skip, Timeout -debugging_test: SkipByDesign -dev_fs_spawn_test: SkipByDesign -developer_extension_test: Skip, Timeout -developer_service_get_isolate_id_test: Skip, Timeout -eval_internal_class_test: SkipByDesign -eval_regression_flutter20255_test: Skip, Timeout -eval_test: Skip, Timeout -evaluate_activation_in_method_class_test: Skip, Timeout +capture_stdio_test: SkipByDesign # Debugger is disabled in AOT mode. +causal_async_stack_contents_test: SkipByDesign # Debugger is disabled in AOT mode. +causal_async_stack_presence_test: SkipByDesign # Debugger is disabled in AOT mode. +causal_async_star_stack_contents_test: SkipByDesign # Debugger is disabled in AOT mode. +causal_async_star_stack_presence_test: SkipByDesign # Debugger is disabled in AOT mode. +client_resume_approvals_reload_test: SkipByDesign # Debugger is disabled in AOT mode. +code_test: SkipByDesign # Debugger is disabled in AOT mode. +column_breakpoint_test: SkipByDesign # Debugger is disabled in AOT mode. +complex_reload_test: SkipByDesign # Debugger is disabled in AOT mode. +coverage_const_field_async_closure_test: SkipByDesign # Debugger is disabled in AOT mode. +coverage_leaf_function_test: SkipByDesign # Debugger is disabled in AOT mode. +coverage_optimized_function_test: SkipByDesign # Debugger is disabled in AOT mode. +dds_log_history_size_*: SkipByDesign # Debugger is disabled in AOT mode. +debugger_inspect_test: SkipByDesign # Debugger is disabled in AOT mode. +debugger_location_second_test: SkipByDesign # Debugger is disabled in AOT mode. +debugger_location_test: SkipByDesign # Debugger is disabled in AOT mode. +debugging_inlined_finally_test: SkipByDesign # Debugger is disabled in AOT mode. +debugging_test: SkipByDesign # Debugger is disabled in AOT mode. +dev_fs_spawn_test: SkipByDesign # Debugger is disabled in AOT mode. +developer_extension_test: SkipByDesign # Debugger is disabled in AOT mode. +developer_service_get_isolate_id_test: SkipByDesign # Debugger is disabled in AOT mode. +eval_internal_class_test: SkipByDesign # Debugger is disabled in AOT mode. +eval_regression_flutter20255_test: SkipByDesign # Debugger is disabled in AOT mode. +eval_test: SkipByDesign # Debugger is disabled in AOT mode. +evaluate_activation_in_method_class_test: SkipByDesign # Debugger is disabled in AOT mode. evaluate_activation_test: SkipByDesign evaluate_async_closure_test: SkipByDesign -evaluate_class_type_parameters_test: Skip, Timeout -evaluate_function_type_parameters_test: Skip, Timeout -evaluate_in_async_activation_test: Skip, Timeout -evaluate_in_async_star_activation_test: Skip, Timeout -evaluate_in_frame_rpc_test: Skip, Timeout -evaluate_in_frame_with_scope_test: Skip, Timeout -evaluate_in_sync_star_activation_test: Skip, Timeout -evaluate_with_escaping_closure_test: SkipByDesign -evaluate_with_scope_test: SkipByDesign -field_script_test: SkipByDesign -get_allocation_samples_test: Skip, Timeout +evaluate_class_type_parameters_test: SkipByDesign # Debugger is disabled in AOT mode. +evaluate_function_type_parameters_test: SkipByDesign # Debugger is disabled in AOT mode. +evaluate_in_async_activation_test: SkipByDesign # Debugger is disabled in AOT mode. +evaluate_in_async_star_activation_test: SkipByDesign # Debugger is disabled in AOT mode. +evaluate_in_frame_rpc_test: SkipByDesign # Debugger is disabled in AOT mode. +evaluate_in_frame_with_scope_test: SkipByDesign # Debugger is disabled in AOT mode. +evaluate_in_sync_star_activation_test: SkipByDesign # Debugger is disabled in AOT mode. +evaluate_with_escaping_closure_test: SkipByDesign # Debugger is disabled in AOT mode. +evaluate_with_scope_test: SkipByDesign # Debugger is disabled in AOT mode. +field_script_test: SkipByDesign # Debugger is disabled in AOT mode. +get_allocation_samples_test: SkipByDesign # Debugger is disabled in AOT mode. get_isolate_after_language_error_test: CompileTimeError -get_object_rpc_test: SkipByDesign -get_source_report_test: Skip, Timeout -get_source_report_with_mixin_test: Skip, Timeout -get_stack_limit_rpc_test: Skip, Timeout -get_stack_rpc_test: Skip, Timeout -implicit_getter_setter_test: SkipByDesign -invoke_test: Skip, Timeout -isolate_lifecycle_test: SkipByDesign -issue_25465_test: SkipByDesign -issue_27238_test: Skip, Timeout -issue_27287_test: Skip, Timeout -issue_30555_test: SkipByDesign -kill_paused_test: Skip, Timeout +get_object_rpc_test: SkipByDesign # Debugger is disabled in AOT mode. +get_source_report_test: SkipByDesign # Debugger is disabled in AOT mode. +get_source_report_with_mixin_test: SkipByDesign # Debugger is disabled in AOT mode. +get_stack_limit_rpc_test: SkipByDesign # Debugger is disabled in AOT mode. +get_stack_rpc_test: SkipByDesign # Debugger is disabled in AOT mode. +implicit_getter_setter_test: SkipByDesign # Debugger is disabled in AOT mode. +invoke_test: SkipByDesign # Debugger is disabled in AOT mode. +isolate_lifecycle_test: SkipByDesign # Debugger is disabled in AOT mode. +issue_25465_test: SkipByDesign # Debugger is disabled in AOT mode. +issue_27238_test: SkipByDesign # Debugger is disabled in AOT mode. +issue_27287_test: SkipByDesign # Debugger is disabled in AOT mode. +issue_30555_test: SkipByDesign # Debugger is disabled in AOT mode. +kill_paused_test: SkipByDesign # Debugger is disabled in AOT mode. library_dependency_test: CompileTimeError -local_variable_declaration_test: Skip, Timeout -local_variable_in_awaiter_async_frame_test: Skip, Timeout -logging_test: Skip, Timeout +local_variable_declaration_test: SkipByDesign # Debugger is disabled in AOT mode. +local_variable_in_awaiter_async_frame_test: SkipByDesign # Debugger is disabled in AOT mode. +logging_test: SkipByDesign # Debugger is disabled in AOT mode. mirror_references_test: CompileTimeError -mixin_break_test: Skip, Timeout -network_profiling_test: Skip, Timeout -next_through_assign_call_test: SkipByDesign -next_through_assign_int_test: SkipByDesign -next_through_await_for_test: SkipByDesign -next_through_call_on_field_in_class_test: SkipByDesign -next_through_call_on_field_test: SkipByDesign -next_through_call_on_static_field_in_class_test: SkipByDesign -next_through_catch_test: SkipByDesign -next_through_closure_test: SkipByDesign -next_through_create_list_and_map_test: SkipByDesign -next_through_for_each_loop_test: SkipByDesign -next_through_for_loop_with_break_and_continue_test: SkipByDesign -next_through_function_expression_test: SkipByDesign -next_through_implicit_call_test: SkipByDesign -next_through_is_and_as_test: SkipByDesign -next_through_multi_catch_test: SkipByDesign -next_through_new_test: SkipByDesign -next_through_operator_bracket_on_super_test: SkipByDesign -next_through_operator_bracket_on_this_test: SkipByDesign -next_through_operator_bracket_test: SkipByDesign -next_through_simple_async_test: SkipByDesign -next_through_simple_async_with_returns_test: SkipByDesign -next_through_simple_linear_2_test: SkipByDesign -next_through_simple_linear_test: SkipByDesign -parameters_in_scope_at_entry_test: Skip, Timeout -pause_idle_isolate_test: Skip, Timeout -pause_on_exception_from_slow_path_test: SkipByDesign -pause_on_exceptions_test: SkipByDesign -pause_on_start_then_step_test: SkipByDesign -pause_on_unhandled_async_exceptions2_test: SkipByDesign -pause_on_unhandled_async_exceptions3_test: SkipByDesign -pause_on_unhandled_async_exceptions_test: SkipByDesign -pause_on_unhandled_exceptions_test: SkipByDesign -positive_token_pos_test: Skip, Timeout -regress_28443_test: SkipByDesign -regress_28980_test: SkipByDesign -regress_34841_test: Skip, Timeout -reload_sources_test: Skip, Timeout -rewind_optimized_out_test: Skip, Timeout -rewind_test: Skip, Timeout -set_library_debuggable_test: Skip, Timeout -simple_reload_test: SkipByDesign -steal_breakpoint_test: SkipByDesign -step_into_async_no_await_test: Skip, Timeout -step_over_await_test: Skip, Timeout -step_test: SkipByDesign -step_through_arithmetic_test: SkipByDesign -step_through_constructor_calls_test: SkipByDesign -step_through_constructor_test: SkipByDesign -step_through_for_each_sync_star_2_test: SkipByDesign -step_through_for_each_sync_star_test: SkipByDesign -step_through_function_2_test: SkipByDesign -step_through_function_test: SkipByDesign -step_through_getter_test: SkipByDesign -step_through_mixin_from_sdk_test: SkipByDesign -step_through_property_get_test: SkipByDesign -step_through_property_set_test: SkipByDesign -step_through_setter_test: SkipByDesign -step_through_switch_test: SkipByDesign -step_through_switch_with_continue_test: SkipByDesign -valid_source_locations_test: Skip, Timeout -validate_timer_port_behavior_test: SkipByDesign, Timeout # Debugger disabled in AOT -vm_timeline_flags_test: Skip, Timeout +mixin_break_test: SkipByDesign # Debugger is disabled in AOT mode. +network_profiling_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_assign_call_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_assign_int_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_await_for_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_call_on_field_in_class_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_call_on_field_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_call_on_static_field_in_class_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_catch_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_closure_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_create_list_and_map_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_for_each_loop_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_for_loop_with_break_and_continue_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_function_expression_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_implicit_call_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_is_and_as_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_multi_catch_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_new_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_operator_bracket_on_super_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_operator_bracket_on_this_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_operator_bracket_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_simple_async_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_simple_async_with_returns_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_simple_linear_2_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_simple_linear_test: SkipByDesign # Debugger is disabled in AOT mode. +parameters_in_scope_at_entry_test: SkipByDesign # Debugger is disabled in AOT mode. +pause_idle_isolate_test: SkipByDesign # Debugger is disabled in AOT mode. +pause_on_exception_from_slow_path_test: SkipByDesign # Debugger is disabled in AOT mode. +pause_on_exceptions_test: SkipByDesign # Debugger is disabled in AOT mode. +pause_on_start_then_step_test: SkipByDesign # Debugger is disabled in AOT mode. +pause_on_unhandled_async_exceptions2_test: SkipByDesign # Debugger is disabled in AOT mode. +pause_on_unhandled_async_exceptions3_test: SkipByDesign # Debugger is disabled in AOT mode. +pause_on_unhandled_async_exceptions_test: SkipByDesign # Debugger is disabled in AOT mode. +pause_on_unhandled_exceptions_test: SkipByDesign # Debugger is disabled in AOT mode. +positive_token_pos_test: SkipByDesign # Debugger is disabled in AOT mode. +regress_28443_test: SkipByDesign # Debugger is disabled in AOT mode. +regress_28980_test: SkipByDesign # Debugger is disabled in AOT mode. +regress_34841_test: SkipByDesign # Debugger is disabled in AOT mode. +reload_sources_test: SkipByDesign # Debugger is disabled in AOT mode. +rewind_optimized_out_test: SkipByDesign # Debugger is disabled in AOT mode. +rewind_test: SkipByDesign # Debugger is disabled in AOT mode. +set_library_debuggable_test: SkipByDesign # Debugger is disabled in AOT mode. +simple_reload_test: SkipByDesign # Hot reload is disabled in AOT mode. +steal_breakpoint_test: SkipByDesign # Debugger is disabled in AOT mode. +step_into_async_no_await_test: SkipByDesign # Debugger is disabled in AOT mode. +step_over_await_test: SkipByDesign # Debugger is disabled in AOT mode. +step_test: SkipByDesign # Debugger is disabled in AOT mode. +step_through_arithmetic_test: SkipByDesign # Debugger is disabled in AOT mode. +step_through_constructor_calls_test: SkipByDesign # Debugger is disabled in AOT mode. +step_through_constructor_test: SkipByDesign # Debugger is disabled in AOT mode. +step_through_for_each_sync_star_2_test: SkipByDesign # Debugger is disabled in AOT mode. +step_through_for_each_sync_star_test: SkipByDesign # Debugger is disabled in AOT mode. +step_through_function_2_test: SkipByDesign # Debugger is disabled in AOT mode. +step_through_function_test: SkipByDesign # Debugger is disabled in AOT mode. +step_through_getter_test: SkipByDesign # Debugger is disabled in AOT mode. +step_through_mixin_from_sdk_test: SkipByDesign # Debugger is disabled in AOT mode. +step_through_property_get_test: SkipByDesign # Debugger is disabled in AOT mode. +step_through_property_set_test: SkipByDesign # Debugger is disabled in AOT mode. +step_through_setter_test: SkipByDesign # Debugger is disabled in AOT mode. +step_through_switch_test: SkipByDesign # Debugger is disabled in AOT mode. +step_through_switch_with_continue_test: SkipByDesign # Debugger is disabled in AOT mode. +valid_source_locations_test: SkipByDesign # Debugger is disabled in AOT mode. +validate_timer_port_behavior_test: SkipByDesign # Debugger is disabled in AOT mode. +vm_timeline_flags_test: SkipByDesign # Debugger is disabled in AOT mode. weak_properties_test: CompileTimeError -yield_positions_with_finally_test: SkipByDesign +yield_positions_with_finally_test: SkipByDesign # Debugger is disabled in AOT mode. [ $fasta ] get_isolate_after_language_error_test: CompileTimeError
diff --git a/runtime/observatory_2/tests/service_2/service_2_kernel.status b/runtime/observatory_2/tests/service_2/service_2_kernel.status index d8996be..2b6e18b 100644 --- a/runtime/observatory_2/tests/service_2/service_2_kernel.status +++ b/runtime/observatory_2/tests/service_2/service_2_kernel.status
@@ -39,158 +39,158 @@ pause_on_unhandled_async_exceptions2_test: Pass, Slow [ $compiler == dartkp ] -add_breakpoint_rpc_kernel_test: SkipByDesign -async_generator_breakpoint_test: SkipByDesign -async_next_regession_18877_test: Skip, Timeout -async_next_test: Skip, Timeout -async_scope_test: Skip, Timeout -async_single_step_exception_test: Skip, Timeout -async_single_step_into_test: Skip, Timeout -async_single_step_out_test: Skip, Timeout -async_star_single_step_into_test: Skip, Timeout -async_star_step_out_test: Skip, Timeout -async_step_out_test: Skip, Timeout -awaiter_async_stack_contents_2_test: Skip, Timeout -awaiter_async_stack_contents_test: Skip, Timeout -bad_reload_test: SkipByDesign -break_on_activation_test: SkipByDesign -break_on_async_function_test: Skip, Timeout -break_on_default_constructor_test: SkipByDesign -break_on_function_test: Skip, Timeout -breakpoint_async_break_test: SkipByDesign -breakpoint_in_package_parts_class_file_uri_test: SkipByDesign -breakpoint_in_package_parts_class_test: SkipByDesign -breakpoint_in_parts_class_test: SkipByDesign -breakpoint_non_debuggable_library_test: SkipByDesign -breakpoint_on_if_null_1_test: SkipByDesign -breakpoint_on_if_null_2_test: SkipByDesign -breakpoint_on_if_null_3_test: SkipByDesign -breakpoint_on_if_null_4_test: SkipByDesign -breakpoint_partfile_test: SkipByDesign -breakpoint_two_args_checked_test: Skip, Timeout +add_breakpoint_rpc_kernel_test: SkipByDesign # Debugger is disabled in AOT mode. +async_generator_breakpoint_test: SkipByDesign # Debugger is disabled in AOT mode. +async_next_regession_18877_test: SkipByDesign # Debugger is disabled in AOT mode. +async_next_test: SkipByDesign # Debugger is disabled in AOT mode. +async_scope_test: SkipByDesign # Debugger is disabled in AOT mode. +async_single_step_exception_test: SkipByDesign # Debugger is disabled in AOT mode. +async_single_step_into_test: SkipByDesign # Debugger is disabled in AOT mode. +async_single_step_out_test: SkipByDesign # Debugger is disabled in AOT mode. +async_star_single_step_into_test: SkipByDesign # Debugger is disabled in AOT mode. +async_star_step_out_test: SkipByDesign # Debugger is disabled in AOT mode. +async_step_out_test: SkipByDesign # Debugger is disabled in AOT mode. +awaiter_async_stack_contents_2_test: SkipByDesign # Debugger is disabled in AOT mode. +awaiter_async_stack_contents_test: SkipByDesign # Debugger is disabled in AOT mode. +bad_reload_test: SkipByDesign # Hot reload is disabled in AOT mode. +break_on_activation_test: SkipByDesign # Debugger is disabled in AOT mode. +break_on_async_function_test: SkipByDesign # Debugger is disabled in AOT mode. +break_on_default_constructor_test: SkipByDesign # Debugger is disabled in AOT mode. +break_on_function_test: SkipByDesign # Debugger is disabled in AOT mode. +breakpoint_async_break_test: SkipByDesign # Debugger is disabled in AOT mode. +breakpoint_in_package_parts_class_file_uri_test: SkipByDesign # Debugger is disabled in AOT mode. +breakpoint_in_package_parts_class_test: SkipByDesign # Debugger is disabled in AOT mode. +breakpoint_in_parts_class_test: SkipByDesign # Debugger is disabled in AOT mode. +breakpoint_non_debuggable_library_test: SkipByDesign # Debugger is disabled in AOT mode. +breakpoint_on_if_null_1_test: SkipByDesign # Debugger is disabled in AOT mode. +breakpoint_on_if_null_2_test: SkipByDesign # Debugger is disabled in AOT mode. +breakpoint_on_if_null_3_test: SkipByDesign # Debugger is disabled in AOT mode. +breakpoint_on_if_null_4_test: SkipByDesign # Debugger is disabled in AOT mode. +breakpoint_partfile_test: SkipByDesign # Debugger is disabled in AOT mode. +breakpoint_two_args_checked_test: SkipByDesign # Debugger is disabled in AOT mode. breakpoints_with_mixin_test: SkipByDesign # Debugger is disabled in AOT mode. -capture_stdio_test: Skip, Timeout -causal_async_stack_contents_test: Skip, Timeout -causal_async_stack_presence_test: Skip, Timeout -causal_async_star_stack_contents_test: Skip, Timeout -causal_async_star_stack_presence_test: Skip, Timeout -client_resume_approvals_reload_test: SkipByDesign # Compiler is disabled in AOT mode. -code_test: SkipByDesign -column_breakpoint_test: SkipByDesign -complex_reload_test: SkipByDesign -coverage_const_field_async_closure_test: Skip, Timeout -coverage_leaf_function_test: Skip, Timeout -coverage_optimized_function_test: Skip, Timeout -dds_log_history_size_*: Skip, Timeout -debugger_inspect_test: SkipByDesign -debugger_location_second_test: Skip, Timeout -debugger_location_test: Skip, Timeout -debugging_inlined_finally_test: Skip, Timeout -debugging_test: SkipByDesign -dev_fs_spawn_test: SkipByDesign -developer_extension_test: Skip, Timeout -developer_service_get_isolate_id_test: Skip, Timeout -eval_internal_class_test: SkipByDesign -eval_regression_flutter20255_test: Skip, Timeout -eval_test: Skip, Timeout -evaluate_activation_in_method_class_test: Skip, Timeout +capture_stdio_test: SkipByDesign # Debugger is disabled in AOT mode. +causal_async_stack_contents_test: SkipByDesign # Debugger is disabled in AOT mode. +causal_async_stack_presence_test: SkipByDesign # Debugger is disabled in AOT mode. +causal_async_star_stack_contents_test: SkipByDesign # Debugger is disabled in AOT mode. +causal_async_star_stack_presence_test: SkipByDesign # Debugger is disabled in AOT mode. +client_resume_approvals_reload_test: SkipByDesign # Debugger is disabled in AOT mode. +code_test: SkipByDesign # Debugger is disabled in AOT mode. +column_breakpoint_test: SkipByDesign # Debugger is disabled in AOT mode. +complex_reload_test: SkipByDesign # Debugger is disabled in AOT mode. +coverage_const_field_async_closure_test: SkipByDesign # Debugger is disabled in AOT mode. +coverage_leaf_function_test: SkipByDesign # Debugger is disabled in AOT mode. +coverage_optimized_function_test: SkipByDesign # Debugger is disabled in AOT mode. +dds_log_history_size_*: SkipByDesign # Debugger is disabled in AOT mode. +debugger_inspect_test: SkipByDesign # Debugger is disabled in AOT mode. +debugger_location_second_test: SkipByDesign # Debugger is disabled in AOT mode. +debugger_location_test: SkipByDesign # Debugger is disabled in AOT mode. +debugging_inlined_finally_test: SkipByDesign # Debugger is disabled in AOT mode. +debugging_test: SkipByDesign # Debugger is disabled in AOT mode. +dev_fs_spawn_test: SkipByDesign # Debugger is disabled in AOT mode. +developer_extension_test: SkipByDesign # Debugger is disabled in AOT mode. +developer_service_get_isolate_id_test: SkipByDesign # Debugger is disabled in AOT mode. +eval_internal_class_test: SkipByDesign # Debugger is disabled in AOT mode. +eval_regression_flutter20255_test: SkipByDesign # Debugger is disabled in AOT mode. +eval_test: SkipByDesign # Debugger is disabled in AOT mode. +evaluate_activation_in_method_class_test: SkipByDesign # Debugger is disabled in AOT mode. evaluate_activation_test: SkipByDesign evaluate_async_closure_test: SkipByDesign -evaluate_class_type_parameters_test: Skip, Timeout -evaluate_function_type_parameters_test: Skip, Timeout -evaluate_in_async_activation_test: Skip, Timeout -evaluate_in_async_star_activation_test: Skip, Timeout -evaluate_in_frame_rpc_test: Skip, Timeout -evaluate_in_frame_with_scope_test: Skip, Timeout -evaluate_in_sync_star_activation_test: Skip, Timeout -evaluate_with_escaping_closure_test: SkipByDesign -evaluate_with_scope_test: SkipByDesign -field_script_test: SkipByDesign -get_allocation_samples_test: Skip, Timeout +evaluate_class_type_parameters_test: SkipByDesign # Debugger is disabled in AOT mode. +evaluate_function_type_parameters_test: SkipByDesign # Debugger is disabled in AOT mode. +evaluate_in_async_activation_test: SkipByDesign # Debugger is disabled in AOT mode. +evaluate_in_async_star_activation_test: SkipByDesign # Debugger is disabled in AOT mode. +evaluate_in_frame_rpc_test: SkipByDesign # Debugger is disabled in AOT mode. +evaluate_in_frame_with_scope_test: SkipByDesign # Debugger is disabled in AOT mode. +evaluate_in_sync_star_activation_test: SkipByDesign # Debugger is disabled in AOT mode. +evaluate_with_escaping_closure_test: SkipByDesign # Debugger is disabled in AOT mode. +evaluate_with_scope_test: SkipByDesign # Debugger is disabled in AOT mode. +field_script_test: SkipByDesign # Debugger is disabled in AOT mode. +get_allocation_samples_test: SkipByDesign # Debugger is disabled in AOT mode. get_isolate_after_language_error_test: CompileTimeError -get_object_rpc_test: SkipByDesign -get_source_report_test: Skip, Timeout -get_source_report_with_mixin_test: Skip, Timeout -get_stack_limit_rpc_test: Skip, Timeout -get_stack_rpc_test: Skip, Timeout -implicit_getter_setter_test: SkipByDesign -invoke_test: Skip, Timeout -isolate_lifecycle_test: SkipByDesign -issue_25465_test: SkipByDesign -issue_27238_test: Skip, Timeout -issue_27287_test: Skip, Timeout -issue_30555_test: SkipByDesign -kill_paused_test: Skip, Timeout +get_object_rpc_test: SkipByDesign # Debugger is disabled in AOT mode. +get_source_report_test: SkipByDesign # Debugger is disabled in AOT mode. +get_source_report_with_mixin_test: SkipByDesign # Debugger is disabled in AOT mode. +get_stack_limit_rpc_test: SkipByDesign # Debugger is disabled in AOT mode. +get_stack_rpc_test: SkipByDesign # Debugger is disabled in AOT mode. +implicit_getter_setter_test: SkipByDesign # Debugger is disabled in AOT mode. +invoke_test: SkipByDesign # Debugger is disabled in AOT mode. +isolate_lifecycle_test: SkipByDesign # Debugger is disabled in AOT mode. +issue_25465_test: SkipByDesign # Debugger is disabled in AOT mode. +issue_27238_test: SkipByDesign # Debugger is disabled in AOT mode. +issue_27287_test: SkipByDesign # Debugger is disabled in AOT mode. +issue_30555_test: SkipByDesign # Debugger is disabled in AOT mode. +kill_paused_test: SkipByDesign # Debugger is disabled in AOT mode. library_dependency_test: CompileTimeError -local_variable_declaration_test: Skip, Timeout -local_variable_in_awaiter_async_frame_test: Skip, Timeout -logging_test: Skip, Timeout +local_variable_declaration_test: SkipByDesign # Debugger is disabled in AOT mode. +local_variable_in_awaiter_async_frame_test: SkipByDesign # Debugger is disabled in AOT mode. +logging_test: SkipByDesign # Debugger is disabled in AOT mode. mirror_references_test: CompileTimeError -mixin_break_test: Skip, Timeout -network_profiling_test: Skip, Timeout -next_through_assign_call_test: SkipByDesign -next_through_assign_int_test: SkipByDesign -next_through_await_for_test: SkipByDesign -next_through_call_on_field_in_class_test: SkipByDesign -next_through_call_on_field_test: SkipByDesign -next_through_call_on_static_field_in_class_test: SkipByDesign -next_through_catch_test: SkipByDesign -next_through_closure_test: SkipByDesign -next_through_create_list_and_map_test: SkipByDesign -next_through_for_each_loop_test: SkipByDesign -next_through_for_loop_with_break_and_continue_test: SkipByDesign -next_through_function_expression_test: SkipByDesign -next_through_implicit_call_test: SkipByDesign -next_through_is_and_as_test: SkipByDesign -next_through_multi_catch_test: SkipByDesign -next_through_new_test: SkipByDesign -next_through_operator_bracket_on_super_test: SkipByDesign -next_through_operator_bracket_on_this_test: SkipByDesign -next_through_operator_bracket_test: SkipByDesign -next_through_simple_async_test: SkipByDesign -next_through_simple_async_with_returns_test: SkipByDesign -next_through_simple_linear_2_test: SkipByDesign -next_through_simple_linear_test: SkipByDesign -parameters_in_scope_at_entry_test: Skip, Timeout -pause_idle_isolate_test: Skip, Timeout -pause_on_exceptions_test: SkipByDesign -pause_on_start_then_step_test: SkipByDesign -pause_on_unhandled_async_exceptions2_test: SkipByDesign -pause_on_unhandled_async_exceptions3_test: SkipByDesign -pause_on_unhandled_async_exceptions_test: SkipByDesign -pause_on_unhandled_exceptions_test: SkipByDesign -positive_token_pos_test: Skip, Timeout -regress_28443_test: SkipByDesign -regress_28980_test: SkipByDesign -regress_34841_test: Skip, Timeout -reload_sources_test: Skip, Timeout -rewind_optimized_out_test: Skip, Timeout -rewind_test: Skip, Timeout -set_library_debuggable_test: Skip, Timeout -simple_reload_test: SkipByDesign -steal_breakpoint_test: SkipByDesign -step_into_async_no_await_test: Skip, Timeout -step_over_await_test: Skip, Timeout -step_test: SkipByDesign -step_through_arithmetic_test: SkipByDesign -step_through_constructor_calls_test: SkipByDesign -step_through_constructor_test: SkipByDesign -step_through_for_each_sync_star_2_test: SkipByDesign -step_through_for_each_sync_star_test: SkipByDesign -step_through_function_2_test: SkipByDesign -step_through_function_test: SkipByDesign -step_through_getter_test: SkipByDesign -step_through_mixin_from_sdk_test: SkipByDesign -step_through_property_get_test: SkipByDesign -step_through_property_set_test: SkipByDesign -step_through_setter_test: SkipByDesign -step_through_switch_test: SkipByDesign -step_through_switch_with_continue_test: SkipByDesign -valid_source_locations_test: Skip, Timeout -validate_timer_port_behavior_test: SkipByDesign, Timeout # Debugger disabled in AOT -vm_timeline_flags_test: Skip, Timeout +mixin_break_test: SkipByDesign # Debugger is disabled in AOT mode. +network_profiling_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_assign_call_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_assign_int_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_await_for_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_call_on_field_in_class_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_call_on_field_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_call_on_static_field_in_class_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_catch_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_closure_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_create_list_and_map_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_for_each_loop_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_for_loop_with_break_and_continue_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_function_expression_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_implicit_call_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_is_and_as_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_multi_catch_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_new_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_operator_bracket_on_super_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_operator_bracket_on_this_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_operator_bracket_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_simple_async_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_simple_async_with_returns_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_simple_linear_2_test: SkipByDesign # Debugger is disabled in AOT mode. +next_through_simple_linear_test: SkipByDesign # Debugger is disabled in AOT mode. +parameters_in_scope_at_entry_test: SkipByDesign # Debugger is disabled in AOT mode. +pause_idle_isolate_test: SkipByDesign # Debugger is disabled in AOT mode. +pause_on_exceptions_test: SkipByDesign # Debugger is disabled in AOT mode. +pause_on_start_then_step_test: SkipByDesign # Debugger is disabled in AOT mode. +pause_on_unhandled_async_exceptions2_test: SkipByDesign # Debugger is disabled in AOT mode. +pause_on_unhandled_async_exceptions3_test: SkipByDesign # Debugger is disabled in AOT mode. +pause_on_unhandled_async_exceptions_test: SkipByDesign # Debugger is disabled in AOT mode. +pause_on_unhandled_exceptions_test: SkipByDesign # Debugger is disabled in AOT mode. +positive_token_pos_test: SkipByDesign # Debugger is disabled in AOT mode. +regress_28443_test: SkipByDesign # Debugger is disabled in AOT mode. +regress_28980_test: SkipByDesign # Debugger is disabled in AOT mode. +regress_34841_test: SkipByDesign # Debugger is disabled in AOT mode. +reload_sources_test: SkipByDesign # Debugger is disabled in AOT mode. +rewind_optimized_out_test: SkipByDesign # Debugger is disabled in AOT mode. +rewind_test: SkipByDesign # Debugger is disabled in AOT mode. +set_library_debuggable_test: SkipByDesign # Debugger is disabled in AOT mode. +simple_reload_test: SkipByDesign # Hot reload is disabled in AOT mode. +steal_breakpoint_test: SkipByDesign # Debugger is disabled in AOT mode. +step_into_async_no_await_test: SkipByDesign # Debugger is disabled in AOT mode. +step_over_await_test: SkipByDesign # Debugger is disabled in AOT mode. +step_test: SkipByDesign # Debugger is disabled in AOT mode. +step_through_arithmetic_test: SkipByDesign # Debugger is disabled in AOT mode. +step_through_constructor_calls_test: SkipByDesign # Debugger is disabled in AOT mode. +step_through_constructor_test: SkipByDesign # Debugger is disabled in AOT mode. +step_through_for_each_sync_star_2_test: SkipByDesign # Debugger is disabled in AOT mode. +step_through_for_each_sync_star_test: SkipByDesign # Debugger is disabled in AOT mode. +step_through_function_2_test: SkipByDesign # Debugger is disabled in AOT mode. +step_through_function_test: SkipByDesign # Debugger is disabled in AOT mode. +step_through_getter_test: SkipByDesign # Debugger is disabled in AOT mode. +step_through_mixin_from_sdk_test: SkipByDesign # Debugger is disabled in AOT mode. +step_through_property_get_test: SkipByDesign # Debugger is disabled in AOT mode. +step_through_property_set_test: SkipByDesign # Debugger is disabled in AOT mode. +step_through_setter_test: SkipByDesign # Debugger is disabled in AOT mode. +step_through_switch_test: SkipByDesign # Debugger is disabled in AOT mode. +step_through_switch_with_continue_test: SkipByDesign # Debugger is disabled in AOT mode. +valid_source_locations_test: SkipByDesign # Debugger is disabled in AOT mode. +validate_timer_port_behavior_test: SkipByDesign # Debugger is disabled in AOT mode. +vm_timeline_flags_test: SkipByDesign # Debugger is disabled in AOT mode. weak_properties_test: CompileTimeError -yield_positions_with_finally_test: SkipByDesign +yield_positions_with_finally_test: SkipByDesign # Debugger is disabled in AOT mode. [ $fasta ] get_isolate_after_language_error_test: CompileTimeError
diff --git a/runtime/vm/canonical_tables.cc b/runtime/vm/canonical_tables.cc new file mode 100644 index 0000000..d5ab2ff --- /dev/null +++ b/runtime/vm/canonical_tables.cc
@@ -0,0 +1,74 @@ +// Copyright (c) 2020, 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. + +#include "vm/canonical_tables.h" + +namespace dart { + +bool MetadataMapTraits::IsMatch(const Object& a, const Object& b) { + // In the absence of hot reload, this can just be an identity check. With + // reload, some old program elements may be retained by the stack, closures + // or mirrors, which are absent from the new version of the library's + // metadata table. This name-based matching fuzzy maps the old program + // elements to corresponding new elements, preserving the behavior of the old + // metaname+fields scheme. + if (a.IsLibrary() && b.IsLibrary()) { + const String& url_a = String::Handle(Library::Cast(a).url()); + const String& url_b = String::Handle(Library::Cast(b).url()); + return url_a.Equals(url_b); + } else if (a.IsClass() && b.IsClass()) { + const String& name_a = String::Handle(Class::Cast(a).Name()); + const String& name_b = String::Handle(Class::Cast(b).Name()); + return name_a.Equals(name_b); + } else if (a.IsFunction() && b.IsFunction()) { + const String& name_a = String::Handle(Function::Cast(a).name()); + const String& name_b = String::Handle(Function::Cast(b).name()); + if (!name_a.Equals(name_b)) { + return false; + } + const Object& owner_a = Object::Handle(Function::Cast(a).Owner()); + const Object& owner_b = Object::Handle(Function::Cast(b).Owner()); + return IsMatch(owner_a, owner_b); + } else if (a.IsField() && b.IsField()) { + const String& name_a = String::Handle(Field::Cast(a).name()); + const String& name_b = String::Handle(Field::Cast(b).name()); + if (!name_a.Equals(name_b)) { + return false; + } + const Object& owner_a = Object::Handle(Field::Cast(a).Owner()); + const Object& owner_b = Object::Handle(Field::Cast(b).Owner()); + return IsMatch(owner_a, owner_b); + } else if (a.IsTypeParameter() && b.IsTypeParameter()) { + const String& name_a = String::Handle(TypeParameter::Cast(a).name()); + const String& name_b = String::Handle(TypeParameter::Cast(b).name()); + if (!name_a.Equals(name_b)) { + return false; + } + const Object& owner_a = Object::Handle(TypeParameter::Cast(a).Owner()); + const Object& owner_b = Object::Handle(TypeParameter::Cast(b).Owner()); + return IsMatch(owner_a, owner_b); + } + return a.raw() == b.raw(); +} + +uword MetadataMapTraits::Hash(const Object& key) { + if (key.IsLibrary()) { + return String::Hash(Library::Cast(key).url()); + } else if (key.IsClass()) { + return String::Hash(Class::Cast(key).Name()); + } else if (key.IsFunction()) { + return CombineHashes(String::Hash(Function::Cast(key).name()), + Hash(Object::Handle(Function::Cast(key).Owner()))); + } else if (key.IsField()) { + return CombineHashes(String::Hash(Field::Cast(key).name()), + Hash(Object::Handle(Field::Cast(key).Owner()))); + } else if (key.IsTypeParameter()) { + return TypeParameter::Cast(key).Hash(); + } else if (key.IsNamespace()) { + return Hash(Library::Handle(Namespace::Cast(key).target())); + } + UNREACHABLE(); +} + +} // namespace dart
diff --git a/runtime/vm/canonical_tables.h b/runtime/vm/canonical_tables.h index 69b79eb..f0c3d2b 100644 --- a/runtime/vm/canonical_tables.h +++ b/runtime/vm/canonical_tables.h
@@ -254,6 +254,15 @@ typedef UnorderedHashSet<CanonicalTypeArgumentsTraits> CanonicalTypeArgumentsSet; +class MetadataMapTraits { + public: + static const char* Name() { return "MetadataMapTraits"; } + static bool ReportStats() { return false; } + static bool IsMatch(const Object& a, const Object& b); + static uword Hash(const Object& key); +}; +typedef UnorderedHashMap<MetadataMapTraits> MetadataMap; + } // namespace dart #endif // RUNTIME_VM_CANONICAL_TABLES_H_
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc index afa2668..175f985 100644 --- a/runtime/vm/class_finalizer.cc +++ b/runtime/vm/class_finalizer.cc
@@ -1503,7 +1503,7 @@ if (old_cid != new_cid) { // Don't touch objects that are unchanged. In particular, Instructions, // which are write-protected. - obj->ptr()->SetClassId(new_cid); + obj->ptr()->SetClassIdUnsynchronized(new_cid); } } }
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc index 023f790..895f537 100644 --- a/runtime/vm/clustered_snapshot.cc +++ b/runtime/vm/clustered_snapshot.cc
@@ -5837,7 +5837,12 @@ WriteUnsigned(num_objects); WriteUnsigned(canonical_clusters.length()); WriteUnsigned(clusters.length()); - WriteUnsigned(initial_field_table_->NumFieldIds()); + // TODO(dartbug.com/36097): Not every snapshot carries the field table. + if (current_loading_unit_id_ <= LoadingUnit::kRootId) { + WriteUnsigned(initial_field_table_->NumFieldIds()); + } else { + WriteUnsigned(0); + } for (SerializationCluster* cluster : canonical_clusters) { cluster->WriteAndMeasureAlloc(this); @@ -6573,8 +6578,8 @@ refs_ = Array::New(num_objects_ + kFirstReference, Heap::kOld); if (initial_field_table_len > 0) { initial_field_table_->AllocateIndex(initial_field_table_len - 1); + ASSERT_EQUAL(initial_field_table_->NumFieldIds(), initial_field_table_len); } - ASSERT_EQUAL(initial_field_table_->NumFieldIds(), initial_field_table_len); { NoSafepointScope no_safepoint;
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc index 61cd91d..7a8f7b8 100644 --- a/runtime/vm/compiler/aot/precompiler.cc +++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -2117,47 +2117,9 @@ void Precompiler::DropMetadata() { Library& lib = Library::Handle(Z); - const GrowableObjectArray& null_growable_list = - GrowableObjectArray::Handle(Z); - Array& dependencies = Array::Handle(Z); - Namespace& ns = Namespace::Handle(Z); - const Field& null_field = Field::Handle(Z); - GrowableObjectArray& metadata = GrowableObjectArray::Handle(Z); - Field& metadata_field = Field::Handle(Z); - for (intptr_t i = 0; i < libraries_.Length(); i++) { lib ^= libraries_.At(i); - metadata ^= lib.metadata(); - for (intptr_t j = 0; j < metadata.Length(); j++) { - metadata_field ^= metadata.At(j); - if (metadata_field.is_static()) { - // Although this field will become garbage after clearing the list - // below, we also need to clear its value from the field table. - // The value may be an instance of an otherwise dead class, and if - // it remains in the field table we can get an instance on the heap - // with a deleted class. - metadata_field.SetStaticValue(Object::null_instance(), - /*save_initial_value=*/true); - } - } - - lib.set_metadata(null_growable_list); - - dependencies = lib.imports(); - for (intptr_t j = 0; j < dependencies.Length(); j++) { - ns ^= dependencies.At(j); - if (!ns.IsNull()) { - ns.set_metadata_field(null_field); - } - } - - dependencies = lib.exports(); - for (intptr_t j = 0; j < dependencies.Length(); j++) { - ns ^= dependencies.At(j); - if (!ns.IsNull()) { - ns.set_metadata_field(null_field); - } - } + lib.set_metadata(Array::null_array()); } }
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc index 49c32bc..2071a31 100644 --- a/runtime/vm/dart_api_impl.cc +++ b/runtime/vm/dart_api_impl.cc
@@ -6013,7 +6013,7 @@ for (intptr_t j = 0; j < imports.Length(); j++) { ns ^= imports.At(j); if (ns.IsNull()) continue; - importee = ns.library(); + importee = ns.target(); importee_uri = importee.url(); if (importee_uri.StartsWith(scheme_vm)) { result.Add(importer);
diff --git a/runtime/vm/heap/sweeper.cc b/runtime/vm/heap/sweeper.cc index f579074..9013eba 100644 --- a/runtime/vm/heap/sweeper.cc +++ b/runtime/vm/heap/sweeper.cc
@@ -27,24 +27,28 @@ uword current = start; while (current < end) { - intptr_t obj_size; ObjectPtr raw_obj = ObjectLayout::FromAddr(current); ASSERT(OldPage::Of(raw_obj) == page); - if (raw_obj->ptr()->IsMarked()) { + // These acquire operations balance release operations in array + // truncaton, ensuring the writes creating the filler object are ordered + // before the writes inserting the filler object into the freelist. + uword tags = raw_obj->ptr()->tags_.load(std::memory_order_acquire); + intptr_t obj_size = raw_obj->ptr()->HeapSize(tags); + if (ObjectLayout::IsMarked(tags)) { // Found marked object. Clear the mark bit and update swept bytes. raw_obj->ptr()->ClearMarkBit(); - obj_size = raw_obj->ptr()->HeapSize(); used_in_bytes += obj_size; } else { - uword free_end = current + raw_obj->ptr()->HeapSize(); + uword free_end = current + obj_size; while (free_end < end) { ObjectPtr next_obj = ObjectLayout::FromAddr(free_end); - if (next_obj->ptr()->IsMarked()) { + tags = next_obj->ptr()->tags_.load(std::memory_order_acquire); + if (ObjectLayout::IsMarked(tags)) { // Reached the end of the free block. break; } // Expand the free block by the size of this object. - free_end += next_obj->ptr()->HeapSize(); + free_end += next_obj->ptr()->HeapSize(tags); } obj_size = free_end - current; if (is_executable) {
diff --git a/runtime/vm/isolate_reload.cc b/runtime/vm/isolate_reload.cc index a9e660f..8e586b3 100644 --- a/runtime/vm/isolate_reload.cc +++ b/runtime/vm/isolate_reload.cc
@@ -961,7 +961,7 @@ for (intptr_t import_idx = 0; import_idx < ports.Length(); import_idx++) { ns ^= ports.At(import_idx); if (!ns.IsNull()) { - target = ns.library(); + target = ns.target(); target_url = target.url(); if (!target_url.StartsWith(Symbols::DartExtensionScheme())) { (*imported_by)[target.index()]->Add(lib.index()); @@ -974,7 +974,7 @@ for (intptr_t export_idx = 0; export_idx < ports.Length(); export_idx++) { ns ^= ports.At(export_idx); if (!ns.IsNull()) { - target = ns.library(); + target = ns.target(); (*imported_by)[target.index()]->Add(lib.index()); } } @@ -992,7 +992,7 @@ import_idx++) { ns ^= ports.At(import_idx); if (!ns.IsNull()) { - target = ns.library(); + target = ns.target(); (*imported_by)[target.index()]->Add(lib.index()); } }
diff --git a/runtime/vm/kernel.cc b/runtime/vm/kernel.cc index 7c53e72..952e41a 100644 --- a/runtime/vm/kernel.cc +++ b/runtime/vm/kernel.cc
@@ -430,26 +430,28 @@ DISALLOW_COPY_AND_ASSIGN(MetadataEvaluator); }; -ObjectPtr EvaluateMetadata(const Field& metadata_field, +ObjectPtr EvaluateMetadata(const Library& library, + intptr_t kernel_offset, bool is_annotations_offset) { LongJumpScope jump; if (setjmp(*jump.Set()) == 0) { Thread* thread = Thread::Current(); Zone* zone = thread->zone(); TranslationHelper helper(thread); - Script& script = Script::Handle(zone, metadata_field.Script()); + Script& script = Script::Handle( + zone, Class::Handle(zone, library.toplevel_class()).script()); helper.InitFromScript(script); - const Class& owner_class = Class::Handle(zone, metadata_field.Owner()); + const Class& owner_class = Class::Handle(zone, library.toplevel_class()); ActiveClass active_class; ActiveClassScope active_class_scope(&active_class, &owner_class); MetadataEvaluator metadata_evaluator( zone, &helper, script, - ExternalTypedData::Handle(zone, metadata_field.KernelData()), - metadata_field.KernelDataProgramOffset(), &active_class); + ExternalTypedData::Handle(zone, library.kernel_data()), + library.kernel_offset(), &active_class); - return metadata_evaluator.EvaluateMetadata(metadata_field.kernel_offset(), + return metadata_evaluator.EvaluateMetadata(kernel_offset, is_annotations_offset); } else {
diff --git a/runtime/vm/kernel.h b/runtime/vm/kernel.h index 9b0d8de..ed66e25 100644 --- a/runtime/vm/kernel.h +++ b/runtime/vm/kernel.h
@@ -196,7 +196,8 @@ void CollectTokenPositionsFor(const Script& script); ObjectPtr EvaluateStaticConstFieldInitializer(const Field& field); -ObjectPtr EvaluateMetadata(const Field& metadata_field, +ObjectPtr EvaluateMetadata(const Library& library, + intptr_t kernel_offset, bool is_annotations_offset); ObjectPtr BuildParameterDescriptor(const Function& function);
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc index e37f325..4dbcfb6 100644 --- a/runtime/vm/kernel_loader.cc +++ b/runtime/vm/kernel_loader.cc
@@ -694,7 +694,7 @@ // Dart_GetImportsOfScheme('dart-ext'). const auto& native_library = Library::Handle(Library::New(uri_path)); library.AddImport(Namespace::Handle(Namespace::New( - native_library, Array::null_array(), Array::null_array()))); + native_library, Array::null_array(), Array::null_array(), library))); } } } @@ -1122,8 +1122,7 @@ if (FLAG_enable_mirrors && annotation_count > 0) { ASSERT(annotations_kernel_offset > 0); - library.AddLibraryMetadata(toplevel_class, TokenPosition::kNoSource, - annotations_kernel_offset); + library.AddMetadata(library, annotations_kernel_offset); } if (register_class) { @@ -1248,7 +1247,7 @@ if ((FLAG_enable_mirrors || has_pragma_annotation) && annotation_count > 0) { - library.AddFieldMetadata(field, TokenPosition::kNoSource, field_offset); + library.AddMetadata(field, field_offset); } fields_.Add(&field); } @@ -1366,7 +1365,7 @@ "import of dart:ffi is not supported in the current Dart runtime"); } String& prefix = H.DartSymbolPlain(dependency_helper.name_index_); - ns = Namespace::New(target_library, show_names, hide_names); + ns = Namespace::New(target_library, show_names, hide_names, *library); if ((dependency_helper.flags_ & LibraryDependencyHelper::Export) != 0) { library->AddExport(ns); } else { @@ -1389,8 +1388,7 @@ if (FLAG_enable_mirrors && dependency_helper.annotation_count_ > 0) { ASSERT(annotations_kernel_offset > 0); - ns.AddMetadata(toplevel_class, TokenPosition::kNoSource, - annotations_kernel_offset); + library->AddMetadata(ns, annotations_kernel_offset); } if (prefix.IsNull()) { @@ -1511,9 +1509,7 @@ } if ((FLAG_enable_mirrors || has_pragma_annotation) && annotation_count > 0) { - library.AddClassMetadata(*out_class, toplevel_class, - TokenPosition::kNoSource, - class_offset - correction_offset_); + library.AddMetadata(*out_class, class_offset - correction_offset_); } // We do not register expression evaluation classes with the VM: @@ -1625,7 +1621,7 @@ } if ((FLAG_enable_mirrors || has_pragma_annotation) && annotation_count > 0) { - library.AddFieldMetadata(field, TokenPosition::kNoSource, field_offset); + library.AddMetadata(field, field_offset); } fields_.Add(&field); } @@ -1724,8 +1720,7 @@ if ((FLAG_enable_mirrors || has_pragma_annotation) && annotation_count > 0) { - library.AddFunctionMetadata(function, TokenPosition::kNoSource, - constructor_offset); + library.AddMetadata(function, constructor_offset); } } @@ -2049,8 +2044,7 @@ helper_.SetOffset(procedure_end); if (annotation_count > 0) { - library.AddFunctionMetadata(function, TokenPosition::kNoSource, - procedure_offset); + library.AddMetadata(function, procedure_offset); } if (has_pragma_annotation) {
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc index 9352916..927cfef 100644 --- a/runtime/vm/object.cc +++ b/runtime/vm/object.cc
@@ -1467,14 +1467,7 @@ // new array length, and so treat it as a pointer. Ensure it is a Smi so // the marker won't dereference it. ASSERT((new_tags & kSmiTagMask) == kSmiTag); - uword tags = raw->ptr()->tags_; - uword old_tags; - // TODO(iposva): Investigate whether CompareAndSwapWord is necessary. - do { - old_tags = tags; - // We can't use obj.CompareAndSwapTags here because we don't have a - // handle for the new object. - } while (!raw->ptr()->tags_.WeakCAS(old_tags, new_tags)); + raw->ptr()->tags_ = new_tags; intptr_t leftover_len = (leftover_size - TypedData::InstanceSize(0)); ASSERT(TypedData::InstanceSize(leftover_len) == leftover_size); @@ -1496,14 +1489,7 @@ // new array length, and so treat it as a pointer. Ensure it is a Smi so // the marker won't dereference it. ASSERT((new_tags & kSmiTagMask) == kSmiTag); - uword tags = raw->ptr()->tags_; - uword old_tags; - // TODO(iposva): Investigate whether CompareAndSwapWord is necessary. - do { - old_tags = tags; - // We can't use obj.CompareAndSwapTags here because we don't have a - // handle for the new object. - } while (!raw->ptr()->tags_.WeakCAS(old_tags, new_tags)); + raw->ptr()->tags_ = new_tags; } } } @@ -11609,175 +11595,25 @@ StoreNonPointer(&raw_ptr()->load_state_, LibraryLayout::kLoaded); } -static StringPtr MakeClassMetaName(Thread* thread, - Zone* zone, - const Class& cls) { - return Symbols::FromConcat(thread, Symbols::At(), - String::Handle(zone, cls.Name())); -} - -static StringPtr MakeFieldMetaName(Thread* thread, - Zone* zone, - const Field& field) { - const String& cname = String::Handle( - zone, - MakeClassMetaName(thread, zone, Class::Handle(zone, field.Origin()))); - GrowableHandlePtrArray<const String> pieces(zone, 3); - pieces.Add(cname); - pieces.Add(Symbols::At()); - pieces.Add(String::Handle(zone, field.name())); - return Symbols::FromConcatAll(thread, pieces); -} - -static StringPtr MakeFunctionMetaName(Thread* thread, - Zone* zone, - const Function& func) { - const String& cname = String::Handle( - zone, - MakeClassMetaName(thread, zone, Class::Handle(zone, func.origin()))); - GrowableHandlePtrArray<const String> pieces(zone, 3); - pieces.Add(cname); - pieces.Add(Symbols::At()); - pieces.Add(String::Handle(zone, func.name())); - return Symbols::FromConcatAll(thread, pieces); -} - -static StringPtr MakeTypeParameterMetaName(Thread* thread, - Zone* zone, - const TypeParameter& param) { - const String& cname = String::Handle( - zone, - MakeClassMetaName(thread, zone, - Class::Handle(zone, param.parameterized_class()))); - GrowableHandlePtrArray<const String> pieces(zone, 3); - pieces.Add(cname); - pieces.Add(Symbols::At()); - pieces.Add(String::Handle(zone, param.name())); - return Symbols::FromConcatAll(thread, pieces); -} - -void Library::AddMetadata(const Object& owner, - const String& name, - TokenPosition token_pos, +void Library::AddMetadata(const Object& declaration, intptr_t kernel_offset) const { #if defined(DART_PRECOMPILED_RUNTIME) UNREACHABLE(); #else - Thread* thread = Thread::Current(); - ASSERT(thread->IsMutatorThread()); - Zone* zone = thread->zone(); - const String& metaname = String::Handle(zone, Symbols::New(thread, name)); - const Field& field = - Field::Handle(zone, Field::NewTopLevel(metaname, - false, // is_final - false, // is_const - false, // is_late - owner, token_pos, token_pos)); - field.SetFieldType(Object::dynamic_type()); - field.set_is_reflectable(false); - field.set_kernel_offset(kernel_offset); - thread->isolate_group()->RegisterStaticField(field, Array::empty_array()); - - GrowableObjectArray& metadata = - GrowableObjectArray::Handle(zone, this->metadata()); - metadata.Add(field, Heap::kOld); + MetadataMap map(metadata()); + map.UpdateOrInsert(declaration, Smi::Handle(Smi::New(kernel_offset))); + set_metadata(map.Release()); #endif // defined(DART_PRECOMPILED_RUNTIME) } -void Library::AddClassMetadata(const Class& cls, - const Object& tl_owner, - TokenPosition token_pos, - intptr_t kernel_offset) const { - Thread* thread = Thread::Current(); - Zone* zone = thread->zone(); - // We use the toplevel class as the owner of a class's metadata field because - // a class's metadata is in scope of the library, not the class. - AddMetadata(tl_owner, - String::Handle(zone, MakeClassMetaName(thread, zone, cls)), - token_pos, kernel_offset); -} - -void Library::AddFieldMetadata(const Field& field, - TokenPosition token_pos, - intptr_t kernel_offset) const { - Thread* thread = Thread::Current(); - Zone* zone = thread->zone(); - const auto& owner = Object::Handle(zone, field.RawOwner()); - const auto& name = - String::Handle(zone, MakeFieldMetaName(thread, zone, field)); - AddMetadata(owner, name, token_pos, kernel_offset); -} - -void Library::AddFunctionMetadata(const Function& func, - TokenPosition token_pos, - intptr_t kernel_offset) const { - Thread* thread = Thread::Current(); - Zone* zone = thread->zone(); - const auto& owner = Object::Handle(zone, func.RawOwner()); - const auto& name = - String::Handle(zone, MakeFunctionMetaName(thread, zone, func)); - AddMetadata(owner, name, token_pos, kernel_offset); -} - -void Library::AddTypeParameterMetadata(const TypeParameter& param, - TokenPosition token_pos) const { - Thread* thread = Thread::Current(); - Zone* zone = thread->zone(); - const auto& owner = Class::Handle(zone, param.parameterized_class()); - const auto& name = - String::Handle(zone, MakeTypeParameterMetaName(thread, zone, param)); - AddMetadata(owner, name, token_pos, 0); -} - -void Library::AddLibraryMetadata(const Object& tl_owner, - TokenPosition token_pos, - intptr_t kernel_offset) const { - AddMetadata(tl_owner, Symbols::TopLevel(), token_pos, kernel_offset); -} - -StringPtr Library::MakeMetadataName(const Object& obj) const { - Thread* thread = Thread::Current(); - Zone* zone = thread->zone(); - if (obj.IsClass()) { - return MakeClassMetaName(thread, zone, Class::Cast(obj)); - } else if (obj.IsField()) { - return MakeFieldMetaName(thread, zone, Field::Cast(obj)); - } else if (obj.IsFunction()) { - return MakeFunctionMetaName(thread, zone, Function::Cast(obj)); - } else if (obj.IsLibrary()) { - return Symbols::TopLevel().raw(); - } else if (obj.IsTypeParameter()) { - return MakeTypeParameterMetaName(thread, zone, TypeParameter::Cast(obj)); - } - UNIMPLEMENTED(); - return String::null(); -} - -FieldPtr Library::GetMetadataField(const String& metaname) const { - const GrowableObjectArray& metadata = - GrowableObjectArray::Handle(this->metadata()); - Field& entry = Field::Handle(); - String& entryname = String::Handle(); - intptr_t num_entries = metadata.Length(); - for (intptr_t i = 0; i < num_entries; i++) { - entry ^= metadata.At(i); - entryname = entry.name(); - if (entryname.Equals(metaname)) { - return entry.raw(); - } - } - return Field::null(); -} - -ObjectPtr Library::GetMetadata(const Object& obj) const { +ObjectPtr Library::GetMetadata(const Object& declaration) const { #if defined(DART_PRECOMPILED_RUNTIME) return Object::empty_array().raw(); #else - if (!obj.IsClass() && !obj.IsField() && !obj.IsFunction() && - !obj.IsLibrary() && !obj.IsTypeParameter()) { - UNREACHABLE(); - } - if (obj.IsLibrary()) { + RELEASE_ASSERT(declaration.IsClass() || declaration.IsField() || + declaration.IsFunction() || declaration.IsLibrary() || + declaration.IsTypeParameter() || declaration.IsNamespace()); + if (declaration.IsLibrary()) { // Ensure top-level class is loaded as it may contain annotations of // a library. const auto& cls = Class::Handle(toplevel_class()); @@ -11785,31 +11621,36 @@ cls.EnsureDeclarationLoaded(); } } - const String& metaname = String::Handle(MakeMetadataName(obj)); - Field& field = Field::Handle(GetMetadataField(metaname)); - if (field.IsNull()) { + Object& value = Object::Handle(); + { + MetadataMap map(metadata()); + value = map.GetOrNull(declaration); + set_metadata(map.Release()); + } + if (value.IsNull()) { // There is no metadata for this object. return Object::empty_array().raw(); } - Object& metadata = Object::Handle(field.StaticValue()); - if (metadata.raw() == Object::empty_array().raw()) { - ASSERT(field.kernel_offset() > 0); - metadata = kernel::EvaluateMetadata( - field, /* is_annotations_offset = */ obj.IsLibrary()); - if (metadata.IsArray() || metadata.IsNull()) { - ASSERT(metadata.raw() != Object::empty_array().raw()); - if (!Compiler::IsBackgroundCompilation()) { - field.SetStaticValue( - metadata.IsNull() ? Object::null_array() : Array::Cast(metadata), - true); - } + if (!value.IsSmi()) { + // Metadata is already evaluated. + ASSERT(value.IsArray()); + return value.raw(); + } + intptr_t kernel_offset = Smi::Cast(value).Value(); + ASSERT(kernel_offset > 0); + value = kernel::EvaluateMetadata( + *this, kernel_offset, + /* is_annotations_offset = */ declaration.IsLibrary() || + declaration.IsNamespace()); + if (value.IsArray() || value.IsNull()) { + ASSERT(value.raw() != Object::empty_array().raw()); + if (!Compiler::IsBackgroundCompilation()) { + MetadataMap map(metadata()); + map.UpdateOrInsert(declaration, value); + set_metadata(map.Release()); } } - if (metadata.IsNull()) { - // Metadata field exists in order to reference extended metadata. - return Object::empty_array().raw(); - } - return metadata.raw(); + return value.raw(); #endif // defined(DART_PRECOMPILED_RUNTIME) } @@ -12356,7 +12197,7 @@ import = ImportAt(i); obj = import.Lookup(name); if (!obj.IsNull()) { - import_lib = import.library(); + import_lib = import.target(); import_lib_url = import_lib.url(); if (found_obj.raw() != obj.raw()) { if (first_import_lib_url.IsNull() || @@ -12480,7 +12321,7 @@ raw_ptr()->set_dependencies(deps.raw()); } -void Library::set_metadata(const GrowableObjectArray& value) const { +void Library::set_metadata(const Array& value) const { raw_ptr()->set_metadata(value.raw()); } @@ -12489,7 +12330,7 @@ if (import.IsNull()) { return Library::null(); } - return import.library(); + return import.target(); } NamespacePtr Library::ImportAt(intptr_t index) const { @@ -12511,7 +12352,7 @@ for (int i = 0; i < imports.Length(); ++i) { ns = Namespace::RawCast(imports.At(i)); if (ns.IsNull()) continue; - lib = ns.library(); + lib = ns.target(); url = lib.url(); if (url.StartsWith(Symbols::DartExtensionScheme())) { native_import_count++; @@ -12522,7 +12363,7 @@ for (int i = 0, j = 0; i < imports.Length(); ++i) { ns = Namespace::RawCast(imports.At(i)); if (ns.IsNull()) continue; - lib = ns.library(); + lib = ns.target(); url = lib.url(); if (url.StartsWith(Symbols::DartExtensionScheme())) { new_imports.SetAt(j++, ns); @@ -12640,10 +12481,11 @@ result.raw_ptr()->set_resolved_names(Array::null()); result.raw_ptr()->set_exported_names(Array::null()); result.raw_ptr()->set_dictionary(Object::empty_array().raw()); - GrowableObjectArray& list = GrowableObjectArray::Handle(zone); - list = GrowableObjectArray::New(4, Heap::kOld); - result.raw_ptr()->set_metadata(list.raw()); + Array& array = Array::Handle(zone); + array = HashTables::New<MetadataMap>(4, Heap::kOld); + result.raw_ptr()->set_metadata(array.raw()); result.raw_ptr()->set_toplevel_class(Class::null()); + GrowableObjectArray& list = GrowableObjectArray::Handle(zone); list = GrowableObjectArray::New(Object::empty_array(), Heap::kOld); result.raw_ptr()->set_used_scripts(list.raw()); result.raw_ptr()->set_imports(Object::empty_array().raw()); @@ -12673,9 +12515,9 @@ if (import_core_lib) { const Library& core_lib = Library::Handle(zone, Library::CoreLibrary()); ASSERT(!core_lib.IsNull()); - const Namespace& ns = Namespace::Handle( - zone, - Namespace::New(core_lib, Object::null_array(), Object::null_array())); + const Namespace& ns = + Namespace::Handle(zone, Namespace::New(core_lib, Object::null_array(), + Object::null_array(), result)); result.AddImport(ns); } return result.raw(); @@ -13300,7 +13142,7 @@ const Array& imports = Array::Handle(this->imports()); Namespace& import = Namespace::Handle(); import ^= imports.At(index); - return import.library(); + return import.target(); } return Library::null(); } @@ -13370,59 +13212,8 @@ return prefix.ToCString(); } -void Namespace::set_metadata_field(const Field& value) const { - raw_ptr()->set_metadata_field(value.raw()); -} - -void Namespace::AddMetadata(const Object& owner, - TokenPosition token_pos, - intptr_t kernel_offset) { - auto thread = Thread::Current(); - auto zone = thread->zone(); - auto isolate_group = thread->isolate_group(); - ASSERT(Field::Handle(zone, metadata_field()).IsNull()); - Field& field = - Field::Handle(zone, Field::NewTopLevel(Symbols::TopLevel(), - false, // is_final - false, // is_const - false, // is_late - owner, token_pos, token_pos)); - field.set_is_reflectable(false); - field.SetFieldType(Object::dynamic_type()); - field.set_kernel_offset(kernel_offset); - isolate_group->RegisterStaticField(field, Array::empty_array()); - set_metadata_field(field); -} - -ObjectPtr Namespace::GetMetadata() const { -#if defined(DART_PRECOMPILED_RUNTIME) - return Object::empty_array().raw(); -#else - Field& field = Field::Handle(metadata_field()); - if (field.IsNull()) { - // There is no metadata for this object. - return Object::empty_array().raw(); - } - Object& metadata = Object::Handle(); - metadata = field.StaticValue(); - if (field.StaticValue() == Object::empty_array().raw()) { - if (field.kernel_offset() > 0) { - metadata = - kernel::EvaluateMetadata(field, /* is_annotations_offset = */ true); - } else { - UNREACHABLE(); - } - if (metadata.IsArray()) { - ASSERT(Array::Cast(metadata).raw() != Object::empty_array().raw()); - field.SetStaticValue(Array::Cast(metadata), true); - } - } - return metadata.raw(); -#endif // defined(DART_PRECOMPILED_RUNTIME) -} - const char* Namespace::ToCString() const { - const Library& lib = Library::Handle(library()); + const Library& lib = Library::Handle(target()); return OS::SCreate(Thread::Current()->zone(), "Namespace for library '%s'", lib.ToCString()); } @@ -13476,7 +13267,7 @@ ObjectPtr Namespace::Lookup(const String& name, ZoneGrowableArray<intptr_t>* trail) const { Zone* zone = Thread::Current()->zone(); - const Library& lib = Library::Handle(zone, library()); + const Library& lib = Library::Handle(zone, target()); if (trail != NULL) { // Look for cycle in reexport graph. @@ -13537,15 +13328,17 @@ return static_cast<NamespacePtr>(raw); } -NamespacePtr Namespace::New(const Library& library, +NamespacePtr Namespace::New(const Library& target, const Array& show_names, - const Array& hide_names) { + const Array& hide_names, + const Library& owner) { ASSERT(show_names.IsNull() || (show_names.Length() > 0)); ASSERT(hide_names.IsNull() || (hide_names.Length() > 0)); const Namespace& result = Namespace::Handle(Namespace::New()); - result.raw_ptr()->set_library(library.raw()); + result.raw_ptr()->set_target(target.raw()); result.raw_ptr()->set_show_names(show_names.raw()); result.raw_ptr()->set_hide_names(hide_names.raw()); + result.raw_ptr()->set_owner(owner.raw()); return result.raw(); } @@ -23228,15 +23021,7 @@ void Array::MakeImmutable() const { if (IsImmutable()) return; ASSERT(!IsCanonical()); - NoSafepointScope no_safepoint; - uword tags = raw_ptr()->tags_; - uword old_tags; - do { - old_tags = tags; - uword new_tags = - ObjectLayout::ClassIdTag::update(kImmutableArrayCid, old_tags); - tags = CompareAndSwapTags(old_tags, new_tags); - } while (tags != old_tags); + raw_ptr()->SetClassId(kImmutableArrayCid); } const char* Array::ToCString() const { @@ -23293,25 +23078,22 @@ // that it can be traversed over successfully during garbage collection. Object::MakeUnusedSpaceTraversable(array, old_size, new_size); - // For the heap to remain walkable by the sweeper, it must observe the - // creation of the filler object no later than the new length of the array. - std::atomic_thread_fence(std::memory_order_release); - // Update the size in the header field and length of the array object. - uword tags = array.raw_ptr()->tags_; - ASSERT(kArrayCid == ObjectLayout::ClassIdTag::decode(tags)); - uword old_tags; + // These release operations are balanced by acquire operations in the + // concurrent sweeper. + uword old_tags = array.raw_ptr()->tags_; + uword new_tags; + ASSERT(kArrayCid == ObjectLayout::ClassIdTag::decode(old_tags)); do { - old_tags = tags; - uword new_tags = ObjectLayout::SizeTag::update(new_size, old_tags); - tags = CompareAndSwapTags(old_tags, new_tags); - } while (tags != old_tags); + new_tags = ObjectLayout::SizeTag::update(new_size, old_tags); + } while (!array.raw_ptr()->tags_.compare_exchange_weak( + old_tags, new_tags, std::memory_order_release)); // Between the CAS of the header above and the SetLength below, the array is // temporarily in an inconsistent state. The header is considered the // overriding source of object size by ObjectLayout::Size, but the ASSERTs in - // ObjectLayout::SizeFromClass must handle this special case. - array.SetLengthIgnoreRace(new_len); + // ObjectLayout::HeapSizeFromClass must handle this special case. + array.SetLengthRelease(new_len); } ArrayPtr Array::MakeFixedLength(const GrowableObjectArray& growable_array, @@ -25089,9 +24871,13 @@ const Library& lib = Library::Handle(cls.library()); switch (kind()) { case FunctionLayout::kRegularFunction: - case FunctionLayout::kImplicitClosureFunction: return dart::VerifyEntryPoint(lib, *this, *this, {EntryPointPragma::kGetterOnly}); + case FunctionLayout::kImplicitClosureFunction: { + const Function& parent = Function::Handle(parent_function()); + return dart::VerifyEntryPoint(lib, parent, parent, + {EntryPointPragma::kGetterOnly}); + } default: UNREACHABLE(); }
diff --git a/runtime/vm/object.h b/runtime/vm/object.h index b729ba3..8ea8ae0 100644 --- a/runtime/vm/object.h +++ b/runtime/vm/object.h
@@ -290,10 +290,6 @@ ObjectPtr raw() const { return raw_; } void operator=(ObjectPtr value) { initializeHandle(this, value); } - uword CompareAndSwapTags(uword old_tags, uword new_tags) const { - raw()->ptr()->tags_.StrongCAS(old_tags, new_tags); - return old_tags; - } bool IsCanonical() const { return raw()->ptr()->IsCanonical(); } void SetCanonical() const { raw()->ptr()->SetCanonical(); } void ClearCanonical() const { raw()->ptr()->ClearCanonical(); } @@ -645,9 +641,6 @@ void StoreSmi(SmiPtr const* addr, SmiPtr value) const { raw()->ptr()->StoreSmi(addr, value); } - void StoreSmiIgnoreRace(SmiPtr const* addr, SmiPtr value) const { - raw()->ptr()->StoreSmiIgnoreRace(addr, value); - } template <typename FieldType> void StoreSimd128(const FieldType* addr, simd128_value_t value) const { @@ -4738,22 +4731,8 @@ void AddExport(const Namespace& ns) const; - void AddClassMetadata(const Class& cls, - const Object& tl_owner, - TokenPosition token_pos, - intptr_t kernel_offset) const; - void AddFieldMetadata(const Field& field, - TokenPosition token_pos, - intptr_t kernel_offset) const; - void AddFunctionMetadata(const Function& func, - TokenPosition token_pos, - intptr_t kernel_offset) const; - void AddLibraryMetadata(const Object& tl_owner, - TokenPosition token_pos, - intptr_t kernel_offset) const; - void AddTypeParameterMetadata(const TypeParameter& param, - TokenPosition token_pos) const; - ObjectPtr GetMetadata(const Object& obj) const; + void AddMetadata(const Object& declaration, intptr_t kernel_offset) const; + ObjectPtr GetMetadata(const Object& declaration) const; // Tries to finds a @pragma annotation on [object]. // @@ -4978,8 +4957,8 @@ void set_flags(uint8_t flags) const; bool HasExports() const; ArrayPtr loaded_scripts() const { return raw_ptr()->loaded_scripts(); } - GrowableObjectArrayPtr metadata() const { return raw_ptr()->metadata(); } - void set_metadata(const GrowableObjectArray& value) const; + ArrayPtr metadata() const { return raw_ptr()->metadata(); } + void set_metadata(const Array& value) const; ArrayPtr dictionary() const { return raw_ptr()->dictionary(); } void InitClassDictionary() const; @@ -5007,13 +4986,6 @@ void AllocatePrivateKey() const; - StringPtr MakeMetadataName(const Object& obj) const; - FieldPtr GetMetadataField(const String& metaname) const; - void AddMetadata(const Object& owner, - const String& name, - TokenPosition token_pos, - intptr_t kernel_offset) const; - FINAL_HEAP_OBJECT_IMPLEMENTATION(Library, Object); friend class Bootstrap; @@ -5031,14 +5003,10 @@ // the show/hide combinators. class Namespace : public Object { public: - LibraryPtr library() const { return raw_ptr()->library(); } + LibraryPtr target() const { return raw_ptr()->target(); } ArrayPtr show_names() const { return raw_ptr()->show_names(); } ArrayPtr hide_names() const { return raw_ptr()->hide_names(); } - - void AddMetadata(const Object& owner, - TokenPosition token_pos, - intptr_t kernel_offset = 0); - ObjectPtr GetMetadata() const; + LibraryPtr owner() const { return raw_ptr()->owner(); } static intptr_t InstanceSize() { return RoundedAllocationSize(sizeof(NamespaceLayout)); @@ -5050,14 +5018,12 @@ static NamespacePtr New(const Library& library, const Array& show_names, - const Array& hide_names); + const Array& hide_names, + const Library& owner); private: static NamespacePtr New(); - FieldPtr metadata_field() const { return raw_ptr()->metadata_field(); } - void set_metadata_field(const Field& value) const; - FINAL_HEAP_OBJECT_IMPLEMENTATION(Namespace, Object); friend class Class; friend class Precompiler; @@ -8265,6 +8231,13 @@ bool IsFunctionTypeParameter() const { return parameterized_function() != Function::null(); } + ObjectPtr Owner() const { + if (IsClassTypeParameter()) { + return parameterized_class(); + } else { + return parameterized_function(); + } + } static intptr_t parameterized_class_id_offset() { return OFFSET_OF(TypeParameterLayout, parameterized_class_id_); @@ -9640,8 +9613,8 @@ void SetLength(intptr_t value) const { raw_ptr()->set_length(Smi::New(value)); } - void SetLengthIgnoreRace(intptr_t value) const { - raw_ptr()->set_length_ignore_race(Smi::New(value)); + void SetLengthRelease(intptr_t value) const { + raw_ptr()->set_length<std::memory_order_release>(Smi::New(value)); } template <typename type, std::memory_order order = std::memory_order_relaxed>
diff --git a/runtime/vm/object_service.cc b/runtime/vm/object_service.cc index 08bfa23..1dfe634 100644 --- a/runtime/vm/object_service.cc +++ b/runtime/vm/object_service.cc
@@ -519,7 +519,7 @@ jsdep.AddProperty("isDeferred", false); jsdep.AddProperty("isExport", false); jsdep.AddProperty("isImport", true); - target = ns.library(); + target = ns.target(); jsdep.AddProperty("target", target); } @@ -533,7 +533,7 @@ jsdep.AddProperty("isDeferred", false); jsdep.AddProperty("isExport", true); jsdep.AddProperty("isImport", false); - target = ns.library(); + target = ns.target(); jsdep.AddProperty("target", target); } @@ -559,7 +559,7 @@ prefix_name = prefix.name(); ASSERT(!prefix_name.IsNull()); jsdep.AddProperty("prefix", prefix_name.ToCString()); - target = ns.library(); + target = ns.target(); jsdep.AddProperty("target", target); } }
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc index 5f87bb1..64adf66 100644 --- a/runtime/vm/raw_object.cc +++ b/runtime/vm/raw_object.cc
@@ -145,7 +145,8 @@ case kArrayCid: case kImmutableArrayCid: { const ArrayPtr raw_array = static_cast<const ArrayPtr>(this); - intptr_t array_length = Smi::Value(raw_array->ptr()->length_); + intptr_t array_length = + Smi::Value(raw_array->ptr()->length<std::memory_order_acquire>()); instance_size = Array::InstanceSize(array_length); break; } @@ -539,7 +540,7 @@ VARIABLE_VISITOR(LocalVarDescriptors, raw_obj->ptr()->num_entries_) VARIABLE_VISITOR(ExceptionHandlers, raw_obj->ptr()->num_entries_) VARIABLE_VISITOR(Context, raw_obj->ptr()->num_variables_) -VARIABLE_COMPRESSED_VISITOR(Array, Smi::Value(raw_obj->ptr()->length_)) +VARIABLE_COMPRESSED_VISITOR(Array, Smi::Value(raw_obj->ptr()->length())) VARIABLE_COMPRESSED_VISITOR( TypedData, TypedData::ElementSizeInBytes(raw_obj->GetClassId()) *
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h index bc02ac3..b6e04fc 100644 --- a/runtime/vm/raw_object.h +++ b/runtime/vm/raw_object.h
@@ -226,14 +226,12 @@ return tags; } - bool StrongCAS(uword old_tags, uword new_tags) { - return tags_.compare_exchange_strong(old_tags, new_tags, - std::memory_order_relaxed); - } + uword load(std::memory_order order) const { return tags_.load(order); } - bool WeakCAS(uword old_tags, uword new_tags) { - return tags_.compare_exchange_weak(old_tags, new_tags, - std::memory_order_relaxed); + bool compare_exchange_weak(uword old_tags, + uword new_tags, + std::memory_order order) { + return tags_.compare_exchange_weak(old_tags, new_tags, order); } template <class TagBitField> @@ -304,6 +302,7 @@ // Support for GC marking bit. Marked objects are either grey (not yet // visited) or black (already visited). + static bool IsMarked(uword tags) { return !OldAndNotMarkedBit::decode(tags); } bool IsMarked() const { ASSERT(IsOldObject()); return !tags_.Read<OldAndNotMarkedBit>(); @@ -529,7 +528,8 @@ intptr_t HeapSizeFromClass(uword tags) const; - void SetClassId(intptr_t new_cid) { + void SetClassId(intptr_t new_cid) { tags_.Update<ClassIdTag>(new_cid); } + void SetClassIdUnsynchronized(intptr_t new_cid) { tags_.UpdateUnsynchronized<ClassIdTag>(new_cid); } @@ -665,12 +665,6 @@ reinterpret_cast<std::atomic<SmiPtr>*>(const_cast<SmiPtr*>(addr)) ->store(value, order); } - NO_SANITIZE_THREAD - void StoreSmiIgnoreRace(SmiPtr const* addr, SmiPtr value) { - // Can't use Contains, as array length is initialized through this method. - ASSERT(reinterpret_cast<uword>(addr) >= ObjectLayout::ToAddr(this)); - *const_cast<SmiPtr*>(addr) = value; - } friend class StoreBufferUpdateVisitor; // RememberCard void RememberCard(ObjectPtr const* slot); @@ -688,6 +682,7 @@ friend class FreeListElement; friend class Function; friend class GCMarker; + friend class GCSweeper; friend class ExternalTypedData; friend class ForwardList; friend class GrowableObjectArray; // StorePointer @@ -785,10 +780,6 @@ ASSERT(!value.IsHeapObject()); \ StoreSmi<order>(&name##_, value); \ } \ - void set_##name##_ignore_race(type value) { \ - ASSERT(!value.IsHeapObject()); \ - StoreSmiIgnoreRace(&name##_, value); \ - } \ \ protected: \ type name##_; @@ -1409,8 +1400,7 @@ POINTER_FIELD(StringPtr, url) POINTER_FIELD(StringPtr, private_key) POINTER_FIELD(ArrayPtr, dictionary) // Top-level names in this library. - POINTER_FIELD(GrowableObjectArrayPtr, - metadata) // Metadata on classes, methods etc. + POINTER_FIELD(ArrayPtr, metadata) // Metadata on classes, methods etc. POINTER_FIELD(ClassPtr, toplevel_class) // Class containing top-level elements. POINTER_FIELD(GrowableObjectArrayPtr, used_scripts) @@ -1462,14 +1452,12 @@ class NamespaceLayout : public ObjectLayout { RAW_HEAP_OBJECT_IMPLEMENTATION(Namespace); - VISIT_FROM(ObjectPtr, library) - POINTER_FIELD(LibraryPtr, library) // library with name dictionary. + VISIT_FROM(ObjectPtr, target) + POINTER_FIELD(LibraryPtr, target) // library with name dictionary. POINTER_FIELD(ArrayPtr, show_names) // list of names that are exported. POINTER_FIELD(ArrayPtr, hide_names) // list of names that are hidden. - POINTER_FIELD(FieldPtr, - metadata_field) // remembers the token pos of metadata if any, - // and the metadata values if computed. - VISIT_TO(ObjectPtr, metadata_field) + POINTER_FIELD(LibraryPtr, owner) + VISIT_TO(ObjectPtr, owner) ObjectPtr* to_snapshot(Snapshot::Kind kind) { return to(); } };
diff --git a/runtime/vm/raw_object_fields.cc b/runtime/vm/raw_object_fields.cc index cf5625b..103611e 100644 --- a/runtime/vm/raw_object_fields.cc +++ b/runtime/vm/raw_object_fields.cc
@@ -75,10 +75,10 @@ F(Library, resolved_names_) \ F(Library, exported_names_) \ F(Library, loaded_scripts_) \ - F(Namespace, library_) \ + F(Namespace, target_) \ F(Namespace, show_names_) \ F(Namespace, hide_names_) \ - F(Namespace, metadata_field_) \ + F(Namespace, owner_) \ F(KernelProgramInfo, string_offsets_) \ F(KernelProgramInfo, string_data_) \ F(KernelProgramInfo, canonical_names_) \
diff --git a/runtime/vm/vm_sources.gni b/runtime/vm/vm_sources.gni index 665d37b..0f71c57 100644 --- a/runtime/vm/vm_sources.gni +++ b/runtime/vm/vm_sources.gni
@@ -21,6 +21,7 @@ "bootstrap_natives.h", "bss_relocs.cc", "bss_relocs.h", + "canonical_tables.cc", "canonical_tables.h", "class_finalizer.cc", "class_finalizer.h",
diff --git a/tools/VERSION b/tools/VERSION index 2f20bdc..c30eba8 100644 --- a/tools/VERSION +++ b/tools/VERSION
@@ -27,5 +27,5 @@ MAJOR 2 MINOR 12 PATCH 0 -PRERELEASE 129 +PRERELEASE 130 PRERELEASE_PATCH 0 \ No newline at end of file
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json index 3ac4fe4..4b3cf6e 100644 --- a/tools/bots/test_matrix.json +++ b/tools/bots/test_matrix.json
@@ -1436,7 +1436,7 @@ "name": "vm tests", "arguments": [ "-ndartk-${sanitizer}-${system}-${mode}-${arch}", - "vm" + "vm/cc" ] } ] @@ -1490,7 +1490,7 @@ "name": "vm tests", "arguments": [ "-ndartkp-${sanitizer}-${system}-${mode}-${arch}", - "vm" + "vm/cc" ] } ]