mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 23:59:47 +00:00
97a762b083
Change-Id: Ia358d4f51c605ca66e5111769d1f716559251f63 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/298780 Commit-Queue: Konstantin Shcheglov <scheglov@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
2456 lines
56 KiB
Dart
2456 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();
|
|
}
|
|
|
|
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'
|
|
],
|
|
failingTests: '123');
|
|
|
|
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);
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|