Version 1.21.0-dev.11.3
Cherry-pick b4820d6a631496afe42d61a7e6e9ffe46711447e into dev
Cherry-pick 24ffedcef0a6661b3de31867780b33b8c179d69c into dev
Cherry-pick 3276a2ea26d67f251f9cc3b42a71a58e82c313cc into dev
Cherry-pick ab6bc6dbfd7bcadfddd6b312926590f6dd832267 into dev
Cherry-pick 2fcf38a156b11bbe1c4c3ace25eac7730eba8ce1 into dev
diff --git a/DEPS b/DEPS
index 44e124f..4f5d541 100644
--- a/DEPS
+++ b/DEPS
@@ -120,7 +120,7 @@
"WebCore_rev": "@a86fe28efadcfc781f836037a80f27e22a5dad17",
"when_tag": "@0.2.0+2",
"which_tag": "@0.1.3+1",
- "yaml_tag": "@2.1.12",
+ "yaml_tag": "@2.1.11",
"zlib_rev": "@c3d0a6190f2f8c924a05ab6cc97b8f975bddd33f",
}
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index e179dda..c8afeae 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -330,7 +330,8 @@
final Set<String> priorityFiles = new Set<String>();
/**
- * The cached results units for [priorityFiles].
+ * The cached results for [priorityFiles].
+ * These results must have not `null` units.
*/
final Map<String, nd.AnalysisResult> priorityFileResults = {};
@@ -1798,7 +1799,8 @@
// TODO(scheglov) send server status
});
analysisDriver.results.listen((result) {
- if (analysisServer.priorityFiles.contains(result.path)) {
+ if (analysisServer.priorityFiles.contains(result.path) &&
+ result.unit != null) {
analysisServer.priorityFileResults[result.path] = result;
}
_runDelayed(() {
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index 58137c6..1cde3a7 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -141,17 +141,19 @@
List<Assist> assists;
if (server.options.enableNewAnalysisDriver) {
AnalysisResult result = await server.getAnalysisResult(params.file);
- CompilationUnit unit = result.unit;
- DartAssistContext dartAssistContext = new _DartAssistContextForValues(
- unit.element.source,
- params.offset,
- params.length,
- unit.element.context,
- unit);
- try {
- AssistProcessor processor = new AssistProcessor(dartAssistContext);
- assists = await processor.compute();
- } catch (_) {}
+ if (result != null) {
+ CompilationUnit unit = result.unit;
+ DartAssistContext dartAssistContext = new _DartAssistContextForValues(
+ unit.element.source,
+ params.offset,
+ params.length,
+ unit.element.context,
+ unit);
+ try {
+ AssistProcessor processor = new AssistProcessor(dartAssistContext);
+ assists = await processor.compute();
+ } catch (_) {}
+ }
} else {
ContextSourcePair pair = server.getContextSourcePair(params.file);
engine.AnalysisContext context = pair.context;
@@ -179,49 +181,50 @@
List<AnalysisErrorFixes> errorFixesList = <AnalysisErrorFixes>[];
if (server.options.enableNewAnalysisDriver) {
AnalysisResult result = await server.getAnalysisResult(file);
- CompilationUnit unit = result.unit;
- LineInfo lineInfo = result.lineInfo;
- int requestLine = lineInfo.getLocation(offset).lineNumber;
- for (engine.AnalysisError error in result.errors) {
- int errorLine = lineInfo.getLocation(error.offset).lineNumber;
- if (errorLine == requestLine) {
- var context = new _DartFixContextImpl(
- server.resourceProvider, unit.element.context, unit, error);
- List<Fix> fixes =
- await new DefaultFixContributor().internalComputeFixes(context);
- if (fixes.isNotEmpty) {
- AnalysisError serverError =
- newAnalysisError_fromEngine(lineInfo, error);
- AnalysisErrorFixes errorFixes = new AnalysisErrorFixes(serverError);
- errorFixesList.add(errorFixes);
- fixes.forEach((fix) {
- errorFixes.fixes.add(fix.change);
- });
+ if (result != null) {
+ CompilationUnit unit = result.unit;
+ LineInfo lineInfo = result.lineInfo;
+ int requestLine = lineInfo.getLocation(offset).lineNumber;
+ for (engine.AnalysisError error in result.errors) {
+ int errorLine = lineInfo.getLocation(error.offset).lineNumber;
+ if (errorLine == requestLine) {
+ var context = new _DartFixContextImpl(
+ server.resourceProvider, unit.element.context, unit, error);
+ List<Fix> fixes =
+ await new DefaultFixContributor().internalComputeFixes(context);
+ if (fixes.isNotEmpty) {
+ AnalysisError serverError =
+ newAnalysisError_fromEngine(lineInfo, error);
+ AnalysisErrorFixes errorFixes =
+ new AnalysisErrorFixes(serverError);
+ errorFixesList.add(errorFixes);
+ fixes.forEach((fix) {
+ errorFixes.fixes.add(fix.change);
+ });
+ }
}
}
}
} else {
CompilationUnit unit = await server.getResolvedCompilationUnit(file);
engine.AnalysisErrorInfo errorInfo = server.getErrors(file);
- if (errorInfo != null) {
- LineInfo lineInfo = errorInfo.lineInfo;
- if (lineInfo != null) {
- int requestLine = lineInfo.getLocation(offset).lineNumber;
- for (engine.AnalysisError error in errorInfo.errors) {
- int errorLine = lineInfo.getLocation(error.offset).lineNumber;
- if (errorLine == requestLine) {
- List<Fix> fixes = await computeFixes(server.serverPlugin,
- server.resourceProvider, unit.element.context, error);
- if (fixes.isNotEmpty) {
- AnalysisError serverError =
- newAnalysisError_fromEngine(lineInfo, error);
- AnalysisErrorFixes errorFixes =
- new AnalysisErrorFixes(serverError);
- errorFixesList.add(errorFixes);
- fixes.forEach((fix) {
- errorFixes.fixes.add(fix.change);
- });
- }
+ LineInfo lineInfo = errorInfo?.lineInfo;
+ if (unit != null && errorInfo != null && lineInfo != null) {
+ int requestLine = lineInfo.getLocation(offset).lineNumber;
+ for (engine.AnalysisError error in errorInfo.errors) {
+ int errorLine = lineInfo.getLocation(error.offset).lineNumber;
+ if (errorLine == requestLine) {
+ List<Fix> fixes = await computeFixes(server.serverPlugin,
+ server.resourceProvider, unit.element.context, error);
+ if (fixes.isNotEmpty) {
+ AnalysisError serverError =
+ newAnalysisError_fromEngine(lineInfo, error);
+ AnalysisErrorFixes errorFixes =
+ new AnalysisErrorFixes(serverError);
+ errorFixesList.add(errorFixes);
+ fixes.forEach((fix) {
+ errorFixes.fixes.add(fix.change);
+ });
}
}
}
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index 409960d..58b4ba0 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -6846,6 +6846,14 @@
keyword != Keyword.OPERATOR &&
(_tokenMatchesIdentifier(next) ||
_tokenMatches(next, TokenType.LT))) {
+ Token afterTypeParameters = _skipTypeParameterList(next);
+ if (afterTypeParameters != null &&
+ _tokenMatches(afterTypeParameters, TokenType.OPEN_PAREN)) {
+ // If the identifier is followed by type parameters and a parenthesis,
+ // then the identifier is the name of a generic method, not a return
+ // type.
+ return null;
+ }
return parseReturnType();
}
Token next2 = next.next;
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index 6ce609f..87feeb2 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -1918,13 +1918,6 @@
[ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN]);
}
- void test_missingIdentifier_functionDeclaration_returnTypeWithoutName() {
- createParser('A<T> () {}');
- Statement statement = parser.parseFunctionDeclarationStatement();
- expectNotNullIfNoErrors(statement);
- listener.assertErrorsWithCodes([ParserErrorCode.MISSING_IDENTIFIER]);
- }
-
void test_missingIdentifier_inEnum() {
createParser('enum E {, TWO}');
EnumDeclaration declaration =
@@ -9553,6 +9546,17 @@
isNotNull);
}
+ void test_parseFunctionDeclarationStatement_typeParameters_noReturnType() {
+ createParser('f<E>(E p) => p * 2;');
+ FunctionDeclarationStatement statement =
+ parser.parseFunctionDeclarationStatement();
+ expectNotNullIfNoErrors(statement);
+ listener.assertNoErrors();
+ expect(statement.functionDeclaration, isNotNull);
+ expect(statement.functionDeclaration.functionExpression.typeParameters,
+ isNotNull);
+ }
+
void test_parseFunctionExpression_body_inExpression() {
createParser('(int i) => i++');
FunctionExpression expression = parser.parseFunctionExpression();
@@ -11855,7 +11859,6 @@
isNotNull);
}
- @failingTest
void test_parseStatement_functionDeclaration_noReturnType_typeParameters() {
createParser('f<E>(a, b) {};');
Statement statement = parser.parseStatement2();
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 61660f0..f13d562 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -2774,12 +2774,17 @@
// a BoundedType itself.
CollectTypeArguments(cls, Type::Cast(mixin_super_type), type_args);
AbstractType& mixin_type = AbstractType::Handle(zone);
- Class& mixin_type_class = Class::Handle(zone);
Class& mixin_app_class = Class::Handle(zone);
+ Class& mixin_super_type_class = Class::Handle(zone);
+ Class& mixin_type_class = Class::Handle(zone);
+ Library& mixin_super_type_library = Library::Handle(zone);
+ Library& mixin_type_library = Library::Handle(zone);
String& mixin_app_class_name = String::Handle(zone);
String& mixin_type_class_name = String::Handle(zone);
AbstractType& super_type_arg = AbstractType::Handle(zone);
AbstractType& mixin_type_arg = AbstractType::Handle(zone);
+ Type& generic_mixin_type = Type::Handle(zone);
+ Array& interfaces = Array::Handle(zone);
const intptr_t depth = mixin_app_type.Depth();
for (intptr_t i = 0; i < depth; i++) {
mixin_type = mixin_app_type.MixinTypeAt(i);
@@ -2787,6 +2792,13 @@
ResolveType(cls, mixin_type);
ASSERT(mixin_type.HasResolvedTypeClass()); // Even if malformed.
ASSERT(mixin_type.IsType());
+ if (mixin_type.IsMalformedOrMalbounded()) {
+ ReportError(Error::Handle(zone, mixin_type.error()));
+ }
+ if (mixin_type.IsDynamicType()) {
+ ReportError(cls, cls.token_pos(), "class '%s' may not mixin 'dynamic'",
+ String::Handle(zone, cls.Name()).ToCString());
+ }
const intptr_t num_super_type_args = type_args.Length();
CollectTypeArguments(cls, Type::Cast(mixin_type), type_args);
@@ -2812,8 +2824,19 @@
}
// The name of the mixin application class is a combination of
- // the super class name and mixin class name.
+ // the super class name and mixin class name, as well as their respective
+ // library private keys if their library is different than the library of
+ // the mixin application class.
+ // Note that appending the library url would break naming conventions (e.g.
+ // no period in the class name).
mixin_app_class_name = mixin_super_type.ClassName();
+ mixin_super_type_class = mixin_super_type.type_class();
+ mixin_super_type_library = mixin_super_type_class.library();
+ if (mixin_super_type_library.raw() != library.raw()) {
+ mixin_app_class_name = String::Concat(
+ mixin_app_class_name,
+ String::Handle(zone, mixin_super_type_library.private_key()));
+ }
mixin_app_class_name =
String::Concat(mixin_app_class_name, Symbols::Ampersand());
// If the type parameters are shared between the super type and the mixin
@@ -2824,6 +2847,13 @@
String::Concat(mixin_app_class_name, Symbols::Ampersand());
}
mixin_type_class_name = mixin_type.ClassName();
+ mixin_type_class = mixin_type.type_class();
+ mixin_type_library = mixin_type_class.library();
+ if (mixin_type_library.raw() != library.raw()) {
+ mixin_type_class_name = String::Concat(
+ mixin_type_class_name,
+ String::Handle(zone, mixin_type_library.private_key()));
+ }
mixin_app_class_name =
String::Concat(mixin_app_class_name, mixin_type_class_name);
mixin_app_class = library.LookupLocalClass(mixin_app_class_name);
@@ -2832,15 +2862,14 @@
mixin_app_class = Class::New(library, mixin_app_class_name, script,
mixin_type.token_pos());
mixin_app_class.set_super_type(mixin_super_type);
- mixin_type_class = mixin_type.type_class();
- const Type& generic_mixin_type = Type::Handle(
- zone, Type::New(mixin_type_class, Object::null_type_arguments(),
- mixin_type.token_pos()));
+ generic_mixin_type =
+ Type::New(mixin_type_class, Object::null_type_arguments(),
+ mixin_type.token_pos());
mixin_app_class.set_mixin(generic_mixin_type);
// Add the mixin type to the list of interfaces that the mixin application
// class implements. This is necessary so that cycle check work at
// compile time (type arguments are ignored by that check).
- const Array& interfaces = Array::Handle(zone, Array::New(1));
+ interfaces = Array::New(1);
interfaces.SetAt(0, generic_mixin_type);
ASSERT(mixin_app_class.interfaces() == Object::empty_array().raw());
mixin_app_class.set_interfaces(interfaces);
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index f9fd601..1a91fcb 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -2071,7 +2071,9 @@
}
// Now that type parameters are declared, the result type can be resolved.
- ResolveType(ClassFinalizer::kResolveTypeParameters, &result_type);
+ ResolveType(is_top_level_ ? ClassFinalizer::kResolveTypeParameters
+ : ClassFinalizer::kCanonicalize,
+ &result_type);
ASSERT(CurrentToken() == Token::kLPAREN);
ParamList func_params;
@@ -2108,11 +2110,12 @@
} else {
if (!parameter.type->IsFinalized()) {
AbstractType& type = AbstractType::ZoneHandle(Z, parameter.type->raw());
- ResolveType(ClassFinalizer::kResolveTypeParameters, &type);
- if (!is_top_level_) {
- type = ClassFinalizer::FinalizeType(
- Class::Handle(Z, innermost_function().origin()), type,
- ClassFinalizer::kCanonicalize);
+ if (is_top_level_) {
+ ResolveType(ClassFinalizer::kResolveTypeParameters, &type);
+ } else {
+ ResolveType(ClassFinalizer::kCanonicalize, &type);
+ type = ClassFinalizer::FinalizeType(current_class(), type,
+ ClassFinalizer::kCanonicalize);
}
parameter.type = &type;
}
@@ -7673,7 +7676,7 @@
if (!found_func && !result_type.IsFinalized()) {
// Now that type parameters are declared, the result type can be resolved
// and finalized.
- ResolveType(ClassFinalizer::kResolveTypeParameters, &result_type);
+ ResolveType(ClassFinalizer::kCanonicalize, &result_type);
result_type = ClassFinalizer::FinalizeType(current_class(), result_type,
ClassFinalizer::kCanonicalize);
function.set_result_type(result_type);
@@ -11917,6 +11920,8 @@
// The referenced class may not have been parsed yet. It would be wrong
// to resolve it too early to an imported class of the same name. Only
// resolve the class when a finalized type is requested.
+ // Note that when compiling a cloned mixin function, library_ may be
+ // different than current_class's library.
if (finalization > ClassFinalizer::kResolveTypeParameters) {
resolved_type_class = library_.LookupClass(unresolved_class_name);
}
diff --git a/tests/language/regress_27957_lib1.dart b/tests/language/regress_27957_lib1.dart
new file mode 100644
index 0000000..7a06ff3
--- /dev/null
+++ b/tests/language/regress_27957_lib1.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2016, 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 regress_27957_lib1;
+
+class Superclass {
+ int m() => 1;
+}
diff --git a/tests/language/regress_27957_lib2.dart b/tests/language/regress_27957_lib2.dart
new file mode 100644
index 0000000..24097d0
--- /dev/null
+++ b/tests/language/regress_27957_lib2.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2016, 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 regress_27957_lib2;
+
+class Superclass {
+ int m() => 2;
+}
diff --git a/tests/language/regress_27957_test.dart b/tests/language/regress_27957_test.dart
new file mode 100644
index 0000000..c9cb543
--- /dev/null
+++ b/tests/language/regress_27957_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+import 'regress_27957_lib1.dart' as s1;
+import 'regress_27957_lib2.dart' as s2;
+
+class Mixin {}
+class C1 = s1.Superclass with Mixin;
+class C2 = s2.Superclass with Mixin;
+
+main() {
+ var c1 = new C1(), c2 = new C2();
+ Expect.equals(1, c1.m());
+ Expect.equals(2, c2.m());
+}
diff --git a/tools/VERSION b/tools/VERSION
index 7b36926..392d057 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -29,4 +29,4 @@
MINOR 21
PATCH 0
PRERELEASE 11
-PRERELEASE_PATCH 2
+PRERELEASE_PATCH 3