Prepare for publishing analyzer 0.33.1, with front_end and kernel.
This is essentially head, with commit
a342cecffd8b57273439fd5fb68676fed0dfe9f9 reverted to avoid a breaking
change for analyzer.
Revert "Disable support for the old super mixins"
This reverts commit a342cecffd8b57273439fd5fb68676fed0dfe9f9.
Change-Id: I09db415e80fff9353d24cc7636d4a2187ebcd532
Reviewed-on: https://dart-review.googlesource.com/c/81333
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Janice Collins <jcollins@google.com>
diff --git a/pkg/analysis_server/lib/src/domain_analysis.dart b/pkg/analysis_server/lib/src/domain_analysis.dart
index a3e3257..ae19037 100644
--- a/pkg/analysis_server/lib/src/domain_analysis.dart
+++ b/pkg/analysis_server/lib/src/domain_analysis.dart
@@ -518,6 +518,11 @@
options.lint = newOptions.generateLints;
});
}
+ if (newOptions.enableSuperMixins != null) {
+ updaters.add((engine.AnalysisOptionsImpl options) {
+ options.enableSuperMixins = newOptions.enableSuperMixins;
+ });
+ }
server.updateOptions(updaters);
return new AnalysisUpdateOptionsResult().toResponse(request.id);
}
diff --git a/pkg/analysis_server/lib/src/status/diagnostics.dart b/pkg/analysis_server/lib/src/status/diagnostics.dart
index 56423be..4628c6f 100644
--- a/pkg/analysis_server/lib/src/status/diagnostics.dart
+++ b/pkg/analysis_server/lib/src/status/diagnostics.dart
@@ -389,6 +389,7 @@
b.write(
writeOption('Analyze function bodies', options.analyzeFunctionBodies));
+ b.write(writeOption('Enable super mixins', options.enableSuperMixins));
b.write(writeOption('Generate dart2js hints', options.dart2jsHint));
b.write(writeOption(
'Generate errors in implicit files', options.generateImplicitErrors));
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index e04d0de..a2911fa 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -13,10 +13,8 @@
import 'package:analyzer/source/error_processor.dart';
import 'package:analyzer/src/context/builder.dart';
import 'package:analyzer/src/context/context_root.dart';
-import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
-import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/engine.dart' hide AnalysisResult;
import 'package:analyzer/src/generated/sdk.dart';
@@ -26,6 +24,8 @@
import 'package:analyzer/src/summary/summary_file_builder.dart';
import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
import 'package:analyzer/src/util/glob.dart';
+import 'package:analyzer/src/dart/analysis/byte_store.dart';
+import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:linter/src/rules.dart';
import 'package:linter/src/rules/avoid_as.dart';
import 'package:path/path.dart' as path;
@@ -1807,6 +1807,8 @@
embedded_libs:
"dart:foobar": "../sdk_ext/entry.dart"
analyzer:
+ language:
+ enableSuperMixins: true
errors:
unused_local_variable: false
linter:
@@ -1821,6 +1823,7 @@
// Verify options were set.
expect(errorProcessors, hasLength(1));
expect(lints, hasLength(1));
+ expect(analysisOptions.enableSuperMixins, isTrue);
// Remove options.
deleteOptionsFile();
@@ -1829,6 +1832,7 @@
// Verify defaults restored.
expect(errorProcessors, isEmpty);
expect(lints, isEmpty);
+ expect(analysisOptions.enableSuperMixins, isFalse);
}
@failingTest
@@ -1855,6 +1859,8 @@
// Setup analysis options
newFile('$projPath/$optionsFileName', content: r'''
analyzer:
+ language:
+ enableSuperMixins: true
errors:
unused_local_variable: false
linter:
@@ -1867,6 +1873,7 @@
await pumpEventQueue();
// Verify options were set.
+ expect(analysisOptions.enableSuperMixins, isTrue);
expect(errorProcessors, hasLength(2));
expect(lints, hasLength(2));
@@ -1875,6 +1882,7 @@
await pumpEventQueue();
// Verify defaults restored.
+ expect(analysisOptions.enableSuperMixins, isFalse);
expect(lints, hasLength(1));
expect(lints.first, const TypeMatcher<AvoidAs>());
expect(errorProcessors, hasLength(1));
@@ -1895,6 +1903,8 @@
''');
newFile('$projPath/other_options.yaml', content: r'''
analyzer:
+ language:
+ enableSuperMixins: true
errors:
unused_local_variable: false
linter:
@@ -1905,6 +1915,7 @@
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
await pumpEventQueue();
// Verify options were set.
+ expect(analysisOptions.enableSuperMixins, isTrue);
expect(errorProcessors, hasLength(1));
expect(lints, hasLength(1));
expect(lints[0].name, 'camel_case_types');
@@ -1922,6 +1933,8 @@
String booLibPosixPath = '/my/pkg/boo/lib';
newFile('$booLibPosixPath/other_options.yaml', content: r'''
analyzer:
+ language:
+ enableSuperMixins: true
errors:
unused_local_variable: false
linter:
@@ -1938,6 +1951,7 @@
manager.setRoots(<String>[projPath], <String>[], <String, String>{});
await pumpEventQueue();
// Verify options were set.
+ expect(analysisOptions.enableSuperMixins, isTrue);
expect(errorProcessors, hasLength(1));
expect(lints, hasLength(1));
expect(lints[0].name, 'camel_case_types');
@@ -1995,6 +2009,8 @@
"dart:foobar": "../sdk_ext/entry.dart"
analyzer:
strong-mode: true
+ language:
+ enableSuperMixins: true
errors:
missing_return: false
linter:
@@ -2010,6 +2026,8 @@
analyzer:
exclude:
- 'test/**'
+ language:
+ enableSuperMixins: true
errors:
unused_local_variable: false
linter:
@@ -2028,8 +2046,12 @@
// Verify options.
// * from `_embedder.yaml`:
- // TODO(brianwilkerson) Figure out what to use in place of 'strongMode'.
+ // TODO(brianwilkerson) Figure out what to use in place of 'strongMode' and
+ // why 'enableSuperMixins' is assumed to come from two different sources.
// expect(analysisOptions.strongMode, isTrue);
+ expect(analysisOptions.enableSuperMixins, isTrue);
+ // * from analysis options:
+ expect(analysisOptions.enableSuperMixins, isTrue);
// * verify tests are excluded
expect(
diff --git a/pkg/analyzer/CHANGELOG.md b/pkg/analyzer/CHANGELOG.md
index f93cc02..9e55512 100644
--- a/pkg/analyzer/CHANGELOG.md
+++ b/pkg/analyzer/CHANGELOG.md
@@ -1,3 +1,13 @@
+## 0.33.1
+* Fix circular typedef stack overflow. (#33599)
+* Check that the implemented member is a valid override of the member from
+ the super constraint. (#34693)
+* Begin replacing InheritanceManager with InheritanceManager2 and
+ deprecate older members.
+* Performance fixups with Analysis Driver.
+* Verify the superconstraint signature invoked by a mixin. (#34896)
+* In_matchInterfaceSubtypeOf, account for mixins having null. (#34907)
+
## 0.33.0
* Support handling 'class C with M', with extends missing.
* Report ABSTRACT_SUPER_MEMBER_REFERENCE as an error.
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 763bd2f..4ec4387 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -48,13 +48,11 @@
AnalysisOptionsWarningCode.UNRECOGNIZED_ERROR_CODE,
AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUE,
AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES,
- AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITHOUT_VALUES,
AnalysisOptionsWarningCode.UNSUPPORTED_VALUE,
AnalysisOptionsWarningCode.SPEC_MODE_REMOVED,
AnalysisOptionsHintCode.DEPRECATED_ANALYSIS_OPTIONS_FILE_NAME,
AnalysisOptionsHintCode.PREVIEW_DART_2_SETTING_DEPRECATED,
AnalysisOptionsHintCode.STRONG_MODE_SETTING_DEPRECATED,
- AnalysisOptionsHintCode.SUPER_MIXINS_SETTING_DEPRECATED,
CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH,
CheckedModeCompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH,
CheckedModeCompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION,
diff --git a/pkg/analyzer/lib/src/analysis_options/error/option_codes.dart b/pkg/analyzer/lib/src/analysis_options/error/option_codes.dart
index 53f4a4e..a76ea1c 100644
--- a/pkg/analyzer/lib/src/analysis_options/error/option_codes.dart
+++ b/pkg/analyzer/lib/src/analysis_options/error/option_codes.dart
@@ -48,60 +48,6 @@
ErrorType get type => ErrorType.COMPILE_TIME_ERROR;
}
-class AnalysisOptionsHintCode extends ErrorCode {
- /**
- * An error code indicating the analysis options file name is deprecated and
- * the file should be renamed.
- *
- * Parameters:
- * 0: the uri of the file which should be renamed
- */
- static const AnalysisOptionsHintCode DEPRECATED_ANALYSIS_OPTIONS_FILE_NAME =
- const AnalysisOptionsHintCode(
- 'DEPRECATED_ANALYSIS_OPTIONS_FILE_NAME',
- "The name of the analysis options file {0} is deprecated;"
- " consider renaming it to analysis_options.yaml.");
-
- /**
- * An error code indicating that the enablePreviewDart2 setting is deprecated.
- */
- static const AnalysisOptionsHintCode PREVIEW_DART_2_SETTING_DEPRECATED =
- const AnalysisOptionsHintCode('PREVIEW_DART_2_SETTING_DEPRECATED',
- "The 'enablePreviewDart2' setting is deprecated.",
- correction: "It is no longer necessary to explicitly enable Dart 2.");
-
- /**
- * An error code indicating that strong-mode: true is deprecated.
- */
- static const AnalysisOptionsHintCode STRONG_MODE_SETTING_DEPRECATED =
- const AnalysisOptionsHintCode('STRONG_MODE_SETTING_DEPRECATED',
- "The 'strong-mode: true' setting is deprecated.",
- correction:
- "It is no longer necessary to explicitly enable strong mode.");
-
- /**
- * An error code indicating that the enablePreviewDart2 setting is deprecated.
- */
- static const AnalysisOptionsHintCode SUPER_MIXINS_SETTING_DEPRECATED =
- const AnalysisOptionsHintCode('SUPER_MIXINS_SETTING_DEPRECATED',
- "The 'enableSuperMixins' setting is deprecated.",
- correction:
- "Support has been added to the language for 'mixin' based mixins.");
-
- /**
- * Initialize a newly created hint code to have the given [name].
- */
- const AnalysisOptionsHintCode(String name, String message,
- {String correction})
- : super.temporary(name, message, correction: correction);
-
- @override
- ErrorSeverity get errorSeverity => ErrorSeverity.INFO;
-
- @override
- ErrorType get type => ErrorType.HINT;
-}
-
/**
* The error codes used for warnings in analysis options files. The convention
* for this class is for the name of the error code to indicate the problem that
@@ -141,26 +87,6 @@
"Warning in the included options file {0}({1}..{2}): {3}");
/**
- * An error code indicating an invalid format for an options file section.
- *
- * Parameters:
- * 0: the section name
- */
- static const AnalysisOptionsWarningCode INVALID_SECTION_FORMAT =
- const AnalysisOptionsWarningCode(
- 'INVALID_SECTION_FORMAT', "Invalid format for the '{0}' section.");
-
- /**
- * An error code indicating that strong-mode: false is has been removed.
- */
- static const AnalysisOptionsWarningCode SPEC_MODE_REMOVED =
- const AnalysisOptionsWarningCode('SPEC_MODE_REMOVED',
- "The option 'strong-mode: false' is no longer supported.",
- correction:
- "It's recommended to remove the 'strong-mode:' setting (and make "
- "your code Dart 2 compliant).");
-
- /**
* An error code indicating that an unrecognized error code is being used to
* specify an error filter.
*
@@ -201,20 +127,6 @@
correction: "Try using one of the supported options: {2}.");
/**
- * An error code indicating that a plugin is being configured with an
- * unsupported option and legal options are provided.
- *
- * Parameters:
- * 0: the plugin name
- * 1: the unsupported option key
- */
- static const AnalysisOptionsWarningCode UNSUPPORTED_OPTION_WITHOUT_VALUES =
- const AnalysisOptionsWarningCode(
- 'UNSUPPORTED_OPTION_WITHOUT_VALUES',
- "The option '{1}' isn't supported by '{0}'.",
- );
-
- /**
* An error code indicating that an option entry is being configured with an
* unsupported value.
*
@@ -229,6 +141,26 @@
correction: "Try using one of the supported options: {2}.");
/**
+ * An error code indicating an invalid format for an options file section.
+ *
+ * Parameters:
+ * 0: the section name
+ */
+ static const AnalysisOptionsWarningCode INVALID_SECTION_FORMAT =
+ const AnalysisOptionsWarningCode(
+ 'INVALID_SECTION_FORMAT', "Invalid format for the '{0}' section.");
+
+ /**
+ * An error code indicating that strong-mode: false is has been removed.
+ */
+ static const AnalysisOptionsWarningCode SPEC_MODE_REMOVED =
+ const AnalysisOptionsWarningCode('SPEC_MODE_REMOVED',
+ "The option 'strong-mode: false' is no longer supported.",
+ correction:
+ "It's recommended to remove the 'strong-mode:' setting (and make "
+ "your code Dart 2 compliant).");
+
+ /**
* Initialize a newly created warning code to have the given [name].
*/
const AnalysisOptionsWarningCode(String name, String message,
@@ -241,3 +173,48 @@
@override
ErrorType get type => ErrorType.STATIC_WARNING;
}
+
+class AnalysisOptionsHintCode extends ErrorCode {
+ /**
+ * An error code indicating the analysis options file name is deprecated and
+ * the file should be renamed.
+ *
+ * Parameters:
+ * 0: the uri of the file which should be renamed
+ */
+ static const AnalysisOptionsHintCode DEPRECATED_ANALYSIS_OPTIONS_FILE_NAME =
+ const AnalysisOptionsHintCode(
+ 'DEPRECATED_ANALYSIS_OPTIONS_FILE_NAME',
+ "The name of the analysis options file {0} is deprecated;"
+ " consider renaming it to analysis_options.yaml.");
+
+ /**
+ * An error code indicating that the enablePreviewDart2 setting is deprecated.
+ */
+ static const AnalysisOptionsHintCode PREVIEW_DART_2_SETTING_DEPRECATED =
+ const AnalysisOptionsHintCode('PREVIEW_DART_2_SETTING_DEPRECATED',
+ "The 'enablePreviewDart2' setting is deprecated.",
+ correction: "It is no longer necessary to explicitly enable Dart 2.");
+
+ /**
+ * An error code indicating that strong-mode: true is deprecated.
+ */
+ static const AnalysisOptionsHintCode STRONG_MODE_SETTING_DEPRECATED =
+ const AnalysisOptionsHintCode('STRONG_MODE_SETTING_DEPRECATED',
+ "The 'strong-mode: true' setting is deprecated.",
+ correction:
+ "It is no longer necessary to explicitly enable strong mode.");
+
+ /**
+ * Initialize a newly created hint code to have the given [name].
+ */
+ const AnalysisOptionsHintCode(String name, String message,
+ {String correction})
+ : super.temporary(name, message, correction: correction);
+
+ @override
+ ErrorSeverity get errorSeverity => ErrorSeverity.INFO;
+
+ @override
+ ErrorType get type => ErrorType.HINT;
+}
diff --git a/pkg/analyzer/lib/src/command_line/arguments.dart b/pkg/analyzer/lib/src/command_line/arguments.dart
index 904684c..df90093 100644
--- a/pkg/analyzer/lib/src/command_line/arguments.dart
+++ b/pkg/analyzer/lib/src/command_line/arguments.dart
@@ -18,7 +18,6 @@
const String declarationCastsFlag = 'declaration-casts';
const String defineVariableOption = 'D';
const String enableInitializingFormalAccessFlag = 'initializing-formal-access';
-@deprecated
const String enableSuperMixinFlag = 'supermixin';
const String flutterAnalysisOptionsPath =
'package:flutter/analysis_options_user.yaml';
@@ -43,6 +42,10 @@
}
}
+ if (args.wasParsed(enableSuperMixinFlag)) {
+ options.enableSuperMixins = args[enableSuperMixinFlag];
+ verbose('$enableSuperMixinFlag = ${options.enableSuperMixins}');
+ }
if (args.wasParsed(implicitCastsFlag)) {
options.implicitCasts = args[implicitCastsFlag];
verbose('$implicitCastsFlag = ${options.implicitCasts}');
@@ -198,6 +201,11 @@
defaultsTo: false,
negatable: false,
hide: hide || ddc);
+ parser.addFlag(enableSuperMixinFlag,
+ help: 'Relax restrictions on mixins (DEP 34).',
+ defaultsTo: false,
+ negatable: false,
+ hide: hide);
if (!ddc) {
parser.addFlag(lintsFlag,
help: 'Show lint results.', defaultsTo: false, negatable: true);
diff --git a/pkg/analyzer/lib/src/context/context.dart b/pkg/analyzer/lib/src/context/context.dart
index 2dc5cfd..490d6e0 100644
--- a/pkg/analyzer/lib/src/context/context.dart
+++ b/pkg/analyzer/lib/src/context/context.dart
@@ -291,6 +291,7 @@
((options is AnalysisOptionsImpl)
? this._options.implicitDynamic != options.implicitDynamic
: false) ||
+ this._options.enableSuperMixins != options.enableSuperMixins ||
!_samePatchPaths(this._options.patchPaths, options.patchPaths);
this._options.analyzeFunctionBodiesPredicate =
options.analyzeFunctionBodiesPredicate;
@@ -299,6 +300,7 @@
this._options.dart2jsHint = options.dart2jsHint;
this._options.enableLazyAssignmentOperators =
options.enableLazyAssignmentOperators;
+ this._options.enableSuperMixins = options.enableSuperMixins;
this._options.enableTiming = options.enableTiming;
this._options.enabledPluginNames = options.enabledPluginNames;
this._options.errorProcessors = options.errorProcessors;
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
index c387512..8a9d293 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -332,7 +332,11 @@
// Use the ErrorVerifier to compute errors.
//
ErrorVerifier errorVerifier = new ErrorVerifier(
- errorReporter, _libraryElement, _typeProvider, _inheritance, false);
+ errorReporter,
+ _libraryElement,
+ _typeProvider,
+ _inheritance,
+ _analysisOptions.enableSuperMixins);
unit.accept(errorVerifier);
}
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 62f46eb..886352f 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -695,11 +695,13 @@
@override
bool get isValidMixin {
- if (hasReferenceToSuper) {
- return false;
- }
- if (!supertype.isObject) {
- return false;
+ if (!context.analysisOptions.enableSuperMixins) {
+ if (hasReferenceToSuper) {
+ return false;
+ }
+ if (!supertype.isObject) {
+ return false;
+ }
}
for (ConstructorElement constructor in constructors) {
if (!constructor.isSynthetic && !constructor.isFactory) {
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index b566cbb..f7018dd 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -1856,6 +1856,16 @@
}
}
+ if (forSuperInvocation) {
+ bool inOldStyleSuperMixin = inMixin &&
+ type.superclass != null &&
+ !type.superclass.isObject &&
+ element.context.analysisOptions.enableSuperMixins;
+ if (inOldStyleSuperMixin) {
+ acceptAbstract = true;
+ }
+ }
+
if (!inMixin || acceptAbstract) {
var mixins = type.mixins;
startMixinIndex ??= mixins.length;
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index 91e3739..5c1d7ec 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -21,12 +21,10 @@
import 'package:analyzer/src/generated/java_engine.dart';
import 'package:analyzer/src/generated/resolver.dart';
import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/timestamped_data.dart';
import 'package:analyzer/src/generated/utilities_general.dart';
import 'package:analyzer/src/plugin/engine_plugin.dart';
import 'package:analyzer/src/plugin/resolver_provider.dart';
import 'package:analyzer/src/services/lint.dart';
-import 'package:analyzer/src/summary/api_signature.dart';
import 'package:analyzer/src/task/api/dart.dart';
import 'package:analyzer/src/task/api/model.dart';
import 'package:analyzer/src/task/dart.dart';
@@ -35,6 +33,8 @@
import 'package:analyzer/src/task/manager.dart';
import 'package:analyzer/src/task/options.dart';
import 'package:analyzer/src/task/yaml.dart';
+import 'package:analyzer/src/summary/api_signature.dart';
+import 'package:analyzer/src/generated/timestamped_data.dart';
import 'package:front_end/src/fasta/scanner/token.dart';
import 'package:html/dom.dart' show Document;
import 'package:path/path.dart' as pathos;
@@ -105,7 +105,8 @@
/**
* Return the set of analysis options controlling the behavior of this
- * context. Clients should not modify the returned set of options.
+ * context. Clients should not modify the returned set of options. The options
+ * should only be set by invoking the method [setAnalysisOptions].
*/
AnalysisOptions get analysisOptions;
@@ -1225,7 +1226,6 @@
* Return `true` if mixins are allowed to inherit from types other than
* Object, and are allowed to reference `super`.
*/
- @deprecated
bool get enableSuperMixins;
/**
@@ -1416,6 +1416,9 @@
bool enableLazyAssignmentOperators = false;
@override
+ bool enableSuperMixins = false;
+
+ @override
bool enableTiming = false;
/**
@@ -1469,6 +1472,7 @@
@override
bool disableCacheFlushing = false;
+ // A no-op setter.
/**
* A flag indicating whether implicit casts are allowed in [strongMode]
* (they are always allowed in Dart 1.0 mode).
@@ -1489,7 +1493,6 @@
*/
bool implicitDynamic = true;
- // A no-op setter.
/**
* Return `true` to enable mixin declarations.
* https://github.com/dart-lang/language/issues/12
@@ -1511,6 +1514,7 @@
dart2jsHint = options.dart2jsHint;
enabledPluginNames = options.enabledPluginNames;
enableLazyAssignmentOperators = options.enableLazyAssignmentOperators;
+ enableSuperMixins = options.enableSuperMixins;
enableTiming = options.enableTiming;
errorProcessors = options.errorProcessors;
excludePatterns = options.excludePatterns;
@@ -1606,15 +1610,6 @@
@deprecated
void set enableInitializingFormalAccess(bool enable) {}
- @override
- @deprecated
- bool get enableSuperMixins => false;
-
- @deprecated
- void set enableSuperMixins(bool enable) {
- // Ignored.
- }
-
@deprecated
@override
bool get enableUriInPartOf => true;
@@ -1669,6 +1664,7 @@
// Append boolean flags.
buffer.addBool(declarationCasts);
buffer.addBool(enableLazyAssignmentOperators);
+ buffer.addBool(enableSuperMixins);
buffer.addBool(implicitCasts);
buffer.addBool(implicitDynamic);
buffer.addBool(strongModeHints);
@@ -1735,6 +1731,7 @@
disableCacheFlushing = false;
enabledPluginNames = const <String>[];
enableLazyAssignmentOperators = false;
+ enableSuperMixins = false;
enableTiming = false;
_errorProcessors = null;
_excludePatterns = null;
@@ -1755,6 +1752,7 @@
@override
void setCrossContextOptionsFrom(AnalysisOptions options) {
enableLazyAssignmentOperators = options.enableLazyAssignmentOperators;
+ enableSuperMixins = options.enableSuperMixins;
if (options is AnalysisOptionsImpl) {
strongModeHints = options.strongModeHints;
}
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 9f5eef9..2a3c763 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -267,6 +267,12 @@
*/
List<InterfaceType> _DISALLOWED_TYPES_TO_EXTEND_OR_IMPLEMENT;
+ /**
+ * If `true`, mixins are allowed to inherit from types other than Object, and
+ * are allowed to reference `super`.
+ */
+ final bool enableSuperMixins;
+
final _UninstantiatedBoundChecker _uninstantiatedBoundChecker;
/// Setting this flag to `true` disables the check for conflicting generics.
@@ -281,7 +287,7 @@
* Initialize a newly created error verifier.
*/
ErrorVerifier(ErrorReporter errorReporter, this._currentLibrary,
- this._typeProvider, this._inheritanceManager, bool enableSuperMixins,
+ this._typeProvider, this._inheritanceManager, this.enableSuperMixins,
{this.disableConflictingGenericsCheck: false})
: _errorReporter = errorReporter,
_uninstantiatedBoundChecker =
@@ -302,13 +308,6 @@
_options = _currentLibrary.context.analysisOptions;
}
- /**
- * If `true`, mixins are allowed to inherit from types other than Object, and
- * are allowed to reference `super`.
- */
- @deprecated
- bool get enableSuperMixins => false;
-
ClassElement get enclosingClass => _enclosingClass;
/**
@@ -1921,7 +1920,8 @@
mixinName, mixinElement)) {
problemReported = true;
}
- if (_checkForMixinInheritsNotFromObject(mixinName, mixinElement)) {
+ if (!enableSuperMixins &&
+ _checkForMixinInheritsNotFromObject(mixinName, mixinElement)) {
problemReported = true;
}
if (_checkForMixinReferencesSuper(mixinName, mixinElement)) {
@@ -4102,7 +4102,7 @@
*/
bool _checkForMixinReferencesSuper(
TypeName mixinName, ClassElement mixinElement) {
- if (mixinElement.hasReferenceToSuper) {
+ if (!enableSuperMixins && mixinElement.hasReferenceToSuper) {
_errorReporter.reportErrorForNode(
CompileTimeErrorCode.MIXIN_REFERENCES_SUPER,
mixinName,
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index 875a093..125ba2d 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -5577,7 +5577,11 @@
// Use the ErrorVerifier to compute errors.
//
ErrorVerifier errorVerifier = new ErrorVerifier(
- errorReporter, libraryElement, typeProvider, inheritanceManager, false,
+ errorReporter,
+ libraryElement,
+ typeProvider,
+ inheritanceManager,
+ context.analysisOptions.enableSuperMixins,
disableConflictingGenericsCheck: true);
unit.accept(errorVerifier);
//
diff --git a/pkg/analyzer/lib/src/task/options.dart b/pkg/analyzer/lib/src/task/options.dart
index c1c96b6..9a3b62f 100644
--- a/pkg/analyzer/lib/src/task/options.dart
+++ b/pkg/analyzer/lib/src/task/options.dart
@@ -73,18 +73,20 @@
exclude,
language,
plugins,
- strong_mode,
+ strong_mode
];
/// Supported `analyzer` strong-mode options.
static const List<String> strongModeOptions = const [
declarationCasts, // deprecated
implicitCasts,
- implicitDynamic,
+ implicitDynamic
];
/// Supported `analyzer` language options.
- static const List<String> languageOptions = const [];
+ static const List<String> languageOptions = const [
+ enableSuperMixins,
+ ];
}
/// Validates `analyzer` options.
@@ -116,21 +118,16 @@
/// Create a builder for the given [supportedOptions].
ErrorBuilder(List<String> supportedOptions) {
- assert(supportedOptions != null);
- if (supportedOptions.isEmpty) {
- code = noProposalCode;
- } else if (supportedOptions.length == 1) {
- proposal = "'${supportedOptions.join()}'";
- code = singularProposalCode;
- } else {
+ assert(supportedOptions != null && !supportedOptions.isEmpty);
+ if (supportedOptions.length > 1) {
proposal = StringUtilities.printListOfQuotedNames(supportedOptions);
code = pluralProposalCode;
+ } else {
+ proposal = "'${supportedOptions.join()}'";
+ code = singularProposalCode;
}
}
- AnalysisOptionsWarningCode get noProposalCode =>
- AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITHOUT_VALUES;
-
AnalysisOptionsWarningCode get pluralProposalCode =>
AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES;
@@ -139,12 +136,8 @@
/// Report an unsupported [node] value, defined in the given [scopeName].
void reportError(ErrorReporter reporter, String scopeName, YamlNode node) {
- if (proposal != null) {
- reporter.reportErrorForSpan(
- code, node.span, [scopeName, node.value, proposal]);
- } else {
- reporter.reportErrorForSpan(code, node.span, [scopeName, node.value]);
- }
+ reporter
+ .reportErrorForSpan(code, node.span, [scopeName, node.value, proposal]);
}
}
@@ -388,10 +381,6 @@
reporter.reportErrorForSpan(
AnalysisOptionsHintCode.PREVIEW_DART_2_SETTING_DEPRECATED,
k.span);
- } else if (AnalyzerOptions.enableSuperMixins == key) {
- reporter.reportErrorForSpan(
- AnalysisOptionsHintCode.SUPER_MIXINS_SETTING_DEPRECATED,
- k.span);
} else if (!AnalyzerOptions.languageOptions.contains(key)) {
builder.reportError(reporter, AnalyzerOptions.language, k);
} else {
@@ -637,7 +626,9 @@
AnalysisOptionsImpl options, Object feature, Object value) {
bool boolValue = toBool(value);
if (boolValue != null) {
- // Currently no supported language options.
+ if (feature == AnalyzerOptions.enableSuperMixins) {
+ options.enableSuperMixins = boolValue;
+ }
}
}
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 9b2b39e..a0f0298 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
name: analyzer
-version: 0.33.0
+version: 0.33.1
author: Dart Team <misc@dartlang.org>
description: Static analyzer for Dart.
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
@@ -11,10 +11,10 @@
collection: ^1.10.1
convert: ^2.0.0
crypto: '>=1.1.1 <3.0.0'
- front_end: 0.1.6
+ front_end: 0.1.6+1
glob: ^1.0.3
html: '>=0.12.0 <1.14.0'
- kernel: 0.3.6
+ kernel: 0.3.6+1
meta: ^1.0.2
package_config: '>=0.1.5 <2.0.0'
path: '>=0.9.0 <2.0.0'
diff --git a/pkg/analyzer/test/generated/compile_time_error_code_driver_test.dart b/pkg/analyzer/test/generated/compile_time_error_code_driver_test.dart
index e2ad9cf..248b5db 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_driver_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_driver_test.dart
@@ -55,6 +55,12 @@
@override
@failingTest
+ test_mixinInference_noMatchingClass_typeParametersSupplied() {
+ return super.test_mixinInference_noMatchingClass_typeParametersSupplied();
+ }
+
+ @override
+ @failingTest
test_mixinOfNonClass() {
return super.test_mixinOfNonClass();
}
diff --git a/pkg/analyzer/test/generated/compile_time_error_code_test.dart b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
index a04cda9..0e032d2 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
@@ -61,6 +61,18 @@
}
@override
+ @failingTest
+ test_mixinInference_noMatchingClass_typeParametersSupplied() {
+ return super.test_mixinInference_noMatchingClass_typeParametersSupplied();
+ }
+
+ @override
+ @failingTest // Does not work with old task model
+ test_mixinInference_recursiveSubtypeCheck() {
+ return super.test_mixinInference_recursiveSubtypeCheck();
+ }
+
+ @override
@failingTest // Does not work with old task model
test_mixinInference_recursiveSubtypeCheck_new_syntax() {
return super.test_mixinInference_recursiveSubtypeCheck_new_syntax();
@@ -3875,6 +3887,35 @@
]);
}
+ test_mixinInference_matchingClass() async {
+ AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+ options.enableSuperMixins = true;
+ resetWith(options: options);
+ Source source = addSource('''
+abstract class A<T> {}
+class B {}
+class M<T> extends A<T> {}
+class C extends A<int> with M {}
+''');
+ await computeAnalysisResult(source);
+ assertNoErrors(source);
+ }
+
+ test_mixinInference_matchingClass_inPreviousMixin() async {
+ AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+ options.enableSuperMixins = true;
+ resetWith(options: options);
+ Source source = addSource('''
+abstract class A<T> {}
+class B {}
+class M1 implements A<B> {}
+class M2<T> extends A<T> {}
+class C extends Object with M1, M2 {}
+''');
+ await computeAnalysisResult(source);
+ assertNoErrors(source);
+ }
+
test_mixinInference_matchingClass_inPreviousMixin_new_syntax() async {
Source source = addSource('''
abstract class A<T> {}
@@ -3898,6 +3939,36 @@
assertNoErrors(source);
}
+ test_mixinInference_noMatchingClass() async {
+ AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+ options.enableSuperMixins = true;
+ resetWith(options: options);
+ Source source = addSource('''
+abstract class A<T> {}
+class B {}
+class M<T> extends A<T> {}
+class C extends Object with M {}
+''');
+ await computeAnalysisResult(source);
+ assertErrors(
+ source, [CompileTimeErrorCode.MIXIN_INFERENCE_NO_MATCHING_CLASS]);
+ }
+
+ test_mixinInference_noMatchingClass_namedMixinApplication() async {
+ AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+ options.enableSuperMixins = true;
+ resetWith(options: options);
+ Source source = addSource('''
+abstract class A<T> {}
+class B {}
+class M<T> extends A<T> {}
+class C = Object with M;
+''');
+ await computeAnalysisResult(source);
+ assertErrors(
+ source, [CompileTimeErrorCode.MIXIN_INFERENCE_NO_MATCHING_CLASS]);
+ }
+
test_mixinInference_noMatchingClass_namedMixinApplication_new_syntax() async {
Source source = addSource('''
abstract class A<T> {}
@@ -3922,6 +3993,20 @@
[CompileTimeErrorCode.MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE]);
}
+ test_mixinInference_noMatchingClass_noSuperclassConstraint() async {
+ AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+ options.enableSuperMixins = true;
+ resetWith(options: options);
+ Source source = addSource('''
+abstract class A<T> {}
+class B {}
+class M<T> {}
+class C extends Object with M {}
+''');
+ await computeAnalysisResult(source);
+ assertNoErrors(source);
+ }
+
test_mixinInference_noMatchingClass_noSuperclassConstraint_new_syntax() async {
Source source = addSource('''
abstract class A<T> {}
@@ -3933,6 +4018,21 @@
assertNoErrors(source);
}
+ test_mixinInference_noMatchingClass_typeParametersSupplied() async {
+ AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+ options.enableSuperMixins = true;
+ resetWith(options: options);
+ Source source = addSource('''
+abstract class A<T> {}
+class B {}
+class M<T> extends A<T> {}
+class C extends Object with M<int> {}
+''');
+ await computeAnalysisResult(source);
+ assertErrors(source,
+ [CompileTimeErrorCode.MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE]);
+ }
+
test_mixinInference_noMatchingClass_typeParametersSupplied_new_syntax() async {
Source source = addSource('''
abstract class A<T> {}
@@ -3945,6 +4045,44 @@
[CompileTimeErrorCode.MIXIN_APPLICATION_NOT_IMPLEMENTED_INTERFACE]);
}
+ test_mixinInference_recursiveSubtypeCheck() async {
+ // See dartbug.com/32353 for a detailed explanation.
+ AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+ options.enableSuperMixins = true;
+ resetWith(options: options);
+ Source source = addSource('''
+class ioDirectory implements ioFileSystemEntity {}
+
+class ioFileSystemEntity {}
+
+abstract class _LocalDirectory
+ extends _LocalFileSystemEntity<_LocalDirectory, ioDirectory>
+ with ForwardingDirectory, DirectoryAddOnsMixin {}
+
+abstract class _LocalFileSystemEntity<T extends FileSystemEntity,
+ D extends ioFileSystemEntity> extends ForwardingFileSystemEntity<T, D> {}
+
+abstract class FileSystemEntity implements ioFileSystemEntity {}
+
+abstract class ForwardingFileSystemEntity<T extends FileSystemEntity,
+ D extends ioFileSystemEntity> implements FileSystemEntity {}
+
+
+abstract class ForwardingDirectory<T extends Directory>
+ extends ForwardingFileSystemEntity<T, ioDirectory>
+ implements Directory {}
+
+abstract class Directory implements FileSystemEntity, ioDirectory {}
+
+abstract class DirectoryAddOnsMixin implements Directory {}
+''');
+ var analysisResult = await computeAnalysisResult(source);
+ assertNoErrors(source);
+ var mixins =
+ analysisResult.unit.declaredElement.getType('_LocalDirectory').mixins;
+ expect(mixins[0].toString(), 'ForwardingDirectory<_LocalDirectory>');
+ }
+
test_mixinInference_recursiveSubtypeCheck_new_syntax() async {
// See dartbug.com/32353 for a detailed explanation.
Source source = addSource('''
diff --git a/pkg/analyzer/test/generated/engine_test.dart b/pkg/analyzer/test/generated/engine_test.dart
index 8f80f48..f1d150d 100644
--- a/pkg/analyzer/test/generated/engine_test.dart
+++ b/pkg/analyzer/test/generated/engine_test.dart
@@ -40,6 +40,7 @@
modifiedOptions.disableCacheFlushing = true;
modifiedOptions.enabledPluginNames = ['somePackage'];
modifiedOptions.enableLazyAssignmentOperators = true;
+ modifiedOptions.enableSuperMixins = true;
modifiedOptions.enableTiming = true;
modifiedOptions.errorProcessors = [null];
modifiedOptions.excludePatterns = ['a'];
@@ -62,6 +63,7 @@
expect(modifiedOptions.enabledPluginNames, isEmpty);
expect(modifiedOptions.enableLazyAssignmentOperators,
defaultOptions.enableLazyAssignmentOperators);
+ expect(modifiedOptions.enableSuperMixins, defaultOptions.enableSuperMixins);
expect(modifiedOptions.enableTiming, defaultOptions.enableTiming);
expect(modifiedOptions.errorProcessors, defaultOptions.errorProcessors);
expect(modifiedOptions.excludePatterns, defaultOptions.excludePatterns);
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
index be2fa81..93f3357 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_test.dart
@@ -34,11 +34,35 @@
@override
@failingTest // Does not work with old task model
+ test_infer_mixin() {
+ return super.test_infer_mixin();
+ }
+
+ @override
+ @failingTest // Does not work with old task model
+ test_infer_mixin_multiplyConstrained() {
+ return super.test_infer_mixin_multiplyConstrained();
+ }
+
+ @override
+ @failingTest // Does not work with old task model
test_infer_mixin_new_syntax() {
return super.test_infer_mixin_new_syntax();
}
@override
+ @failingTest // Does not work with old task model
+ test_infer_mixin_with_substitution() {
+ return super.test_infer_mixin_with_substitution();
+ }
+
+ @override
+ @failingTest // Does not work with old task model
+ test_infer_mixin_with_substitution_functionType() {
+ return super.test_infer_mixin_with_substitution_functionType();
+ }
+
+ @override
@failingTest
test_infer_mixin_with_substitution_functionType_new_syntax() {
return super.test_infer_mixin_with_substitution_functionType_new_syntax();
@@ -75,6 +99,12 @@
}
@override
+ @failingTest // Does not work with old task model
+ test_mixinInference_with_actual_mixins_supermixins_enabled() {
+ return super.test_mixinInference_with_actual_mixins_supermixins_enabled();
+ }
+
+ @override
@failingTest
test_null_callMethod() {
return super.test_null_callMethod();
@@ -1291,6 +1321,19 @@
verify([source]);
}
+ test_constConstructorWithMixinWithField_withSuperMixins() async {
+ resetWith(options: new AnalysisOptionsImpl()..enableSuperMixins = true);
+ Source source = addSource(r'''
+class M {
+}
+class A extends Object with M {
+ const A();
+}''');
+ await computeAnalysisResult(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
test_constConstructorWithMixinWithField_withSuperMixins_new_syntax() async {
Source source = addSource(r'''
mixin M {
@@ -2635,6 +2678,58 @@
verify([source]);
}
+ test_infer_mixin() async {
+ AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+ options.enableSuperMixins = true;
+ resetWith(options: options);
+ Source source = addSource('''
+abstract class A<T> {}
+
+class B {}
+
+class M<T> extends A<T> {}
+
+class C extends A<B> with M {}
+''');
+ TestAnalysisResult analysisResult = await computeAnalysisResult(source);
+ assertNoErrors(source);
+ verify([source]);
+ CompilationUnit unit = analysisResult.unit;
+ ClassElement classC =
+ resolutionMap.elementDeclaredByCompilationUnit(unit).getType('C');
+ expect(classC.mixins, hasLength(1));
+ expect(classC.mixins[0].toString(), 'M<B>');
+ }
+
+ test_infer_mixin_multiplyConstrained() async {
+ AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+ options.enableSuperMixins = true;
+ resetWith(options: options);
+ Source source = addSource('''
+abstract class A<T> {}
+
+abstract class B<U> {}
+
+class C {}
+
+class D {}
+
+class M<T, U> extends A<T> with B<U> {}
+
+class E extends A<C> implements B<D> {}
+
+class F extends E with M {}
+''');
+ TestAnalysisResult analysisResult = await computeAnalysisResult(source);
+ assertNoErrors(source);
+ verify([source]);
+ CompilationUnit unit = analysisResult.unit;
+ ClassElement classF =
+ resolutionMap.elementDeclaredByCompilationUnit(unit).getType('F');
+ expect(classF.mixins, hasLength(1));
+ expect(classF.mixins[0].toString(), 'M<C, D>');
+ }
+
test_infer_mixin_new_syntax() async {
Source source = addSource('''
abstract class A<T> {}
@@ -2655,6 +2750,51 @@
expect(classC.mixins[0].toString(), 'M<B>');
}
+ test_infer_mixin_with_substitution() async {
+ AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+ options.enableSuperMixins = true;
+ resetWith(options: options);
+ Source source = addSource('''
+abstract class A<T> {}
+
+class B {}
+
+class M<T> extends A<List<T>> {}
+
+class C extends A<List<B>> with M {}
+''');
+ TestAnalysisResult analysisResult = await computeAnalysisResult(source);
+ assertNoErrors(source);
+ verify([source]);
+ CompilationUnit unit = analysisResult.unit;
+ ClassElement classC =
+ resolutionMap.elementDeclaredByCompilationUnit(unit).getType('C');
+ expect(classC.mixins, hasLength(1));
+ expect(classC.mixins[0].toString(), 'M<B>');
+ }
+
+ test_infer_mixin_with_substitution_functionType() async {
+ AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+ options.enableSuperMixins = true;
+ resetWith(options: options);
+ Source source = addSource('''
+abstract class A<T> {}
+
+class B {}
+
+class M<T, U> extends A<T Function(U)> {}
+
+class C extends A<int Function(String)> with M {}
+''');
+ TestAnalysisResult analysisResult = await computeAnalysisResult(source);
+ assertNoErrors(source);
+ CompilationUnit unit = analysisResult.unit;
+ ClassElement classC =
+ resolutionMap.elementDeclaredByCompilationUnit(unit).getType('C');
+ expect(classC.mixins, hasLength(1));
+ expect(classC.mixins[0].toString(), 'M<int, String>');
+ }
+
test_infer_mixin_with_substitution_functionType_new_syntax() async {
Source source = addSource('''
abstract class A<T> {}
@@ -3922,6 +4062,48 @@
expect(xElem.type.toString(), 'int');
}
+ test_mixinInference_with_actual_mixins_supermixins_enabled() async {
+ AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+ options.enableSuperMixins = true;
+ resetWith(options: options);
+ Source source = addSource('''
+class I<X> {}
+
+mixin M0<T> on I<T> {}
+
+mixin M1<T> on I<T> {
+ T foo() => null;
+}
+
+class A = I<int> with M0, M1;
+
+void main () {
+ var x = new A().foo();
+}
+''');
+ var result = await computeAnalysisResult(source);
+ assertNoErrors(source);
+ verify([source]);
+ var main = result.unit.declarations.last as FunctionDeclaration;
+ var mainBody = main.functionExpression.body as BlockFunctionBody;
+ var xDecl = mainBody.block.statements[0] as VariableDeclarationStatement;
+ var xElem = xDecl.variables.variables[0].declaredElement;
+ expect(xElem.type.toString(), 'int');
+ }
+
+ test_mixinInheritsFromNotObject_classDeclaration_extends() async {
+ AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+ options.enableSuperMixins = true;
+ resetWith(options: options);
+ Source source = addSource(r'''
+class A {}
+class B extends A {}
+class C extends A with B {}''');
+ await computeAnalysisResult(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
test_mixinInheritsFromNotObject_classDeclaration_extends_new_syntax() async {
Source source = addSource(r'''
class A {}
@@ -3942,6 +4124,32 @@
verify([source]);
}
+ test_mixinInheritsFromNotObject_classDeclaration_with() async {
+ AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+ options.enableSuperMixins = true;
+ resetWith(options: options);
+ Source source = addSource(r'''
+class A {}
+class B extends Object with A {}
+class C extends Object with B {}''');
+ await computeAnalysisResult(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
+ test_mixinInheritsFromNotObject_typeAlias_extends() async {
+ AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+ options.enableSuperMixins = true;
+ resetWith(options: options);
+ Source source = addSource(r'''
+class A {}
+class B extends A {}
+class C = A with B;''');
+ await computeAnalysisResult(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
test_mixinInheritsFromNotObject_typeAlias_extends_new_syntax() async {
Source source = addSource(r'''
class A {}
@@ -3952,6 +4160,19 @@
verify([source]);
}
+ test_mixinInheritsFromNotObject_typeAlias_with() async {
+ AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+ options.enableSuperMixins = true;
+ resetWith(options: options);
+ Source source = addSource(r'''
+class A {}
+class B extends Object with A {}
+class C = Object with B;''');
+ await computeAnalysisResult(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
test_mixinInheritsFromNotObject_typedef_mixTypeAlias() async {
Source source = addSource(r'''
class A {}
@@ -3962,6 +4183,20 @@
verify([source]);
}
+ test_mixinReferencesSuper() async {
+ AnalysisOptionsImpl options = new AnalysisOptionsImpl();
+ options.enableSuperMixins = true;
+ resetWith(options: options);
+ Source source = addSource(r'''
+class A {
+ toString() => super.toString();
+}
+class B extends Object with A {}''');
+ await computeAnalysisResult(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
test_mixinReferencesSuper_new_syntax() async {
Source source = addSource(r'''
mixin A {
diff --git a/pkg/analyzer/test/generated/simple_resolver_test.dart b/pkg/analyzer/test/generated/simple_resolver_test.dart
index 3d64b48..6464b4b 100644
--- a/pkg/analyzer/test/generated/simple_resolver_test.dart
+++ b/pkg/analyzer/test/generated/simple_resolver_test.dart
@@ -9,6 +9,7 @@
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/exception/exception.dart';
import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -1037,6 +1038,23 @@
verify([source]);
}
+ test_isValidMixin_badSuperclass_withSuperMixins() async {
+ resetWith(options: new AnalysisOptionsImpl()..enableSuperMixins = true);
+ Source source = addSource(r'''
+class A extends B {}
+class B {}
+class C = Object with A;''');
+ LibraryElement library = resolve2(source);
+ expect(library, isNotNull);
+ CompilationUnitElement unit = library.definingCompilationUnit;
+ expect(unit, isNotNull);
+ ClassElement a = unit.getType('A');
+ expect(a.isValidMixin, isTrue);
+ await computeAnalysisResult(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
test_isValidMixin_constructor() async {
Source source = addSource(r'''
class A {
@@ -1057,6 +1075,27 @@
verify([source]);
}
+ test_isValidMixin_constructor_withSuperMixins() async {
+ resetWith(options: new AnalysisOptionsImpl()..enableSuperMixins = true);
+ Source source = addSource(r'''
+class A {
+ A() {}
+}
+class C = Object with A;''');
+ LibraryElement library = resolve2(source);
+ expect(library, isNotNull);
+ CompilationUnitElement unit = library.definingCompilationUnit;
+ expect(unit, isNotNull);
+ ClassElement a = unit.getType('A');
+ expect(a.isValidMixin, isFalse);
+ await computeAnalysisResult(source);
+ assertErrors(
+ source,
+ [CompileTimeErrorCode.MIXIN_CLASS_DECLARES_CONSTRUCTOR],
+ );
+ verify([source]);
+ }
+
test_isValidMixin_factoryConstructor() async {
Source source = addSource(r'''
class A {
@@ -1074,6 +1113,24 @@
verify([source]);
}
+ test_isValidMixin_factoryConstructor_withSuperMixins() async {
+ resetWith(options: new AnalysisOptionsImpl()..enableSuperMixins = true);
+ Source source = addSource(r'''
+class A {
+ factory A() => null;
+}
+class C = Object with A;''');
+ LibraryElement library = resolve2(source);
+ expect(library, isNotNull);
+ CompilationUnitElement unit = library.definingCompilationUnit;
+ expect(unit, isNotNull);
+ ClassElement a = unit.getType('A');
+ expect(a.isValidMixin, isTrue);
+ await computeAnalysisResult(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
test_isValidMixin_super() async {
Source source = addSource(r'''
class A {
@@ -1093,6 +1150,26 @@
verify([source]);
}
+ test_isValidMixin_super_withSuperMixins() async {
+ resetWith(options: new AnalysisOptionsImpl()..enableSuperMixins = true);
+ Source source = addSource(r'''
+class A {
+ toString() {
+ return super.toString();
+ }
+}
+class C = Object with A;''');
+ LibraryElement library = resolve2(source);
+ expect(library, isNotNull);
+ CompilationUnitElement unit = library.definingCompilationUnit;
+ expect(unit, isNotNull);
+ ClassElement a = unit.getType('A');
+ expect(a.isValidMixin, isTrue);
+ await computeAnalysisResult(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
test_isValidMixin_valid() async {
Source source = addSource('''
class A {}
@@ -1108,6 +1185,22 @@
verify([source]);
}
+ test_isValidMixin_valid_withSuperMixins() async {
+ resetWith(options: new AnalysisOptionsImpl()..enableSuperMixins = true);
+ Source source = addSource('''
+class A {}
+class C = Object with A;''');
+ LibraryElement library = resolve2(source);
+ expect(library, isNotNull);
+ CompilationUnitElement unit = library.definingCompilationUnit;
+ expect(unit, isNotNull);
+ ClassElement a = unit.getType('A');
+ expect(a.isValidMixin, isTrue);
+ await computeAnalysisResult(source);
+ assertNoErrors(source);
+ verify([source]);
+ }
+
test_labels_switch() async {
Source source = addSource(r'''
void doSwitch(int target) {
diff --git a/pkg/analyzer/test/generated/static_type_warning_code_test.dart b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
index e4f9e69..810ee0c 100644
--- a/pkg/analyzer/test/generated/static_type_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
@@ -21,6 +21,71 @@
@reflectiveTest
class StaticTypeWarningCodeTest extends ResolverTestCase {
+ fail_method_lookup_mixin_of_extends() async {
+ // See dartbug.com/25605
+ resetWith(options: new AnalysisOptionsImpl()..enableSuperMixins = true);
+ await assertErrorsInUnverifiedCode('''
+class A { a() => null; }
+class B {}
+abstract class M extends A {}
+class T = B with M; // Warning: B does not extend A
+main() {
+ new T().a(); // Warning: The method 'a' is not defined for the class 'T'
+}
+''', [
+ // TODO(paulberry): when dartbug.com/25614 is fixed, add static warning
+ // code for "B does not extend A".
+ StaticTypeWarningCode.UNDEFINED_METHOD
+ ]);
+ }
+
+ fail_method_lookup_mixin_of_implements() async {
+ // See dartbug.com/25605
+ resetWith(options: new AnalysisOptionsImpl()..enableSuperMixins = true);
+ await assertErrorsInUnverifiedCode('''
+class A { a() => null; }
+class B {}
+abstract class M implements A {}
+class T = B with M; // Warning: Missing concrete implementation of 'A.a'
+main() {
+ new T().a(); // Warning: The method 'a' is not defined for the class 'T'
+}
+''', [
+ StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE,
+ StaticTypeWarningCode.UNDEFINED_METHOD
+ ]);
+ }
+
+ fail_method_lookup_mixin_of_mixin() async {
+ // See dartbug.com/25605
+ resetWith(options: new AnalysisOptionsImpl()..enableSuperMixins = true);
+ await assertErrorsInUnverifiedCode('''
+class A {}
+class B { b() => null; }
+class C {}
+class M extends A with B {}
+class T = C with M;
+main() {
+ new T().b();
+}
+''', [StaticTypeWarningCode.UNDEFINED_METHOD]);
+ }
+
+ fail_method_lookup_mixin_of_mixin_application() async {
+ // See dartbug.com/25605
+ resetWith(options: new AnalysisOptionsImpl()..enableSuperMixins = true);
+ await assertErrorsInUnverifiedCode('''
+class A { a() => null; }
+class B {}
+class C {}
+class M = A with B;
+class T = C with M;
+main() {
+ new T().a();
+}
+''', [StaticTypeWarningCode.UNDEFINED_METHOD]);
+ }
+
fail_undefinedEnumConstant() async {
// We need a way to set the parseEnum flag in the parser to true.
await assertErrorsInCode(r'''
diff --git a/pkg/analyzer/test/generated/static_warning_code_test.dart b/pkg/analyzer/test/generated/static_warning_code_test.dart
index 4b7068e..59f2624 100644
--- a/pkg/analyzer/test/generated/static_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_warning_code_test.dart
@@ -5,6 +5,7 @@
import 'package:analyzer/dart/ast/ast.dart';
import 'package:analyzer/error/error.dart';
import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source_io.dart';
import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -1310,28 +1311,6 @@
verify([source]);
}
- test_generalizedVoid_andVoidLhsError() async {
- Source source = addSource(r'''
-void main() {
- void x;
- x && true;
-}
-''');
- await computeAnalysisResult(source);
- assertErrors(source, [StaticWarningCode.USE_OF_VOID_RESULT]);
- }
-
- test_generalizedVoid_andVoidRhsError() async {
- Source source = addSource(r'''
-void main() {
- void x;
- true && x;
-}
-''');
- await computeAnalysisResult(source);
- assertErrors(source, [StaticWarningCode.USE_OF_VOID_RESULT]);
- }
-
test_generalizedVoid_assignmentToVoidParameterOk() async {
// Note: the spec may decide to disallow this, but at this point that seems
// highly unlikely.
@@ -1363,17 +1342,6 @@
}
}
- test_generalizedVoid_interpolateVoidValueError() async {
- Source source = addSource(r'''
-void main() {
- void x;
- "$x";
-}
-''');
- await computeAnalysisResult(source);
- assertErrors(source, [StaticWarningCode.USE_OF_VOID_RESULT]);
- }
-
test_generalizedVoid_invocationOfVoidFieldError() async {
Source source = addSource(r'''
class Container<T>{
@@ -1430,6 +1398,28 @@
assertErrors(source, [StaticWarningCode.USE_OF_VOID_RESULT]);
}
+ test_generalizedVoid_throwVoidValueError() async {
+ Source source = addSource(r'''
+void main() {
+ void x;
+ throw x;
+}
+''');
+ await computeAnalysisResult(source);
+ assertErrors(source, [StaticWarningCode.USE_OF_VOID_RESULT]);
+ }
+
+ test_generalizedVoid_interpolateVoidValueError() async {
+ Source source = addSource(r'''
+void main() {
+ void x;
+ "$x";
+}
+''');
+ await computeAnalysisResult(source);
+ assertErrors(source, [StaticWarningCode.USE_OF_VOID_RESULT]);
+ }
+
test_generalizedVoid_orVoidLhsError() async {
Source source = addSource(r'''
void main() {
@@ -1452,11 +1442,22 @@
assertErrors(source, [StaticWarningCode.USE_OF_VOID_RESULT]);
}
- test_generalizedVoid_throwVoidValueError() async {
+ test_generalizedVoid_andVoidLhsError() async {
Source source = addSource(r'''
void main() {
void x;
- throw x;
+ x && true;
+}
+''');
+ await computeAnalysisResult(source);
+ assertErrors(source, [StaticWarningCode.USE_OF_VOID_RESULT]);
+ }
+
+ test_generalizedVoid_andVoidRhsError() async {
+ Source source = addSource(r'''
+void main() {
+ void x;
+ true && x;
}
''');
await computeAnalysisResult(source);
@@ -3202,6 +3203,22 @@
verify([source]);
}
+ test_nonAbstractClassInheritsAbstractMemberTwo_variable_fromMixin_missingBoth() async {
+ // 26411
+ resetWith(options: new AnalysisOptionsImpl()..enableSuperMixins = true);
+ Source source = addSource(r'''
+class A {
+ int f;
+}
+class B extends A {}
+class C extends Object with B {}
+''');
+ await computeAnalysisResult(source);
+ assertErrors(source,
+ [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO]);
+ verify([source]);
+ }
+
test_nonTypeInCatchClause_noElement() async {
Source source = addSource(r'''
f() {
diff --git a/pkg/analyzer/test/src/command_line/arguments_test.dart b/pkg/analyzer/test/src/command_line/arguments_test.dart
index c612c12..99ffbe0 100644
--- a/pkg/analyzer/test/src/command_line/arguments_test.dart
+++ b/pkg/analyzer/test/src/command_line/arguments_test.dart
@@ -38,6 +38,7 @@
'--options=$defaultAnalysisOptionsFilePath',
'--packages=$defaultPackageFilePath',
'--package-root=$defaultPackagesDirectoryPath',
+ '--supermixin',
];
ArgResults result = parse(provider, parser, args);
ContextBuilderOptions options = createContextBuilderOptions(result);
@@ -150,7 +151,7 @@
void test_defineAnalysisArguments() {
ArgParser parser = new ArgParser();
defineAnalysisArguments(parser);
- expect(parser.options, hasLength(12));
+ expect(parser.options, hasLength(13));
}
void test_extractDefinedVariables() {
diff --git a/pkg/analyzer/test/src/context/builder_test.dart b/pkg/analyzer/test/src/context/builder_test.dart
index 45d21f0..8dc66ad 100644
--- a/pkg/analyzer/test/src/context/builder_test.dart
+++ b/pkg/analyzer/test/src/context/builder_test.dart
@@ -241,29 +241,28 @@
_expectEqualOptions(options, expected);
}
- @failingTest
void test_cmdline_options_override_options_file() {
- fail('No clear choice of option to override.');
-// ArgParser argParser = new ArgParser();
-// defineAnalysisArguments(argParser);
-// ArgResults argResults = argParser.parse(['--$enableSuperMixinFlag']);
-// var builder = new ContextBuilder(resourceProvider, sdkManager, contentCache,
-// options: createContextBuilderOptions(argResults));
-//
-// AnalysisOptionsImpl expected = new AnalysisOptionsImpl();
-// expected.previewDart2 = true;
-//
-// String path = resourceProvider.convertPath('/some/directory/path');
-// String filePath =
-// pathContext.join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
-// resourceProvider.newFile(filePath, '''
-//analyzer:
-// language:
-// enablePreviewDart2: true
-//''');
-//
-// AnalysisOptions options = builder.getAnalysisOptions(path);
-// _expectEqualOptions(options, expected);
+ ArgParser argParser = new ArgParser();
+ defineAnalysisArguments(argParser);
+ ArgResults argResults = argParser.parse(['--$enableSuperMixinFlag']);
+ var builder = new ContextBuilder(resourceProvider, sdkManager, contentCache,
+ options: createContextBuilderOptions(argResults));
+
+ AnalysisOptionsImpl expected = new AnalysisOptionsImpl();
+ expected.enableSuperMixins = true;
+ expected.previewDart2 = true;
+
+ String path = resourceProvider.convertPath('/some/directory/path');
+ String filePath =
+ pathContext.join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
+ resourceProvider.newFile(filePath, '''
+analyzer:
+ language:
+ enablePreviewDart2: true
+''');
+
+ AnalysisOptions options = builder.getAnalysisOptions(path);
+ _expectEqualOptions(options, expected);
}
void test_convertPackagesToMap_noPackages() {
@@ -299,6 +298,7 @@
defaultOptions.dart2jsHint = !defaultOptions.dart2jsHint;
defaultOptions.enableLazyAssignmentOperators =
!defaultOptions.enableLazyAssignmentOperators;
+ defaultOptions.enableSuperMixins = !defaultOptions.enableSuperMixins;
builderOptions.defaultOptions = defaultOptions;
AnalysisOptions options = builder.createDefaultOptions();
_expectEqualOptions(options, defaultOptions);
@@ -712,17 +712,19 @@
void test_getAnalysisOptions_default_overrides() {
AnalysisOptionsImpl defaultOptions = new AnalysisOptionsImpl();
- defaultOptions.implicitDynamic = true;
+ defaultOptions.enableSuperMixins = false;
+ defaultOptions.enableLazyAssignmentOperators = true;
builderOptions.defaultOptions = defaultOptions;
AnalysisOptionsImpl expected = new AnalysisOptionsImpl();
- expected.implicitDynamic = false;
+ expected.enableSuperMixins = true;
+ expected.enableLazyAssignmentOperators = true;
String path = resourceProvider.convertPath('/some/directory/path');
String filePath =
pathContext.join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
resourceProvider.newFile(filePath, '''
analyzer:
- strong-mode:
- implicit-dynamic: false
+ language:
+ enableSuperMixins : true
''');
AnalysisOptions options = builder.getAnalysisOptions(path);
@@ -751,8 +753,10 @@
void test_getAnalysisOptions_includes() {
_defineMockLintRules();
AnalysisOptionsImpl defaultOptions = new AnalysisOptionsImpl();
+ defaultOptions.enableSuperMixins = false;
builderOptions.defaultOptions = defaultOptions;
AnalysisOptionsImpl expected = new AnalysisOptionsImpl();
+ expected.enableSuperMixins = true;
expected.lint = true;
expected.lintRules = <Linter>[
_mockLintRule,
@@ -771,6 +775,9 @@
''');
resourceProvider.newFile(pathContext.join(path, 'bar.yaml'), '''
include: package:somepkg/here.yaml
+analyzer:
+ language:
+ enableSuperMixins : true
linter:
rules:
- mock_lint_rule2
@@ -814,14 +821,14 @@
void test_getAnalysisOptions_noDefault_overrides() {
AnalysisOptionsImpl expected = new AnalysisOptionsImpl();
- expected.implicitDynamic = false;
+ expected.enableSuperMixins = true;
String path = resourceProvider.convertPath('/some/directory/path');
String filePath =
pathContext.join(path, AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE);
resourceProvider.newFile(filePath, '''
analyzer:
- strong-mode:
- implicit-dynamic: false
+ language:
+ enableSuperMixins : true
''');
AnalysisOptions options = builder.getAnalysisOptions(path);
@@ -919,6 +926,7 @@
expect(actual.dart2jsHint, expected.dart2jsHint);
expect(actual.enableLazyAssignmentOperators,
expected.enableLazyAssignmentOperators);
+ expect(actual.enableSuperMixins, expected.enableSuperMixins);
expect(actual.enableTiming, expected.enableTiming);
expect(actual.generateImplicitErrors, expected.generateImplicitErrors);
expect(actual.generateSdkErrors, expected.generateSdkErrors);
diff --git a/pkg/analyzer/test/src/dart/resolution/class_test.dart b/pkg/analyzer/test/src/dart/resolution/class_test.dart
index f825033..3df016e 100644
--- a/pkg/analyzer/test/src/dart/resolution/class_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/class_test.dart
@@ -96,6 +96,33 @@
assertElement(findNode.simple('foo; // ref'), findElement.method('foo'));
}
+ test_abstractSuperMemberReference_noSuchMethod() async {
+ setAnalysisOptions(enableSuperMixins: true);
+ addTestFile('''
+class A {
+ void foo();
+ noSuchMethod(im) {}
+}
+
+abstract class B {
+ void foo();
+ noSuchMethod(im) {}
+}
+
+class C extends A with B {
+ void bar() {
+ super.foo(); // ref
+ }
+}
+''');
+ await resolveTestFile();
+ assertTestErrors([CompileTimeErrorCode.ABSTRACT_SUPER_MEMBER_REFERENCE]);
+ assertElement(
+ findNode.simple('foo(); // ref'),
+ findElement.method('foo', of: 'B'),
+ );
+ }
+
test_abstractSuperMemberReference_OK_mixinHasConcrete2_method() async {
addTestFile('''
class A {
@@ -1483,6 +1510,62 @@
]);
}
+ test_mixinInference_conflictingSubstitution() async {
+ setAnalysisOptions(enableSuperMixins: true);
+ addTestFile('''
+abstract class A<T> {}
+class M<T> extends A<Map<T, T>> {}
+class C extends A<Map<int, String>> with M {}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ CompileTimeErrorCode.MIXIN_INFERENCE_NO_POSSIBLE_SUBSTITUTION,
+ CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES
+ ]);
+ }
+
+ test_mixinInference_doNotIgnorePreviousExplicitMixins() async {
+ setAnalysisOptions(enableSuperMixins: true);
+ addTestFile('''
+class A extends Object with B<String>, C {}
+class B<T> {}
+class C<T> extends B<T> {}
+''');
+ await resolveTestFile();
+ assertNoTestErrors();
+ var mixins = result.unit.declaredElement.getType('A').mixins;
+ expect(mixins[1].toString(), 'C<String>');
+ }
+
+ test_mixinInference_impossibleSubstitution() async {
+ setAnalysisOptions(enableSuperMixins: true);
+ addTestFile('''
+abstract class A<T> {}
+class M<T> extends A<Map<T, T>> {}
+class C extends A<List<int>> with M {}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ CompileTimeErrorCode.MIXIN_INFERENCE_NO_POSSIBLE_SUBSTITUTION,
+ CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES
+ ]);
+ }
+
+ test_mixinInference_noMatchingClass_constraintSatisfiedByImplementsClause() async {
+ setAnalysisOptions(enableSuperMixins: true);
+ addTestFile('''
+abstract class A<T> {}
+class B {}
+class M<T> extends A<T> {}
+class C extends Object with M implements A<B> {}
+''');
+ await resolveTestFile();
+ assertTestErrors([
+ CompileTimeErrorCode.MIXIN_INFERENCE_NO_MATCHING_CLASS,
+ CompileTimeErrorCode.CONFLICTING_GENERIC_INTERFACES,
+ ]);
+ }
+
test_recursiveInterfaceInheritance_extends() async {
addTestFile(r'''
class A extends B {}
@@ -1722,4 +1805,25 @@
test_conflictingGenericInterfaces_viaMixin() {
return super.test_conflictingGenericInterfaces_viaMixin();
}
+
+ @failingTest
+ test_mixinInference_conflictingSubstitution() {
+ return super.test_mixinInference_conflictingSubstitution();
+ }
+
+ @failingTest
+ test_mixinInference_doNotIgnorePreviousExplicitMixins() {
+ return super.test_mixinInference_doNotIgnorePreviousExplicitMixins();
+ }
+
+ @failingTest
+ test_mixinInference_impossibleSubstitution() {
+ return super.test_mixinInference_impossibleSubstitution();
+ }
+
+ @failingTest
+ test_mixinInference_noMatchingClass_constraintSatisfiedByImplementsClause() {
+ return super
+ .test_mixinInference_noMatchingClass_constraintSatisfiedByImplementsClause();
+ }
}
diff --git a/pkg/analyzer/test/src/dart/resolution/driver_resolution.dart b/pkg/analyzer/test/src/dart/resolution/driver_resolution.dart
index fb034da..1ad3cfa 100644
--- a/pkg/analyzer/test/src/dart/resolution/driver_resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/driver_resolution.dart
@@ -41,6 +41,15 @@
);
}
+ @override
+ void setAnalysisOptions({bool enableSuperMixins}) {
+ var analysisOptions = new AnalysisOptionsImpl();
+ if (enableSuperMixins != null) {
+ analysisOptions.enableSuperMixins = enableSuperMixins;
+ }
+ driver.configure(analysisOptions: analysisOptions);
+ }
+
void setUp() {
sdk = new MockSdk(resourceProvider: resourceProvider);
logger = new PerformanceLog(logBuffer);
diff --git a/pkg/analyzer/test/src/dart/resolution/resolution.dart b/pkg/analyzer/test/src/dart/resolution/resolution.dart
index f6fdc6f..99207fd 100644
--- a/pkg/analyzer/test/src/dart/resolution/resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/resolution.dart
@@ -326,6 +326,8 @@
findElement = new FindElement(result.unit);
}
+ void setAnalysisOptions({bool enableSuperMixins});
+
Element _unwrapHandle(Element element) {
if (element is ElementHandle && element is! Member) {
return element.actualElement;
diff --git a/pkg/analyzer/test/src/dart/resolution/task_resolution.dart b/pkg/analyzer/test/src/dart/resolution/task_resolution.dart
index 7e02ab4..3bfd858 100644
--- a/pkg/analyzer/test/src/dart/resolution/task_resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/task_resolution.dart
@@ -39,6 +39,15 @@
return new TestAnalysisResult(path, content, unit, errors);
}
+ @override
+ void setAnalysisOptions({bool enableSuperMixins}) {
+ var analysisOptions = new AnalysisOptionsImpl();
+ if (enableSuperMixins != null) {
+ analysisOptions.enableSuperMixins = enableSuperMixins;
+ }
+ analysisContext.analysisOptions = analysisOptions;
+ }
+
void setUp() {
sdk = new MockSdk(resourceProvider: resourceProvider);
diff --git a/pkg/analyzer/test/src/task/options_test.dart b/pkg/analyzer/test/src/task/options_test.dart
index befc23b..e00db4f 100644
--- a/pkg/analyzer/test/src/task/options_test.dart
+++ b/pkg/analyzer/test/src/task/options_test.dart
@@ -51,6 +51,33 @@
YamlMap parseOptions(String source) =>
optionsProvider.getOptionsFromString(source);
+ test_configure_bad_options_contents() {
+ configureContext('''
+analyzer:
+ language:
+ enableSuperMixins true; # misformatted
+''');
+ expect(analysisOptions.enableSuperMixins, false);
+ }
+
+ test_configure_enableSuperMixins() {
+ configureContext('''
+analyzer:
+ language:
+ enableSuperMixins: true
+''');
+ expect(analysisOptions.enableSuperMixins, true);
+ }
+
+ test_configure_enableSuperMixins_badValue() {
+ configureContext('''
+analyzer:
+ language:
+ enableSuperMixins: true;
+''');
+ expect(analysisOptions.enableSuperMixins, false);
+ }
+
test_configure_error_processors() {
configureContext('''
analyzer:
@@ -528,6 +555,14 @@
''', [AnalysisOptionsWarningCode.INVALID_SECTION_FORMAT]);
}
+ test_analyzer_language_supported() {
+ validate('''
+analyzer:
+ language:
+ enableSuperMixins: true
+''', []);
+ }
+
test_analyzer_language_supports_empty() {
validate('''
analyzer:
@@ -540,14 +575,14 @@
analyzer:
language:
unsupported: true
-''', [AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITHOUT_VALUES]);
+''', [AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUE]);
}
test_analyzer_language_unsupported_value() {
validate('''
analyzer:
- strong-mode:
- implicit-dynamic: foo
+ language:
+ enableSuperMixins: foo
''', [AnalysisOptionsWarningCode.UNSUPPORTED_VALUE]);
}
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index 5e74843..072bed7 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -3849,6 +3849,52 @@
''');
}
+ @failingTest
+ test_superMixin_invalidApplication() {
+ // Failing: https://github.com/dart-lang/sdk/issues/30283
+ return checkFile(r'''
+ class A {
+ int get foo => 3;
+}
+
+// This expects a super class which satisfies the contract of A
+class B extends A {}
+
+class C {
+ num get foo => null;
+}
+
+// This mixin application doesn't provide a valid superclass for B
+class D extends C with /*error:INCONSISTENT_INHERITANCE*/B {}
+}
+ ''', superMixins: true);
+ }
+
+ test_superMixinsMakeSuperclassMethodsAbstract() {
+ return checkFile(r'''
+ abstract class A {}
+
+abstract class B extends A {}
+
+abstract class ProvidesConcreteAGetter {
+ A get constraints => null;
+}
+
+abstract class ProvidesConcreteBGetter extends ProvidesConcreteAGetter {
+ @override
+ B get constraints => null;
+}
+
+abstract class ProvidesAbstractBGetter implements ProvidesConcreteBGetter {}
+
+abstract class ProvidesAbstractAGetterMixin extends ProvidesConcreteAGetter {}
+
+abstract class HasConcreteBGetterButMixesinAbstractAGetter
+ extends ProvidesConcreteBGetter
+ with ProvidesAbstractAGetterMixin, ProvidesAbstractBGetter {}
+ ''', superMixins: true);
+ }
+
test_tearOffTreatedConsistentlyAsStrictArrow() async {
await checkFile(r'''
void foo(void f(String x)) {}
diff --git a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
index ccef7a7..f9a8a2b 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -41,7 +41,8 @@
Future<CompilationUnit> checkFile(String content,
{bool declarationCasts: true,
bool implicitCasts: true,
- bool implicitDynamic: true});
+ bool implicitDynamic: true,
+ bool superMixins: false});
/**
* Add the file, process it (resolve, validate, etc) and return the resolved
diff --git a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
index d9e4081..86eadb4 100644
--- a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
+++ b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
@@ -16,15 +16,15 @@
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/memory_file_system.dart';
import 'package:analyzer/source/error_processor.dart';
-import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
-import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:analyzer/src/dart/ast/token.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/dart/analysis/byte_store.dart';
+import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:source_span/source_span.dart';
import 'package:test/test.dart';
@@ -279,7 +279,8 @@
Future<CompilationUnit> check(
{bool declarationCasts: true,
bool implicitCasts: true,
- bool implicitDynamic: true}) async {
+ bool implicitDynamic: true,
+ bool superMixins: false}) async {
_checkCalled = true;
File mainFile =
@@ -291,6 +292,7 @@
analysisOptions.declarationCasts = declarationCasts;
analysisOptions.implicitCasts = implicitCasts;
analysisOptions.implicitDynamic = implicitDynamic;
+ analysisOptions.enableSuperMixins = superMixins;
var mockSdk = new MockSdk(resourceProvider: _resourceProvider);
mockSdk.context.analysisOptions = analysisOptions;
@@ -369,12 +371,14 @@
Future<CompilationUnit> checkFile(String content,
{bool declarationCasts: true,
bool implicitCasts: true,
- bool implicitDynamic: true}) async {
+ bool implicitDynamic: true,
+ bool superMixins: false}) async {
addFile(content);
return await check(
declarationCasts: declarationCasts,
implicitCasts: implicitCasts,
- implicitDynamic: implicitDynamic);
+ implicitDynamic: implicitDynamic,
+ superMixins: superMixins);
}
void setUp() {
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart
index 63ed79f..1806bc7 100644
--- a/pkg/analyzer_cli/lib/src/driver.dart
+++ b/pkg/analyzer_cli/lib/src/driver.dart
@@ -11,10 +11,8 @@
import 'package:analyzer/file_system/file_system.dart';
import 'package:analyzer/file_system/physical_file_system.dart';
import 'package:analyzer/src/context/builder.dart';
-import 'package:analyzer/src/dart/analysis/byte_store.dart';
import 'package:analyzer/src/dart/analysis/driver.dart';
import 'package:analyzer/src/dart/analysis/file_state.dart';
-import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:analyzer/src/dart/sdk/sdk.dart';
import 'package:analyzer/src/file_system/file_system.dart';
import 'package:analyzer/src/generated/engine.dart';
@@ -46,6 +44,8 @@
import 'package:analyzer_cli/src/options.dart';
import 'package:analyzer_cli/src/perf_report.dart';
import 'package:analyzer_cli/starter.dart' show CommandLineStarter;
+import 'package:analyzer/src/dart/analysis/byte_store.dart';
+import 'package:analyzer/src/dart/analysis/performance_logger.dart';
import 'package:linter/src/rules.dart' as linter;
import 'package:meta/meta.dart';
import 'package:package_config/discovery.dart' as pkg_discovery;
@@ -834,6 +834,9 @@
if (newOptions.strongMode != previous.strongMode) {
return false;
}
+ if (newOptions.enableSuperMixins != previous.enableSuperMixins) {
+ return false;
+ }
if (!_equalLists(
newOptions.buildSummaryInputs, previous.buildSummaryInputs)) {
return false;
diff --git a/pkg/analyzer_cli/lib/src/options.dart b/pkg/analyzer_cli/lib/src/options.dart
index 640fd1a..3c1fb51 100644
--- a/pkg/analyzer_cli/lib/src/options.dart
+++ b/pkg/analyzer_cli/lib/src/options.dart
@@ -20,8 +20,6 @@
/// *Visible for testing.*
ExitHandler exitHandler = exit;
-T cast<T>(dynamic value) => value as T;
-
/// Print the given [message] to stderr and exit with the given [exitCode].
void printAndFail(String message, {int exitCode: 15}) {
errorSink.writeln(message);
@@ -112,6 +110,11 @@
/// Whether to enable parsing via the Fasta parser.
final bool useFastaParser;
+ /// Whether to enable the Dart 2.0 Preview.
+ ///
+ /// This flag is deprecated and hard-coded to `true`.
+ bool get previewDart2 => true;
+
/// Batch mode (for unit testing)
final bool batchMode;
@@ -144,10 +147,10 @@
/// Whether implicit dynamic is enabled (mainly for strong mode users)
final bool implicitDynamic;
+ // TODO(devoncarew): Deprecate and remove this flag.
/// Whether to treat lints as fatal
final bool lintsAreFatal;
- // TODO(devoncarew): Deprecate and remove this flag.
/// Emit output in a verbose mode.
final bool verbose;
@@ -212,6 +215,10 @@
Map<String, String> get definedVariables =>
contextBuilderOptions.declaredVariables;
+ /// Whether to relax restrictions on mixins (DEP 34).
+ bool get enableSuperMixins =>
+ contextBuilderOptions.defaultOptions.enableSuperMixins;
+
/// The path to a `.packages` configuration file
String get packageConfigPath => contextBuilderOptions.defaultPackageFilePath;
@@ -219,11 +226,6 @@
String get packageRootPath =>
contextBuilderOptions.defaultPackagesDirectoryPath;
- /// Whether to enable the Dart 2.0 Preview.
- ///
- /// This flag is deprecated and hard-coded to `true`.
- bool get previewDart2 => true;
-
/// The source files to analyze
List<String> get sourceFiles => _sourceFiles;
@@ -643,3 +645,5 @@
For more information, see https://www.dartlang.org/tools/analyzer.\n''');
}
}
+
+T cast<T>(dynamic value) => value as T;
diff --git a/pkg/analyzer_cli/test/all.dart b/pkg/analyzer_cli/test/all.dart
index b5015f7..82706ab 100644
--- a/pkg/analyzer_cli/test/all.dart
+++ b/pkg/analyzer_cli/test/all.dart
@@ -14,6 +14,7 @@
import 'perf_report_test.dart' as perf_report_test;
import 'reporter_test.dart' as reporter_test;
import 'sdk_ext_test.dart' as sdk_ext_test;
+import 'super_mixin_test.dart' as super_mixin_test;
import 'strong_mode_test.dart' as strong_mode_test;
main() {
@@ -29,5 +30,6 @@
perf_report_test.main();
reporter_test.main();
sdk_ext_test.main();
+ super_mixin_test.main();
strong_mode_test.main();
}
diff --git a/pkg/analyzer_cli/test/driver_test.dart b/pkg/analyzer_cli/test/driver_test.dart
index cb85943..706f3cb 100644
--- a/pkg/analyzer_cli/test/driver_test.dart
+++ b/pkg/analyzer_cli/test/driver_test.dart
@@ -905,6 +905,11 @@
expect(outSink.toString(), contains("1 error and 1 warning found."));
}
+ test_basic_language() async {
+ await _driveBasic();
+ expect(analysisOptions.enableSuperMixins, isTrue);
+ }
+
test_includeDirective() async {
String testDir = path.join(
testDirectory, 'data', 'options_include_directive_tests_project');
diff --git a/pkg/analyzer_cli/test/options_test.dart b/pkg/analyzer_cli/test/options_test.dart
index b0c8a8c..32c08eb 100644
--- a/pkg/analyzer_cli/test/options_test.dart
+++ b/pkg/analyzer_cli/test/options_test.dart
@@ -60,6 +60,7 @@
expect(options.disableHints, isFalse);
expect(options.lints, isFalse);
expect(options.displayVersion, isFalse);
+ expect(options.enableSuperMixins, isFalse);
expect(options.infosAreFatal, isFalse);
expect(options.ignoreUnrecognizedFlags, isFalse);
expect(options.log, isFalse);
@@ -95,6 +96,12 @@
expect(options.disableCacheFlushing, isTrue);
});
+ test('enable super mixins', () {
+ CommandLineOptions options = CommandLineOptions.parse(
+ ['--dart-sdk', '.', '--supermixin', 'foo.dart']);
+ expect(options.enableSuperMixins, isTrue);
+ });
+
test('hintsAreFatal', () {
CommandLineOptions options = CommandLineOptions.parse(
['--dart-sdk', '.', '--fatal-hints', 'foo.dart']);
diff --git a/pkg/analyzer_cli/test/super_mixin_test.dart b/pkg/analyzer_cli/test/super_mixin_test.dart
new file mode 100644
index 0000000..56903f0
--- /dev/null
+++ b/pkg/analyzer_cli/test/super_mixin_test.dart
@@ -0,0 +1,71 @@
+// Copyright (c) 2015, 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.
+
+library analyzer_cli.test.super_mixin;
+
+import 'dart:io';
+
+import 'package:analyzer_cli/src/ansi.dart' as ansi;
+import 'package:analyzer_cli/src/driver.dart' show Driver, errorSink, outSink;
+import 'package:path/path.dart' as path;
+import 'package:test/test.dart';
+
+import 'utils.dart';
+
+/// End-to-end test for --supermixins.
+///
+/// Most super mixin tests are in Analyzer, but this verifies the option is
+/// working and producing extra errors as expected.
+///
+/// Generally we don't want a lot of cases here as it requires spinning up a
+/// full analysis context.
+void main() {
+ group('--supermixins', () {
+ StringSink savedOutSink, savedErrorSink;
+ int savedExitCode;
+
+ setUp(() {
+ ansi.runningTests = true;
+ savedOutSink = outSink;
+ savedErrorSink = errorSink;
+ savedExitCode = exitCode;
+ outSink = new StringBuffer();
+ errorSink = new StringBuffer();
+ });
+
+ tearDown(() {
+ outSink = savedOutSink;
+ errorSink = savedErrorSink;
+ exitCode = savedExitCode;
+ ansi.runningTests = false;
+ });
+
+ test('produces errors when option absent', () async {
+ var testPath = path.join(testDirectory, 'data/super_mixin_example.dart');
+ await new Driver(isTesting: true).start([testPath]);
+
+ expect(exitCode, 3);
+ var stdout = outSink.toString();
+ expect(
+ stdout,
+ contains(
+ "error • The class 'C' can't be used as a mixin because it extends a class other than Object"));
+ expect(
+ stdout,
+ contains(
+ "error • The class 'C' can't be used as a mixin because it references 'super'"));
+ expect(stdout, contains('2 errors found.'));
+ expect(errorSink.toString(), '');
+ });
+
+ test('produces no errors when option present', () async {
+ var testPath = path.join(testDirectory, 'data/super_mixin_example.dart');
+ await new Driver(isTesting: true).start(['--supermixin', testPath]);
+
+ expect(exitCode, 0);
+ var stdout = outSink.toString();
+ expect(stdout, contains('No issues found'));
+ });
+ });
+}
diff --git a/pkg/front_end/pubspec.yaml b/pkg/front_end/pubspec.yaml
index 478a4d8..e98e165 100644
--- a/pkg/front_end/pubspec.yaml
+++ b/pkg/front_end/pubspec.yaml
@@ -1,7 +1,7 @@
name: front_end
# Currently, front_end API is not stable and users should not
# depend on semver semantics when depending on this package.
-version: 0.1.6
+version: 0.1.6+1
author: Dart Team <misc@dartlang.org>
description: Front end for compilation of Dart code.
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/front_end
@@ -11,14 +11,14 @@
charcode: '^1.1.1'
convert: '^2.0.1'
crypto: '^2.0.2'
- kernel: 0.3.6
+ kernel: 0.3.6+1
meta: '^1.1.1'
package_config: '^1.0.1'
path: '^1.3.9'
source_span: '^1.2.3'
yaml: '^2.1.12'
dev_dependencies:
- analyzer: '^0.33.0'
+ analyzer: '^0.33.1'
args: '>=0.13.0 <2.0.0'
build_integration:
path: ../build_integration
diff --git a/pkg/kernel/pubspec.yaml b/pkg/kernel/pubspec.yaml
index 0f1e39a..8cb1942 100644
--- a/pkg/kernel/pubspec.yaml
+++ b/pkg/kernel/pubspec.yaml
@@ -1,7 +1,7 @@
name: kernel
# Currently, kernel API is not stable and users should
# not depend on semver semantics when depending on this package.
-version: 0.3.6
+version: 0.3.6+1
author: Dart Team <misc@dartlang.org>
description: Dart IR (Intermediate Representation)
homepage: https://github.com/dart-lang/sdk/tree/master/pkg/kernel
@@ -13,7 +13,7 @@
logging: ^0.11.2
package_config: ^1.0.0
dev_dependencies:
- front_end: 0.1.6
+ front_end: 0.1.6+1
test: ^1.3.4
stack_trace: ^1.6.6
test_reflective_loader: ^0.1.0