Version 1.1.0-dev.5.9
svn merge -c 31467 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
svn merge -c 31482 https://dart.googlecode.com/svn/branches/bleeding_edge trunk
R=kasperl@google.com
Review URL: https://codereview.chromium.org//136753002
git-svn-id: http://dart.googlecode.com/svn/trunk@31736 260f80e4-7a28-3924-810f-c04153c831b5
diff --git a/sdk/lib/_internal/compiler/implementation/dart_types.dart b/sdk/lib/_internal/compiler/implementation/dart_types.dart
index a4603f0..5f14cc2 100644
--- a/sdk/lib/_internal/compiler/implementation/dart_types.dart
+++ b/sdk/lib/_internal/compiler/implementation/dart_types.dart
@@ -60,6 +60,11 @@
*/
DartType subst(Link<DartType> arguments, Link<DartType> parameters);
+ /// Performs the substitution of the type arguments of [type] for their
+ /// corresponding type variables in this type.
+ DartType substByContext(GenericType type) =>
+ subst(type.typeArguments, type.element.typeVariables);
+
/**
* Returns the unaliased type of this type.
*
@@ -797,8 +802,7 @@
compiler.resolveTypedef(element);
element.checkCyclicReference(compiler);
DartType definition = element.alias.unalias(compiler);
- TypedefType declaration = element.computeType(compiler);
- return definition.subst(typeArguments, declaration.typeArguments);
+ return definition.substByContext(this);
}
int get hashCode => super.hashCode;
@@ -889,10 +893,8 @@
type = element.computeType(compiler);
}
if (!declarer.element.typeVariables.isEmpty) {
- type = type.subst(declarer.typeArguments,
- declarer.element.typeVariables);
- type = type.subst(receiver.typeArguments,
- receiver.element.typeVariables);
+ type = type.substByContext(declarer);
+ type = type.substByContext(receiver);
}
cachedType = type;
}
@@ -1305,8 +1307,7 @@
Link<DartType> typeVariables = element.typeVariables;
while (!typeVariables.isEmpty && !typeArguments.isEmpty) {
TypeVariableType typeVariable = typeVariables.head;
- DartType bound = typeVariable.element.bound.subst(
- type.typeArguments, element.typeVariables);
+ DartType bound = typeVariable.element.bound.substByContext(type);
DartType typeArgument = typeArguments.head;
checkTypeVariableBound(type, typeArgument, typeVariable, bound);
typeVariables = typeVariables.tail;
@@ -1501,13 +1502,10 @@
/// Returns the set of supertypes of [type] at depth [depth].
Set<DartType> getSupertypesAtDepth(InterfaceType type, int depth) {
- ClassElement cls = type.element;
- OrderedTypeSet types = cls.allSupertypesAndSelf;
- Link<DartType> typeVariables = cls.typeVariables;
- Link<DartType> typeArguments = type.typeArguments;
+ OrderedTypeSet types = type.element.allSupertypesAndSelf;
Set<DartType> set = new Set<DartType>();
- types.forEach(depth, (DartType type) {
- set.add(type.subst(typeArguments, typeVariables));
+ types.forEach(depth, (DartType supertype) {
+ set.add(supertype.substByContext(type));
});
return set;
}
diff --git a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
index f72260c..78ad547 100644
--- a/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
+++ b/sdk/lib/_internal/compiler/implementation/elements/modelx.dart
@@ -1518,8 +1518,7 @@
assert(invariant(this, redirectionTargetType != null,
message: 'Redirection target type has not yet been computed for '
'$this.'));
- return redirectionTargetType.subst(newType.typeArguments,
- newType.element.typeVariables);
+ return redirectionTargetType.substByContext(newType);
}
/**
@@ -1671,6 +1670,8 @@
return functionSignature = compiler.objectClass.localLookup('')
.computeSignature(compiler);
}
+ // TODO(johnniwinther): Ensure that the function signature (and with it the
+ // function type) substitutes type variables correctly.
return functionSignature = superMember.computeSignature(compiler);
}
diff --git a/sdk/lib/_internal/compiler/implementation/js_emitter/container_builder.dart b/sdk/lib/_internal/compiler/implementation/js_emitter/container_builder.dart
index c3a33a5..688a7eb 100644
--- a/sdk/lib/_internal/compiler/implementation/js_emitter/container_builder.dart
+++ b/sdk/lib/_internal/compiler/implementation/js_emitter/container_builder.dart
@@ -413,9 +413,7 @@
expressions.add(code);
- // TODO(ahe): Remove comments from output.
- List tearOffInfo =
- [new jsAst.LiteralString('$callSelectorString /* tearOffInfo */')];
+ List tearOffInfo = [new jsAst.LiteralString('$callSelectorString')];
if (needsStubs || canTearOff) {
addParameterStubs(member, (Selector selector, jsAst.Fun function) {
@@ -447,8 +445,7 @@
callSelectors.contains(callSelector)) {
callSelectorString = '"${namer.invocationName(callSelector)}"';
}
- tearOffInfo.add(
- new jsAst.LiteralString('$callSelectorString /* tearOffInfo */'));
+ tearOffInfo.add(new jsAst.LiteralString('$callSelectorString'));
}, canTearOff);
}
diff --git a/sdk/lib/_internal/compiler/implementation/resolution/members.dart b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
index a396889..455a091 100644
--- a/sdk/lib/_internal/compiler/implementation/resolution/members.dart
+++ b/sdk/lib/_internal/compiler/implementation/resolution/members.dart
@@ -645,8 +645,7 @@
InterfaceType factoryType =
treeElements.getType(redirectionNode.expression);
- targetType = targetType.subst(factoryType.typeArguments,
- factoryType.element.typeVariables);
+ targetType = targetType.substByContext(factoryType);
factory.redirectionTarget = target;
factory.redirectionTargetType = targetType;
}
@@ -2738,7 +2737,7 @@
} else if (target.modifiers.isFinal() ||
target.modifiers.isConst() ||
(target.isFunction() &&
- Elements.isStaticOrTopLevelFunction(target) &&
+ Elements.isStaticOrTopLevelFunction(target) &&
!target.isSetter())) {
if (target.isFunction()) {
setter = warnAndCreateErroneousElement(
@@ -4166,17 +4165,14 @@
*/
void addAllSupertypes(OrderedTypeSetBuilder allSupertypes,
InterfaceType type) {
- Link<DartType> typeArguments = type.typeArguments;
ClassElement classElement = type.element;
- Link<DartType> typeVariables = classElement.typeVariables;
Link<DartType> supertypes = classElement.allSupertypes;
assert(invariant(element, supertypes != null,
message: "Supertypes not computed on $classElement "
"during resolution of $element"));
while (!supertypes.isEmpty) {
DartType supertype = supertypes.head;
- allSupertypes.add(compiler,
- supertype.subst(typeArguments, typeVariables));
+ allSupertypes.add(compiler, supertype.substByContext(type));
supertypes = supertypes.tail;
}
}
diff --git a/sdk/lib/_internal/compiler/implementation/typechecker.dart b/sdk/lib/_internal/compiler/implementation/typechecker.dart
index 5dd026a..ff499fc 100644
--- a/sdk/lib/_internal/compiler/implementation/typechecker.dart
+++ b/sdk/lib/_internal/compiler/implementation/typechecker.dart
@@ -1334,10 +1334,19 @@
if (Elements.isUnresolved(constructor)) return types.dynamicType;
DartType constructorType = constructor.computeType(compiler);
if (identical(type.kind, TypeKind.INTERFACE)) {
- InterfaceType interfaceType = type;
- constructorType = constructorType.subst(
- interfaceType.typeArguments,
- interfaceType.element.typeVariables);
+ if (constructor.isSynthesized) {
+ // TODO(johnniwinther): Remove this when synthesized constructors handle
+ // type variables correctly.
+ InterfaceType interfaceType = type;
+ ClassElement receiverElement = interfaceType.element;
+ while (receiverElement.isMixinApplication) {
+ receiverElement = receiverElement.supertype.element;
+ }
+ constructorType = constructorType.substByContext(
+ interfaceType.asInstanceOf(receiverElement));
+ } else {
+ constructorType = constructorType.substByContext(type);
+ }
}
return constructorType;
}
diff --git a/tests/compiler/dart2js/memory_compiler.dart b/tests/compiler/dart2js/memory_compiler.dart
index 9366565..c33e7f0 100644
--- a/tests/compiler/dart2js/memory_compiler.dart
+++ b/tests/compiler/dart2js/memory_compiler.dart
@@ -84,7 +84,7 @@
bool showDiagnostics: true}) {
Uri script = currentDirectory.resolveUri(Platform.script);
Uri libraryRoot = script.resolve('../../../sdk/');
- Uri packageRoot = script.resolve('./packages/');
+ Uri packageRoot = currentDirectory.resolve('${Platform.packageRoot}/');
MemorySourceFileProvider provider;
var readStringFromUri;
diff --git a/tests/compiler/dart2js/mixin_language_test.dart b/tests/compiler/dart2js/mixin_language_test.dart
new file mode 100644
index 0000000..f4be3b2
--- /dev/null
+++ b/tests/compiler/dart2js/mixin_language_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2013, 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.
+
+// Test that dart2js produces the expected static type warnings for these
+// language tests. This ensures that the analyzer and dart2js agrees on the
+// tests.
+
+import 'warnings_checker.dart';
+
+/// Map from test files to a map of their expected status. If the status map is
+/// `null` no warnings must be missing or unexpected, otherwise the status map
+/// can contain a list of line numbers for keys 'missing' and 'unexpected' for
+/// the warnings of each category.
+const Map<String, dynamic> TESTS = const {
+ 'language/typevariable_substitution2_test.dart': null,
+};
+
+void main(List<String> arguments) {
+ checkWarnings(TESTS, arguments);
+}
diff --git a/tests/compiler/dart2js/warnings_checker.dart b/tests/compiler/dart2js/warnings_checker.dart
index 1105b38..aa84570 100644
--- a/tests/compiler/dart2js/warnings_checker.dart
+++ b/tests/compiler/dart2js/warnings_checker.dart
@@ -16,10 +16,11 @@
import '../../../sdk/lib/_internal/compiler/implementation/util/uri_extras.dart';
import 'dart:convert';
-void checkWarnings(Map<String, dynamic> tests) {
+void checkWarnings(Map<String, dynamic> tests, [List<String> arguments]) {
bool isWindows = Platform.isWindows;
Uri script = currentDirectory.resolveUri(Platform.script);
bool warningsMismatch = false;
+ bool verbose = arguments != null && arguments.contains('-v');
asyncTest(() => Future.forEach(tests.keys, (String test) {
Uri uri = script.resolve('../../$test');
String source = UTF8.decode(readAll(uriPathToNative(uri.path)));
@@ -38,7 +39,7 @@
var compiler = compilerFor(const {},
diagnosticHandler: collector,
options: ['--analyze-only'],
- showDiagnostics: false);
+ showDiagnostics: verbose);
return compiler.run(uri).then((_) {
Map<String, List<int>> statusMap = tests[test];
// Line numbers with known unexpected warnings.
diff --git a/tests/language/checked_mode_helper.dart b/tests/language/checked_mode_helper.dart
new file mode 100644
index 0000000..695222d
--- /dev/null
+++ b/tests/language/checked_mode_helper.dart
@@ -0,0 +1,54 @@
+// Copyright (c) 2013, 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 checked_mode_helper;
+
+import 'package:expect/expect.dart';
+
+/// Returns `true` if the program is running in checked mode.
+bool inCheckedMode() {
+ try {
+ var i = 42;
+ String s = i;
+ } on TypeError catch (e) {
+ return true;
+ }
+ return false;
+}
+
+/// Checks that a dynamic type error is thrown if and only if [f] is executed in
+/// checked mode and [expectTypeError] is `true`.
+void testDynamicTypeError(bool expectTypeError, f(), [String message]) {
+ if (expectTypeError) {
+ checkDynamicTypeError(f, message);
+ } else {
+ checkNoDynamicTypeError(f, message);
+ }
+}
+
+/// Checks that a dynamic type error is thrown if and only if [f] is executed in
+/// checked mode.
+void checkDynamicTypeError(f(), [String message]) {
+ message = message != null ? ': $message' : '';
+ try {
+ f();
+ Expect.isFalse(inCheckedMode(),
+ 'Missing type error in checked mode$message.');
+ } on TypeError catch (e) {
+ Expect.isTrue(inCheckedMode(),
+ 'Unexpected type error in production mode.');
+ }
+}
+
+/// Checks that no dynamic type error is thrown when [f] is executed regardless
+/// of execution mode.
+void checkNoDynamicTypeError(f(), [String message]) {
+ message = message != null ? ': $message' : '';
+ try {
+ f();
+ } on TypeError catch (e) {
+ String mode = inCheckedMode() ? 'checked mode' : 'production mode';
+ Expect.fail('Unexpected type error in $mode$message.');
+ }
+}
diff --git a/tests/language/language_analyzer.status b/tests/language/language_analyzer.status
index ee85f4c..b10f1a2 100644
--- a/tests/language/language_analyzer.status
+++ b/tests/language/language_analyzer.status
@@ -176,6 +176,9 @@
proxy_test/05: StaticWarning # Issue 15467
proxy_test/06: StaticWarning # Issue 15467
+# test issue 15714
+typevariable_substitution2_test/01: StaticWarning # Issue 15714
+
abstract_exact_selector_test: StaticWarning
abstract_getter_test: StaticWarning
abstract_object_method_test: StaticWarning
diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status
index e7da090..3ce7bcc 100644
--- a/tests/language/language_analyzer2.status
+++ b/tests/language/language_analyzer2.status
@@ -176,6 +176,9 @@
proxy_test/05: StaticWarning # Issue 15467
proxy_test/06: StaticWarning # Issue 15467
+# test issue 15714
+typevariable_substitution2_test/01: StaticWarning # Issue 15714
+
abstract_exact_selector_test: StaticWarning
abstract_getter_test: StaticWarning
abstract_object_method_test: StaticWarning
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 1942eb0..18a5a57 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -50,6 +50,8 @@
malbounded_type_test_test/03: Fail # Issue 14121
malbounded_type_test_test/04: Fail # Issue 14121
default_factory2_test/01: Fail # Issue 14121
+typevariable_substitution2_test/01: CompileTimeError # Issue 15875
+typevariable_substitution2_test/02: CompileTimeError # Issue 15875
[ $compiler == dart2js && $unchecked ]
type_checks_in_factory_method_test: RuntimeError # Issue 12746
diff --git a/tests/language/typevariable_substitution2_test.dart b/tests/language/typevariable_substitution2_test.dart
new file mode 100644
index 0000000..dffa913
--- /dev/null
+++ b/tests/language/typevariable_substitution2_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2013, 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.
+
+// Test that mixins don't interfere with type variable substitution.
+
+import 'checked_mode_helper.dart';
+
+class B<T> {
+ B(T x);
+}
+
+class M {}
+
+class A<T> extends B<T> with M {
+ A(T x) : super(x); // This line must be warning free.
+}
+
+class C<T> = B<T> with M;
+
+
+main() {
+ new A(null);
+ new C<String>(''); /// 01: ok
+ checkDynamicTypeError(() => new C<String>(0)); /// 02: static type warning
+}
diff --git a/tools/VERSION b/tools/VERSION
index 27e6014..6546847 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -28,4 +28,4 @@
MINOR 1
PATCH 0
PRERELEASE 5
-PRERELEASE_PATCH 8
+PRERELEASE_PATCH 9