blob: 57dbddb109696580c2d2ab788fb28795948e4b48 [file] [log] [blame]
// 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:async_helper/async_helper.dart';
import 'package:compiler/src/commandline_options.dart';
import 'package:compiler/src/diagnostics/messages.dart';
import 'package:compiler/src/io/source_file.dart';
import 'package:expect/expect.dart';
import 'memory_compiler.dart';
import 'memory_source_file_helper.dart';
const List<Test> TESTS = const <Test>[
const Test(
'''
class A { A(b); }
class B extends A {
a() {}
lot() {}
of() {}
var members;
}
main() => new B();''',
const {
MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT: '''
class B extends A {
^^^^^^^^^^^^^^^^^'''
}),
const Test(
'''
class I {}
class A { A(b); }
class B extends A implements I {
a() {}
lot() {}
of() {}
var members;
}
main() => new B();''',
const {
MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT: '''
class B extends A implements I {
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^'''
}),
const Test(
'''
class M<T> {}
class A { A(b); }
class B extends A with M<int> {
a() {}
lot() {}
of() {}
var members;
}
main() => new B();''',
const {
MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT: '''
class B extends A with M<int> {
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^'''
}),
const Test(
'''
class A { A(b); }
class B
extends A {
a() {}
lot() {}
of() {}
var members;
}
main() => new B();''',
const {
MessageKind.NO_MATCHING_CONSTRUCTOR_FOR_IMPLICIT: '''
class B
extends A {
'''
}),
const Test(
'''
void foo(int a) {
// a
// non-empty
// body
}
main() => foo('');''',
const {
MessageKind.THIS_IS_THE_METHOD: '''
void foo(int a) {
^^^^^^^^^^^^^^^'''
}),
const Test(
'''
void foo(int a,
int b) {
// a
// non-empty
// body
}
main() => foo('', 0);''',
const {
MessageKind.THIS_IS_THE_METHOD: '''
void foo(int a,
int b) {
'''
}),
const Test(
'''
class A {
int foo() {
// a
// non-empty
// body
}
}
class B extends A {
int get foo {
// a
// non-empty
// body
return 0;
}
}
main() => new B();''',
const {
MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER: '''
int get foo {
^^^^^^^^^^^''',
MessageKind.CANNOT_OVERRIDE_METHOD_WITH_GETTER_CONT: '''
int foo() {
^^^^^^^^^'''
}),
];
class Test {
final String code;
final Map<MessageKind, String> kindToSpan;
const Test(this.code, this.kindToSpan);
}
const String MARKER = '---marker---';
main() {
asyncTest(() async {
var cachedCompiler;
for (Test test in TESTS) {
DiagnosticCollector collector = new DiagnosticCollector();
CompilationResult result = await runCompiler(
memorySourceFiles: {'main.dart': test.code},
options: [Flags.analyzeOnly],
diagnosticHandler: collector,
cachedCompiler: cachedCompiler);
cachedCompiler = result.compiler;
MemorySourceFileProvider provider = cachedCompiler.provider;
Map<MessageKind, String> kindToSpan =
new Map<MessageKind, String>.from(test.kindToSpan);
for (CollectedMessage message in collector.messages) {
String expectedSpanText = kindToSpan[message.messageKind];
if (expectedSpanText != null) {
SourceFile sourceFile = provider.getSourceFile(message.uri);
String locationMessage =
sourceFile.getLocationMessage(MARKER, message.begin, message.end);
// Remove `filename:line:column:` and message.
String strippedLocationMessage = locationMessage
.substring(locationMessage.indexOf(MARKER) + MARKER.length + 1);
Expect.equals(
expectedSpanText,
strippedLocationMessage,
"Unexpected span for ${message.messageKind} in\n${test.code}"
"\nExpected:${expectedSpanText.codeUnits}"
"\nActual :${strippedLocationMessage.codeUnits}");
kindToSpan.remove(message.messageKind);
}
}
kindToSpan.forEach((MessageKind kind, _) {
Expect.fail("Missing message kin $kind in\n${test.code}");
});
}
});
}