dart-sdk/pkg/analysis_server/test/completion_test.dart
Brian Wilkerson 69dd787ff0 Cleanup invalid declarations of main, part 1
The purpose of this CL is to clean up test code that references `main`
in a way that will be invalid when the tests are converted to analyze
the test code under null safety by default. This is the first of three
such CLs.

In all three I only touched test files that contained an invalid use of
`main`, but in any file I touched I removed any use of `main` where the
name of the function/method was not critical to the test.

Change-Id: Ib753302a4c3ffc7eb5f248e9c6000e80dc77fca9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/205062
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Brian Wilkerson <brianwilkerson@google.com>
2021-06-28 18:13:24 +00:00

2455 lines
56 KiB
Dart

// Copyright (c) 2017, 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 'dart:collection';
import 'package:test/test.dart';
import 'completion_test_support.dart';
void main() {
var builder = CompletionTestBuilder();
builder.buildAll();
}
/// A builder that builds the completion tests.
class CompletionTestBuilder {
/// Number of tests that have been built that are expected to pass.
int expectedPassCount = 0;
/// Number of tests that have been built that are expected to fail.
int expectedFailCount = 0;
void buildAll() {
buildNumberedTests();
buildCommentSnippetTests();
buildCompletionTests();
buildOtherTests();
buildLibraryTests();
var testCount = expectedPassCount + expectedFailCount;
print(
'Total $testCount tests, of which $expectedFailCount are expected to fail.');
}
void buildCommentSnippetTests() {
buildTests('testCommentSnippets001', '''
class X {static final num MAX = 0;num yc,xc;mth() {xc = yc = MA!1X;x!2c.abs();num f = M!3AX;}}''',
<String>['1+MAX', '2+xc', '3+MAX']);
buildTests('testCommentSnippets002', '''
class Y {String x='hi';mth() {x.l!1ength;int n = 0;x!2.codeUnitAt(n!3);}}''',
<String>['1+length', '2+x', '3+n']);
buildTests('testCommentSnippets004', '''
class A {!1int x; !2mth() {!3int y = this.!5x!6;}}class B{}''',
<String>['1+A', '2+B', '3+x', '3-y', '5+mth', '6+x']);
buildTests('testCommentSnippets005', '''
class Date { static Date JUN, JUL;}class X { m() { return Da!1te.JU!2L; }}''',
<String>['1+Date', '2+JUN', '2+JUL']);
buildTests('testCommentSnippets007', '''
class C {mth(Map x, !1) {}mtf(!2, Map x) {}m() {for (in!3t i=0; i<5; i++); A!4 x;}}class int{}class Arrays{}''',
<String>['1+bool', '2+bool', '3+int', '4+Arrays']);
buildTests('testCommentSnippets008', '''
class Date{}final num M = Dat!1''', <String>['1+Date']);
// space, char, eol are important
buildTests(
'testCommentSnippets009',
'''
class Maps{}class x extends!5 !2M!3 !4implements!6 !1\n{}''',
<String>[
'1+Map',
'2+Maps',
'3+Maps',
'4-Maps',
'4+implements',
'5-Maps',
'6-Map',
'6+implements'
],
failingTests: '46');
// space, char, eol are important
buildTests('testCommentSnippets010', '''
class x implements !1{}''', <String>['1+Map']);
// space, char, eol are important
buildTests('testCommentSnippets011', '''
class x implements M!1{}''', <String>['1+Map']);
// space, char, eol are important
buildTests('testCommentSnippets012', '''
class x implements M!1\n{}''', <String>['1+Map']);
buildTests('testCommentSnippets013', '''
class x !2{!1}!3''', <String>['1+num', '2-num', '3+num']);
// trailing space is important
buildTests('testCommentSnippets014', '''
typedef n!1 ;''', <String>['1+num']);
buildTests('testCommentSnippets015', '''
class D {f(){} g(){f!1(f!2);}}''', <String>['1+f', '2+f']);
buildTests('testCommentSnippets016', '''
class F {m() { m(); !1}}''', <String>['1+m']);
buildTests('testCommentSnippets017', '''
class F {var x = !1false;}''', <String>['1+true']);
buildTests('testCommentSnippets018', '''
class Map{}class Arrays{}class C{ m(!1){} n(!2 x, q)''', <String>[
'1+Map',
'1+dynamic',
'1+void',
'1-null',
'2+Arrays',
'2+void',
'2-null'
]);
buildTests('testCommentSnippets019', '''
class A{m(){Object x;x.!1/**/clear()''', <String>['1+toString']);
buildTests('testCommentSnippets020', '''
classMap{}class tst {var newt;void newf(){}test() {var newz;new!1/**/;}}''',
<String>['1+newt', '1+newf', '1+newz', '1-Map']);
buildTests('testCommentSnippets021', '''
class Map{}class tst {var newt;void newf(){}test() {var newz;new !1/**/;}}''',
<String>['1+Map', '1-newt']);
buildTests('testCommentSnippets022', '''
class Map{}class F{m(){new !1;}}''', <String>['1+Map']);
buildTests('testCommentSnippets022a', '''
class Map{}class F{m(){new !1''', <String>['1+Map']);
buildTests('testCommentSnippets022b', '''
class Map{factory Map.qq(){return null;}}class F{m(){new Map.!1qq();}}''',
<String>['1+qq']);
buildTests('testCommentSnippets023', '''
class X {X c; X(this.!1c!3) : super() {c.!2}}''',
<String>['1+c', '2+c', '3+c']);
buildTests('testCommentSnippets024', '''
class q {m(Map q){var x;m(!1)}n(){var x;n(!2)}}''', <String>['1+x', '2+x']);
buildTests('testCommentSnippets025', '''
class C {num m() {var q; num x=!1 q!3 + !2/**/;}}''',
<String>['1+q', '2+q', '3+q']);
buildTests('testCommentSnippets026', '''
class List{}class a implements !1{}''', <String>['1+List']);
buildTests('testCommentSnippets027', '''
class String{}class List{}class test <X extends !1String!2> {}''',
<String>['1+List', '2+String', '2-List']);
buildTests('testCommentSnippets028', '''
class String{}class List{}class DateTime{}typedef T Y<T extends !1>(List input);''',
<String>['1+DateTime', '1+String']);
buildTests('testCommentSnippets029', '''
interface A<X> default B<X extends !1List!2> {}''',
<String>['1+DateTime', '2+List']);
buildTests('testCommentSnippets030', '''
class Bar<T extends Foo> {const Bar(!1T!2 k);T!3 m(T!4 a, T!5 b){}final T!6 f = null;}''',
<String>['1+T', '2+T', '3+T', '4+T', '5+T', '6+T']);
buildTests('testCommentSnippets031', '''
class Bar<T extends Foo> {m(x){if (x is !1) return;if (x is!!!2)}}''',
<String>['1+Bar', '1+T', '2+T', '2+Bar']);
buildTests(
'testCommentSnippets032',
'''
class Fit{}class Bar<T extends Fooa> {const !2F!1ara();}''',
<String>['1+Fit', '1+Fara', '1-Bar', '2+Fit'],
failingTests: '1');
// Type propagation
buildTests('testCommentSnippets033', '''
class List{add(){}length(){}}t1() {var x;if (x is List) {x.!1add(3);}}''',
<String>['1+add', '1+length']);
// Type propagation
buildTests('testCommentSnippets035', '''
class List{clear(){}length(){}}t3() {var x=[], y=x.!1length();x.!2clear();}''',
<String>['1+length', '2+clear']);
buildTests('testCommentSnippets036', '''
class List{}t3() {var x=new List!1}''', <String>['1+List']);
buildTests('testCommentSnippets037', '''
class List{factory List.from(){}}t3() {var x=new List.!1}''',
<String>['1+from']);
buildTests('testCommentSnippets038', '''
f(){int xa; String s = '\$x!1';}''', <String>['1+xa']);
buildTests('testCommentSnippets038a', '''
int xa; String s = '\$x!1\'''', <String>['1+xa']);
buildTests('testCommentSnippets039', '''
f(){int xa; String s = '\$!1';}''', <String>['1+xa']);
buildTests('testCommentSnippets039a', '''
int xa; String s = '\$!1\'''', <String>['1+xa']);
buildTests('testCommentSnippets040', '''
class List{add(){}}class Map{}class X{m(){List list; list.!1 Map map;}}''',
<String>['1+add']);
buildTests('testCommentSnippets041', '''
class List{add(){}length(){}}class X{m(){List list; list.!1 zox();}}''',
<String>['1+add']);
buildTests('testCommentSnippets042', '''
class DateTime{static const int WED=3;int get day;}fd(){DateTime d=new DateTime.now();d.!1WED!2;}''',
<String>['1+day', '2-WED']);
buildTests('testCommentSnippets043', '''
class L{var k;void.!1}''', <String>['1-k']);
buildTests('testCommentSnippets044', '''
class List{}class XXX {XXX.fisk();}void f() {f(); new !1}}''',
<String>['1+List', '1+XXX.fisk']);
buildTests('testCommentSnippets045', '''
class List{}class XXX {XXX.fisk();}void f() {f(); !1}}''',
<String>['1+List', '1+XXX.fisk']);
buildTests('testCommentSnippets047', '''
f(){int x;int y=!1;}''', <String>['1+x']);
buildTests('testCommentSnippets048', '''
import 'dart:convert' as json;f() {var x=new js!1}''', <String>['1+json']);
buildTests('testCommentSnippets049', '''
import 'dart:convert' as json;
import 'dart:convert' as jxx;
class JsonDecoderX{}
f1() {var x=new !2j!1s!3}''', <String>[
'1+json',
'1+jxx',
'2+json',
'2+jxx',
'2-JsonDecoder',
'3+json',
'3-jxx'
]);
buildTests('testCommentSnippets050', '''
class xdr {
xdr();
const xdr.a(a,b,c);
xdr.b();
f() => 3;
}
class xa{}
k() {
new x!1dr().f();
const x!2dr.!3a(1, 2, 3);
}''', <String>[
'1+xdr',
'1+xa',
'1+xdr.a',
'1+xdr.b',
'2+xa', // suggest default constructor
'2+xdr', // suggest normal constructor
'2+xdr.a',
'2+xdr.b', // suggest named constructor
'3+b', // suggest named constructor
'3+a'
]);
// Type propagation.
buildTests('testCommentSnippets051', '''
class String{int length(){} String toUpperCase(){} bool isEmpty(){}}class Map{getKeys(){}}
void r() {
var v;
if (v is String) {
v.!1length;
v.!2getKeys;
}
}''', <String>['1+length', '2-getKeys']);
// Type propagation.
buildTests('testCommentSnippets052', '''
class String{int length(){} String toUpperCase(){} bool isEmpty(){}}class Map{getKeys(){}}
void r() {
List<String> values = ['a','b','c'];
for (var v in values) {
v.!1toUpperCase;
v.!2getKeys;
}
}''', <String>['1+toUpperCase', '2-getKeys']);
buildTests('testCommentSnippets055', '''
class String{int length(){} String toUpperCase(){} bool isEmpty(){}}class Map{getKeys(){}}
void r() {
String v;
if (v is Object) {
v.!1toUpperCase;
}
}''', <String>['1+toUpperCase']);
buildTests(
'testCommentSnippets058',
'''
typedef vo!2id callback(int k);
void x(callback q){}
void r() {
callback v;
x(!1);
}''',
<String>['1+v', '2+void'],
failingTests: '2');
buildTests('testCommentSnippets060', '''
class Map{}
abstract class MM extends Map{factory MM() => new Map();}
class Z {
MM x;
f() {
x!1
}
}''', <String>['1+x', '1-x[]']);
buildTests('testCommentSnippets061', '''
class A{m(){!1f(3);!2}}n(){!3f(3);!4}f(x)=>x*3;''',
<String>['1+f', '1+n', '2+f', '2+n', '3+f', '3+n', '4+f', '4+n']);
buildTests('testCommentSnippets064', '''
class Spline {
Line c;
Spline a() {
return this;
}
Line b() {
return null;
}
Spline f() {
Line x = new Line();
x.!9h()..!1a()..!2b().!7g();
x.!8j..!3b()..!4c..!6c..!5a();
}
}
class Line {
Spline j;
Line g() {
return this;
}
Spline h() {
return null;
}
}''', <String>[
'1+a',
'2+b',
'1-g',
'2-h',
'3+b',
'4+c',
'5+a',
'6+c',
'7+g',
'8+j',
'9+h'
]);
buildTests('testCommentSnippets065', '''
class Spline {
Line c;
Spline a() {
return this;
}
Line b() {
return null;
}
Spline f() {
Line x = new Line();
x.h()..!1;
}
}
class Line {
Spline j;
Line g() {
return this;
}
Spline h() {
return null;
}
}''', <String>['1+a']);
buildTests('testCommentSnippets066', '''
class Spline {
Line c;
Spline a() {
return this;
}
Line b() {
return null;
}
Spline f() {
Line x = new Line();
x.h()..a()..!1;
}
}
class Line {
Spline j;
Line g() {
return this;
}
Spline h() {
return null;
}
}''', <String>['1+b']);
buildTests('testCommentSnippets067', '''
class Spline {
Line c;
Spline a() {
return this;
}
Line b() {
return null;
}
Spline f() {
Line x = new Line();
x.h()..a()..c..!1;
}
}
class Line {
Spline j;
Line g() {
return this;
}
Spline h() {
return null;
}
}''', <String>['1+b']);
buildTests('testCommentSnippets068', '''
class Spline {
Line c;
Spline a() {
return this;
}
Line b() {
return null;
}
Spline f() {
Line x = new Line();
x.j..b()..c..!1;
}
}
class Line {
Spline j;
Line g() {
return this;
}
Spline h() {
return null;
}
}''', <String>['1+c']);
buildTests('testCommentSnippets069', '''
class Spline {
Line c;
Spline a() {
return this;
}
Line b() {
return null;
}
Spline f() {
Line x = new Line();
x.j..b()..!1;
}
}
class Line {
Spline j;
Line g() {
return this;
}
Spline h() {
return null;
}
}''', <String>['1+c']);
buildTests('testCommentSnippets070', '''
class Spline {
Line c;
Spline a() {
return this;
}
Line b() {
return null;
}
Spline f() {
Line x = new Line();
x.j..!1;
}
}
class Line {
Spline j;
Line g() {
return this;
}
Spline h() {
return null;
}
}''', <String>['1+b']);
buildTests('testCommentSnippets072', '''
class X {
int _p;
set p(int x) => _p = x;
}
f() {
X x = new X();
x.!1p = 3;
}''', <String>['1+p']);
buildTests('testCommentSnippets073', '''
class X {
m() {
JSON.stri!1;
X f = null;
}
}
class JSON {
static stringify() {}
}''', <String>['1+stringify']);
buildTests('testCommentSnippets074', '''
class X {
m() {
_x!1
}
_x1(){}
}''', <String>['1+_x1']);
buildTests('testCommentSnippets075', '''
p(x)=>0;var E;f(q)=>!1p(!2E);''', <String>['1+p', '2+E']);
buildTests('testCommentSnippets076', '''
class Map<K,V>{}class List<E>{}class int{}void f() {var m=new Map<Lis!1t<Map<int,in!2t>>,List<!3int>>();}''',
<String>['1+List', '2+int', '3+int']);
buildTests('testCommentSnippets076a', '''
class Map<K,V>{}class List<E>{}class int{}void f() {var m=new Map<Lis!1t<Map<int,in!2t>>,List<!3>>();}''',
<String>['1+List', '2+int', '3+int']);
buildTests('testCommentSnippets077', '''
class FileMode {
static const READ = const FileMode._internal(0);
static const WRITE = const FileMode._internal(1);
static const APPEND = const FileMode._internal(2);
const FileMode._internal(int this._mode);
factory FileMode._internal1(int this._mode);
factory FileMode(_mode);
final int _mode;
}
class File {
File(String path);
File.fromPath(Path path);
}
f() => new Fil!1''', <String>[
'1+File',
'1+File.fromPath',
'1+FileMode',
'1+FileMode._internal1',
'1+FileMode._internal'
]);
buildTests('testCommentSnippets078', '''
class Map{static from()=>null;clear(){}}void f() { Map.!1 }''',
<String>['1+from', '1-clear']); // static method, instance method
buildTests('testCommentSnippets079', '''
class Map{static from()=>null;clear(){}}void f() { Map s; s.!1 }''',
<String>['1-from', '1+clear']); // static method, instance method
buildTests('testCommentSnippets080', '''
class RuntimeError{var message;}void f() { RuntimeError.!1 }''',
<String>['1-message']); // field
buildTests(
'testCommentSnippets081',
'''
class Foo {this.!1}''',
<String>['1-Object'],
failingTests: '1');
// https://github.com/dart-lang/sdk/issues/33992
buildTests(
'testCommentSnippets082',
'''
class HttpRequest {}
class HttpResponse {}
void f() {
var v = (HttpRequest req, HttpResp!1)
}''',
<String>['1+HttpResponse'],
failingTests: '1');
buildTests('testCommentSnippets083', '''
void f() {(.!1)}''', <String>['1-toString']);
buildTests('testCommentSnippets083a', '''
void f() { .!1 }''', <String>['1-toString']);
buildTests('testCommentSnippets083b', '''
void f() { null.!1 }''', <String>['1+toString']);
buildTests('testCommentSnippets085', '''
class List{}class Map{}class Z extends List with !1Ma!2p {}''',
<String>['1+List', '1+Map', '2+Map', '2-List']);
buildTests(
'testCommentSnippets086',
'''
class Q{f(){xy() {!2};x!1y();}}''',
<String>['1+xy', '2+f', '2-xy'],
failingTests: '2');
buildTests('testCommentSnippets087', '''
class Map{}class Q extends Object with !1Map {}''',
<String>['1+Map', '1-HashMap']);
buildTests('testCommentSnippets088', '''
class A {
int f;
B m(){}
}
class B extends A {
num f;
A m(){}
}
class Z {
B q;
f() {q.!1}
}''', <String>['1+f', '1+m']); // f->num, m()->A
buildTests(
'testCommentSnippets089',
'''
class Q {
fqe() {
xya() {
xyb() {
!1
}
!3 xyb();
};
xza() {
!2
}
xya();
!4 xza();
}
fqi() {
!5
}
}''',
<String>[
'1+fqe',
'1+fqi',
'1+Q',
'1-xya',
'1-xyb',
'1-xza',
'2+fqe',
'2+fqi',
'2+Q',
'2-xya',
'2-xyb',
'2-xza',
'3+fqe',
'3+fqi',
'3+Q',
'3-xya',
'3+xyb',
'3-xza',
'4+fqe',
'4+fqi',
'4+Q',
'4+xya',
'4-xyb',
'4+xza',
'5+fqe',
'5+fqi',
'5+Q',
'5-xya',
'5-xyb',
'5-xza'
],
failingTests: '123');
buildTests('testCommentSnippets090', '''
class X { f() { var a = 'x'; a.!1 }}''', <String>['1+length']);
}
void buildCompletionTests() {
buildTests('testCompletion_alias_field', '''
typedef int fnint(int k); fn!1int x;''', <String>['1+fnint']);
buildTests(
'testCompletion_annotation_argumentList',
'''
class AAA {",
const AAA({int aaa, int bbb});",
}",
",
@AAA(!1)
void f() {
}''',
<String>[
'1+AAA' /*":" + ProposalKind.ARGUMENT_LIST*/,
'1+aaa',
'1+bbb'
],
failingTests: '1');
buildTests(
'testCompletion_annotation_topLevelVar',
'''
const fooConst = null;
final fooNotConst = null;
const bar = null;
@foo!1
void f() {
}''',
<String>['1+fooConst', '1-fooNotConst', '1-bar'],
failingTests: '1');
buildTests('testCompletion_annotation_type', '''
class AAA {
const AAA({int a, int b});
const AAA.nnn(int c, int d);
}
@AAA!1
void f() {
}''', <String>[
'1+AAA' /*":" + ProposalKind.CONSTRUCTOR*/,
'1+AAA.nnn' /*":" + ProposalKind.CONSTRUCTOR*/
]);
buildTests('testCompletion_annotation_type_inClass_withoutMember', '''
class AAA {
const AAA();
}
class C {
@A!1
}''', <String>[
'1+AAA' /*":" + ProposalKind.CONSTRUCTOR*/
]);
buildTests('testCompletion_argument_typeName', '''
class Enum {
static Enum FOO = new Enum();
}
f(Enum e) {}
void f() {
f(En!1);
}''', <String>['1+Enum']);
buildTests('testCompletion_arguments_ignoreEmpty', '''
class A {
test() {}
}
void f(A a) {
a.test(!1);
}''', <String>['1-test']);
buildTests('testCompletion_as_asIdentifierPrefix', '''
void f(p) {
var asVisible;
var v = as!1;
}''', <String>['1+asVisible']);
buildTests('testCompletion_as_asPrefixedIdentifierStart', '''
class A {
var asVisible;
}
void f(A p) {
var v = p.as!1;
}''', <String>['1+asVisible']);
buildTests('testCompletion_as_incompleteStatement', '''
class MyClass {}
void f(p) {
var justSomeVar;
var v = p as !1
}''', <String>['1+MyClass', '1-justSomeVar']);
buildTests('testCompletion_cascade', '''
class A {
aaa() {}
}
void f(A a) {
a..!1 aaa();
}''', <String>['1+aaa', '1-f']);
buildTests('testCompletion_combinator_afterComma', '''
import 'dart:math' show cos, !1;''',
<String>['1+pi', '1+sin', '1+Random', '1-String']);
buildTests('testCompletion_combinator_ended', '''
import 'dart:math' show !1;"''',
<String>['1+pi', '1+sin', '1+Random', '1-String']);
buildTests('testCompletion_combinator_export', '''
export 'dart:math' show !1;"''',
<String>['1+pi', '1+sin', '1+Random', '1-String']);
buildTests('testCompletion_combinator_hide', '''
import 'dart:math' hide !1;"''',
<String>['1+pi', '1+sin', '1+Random', '1-String']);
buildTests('testCompletion_combinator_notEnded', '''
import 'dart:math' show !1"''',
<String>['1+pi', '1+sin', '1+Random', '1-String']);
buildTests('testCompletion_combinator_usePrefix', '''
import 'dart:math' show s!1"''',
<String>['1+sin', '1+sqrt', '1-cos', '1-String']);
buildTests(
'testCompletion_constructor_field',
'''
class X { X(this.field); int f!1ield;}''',
<String>['1+field'],
failingTests: '1');
buildTests(
'testCompletion_constructorArguments_showOnlyCurrent',
'''
class A {
A.first(int p);
A.second(double p);
}
void f() {
new A.first(!1);
}''',
<String>['1+A.first', '1-A.second'],
failingTests: '1');
buildTests(
'testCompletion_constructorArguments_whenPrefixedType',
'''
import 'dart:math' as m;
void f() {
new m.Random(!1);
}''',
<String>['1+Random:ARGUMENT_LIST'],
failingTests: '1');
buildTests('testCompletion_dartDoc_reference_forClass', '''
/**
* [int!1]
* [method!2]
*/
class AAA {
methodA() {}
}''', <String>['1+int', '1-method', '2+methodA', '2-int']);
buildTests('testCompletion_dartDoc_reference_forConstructor', '''
class A {
/**
* [aa!1]
* [int!2]
* [method!3]
*/
A.named(aaa, bbb) {}
methodA() {}
}''', <String>['1+aaa', '1-bbb', '2+int', '2-double', '3+methodA']);
buildTests(
'testCompletion_dartDoc_reference_forFunction',
'''
/**
* [aa!1]
* [int!2]
* [function!3]
*/
functionA(aaa, bbb) {}
functionB() {}''',
<String>[
'1+aaa',
'1-bbb',
'2+int',
'2-double',
'3+functionA',
'3+functionB',
'3-int'
],
failingTests: '1');
buildTests(
'testCompletion_dartDoc_reference_forFunctionTypeAlias',
'''
/**
* [aa!1]
* [int!2]
* [Function!3]
*/
typedef FunctionA(aaa, bbb) {}
typedef FunctionB() {}''',
<String>[
'1+aaa',
'1-bbb',
'2+int',
'2-double',
'3+FunctionA',
'3+FunctionB',
'3-int'
],
failingTests: '1');
buildTests('testCompletion_dartDoc_reference_forMethod', '''
class A {
/**
* [aa!1]
* [int!2]
* [method!3]
*/
methodA(aaa, bbb) {}
methodB() {}
}''', <String>[
'1+aaa',
'1-bbb',
'2+int',
'2-double',
'3+methodA',
'3+methodB',
'3-int'
]);
buildTests('testCompletion_dartDoc_reference_incomplete', '''
/**
* [doubl!1 some text
* other text
*/
class A {}
/**
* [!2 some text
* other text
*/
class B {}
/**
* [!3] some text
*/
class C {}''', <String>[
'1+double',
'1-int',
'2+int',
'2+String',
'3+int',
'3+String'
]);
buildTests('testCompletion_double_inFractionPart', '''
void f() {
1.0!1
}''', <String>['1-abs', '1-f']);
buildTests('testCompletion_enum', '''
enum MyEnum {A, B, C}
void f() {
MyEnum.!1;
}''', <String>['1+values', '1+A', '1+B', '1+C']);
buildTests('testCompletion_exactPrefix_hasHigherRelevance', '''
var STR;
void f(p) {
var str;
str!1;
STR!2;
Str!3;
}''', <String>[
'1+str' /*",rel=" + (CompletionProposal.RELEVANCE_DEFAULT + 1)*/,
'1+STR' /*",rel=" + (CompletionProposal.RELEVANCE_DEFAULT + 0)*/,
'2+STR' /*",rel=" + (CompletionProposal.RELEVANCE_DEFAULT + 1)*/,
'2+str' /*",rel=" + (CompletionProposal.RELEVANCE_DEFAULT + 0)*/,
'3+String' /*",rel=" + (CompletionProposal.RELEVANCE_DEFAULT + 1)*/,
'3+STR' /*",rel=" + (CompletionProposal.RELEVANCE_DEFAULT + 0)*/,
'3+str' /*",rel=" + (CompletionProposal.RELEVANCE_DEFAULT + 0)*/
]);
buildTests('testCompletion_export_dart', '''
import 'dart:math
import 'dart:_collection.dev
export 'dart:!1''', <String>[
'1+dart:core',
'1+dart:math',
'1-dart:_collection.dev',
]);
buildTests(
'testCompletion_export_noStringLiteral_noSemicolon',
'''
import !1
class A {}''',
<String>["1+'dart:!';", "1+'package:!';"],
failingTests: '1');
buildTests('testCompletion_forStmt_vars', '''
class int{}class Foo { mth() { for (in!1t i = 0; i!2 < 5; i!3++); }}''',
<String>['1+int', '2+i', '3+i']);
buildTests('testCompletion_function', '''
class Foo { int boo = 7; mth() { PNGS.sort((String a, Str!1) => a.compareTo(b)); }}''',
<String>['1+String']);
// https://github.com/dart-lang/sdk/issues/33992
buildTests(
'testCompletion_function_partial',
'''
class Foo { int boo = 7; mth() { PNGS.sort((String a, Str!1)); }}''',
<String>['1+String'],
failingTests: '1');
buildTests(
'testCompletion_functionTypeParameter_namedArgument',
'''
typedef FFF(a, b, {x1, x2, y});
void f(FFF fff) {
fff(1, 2, !1)!2;
}''',
<String>['1+x1', '2-x2'],
failingTests: '1');
buildTests('testCompletion_ifStmt_field1', '''
class Foo { int myField = 7; mth() { if (!1) {}}}''', <String>['1+myField']);
buildTests('testCompletion_ifStmt_field1a', '''
class Foo { int myField = 7; mth() { if (!1) }}''', <String>['1+myField']);
buildTests('testCompletion_ifStmt_field2', '''
class Foo { int myField = 7; mth() { if (m!1) {}}}''', <String>['1+myField']);
buildTests('testCompletion_ifStmt_field2a', '''
class Foo { int myField = 7; mth() { if (m!1) }}''', <String>['1+myField']);
buildTests('testCompletion_ifStmt_field2b', '''
class Foo { myField = 7; mth() { if (m!1) {}}}''', <String>['1+myField']);
buildTests('testCompletion_ifStmt_localVar', '''
class Foo { mth() { int value = 7; if (v!1) {}}}''', <String>['1+value']);
buildTests('testCompletion_ifStmt_localVara', '''
class Foo { mth() { value = 7; if (v!1) {}}}''', <String>['1-value']);
buildTests('testCompletion_ifStmt_topLevelVar', '''
int topValue = 7; class Foo { mth() { if (t!1) {}}}''', <String>['1+topValue']);
buildTests('testCompletion_ifStmt_topLevelVara', '''
topValue = 7; class Foo { mth() { if (t!1) {}}}''', <String>['1+topValue']);
buildTests(
'testCompletion_ifStmt_unionType_nonStrict',
'''
class A { a() => null; x() => null}
class B { a() => null; y() => null}
void f() {
var x;
var c;
if(c) {
x = new A();
} else {
x = new B();
}
x.!1;
}''',
<String>['1+a', '1+x', '1+y'],
failingTests: '1');
buildTests(
'testCompletion_ifStmt_unionType_strict',
'''
class A { a() => null; x() => null}
class B { a() => null; y() => null}
void f() {
var x;
var c;
if(c) {
x = new A();
} else {
x = new B();
}
x.!1;
}''',
<String>['1+a', '1-x', '1-y'],
failingTests: '1');
buildTests('testCompletion_import', '''
import '!1';''', <String>['1+dart:!', '1+package:!']);
buildTests('testCompletion_import_dart', '''
import 'dart:math
import 'dart:_collection.dev
import 'dart:!1''', <String>[
'1+dart:core',
'1+dart:math',
'1-dart:_collection.dev',
]);
buildTests('testCompletion_import_hasStringLiteral_noSemicolon', '''
import '!1'
class A {}''', <String>['1+dart:!', '1+package:!']);
buildTests(
'testCompletion_import_noSpace',
'''
import!1''',
<String>["1+ 'dart:!';", "1+ 'package:!';"],
failingTests: '1');
buildTests(
'testCompletion_import_noStringLiteral',
'''
import !1;''',
<String>["1+'dart:!'", "1+'package:!'"],
failingTests: '1');
buildTests(
'testCompletion_import_noStringLiteral_noSemicolon',
'''
import !1
class A {}''',
<String>["1+'dart:!';", "1+'package:!';"],
failingTests: '1');
buildTests('testCompletion_incompleteClassMember', '''
class A {
Str!1
final f = null;
}''', <String>['1+String', '1-bool']);
buildTests('testCompletion_incompleteClosure_parameterType', '''
f1(cb(String s)) {}
f2(String s) {}
void f() {
f1((Str!1));
f2((Str!2));
}''', <String>['1+String', '1-bool', '2+String', '2-bool']);
buildTests(
'testCompletion_inPeriodPeriod',
'''
void f(String str) {
1 < str.!1.length;
1 + str.!2.length;
1 + 2 * str.!3.length;
}''',
<String>['1+codeUnits', '2+codeUnits', '3+codeUnits'],
failingTests: '123');
// no checks, but no exceptions
buildTests('testCompletion_instanceCreation_unresolved', '''
class A {
}
void f() {
new NoSuchClass(!1);
new A.noSuchConstructor(!2);
}''', <String>['1+int', '2+int']);
buildTests(
'testCompletion_import_lib',
'''
import '!1''',
<String>['1+my_lib.dart'],
extraFiles: <String, String>{'/my_lib.dart': ''},
failingTests: '1');
buildTests('testCompletion_is', '''
class MyClass {}
void f(p) {
var isVariable;
if (p is MyCla!1) {}
var v1 = p is MyCla!2;
var v2 = p is !3;
var v2 = p is!4;
}''', <String>[
'1+MyClass',
'2+MyClass',
'3+MyClass',
'3-v1',
'4+is',
'4-isVariable'
]);
// https://github.com/dart-lang/sdk/issues/33992
buildTests(
'testCompletion_is_asIdentifierStart',
'''
void f(p) {
var isVisible;
var v1 = is!1;
var v2 = is!2
}''',
<String>['1+isVisible', '2+isVisible'],
failingTests: '12');
buildTests('testCompletion_is_asPrefixedIdentifierStart', '''
class A {
var isVisible;
}
void f(A p) {
var v1 = p.is!1;
var v2 = p.is!2
}''', <String>['1+isVisible', '2+isVisible']);
buildTests('testCompletion_is_incompleteStatement1', '''
class MyClass {}
void f(p) {
var justSomeVar;
var v = p is !1
}''', <String>['1+MyClass', '1-justSomeVar']);
buildTests('testCompletion_is_incompleteStatement2', '''
class MyClass {}
void f(p) {
var isVariable;
var v = p is!1
}''', <String>['1+is', '1-isVariable']);
buildTests('testCompletion_keyword_in', '''
class Foo { int input = 7; mth() { if (in!1) {}}}''', <String>['1+input']);
buildTests('testCompletion_keyword_syntheticIdentifier', '''
void f() {
var caseVar;
var otherVar;
var v = case!1
}''', <String>['1+caseVar', '1-otherVar']);
buildTests('testCompletion_libraryIdentifier_atEOF', '''
library int.!1''', <String>['1-parse', '1-bool']);
buildTests('testCompletion_libraryIdentifier_notEOF', '''
library int.!1''', <String>['1-parse', '1-bool']);
buildTests(
'testCompletion_methodRef_asArg_incompatibleFunctionType',
'''
foo( f(int p) ) {}
class Functions {
static myFuncInt(int p) {}
static myFuncDouble(double p) {}
}
bar(p) {}
void f(p) {
foo( Functions.!1; );
}''',
<String>[
'1+myFuncInt' /*":" + ProposalKind.METHOD_NAME*/,
'1-myFuncDouble' /*":" + ProposalKind.METHOD_NAME*/
],
failingTests: '1');
buildTests(
'testCompletion_methodRef_asArg_notFunctionType',
'''
foo( f(int p) ) {}
class Functions {
static myFunc(int p) {}
}
bar(p) {}
void f(p) {
foo( (int p) => Functions.!1; );
}''',
<String>[
'1+myFunc' /*":" + ProposalKind.METHOD*/,
'1-myFunc' /*":" + ProposalKind.METHOD_NAME*/
],
failingTests: '1');
buildTests('testCompletion_methodRef_asArg_ofFunctionType', '''
foo( f(int p) ) {}
class Functions {
static int myFunc(int p) {}
}
void f(p) {
foo(Functions.!1);
}''', <String>[
'1+myFunc' /*":" + ProposalKind.METHOD*/,
'1+myFunc' /*":" + ProposalKind.METHOD_NAME*/
]);
buildTests('testCompletion_namedArgument_alreadyUsed', '''
func({foo}) {} void f() { func(foo: 0, fo!1); }''', <String>['1-foo']);
buildTests(
'testCompletion_namedArgument_constructor',
'''
class A {A({foo, bar}) {}} void f() { new A(fo!1); }''',
<String>['1+foo', '1-bar'],
failingTests: '1');
buildTests(
'testCompletion_namedArgument_empty',
'''
func({foo, bar}) {} void f() { func(!1); }''',
<String>[
'1+foo' /*":" + ProposalKind.NAMED_ARGUMENT*/,
'1-foo' /*":" + ProposalKind.OPTIONAL_ARGUMENT*/
],
failingTests: '1');
buildTests(
'testCompletion_namedArgument_function',
'''
func({foo, bar}) {} void f() { func(fo!1); }''',
<String>['1+foo', '1-bar'],
failingTests: '1');
buildTests('testCompletion_namedArgument_notNamed', '''
func([foo]) {} void f() { func(fo!1); }''', <String>['1-foo']);
buildTests('testCompletion_namedArgument_unresolvedFunction', '''
void f() { func(fo!1); }''', <String>['1-foo']);
buildTests('testCompletion_newMemberType1', '''
class Collection{}class List extends Collection{}class Foo { !1 }''',
<String>['1+Collection', '1+List']);
buildTests('testCompletion_newMemberType2', '''
class Collection{}class List extends Collection{}class Foo {!1}''',
<String>['1+Collection', '1+List']);
buildTests('testCompletion_newMemberType3', '''
class Collection{}class List extends Collection{}class Foo {L!1}''',
<String>['1-Collection', '1+List']);
buildTests('testCompletion_newMemberType4', '''
class Collection{}class List extends Collection{}class Foo {C!1}''',
<String>['1+Collection', '1-List']);
buildTests(
'testCompletion_positionalArgument_constructor',
'''
class A {
A([foo, bar]);
}
void f() {
new A(!1);
new A(0, !2);
}''',
<String>[
'1+foo' /*":" + ProposalKind.OPTIONAL_ARGUMENT*/,
'1-bar',
'2-foo',
'2+bar' /*":"
+ ProposalKind.OPTIONAL_ARGUMENT*/
],
failingTests: '12');
buildTests(
'testCompletion_positionalArgument_function',
'''
func([foo, bar]) {}
void f() {
func(!1);
func(0, !2);
}''',
<String>[
'1+foo' /*":" + ProposalKind.OPTIONAL_ARGUMENT*/,
'1-bar',
'2-foo',
'2+bar' /*":"
+ ProposalKind.OPTIONAL_ARGUMENT*/
],
failingTests: '12');
buildTests(
'testCompletion_preferStaticType',
'''
class A {
foo() {}
}
class B extends A {
bar() {}
}
void f() {
A v = new B();
v.!1
}''',
<String>[
'1+foo',
'1-bar,potential=false,declaringType=B',
'1+bar,potential=true,declaringType=B'
],
failingTests: '1');
buildTests('testCompletion_privateElement_sameLibrary_constructor', '''
class A {
A._c();
A.c();
}
void f() {
new A.!1
}''', <String>['1+_c', '1+c']);
buildTests('testCompletion_privateElement_sameLibrary_member', '''
class A {
_m() {}
m() {}
}
void f(A a) {
a.!1
}''', <String>['1+_m', '1+m']);
buildTests('testCompletion_propertyAccess_whenClassTarget', '''
class A {
static int FIELD;
int field;
}
void f() {
A.!1
}''', <String>['1+FIELD', '1-field']);
buildTests('testCompletion_propertyAccess_whenClassTarget_excludeSuper', '''
class A {
static int FIELD_A;
static int methodA() {}
}
class B extends A {
static int FIELD_B;
static int methodB() {}
}
void f() {
B.!1;
}''', <String>['1+FIELD_B', '1-FIELD_A', '1+methodB', '1-methodA']);
buildTests('testCompletion_propertyAccess_whenInstanceTarget', '''
class A {
static int FIELD;
int fieldA;
}
class B {
A a;
}
class C extends A {
int fieldC;
}
void f(B b, C c) {
b.a.!1;
c.!2;
}''', <String>['1-FIELD', '1+fieldA', '2+fieldC', '2+fieldA']);
buildTests('testCompletion_return_withIdentifierPrefix', '''
f() { var vvv = 42; return v!1 }''', <String>['1+vvv']);
buildTests('testCompletion_return_withoutExpression', '''
f() { var vvv = 42; return !1 }''', <String>['1+vvv']);
buildTests('testCompletion_staticField1', '''
class num{}class Sunflower {static final n!2um MAX_D = 300;nu!3m xc, yc;Sun!4flower() {x!Xc = y!Yc = MA!1 }}''',
<String>['1+MAX_D', 'X+xc', 'Y+yc', '2+num', '3+num', '4+Sunflower']);
buildTests('testCompletion_staticField_withoutVarOrFinal', '''
class num{}class Sunflower {static n!1}''', <String>['1+num']);
buildTests('testCompletion_super_superType', '''
class A {
var fa;
ma() {}
}
class B extends A {
var fb;
mb() {}
void f() {
super.!1
}
}''', <String>['1+fa', '1-fb', '1+ma', '1-mb']);
buildTests('testCompletion_superConstructorInvocation_noNamePrefix', '''
class A {
A.fooA();
A.fooB();
A.bar();
}
class B extends A {
B() : super.!1
}''', <String>['1+fooA', '1+fooB', '1+bar']);
buildTests('testCompletion_superConstructorInvocation_withNamePrefix', '''
class A {
A.fooA();
A.fooB();
A.bar();
}
class B extends A {
B() : super.f!1
}''', <String>['1+fooA', '1+fooB', '1-bar']);
buildTests(
'testCompletion_this_bad_inConstructorInitializer',
'''
class A {
var f;
A() : f = this.!1;
}''',
<String>['1-toString'],
failingTests: '1');
buildTests(
'testCompletion_this_bad_inFieldDeclaration',
'''
class A {
var f = this.!1;
}''',
<String>['1-toString'],
failingTests: '1');
buildTests(
'testCompletion_this_bad_inStaticMethod',
'''
class A {
static m() {
this.!1;
}
}''',
<String>['1-toString'],
failingTests: '1');
buildTests(
'testCompletion_this_bad_inTopLevelFunction',
'''
void f() {
this.!1;
}''',
<String>['1-toString'],
failingTests: '1');
buildTests(
'testCompletion_this_bad_inTopLevelVariableDeclaration',
'''
var v = this.!1;''',
<String>['1-toString'],
failingTests: '1');
buildTests('testCompletion_this_OK_inConstructorBody', '''
class A {
var f;
m() {}
A() {
this.!1;
}
}''', <String>['1+f', '1+m']);
buildTests('testCompletion_this_OK_localAndSuper', '''
class A {
var fa;
ma() {}
}
class B extends A {
var fb;
mb() {}
void m() {
this.!1
}
}''', <String>['1+fa', '1+fb', '1+ma', '1+mb']);
buildTests('testCompletion_topLevelField_init2', '''
class DateTime{static var JUN;}final num M = Dat!1eTime.JUN;''',
<String>['1+DateTime', '1-void']);
buildTests('testCompletion_while', '''
class Foo { int boo = 7; mth() { while (b!1) {} }}''', <String>['1+boo']);
}
void buildLibraryTests() {
Map<String, String> sources = HashMap<String, String>();
buildTests('test_export_ignoreIfThisLibraryExports', '''
export 'dart:math';
libFunction() {};
void f() {
!1
}''', <String>['1-cos', '1+libFunction']);
sources.clear();
sources['/lib.dart'] = '''
library lib;
export 'dart:math' hide sin;
libFunction() {};''';
buildTests(
'test_export_showIfImportLibraryWithExport',
'''
import 'lib.dart' as p;
void f() {
p.!1
}''',
<String>['1+cos', '1-sin', '1+libFunction'],
extraFiles: sources,
failingTests: '1');
buildTests('test_importPrefix_hideCombinator', '''
import 'dart:math' as math hide pi;
void f() {
math.!1
}''', <String>['1-pi', '1+ln10']);
buildTests('test_importPrefix_showCombinator', '''
import 'dart:math' as math show pi;
void f() {
math.!1
}''', <String>['1+pi', '1-ln10']);
sources.clear();
sources['/lib.dart'] = '''
library lib
class _A
foo() {}
class A extends _A {
}''';
buildTests(
'test_memberOfPrivateClass_otherLibrary',
'''
import 'lib.dart';
void f(A a) {
a.!1
}''',
<String>['1+foo'],
extraFiles: sources,
failingTests: '1');
sources.clear();
sources['/lib.dart'] = '''
library lib;
class A {
A.c();
A._c();
}''';
buildTests(
'test_noPrivateElement_otherLibrary_constructor',
'''
import 'lib.dart';
void f() {
new A.!1
}''',
<String>['1-_c', '1+c'],
failingTests: '1');
sources.clear();
sources['/lib.dart'] = '''
library lib;
class A {
var f;
var _f;
}''';
buildTests(
'test_noPrivateElement_otherLibrary_member',
'''
import 'lib.dart';
void f(A a) {
a.!1
}''',
<String>['1-_f', '1+f'],
extraFiles: sources,
failingTests: '1');
sources.clear();
sources['/firth.dart'] = '''
library firth;
class SerializationException {
const SerializationException();
}''';
buildTests(
'testLibrary001',
'''
import 'firth.dart';
void f() {
throw new Seria!1lizationException();}''',
<String>['1+SerializationException'],
extraFiles: sources,
failingTests: '1');
// Type propagation.
// TODO Include corelib analysis (this works in the editor)
buildTests(
'testLibrary002',
'''t2() {var q=[0],z=q.!1length;q.!2clear();}''',
<String>['1+length', '1+isEmpty', '2+clear']);
// TODO Include corelib analysis
buildTests('testLibrary003', '''class X{var q; f() {q.!1a!2}}''',
<String>['1+end', '2+abs', '2-end'],
failingTests: '12');
// TODO Include corelib analysis
// Resolving dart:html takes between 2.5s and 30s; json, about 0.12s
buildTests('testLibrary004', '''
library foo;
import 'dart:convert' as json;
class JsonDecoderX{}
f1() {var x=new json.!1}
f2() {var x=new json.JsonDe!2}
f3() {var x=new json.JsonDecoder!3}''', <String>[
'1+JsonDecoder',
'1-JsonDecoderX',
'2+JsonDecoder',
'2-JsonDecoderX',
'3+JsonDecoder',
'3-JsonDecoderX'
]);
// TODO Enable after type propagation is implemented. Not yet.
// TODO Include corelib analysis
buildTests(
'testLibrary005',
'''var PHI;void f(){PHI=5.3;PHI.abs().!1 Object x;}''',
<String>['1+abs'],
failingTests: '1');
// Exercise import and export handling.
// Libraries are defined in partial order of increasing dependency.
sources.clear();
sources['/exp2a.dart'] = '''
library exp2a;
e2a() {}''';
sources['/exp1b.dart'] = '''
library exp1b;",
e1b() {}''';
sources['/exp1a.dart'] = '''
library exp1a;",
export 'exp1b.dart';",
e1a() {}''';
sources['/imp1.dart'] = '''
library imp1;
export 'exp1a.dart';
i1() {}''';
sources['/imp2.dart'] = '''
library imp2;
export 'exp2a.dart';
i2() {}''';
buildTests(
'testLibrary006',
'''
import 'imp1.dart';
import 'imp2.dart';
void f() {!1
i1();
i2();
e1a();
e1b();
e2a();
}''',
<String>['1+i1', '1+i2', '1+e1a', '1+e2a', '1+e1b'],
extraFiles: sources,
failingTests: '1');
// Exercise import and export handling.
// Libraries are defined in partial order of increasing dependency.
sources.clear();
sources['/l1.dart'] = '''
library l1;
var _l1t; var l1t;''';
buildTests(
'testLibrary007',
'''
import 'l1.dart';
void f() {
var x = l!1
var y = _!2
}''',
<String>['1+l1t', '1-_l1t', '2-_l1t'],
extraFiles: sources,
failingTests: '1');
// Check private library exclusion
sources.clear();
sources['/public.dart'] = '''
library public;
class NonPrivate {
void publicMethod() {
}
}''';
sources['/private.dart'] = '''
library _private;
import 'public.dart';
class Private extends NonPrivate {
void privateMethod() {
}
}''';
buildTests(
'testLibrary008',
'''
import 'private.dart';
import 'public.dart';
class Test {
void test() {
NonPrivate x = new NonPrivate();
x.!1 //publicMethod but not privateMethod should appear
}
}''',
<String>['1-privateMethod', '1+publicMethod'],
extraFiles: sources,
failingTests: '1');
// Exercise library prefixes.
sources.clear();
sources['/lib.dart'] = '''
library lib;
int X = 1;
void m(){}
class Y {}''';
buildTests(
'testLibrary009',
'''
import 'lib.dart' as Q;
void a() {
var x = Q.!1
}
void b() {
var x = [Q.!2]
}
void c() {
var x = new List.filled([Q.!3], null)
}
void d() {
new Q.!4
}''',
<String>[
'1+X',
'1+m',
'1+Y',
'2+X',
'2+m',
'2+Y',
'3+X',
'3+m',
'3+Y',
'4+Y',
'4-m',
'4-X'
],
extraFiles: sources,
failingTests: '1234');
}
void buildNumberedTests() {
buildTests('test001', '''
void r1(var v) {
v.!1toString!2().!3hash!4Code
}''', <String>[
'1+toString',
'1-==',
'2+toString',
'3+hashCode',
'3+toString',
'4+hashCode',
'4-toString'
]);
buildTests('test002', '''
void r2(var vim) {
v!1.toString()
}''', <String>['1+vim']);
buildTests('test003', '''
class A {
int a() => 3;
int b() => this.!1a();
}''', <String>['1+a']);
buildTests(
'test004',
'''
class A {
int x;
A() : this.!1x = 1;
A.b() : this();
A.c() : this.!2b();
g() => new A.!3c();
}''',
<String>['1+x', '2+b', '3+c'],
failingTests: '12');
buildTests(
'test005',
'''
class A {}
void rr(var vim) {
var !1vq = v!2.toString();
var vf;
v!3.toString();
}''',
<String>[
'1-A',
'1-vim',
'1+vq',
'1-vf',
'1-this',
'1-void',
'1-null',
'1-false',
'2-A',
'2+vim',
'2-vf',
'2-vq',
'2-this',
'2-void',
'2-null',
'2-false',
'3+vf',
'3+vq',
'3+vim',
'3-A'
],
failingTests: '1');
buildTests('test006', '''
void r2(var vim, {va: 2, b: 3}) {
v!1.toString()
}''', <String>['1+va', '1-b']);
buildTests('test007', '''
void r2(var vim, [va: 2, b: 3]) {
v!1.toString()
}''', <String>['1+va', '1-b']);
// keywords
buildTests(
'test008',
'''
!1class Aclass {}
class Bclass !2extends!3 !4Aclass {}
!5abstract class Eclass implements Aclass, Bclass {}
class Fclass extends Bclass !6with !7 Eclass {}''',
<String>[
'1+class',
'1-implements',
'1-extends',
'1-with',
'2+extends',
'3+extends',
'4+Aclass',
'4-Bclass',
'5+abstract',
'6+with',
'7+Eclass',
'7-Dclass',
'7-Ctype',
],
failingTests: '2346');
// keywords
buildTests(
'test009',
'''
typedef !1dy!2namic TestFn1();
typedef !3vo!4id TestFn2();
typ!7edef !5n!6''',
<String>[
'1+void',
'1+TestFn2',
'2+dynamic',
'2-void',
'3+dynamic',
'4+void',
'4-dynamic',
'5+TestFn2',
'6+num',
'7+typedef'
],
failingTests: '1234');
buildTests(
'test010',
'''
class test !8<!1t !2 !3extends String,!4 List,!5 !6>!7 {}
class tezetst !9<!BString,!C !DList>!A {}''',
<String>[
'1-String',
'1-List',
'1-test',
'2-String',
'2-test',
'3+extends',
'4-tezetst',
'4-test',
'5-String',
'6-List',
'7-List',
'8-List',
'9-String',
'A-String',
'B-String',
'C-List',
'C-tezetst',
'D-List',
'D-test'
],
failingTests: '23');
// name generation with conflicts
buildTests('test011', '''r2(var object, Object object1, Object !1);''',
<String>['1+object2'],
failingTests: '1');
// reserved words
buildTests(
'test012',
'''
class X {
f() {
g(!1var!2 z) {!3true.!4toString();};
}
}''',
<String>[
'1+var',
'1+dynamic',
'1-f',
'2+var',
'2-dynamic',
'3+false',
'3+true',
'4+toString'
],
failingTests: '123');
// conditions & operators
buildTests(
'test013',
'''
class Q {
bool x;
List zs;
int k;
var a;
mth() {
while (!1x !9);
do{} while(!2x !8);
for(z in !3zs) {}
switch(!4k) {case 1:{!0}}
try {
} on !5Object catch(a){}
if (!7x !6) {} else {};
}
}''',
<String>[
'1+x',
'2+x',
'3+zs',
'4+k',
'5+Q',
'5-a',
'6+==',
'7+x',
'8+==',
'9+==',
'0+k'
],
failingTests: '689');
// keywords
buildTests(
'test014',
'''
class Q {
bool x;
List zs;
int k;
!Dvar a;
!Evoid mth() {
!1while (z) { !Gcontinue; };
!2do{ !Hbreak; } !3while(x);
!4for(z !5in zs) {}
!6for (int i; i < 3; i++);
!7switch(k) {!8case 1:{} !9default:{}}
!Atry {
} !Bon Object !Ccatch(a){}
!Fassert true;
!Jif (x) {} !Kelse {};
!Lreturn;
}
}''',
<String>[
'1+while',
'2+do',
'3+while',
'4+for',
'5+in',
'6+for',
'7+switch',
'8+case',
'9+default:',
'A+try',
'B+on',
'C+catch',
'D+var',
'E+void',
'F+assert',
'G+continue',
'H+break',
'J+if',
'K+else',
'L+return'
],
failingTests: '3CK');
// operators in function
buildTests('test015', '''f(a,b,c) => a + b * c !1;''', <String>['1+=='],
failingTests: '1');
// operators in return
buildTests(
'test016',
'''class X {dynamic f(a,b,c) {return a + b * c !1;}}''',
<String>['1+=='],
failingTests: '1');
// keywords
buildTests(
'test017',
'''
!1!2import 'x' !5as r;
!3export '!8uri' !6hide Q !7show X;
!4part 'x';''',
<String>[
'1+library',
"2+import \'\';",
"3+export \'\';",
"4+part \'\';",
'5+as',
'6+hide',
'7+show',
'8-null'
],
failingTests: '234567'); //TODO(jwren) 234 failing as correct selection
// offset assertions can't be passed into buildTests(..)
// keywords
buildTests('test018', '''!1part !2of foo;''', <String>['1+part', '2+of'],
failingTests: '12');
buildTests('test019', '''
var truefalse = 0;
var falsetrue = 1;
void f() {
var foo = true!1
}''', <String>['1+true', '1+truefalse', '1-falsetrue']);
buildTests('test020', '''var x = null.!1''', <String>['1+toString']);
buildTests('test021', '''var x = .!1''', <String>['1-toString']);
buildTests('test022', '''var x = .!1;''', <String>['1-toString']);
buildTests('test023', '''
class Map{getKeys(){}}
class X {
static x1(Map m) {
m.!1getKeys;
}
x2(Map m) {
m.!2getKeys;
}
}''', <String>['1+getKeys', '2+getKeys']);
// Note lack of semicolon following completion location
buildTests('test024', '''
class List{factory List.from(Iterable other) {}}
class F {
f() {
new List.!1
}
}''', <String>['1+from']);
buildTests('test025', '''
class R {
static R _m;
static R m;
f() {
var a = !1m;
var b = _!2m;
var c = !3g();
}
static g() {
var a = !4m;
var b = _!5m;
var c = !6g();
}
}
class T {
f() {
R x;
x.!7g();
x.!8m;
x._!9m;
}
static g() {
var q = R._!Am;
var g = R.!Bm;
var h = R.!Cg();
}
h() {
var q = R._!Dm;
var g = R.!Em;
var h = R.!Fg();
}
}''', <String>[
'1+m',
'2+_m',
'3+g',
'4+m',
'5+_m',
'6+g',
'7-g',
'8-m',
'9-_m',
'A+_m',
'B+m',
'C+g',
'D+_m',
'E+m',
'F+g'
]);
buildTests('test026', '''var aBcD; var x=ab!1''', <String>['1+aBcD']);
buildTests(
'test027', '''m(){try{}catch(eeee,ssss){s!1}''', <String>['1+ssss']);
// https://github.com/dart-lang/sdk/issues/33992
buildTests('test028', '''m(){var isX=3;if(is!1)''', <String>['1+isX'],
failingTests: '1');
buildTests('test029', '''m(){[1].forEach((x)=>!1x);}''', <String>['1+x']);
buildTests('test030', '''n(){[1].forEach((x){!1});}''', <String>['1+x']);
buildTests(
'test031',
'''class Caster {} m() {try {} on Cas!1ter catch (CastBlock) {!2}}''',
<String>['1+Caster', '1-CastBlock', '2+Caster', '2+CastBlock']);
buildTests('test032', '''
const ONE = 1;
const ICHI = 10;
const UKSI = 100;
const EIN = 1000;
m() {
int x;
switch (x) {
case !3ICHI:
case UKSI:
case EIN!2:
case ONE!1: return;
default: return;
}
}''', <String>[
'1+ONE',
'1-UKSI',
'2+EIN',
'2-ICHI',
'3+ICHI',
'3+UKSI',
'3+EIN',
'3+ONE'
]);
buildTests(
'test033',
'''class A{}class B extends A{b(){}}class C implements A {c(){}}class X{x(){A f;f.!1}}''',
<String>['1+b', '1-c'],
failingTests: '1');
// TODO(scheglov) decide what to do with Type for untyped field (not
// supported by the new store)
// test analysis of untyped fields and top-level vars
buildTests(
'test034',
'''
var topvar;
class Top {top(){}}
class Left extends Top {left(){}}
class Right extends Top {right(){}}
t1() {
topvar = new Left();
}
t2() {
topvar = new Right();
}
class A {
var field;
a() {
field = new Left();
}
b() {
field = new Right();
}
test() {
topvar.!1top();
field.!2top();
}
}''',
<String>['1+top', '2+top'],
failingTests: '12');
// test analysis of untyped fields and top-level vars
buildTests('test035', '''class Y {final x='hi';mth() {x.!1length;}}''',
<String>['1+length']);
// TODO(scheglov) decide what to do with Type for untyped field (not
// supported by the new store)
// test analysis of untyped fields and top-level vars
buildTests(
'test036',
'''
class A1 {
var field;
A1() : field = 0;
q() {
A1 a = new A1();
a.field.!1
}
}
void f() {
A1 a = new A1();
a.field.!2
}''',
<String>['1+round', '2+round'],
failingTests: '12');
buildTests(
'test037',
'''
class HttpServer{}
class HttpClient{}
void f() {
new HtS!1
}''',
<String>['1+HttpServer', '1-HttpClient'],
failingTests: '1');
buildTests('test038', '''
class X {
x(){}
}
class Y {
y(){}
}
class A<Z extends X> {
Y ay;
Z az;
A(this.ay, this.az) {
ay.!1y;
az.!2x;
}
}''', <String>['1+y', '1-x', '2+x', '2-y']);
// test analysis of untyped fields and top-level vars
buildTests(
'test039', '''class X{}var x = null as !1X;''', <String>['1-void']);
// test arg lists with named params
buildTests('test040', '''m(){f(a, b, {x1, x2, y}) {};f(1, 2, !1)!2;}''',
<String>['1+x1', '2-x2'],
failingTests: '1');
// test arg lists with named params
buildTests('test041', '''m(){f(a, b, {x1, x2, y}) {};f(1, 2, !1''',
<String>['1+x1', '1+x2', '1+y'],
failingTests: '1');
// test arg lists with named params
buildTests('test042', '''m(){f(a, b, {x1, x2, y}) {};f(1, 2, !1;!2''',
<String>['1+x1', '1+x2', '2-y'],
failingTests: '1');
}
void buildOtherTests() {
buildTests('test_classMembers_inGetter',
'''class A { var fff; get z {ff!1}}''', <String>['1+fff']);
buildTests(
'testSingle',
'''class A {int x; !2mth() {int y = this.x;}}class B{}''',
<String>['2+B']);
}
/// Generate a set of completion tests based on the given [originalSource].
///
/// The source string has completion points embedded in it, which are
/// identified by '!X' where X is a single character. Each X is matched to
/// positive or negative results in the array of [validationStrings].
/// Validation strings contain the name of a prediction with a two character
/// prefix. The first character of the prefix corresponds to an X in the
/// [originalSource]. The second character is either a '+' or a '-' indicating
/// whether the string is a positive or negative result.
///
/// The [originalSource] is the source for a completion test that contains
/// completion points. The [validationStrings] are the positive and negative
/// predictions.
///
/// Optional argument [failingTests], if given, is a string, each character of
/// which corresponds to an X in the [originalSource] for which the test is
/// expected to fail. This should be used to mark known completion bugs that
/// have not yet been fixed.
void buildTests(String baseName, String originalSource, List<String> results,
{Map<String, String>? extraFiles, String failingTests = ''}) {
var completionTests = LocationSpec.from(originalSource, results);
completionTests.sort((LocationSpec first, LocationSpec second) {
return first.id.compareTo(second.id);
});
if (completionTests.isEmpty) {
test(baseName, () {
fail("Expected exclamation point ('!') within the source denoting the"
'position at which code completion should occur');
});
}
var allSpecIds =
completionTests.map((LocationSpec spec) => spec.id).toSet();
for (var id in failingTests.split('')) {
if (!allSpecIds.contains(id)) {
test('$baseName-$id', () {
fail(
"Test case '$id' included in failingTests, but this id does not exist.");
});
}
}
for (var spec in completionTests) {
var testName = '$baseName-${spec.id}';
if (failingTests.contains(spec.id)) {
++expectedFailCount;
test('$testName (expected failure $expectedFailCount)', () {
var test = CompletionTestCase();
expect(
() => test.runTest(spec, extraFiles),
throwsA(anything),
);
});
} else {
++expectedPassCount;
test(testName, () {
var test = CompletionTestCase();
return test.runTest(spec, extraFiles);
});
}
}
}
}