|  | // 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:async'; | 
|  | import 'dart:collection'; | 
|  |  | 
|  | import 'package:test/test.dart'; | 
|  |  | 
|  | import 'completion_test_support.dart'; | 
|  |  | 
|  | main() { | 
|  | CompletionTestBuilder builder = new 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(); | 
|  | int 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-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 q {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"]); | 
|  |  | 
|  | // https://github.com/dart-lang/sdk/issues/33992 | 
|  | buildTests( | 
|  | 'testCommentSnippets029', | 
|  | ''' | 
|  | interface A<X> default B<X extends !1List!2> {}''', | 
|  | <String>["1+DateTime", "2+List"], | 
|  | failingTests: '12'); | 
|  |  | 
|  | 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"], | 
|  | failingTests: '123456'); | 
|  |  | 
|  | 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"], | 
|  | failingTests: '12'); | 
|  |  | 
|  | 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=new List(), 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();}main() {main(); new !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('testCommentSnippets059', ''' | 
|  | f(){((int x) => x+4).!1call(1);}''', <String>["1-call"]); | 
|  |  | 
|  | 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{}main() {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{}main() {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 { | 
|  | factory File(String path) => null; | 
|  | factory File.fromPath(Path path) => null; | 
|  | } | 
|  | 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 main() { Map.!1 }''', | 
|  | <String>["1+from", "1-clear"]); // static method, instance method | 
|  |  | 
|  | buildTests('testCommentSnippets079', ''' | 
|  | class Map{static from()=>null;clear(){}}void main() { Map s; s.!1 }''', | 
|  | <String>["1-from", "1+clear"]); // static method, instance method | 
|  |  | 
|  | buildTests('testCommentSnippets080', ''' | 
|  | class RuntimeError{var message;}void main() { 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 {} | 
|  | main() { | 
|  | var v = (HttpRequest req, HttpResp!1) | 
|  | }''', | 
|  | <String>["1+HttpResponse"], | 
|  | failingTests: '1'); | 
|  |  | 
|  | buildTests('testCommentSnippets083', ''' | 
|  | main() {(.!1)}''', <String>["1-toString"]); | 
|  |  | 
|  | buildTests('testCommentSnippets083a', ''' | 
|  | main() { .!1 }''', <String>["1-toString"]); | 
|  |  | 
|  | buildTests('testCommentSnippets083b', ''' | 
|  | main() { 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) | 
|  | main() { | 
|  | }''', | 
|  | <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 | 
|  | main() { | 
|  | }''', | 
|  | <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 | 
|  | main() { | 
|  | }''', <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) {} | 
|  | main() { | 
|  | f(En!1); | 
|  | }''', <String>["1+Enum"]); | 
|  |  | 
|  | buildTests('testCompletion_arguments_ignoreEmpty', ''' | 
|  | class A { | 
|  | test() {} | 
|  | } | 
|  | main(A a) { | 
|  | a.test(!1); | 
|  | }''', <String>["1-test"]); | 
|  |  | 
|  | buildTests('testCompletion_as_asIdentifierPrefix', ''' | 
|  | main(p) { | 
|  | var asVisible; | 
|  | var v = as!1; | 
|  | }''', <String>["1+asVisible"]); | 
|  |  | 
|  | buildTests('testCompletion_as_asPrefixedIdentifierStart', ''' | 
|  | class A { | 
|  | var asVisible; | 
|  | } | 
|  |  | 
|  | main(A p) { | 
|  | var v = p.as!1; | 
|  | }''', <String>["1+asVisible"]); | 
|  |  | 
|  | buildTests('testCompletion_as_incompleteStatement', ''' | 
|  | class MyClass {} | 
|  | main(p) { | 
|  | var justSomeVar; | 
|  | var v = p as !1 | 
|  | }''', <String>["1+MyClass", "1-justSomeVar"]); | 
|  |  | 
|  | buildTests('testCompletion_cascade', ''' | 
|  | class A { | 
|  | aaa() {} | 
|  | } | 
|  |  | 
|  |  | 
|  | main(A a) { | 
|  | a..!1 aaa(); | 
|  | }''', <String>["1+aaa", "1-main"]); | 
|  |  | 
|  | 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); | 
|  | } | 
|  | main() { | 
|  | new A.first(!1); | 
|  | }''', | 
|  | <String>["1+A.first", "1-A.second"], | 
|  | failingTests: '1'); | 
|  |  | 
|  | buildTests( | 
|  | 'testCompletion_constructorArguments_whenPrefixedType', | 
|  | ''' | 
|  | import 'dart:math' as m; | 
|  | main() { | 
|  | 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', ''' | 
|  | main() { | 
|  | 1.0!1 | 
|  | }''', <String>["1-abs", "1-main"]); | 
|  |  | 
|  | buildTests('testCompletion_enum', ''' | 
|  | enum MyEnum {A, B, C} | 
|  | main() { | 
|  | MyEnum.!1; | 
|  | }''', <String>["1+values", "1+A", "1+B", "1+C"]); | 
|  |  | 
|  | buildTests('testCompletion_exactPrefix_hasHigherRelevance', ''' | 
|  | var STR; | 
|  | main(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:_chrome | 
|  | import 'dart:_collection.dev | 
|  | export 'dart:!1''', <String>[ | 
|  | "1+dart:core", | 
|  | "1+dart:math", | 
|  | "1-dart:_chrome", | 
|  | "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}); | 
|  | main(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 main() { | 
|  | 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 main() { | 
|  | 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:_chrome | 
|  | import 'dart:_collection.dev | 
|  | import 'dart:!1''', <String>[ | 
|  | "1+dart:core", | 
|  | "1+dart:math", | 
|  | "1-dart:_chrome", | 
|  | "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) {} | 
|  | main() { | 
|  | f1((Str!1)); | 
|  | f2((Str!2)); | 
|  | }''', <String>["1+String", "1-bool", "2+String", "2-bool"]); | 
|  |  | 
|  | buildTests( | 
|  | 'testCompletion_inPeriodPeriod', | 
|  | ''' | 
|  | main(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 { | 
|  | } | 
|  | main() { | 
|  | 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 {} | 
|  | main(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', | 
|  | ''' | 
|  | main(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; | 
|  | } | 
|  |  | 
|  | main(A p) { | 
|  | var v1 = p.is!1; | 
|  | var v2 = p.is!2 | 
|  | }''', <String>["1+isVisible", "2+isVisible"]); | 
|  |  | 
|  | buildTests('testCompletion_is_incompleteStatement1', ''' | 
|  | class MyClass {} | 
|  | main(p) { | 
|  | var justSomeVar; | 
|  | var v = p is !1 | 
|  | }''', <String>["1+MyClass", "1-justSomeVar"]); | 
|  |  | 
|  | buildTests('testCompletion_is_incompleteStatement2', ''' | 
|  | class MyClass {} | 
|  | main(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', ''' | 
|  | main() { | 
|  | 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) {} | 
|  | main(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) {} | 
|  | main(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) {} | 
|  | } | 
|  | main(p) { | 
|  | foo(Functions.!1); | 
|  | }''', <String>[ | 
|  | "1+myFunc" /*":" + ProposalKind.METHOD*/, | 
|  | "1+myFunc" /*":" + ProposalKind.METHOD_NAME*/ | 
|  | ]); | 
|  |  | 
|  | buildTests('testCompletion_namedArgument_alreadyUsed', ''' | 
|  | func({foo}) {} main() { func(foo: 0, fo!1); }''', <String>["1-foo"]); | 
|  |  | 
|  | buildTests( | 
|  | 'testCompletion_namedArgument_constructor', | 
|  | ''' | 
|  | class A {A({foo, bar}) {}} main() { new A(fo!1); }''', | 
|  | <String>["1+foo", "1-bar"], | 
|  | failingTests: '1'); | 
|  |  | 
|  | buildTests( | 
|  | 'testCompletion_namedArgument_empty', | 
|  | ''' | 
|  | func({foo, bar}) {} main() { func(!1); }''', | 
|  | <String>[ | 
|  | "1+foo" /*":" + ProposalKind.NAMED_ARGUMENT*/, | 
|  | "1-foo" /*":" + ProposalKind.OPTIONAL_ARGUMENT*/ | 
|  | ], | 
|  | failingTests: '1'); | 
|  |  | 
|  | buildTests( | 
|  | 'testCompletion_namedArgument_function', | 
|  | ''' | 
|  | func({foo, bar}) {} main() { func(fo!1); }''', | 
|  | <String>["1+foo", "1-bar"], | 
|  | failingTests: '1'); | 
|  |  | 
|  | buildTests('testCompletion_namedArgument_notNamed', ''' | 
|  | func([foo]) {} main() { func(fo!1); }''', <String>["1-foo"]); | 
|  |  | 
|  | buildTests('testCompletion_namedArgument_unresolvedFunction', ''' | 
|  | main() { 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]); | 
|  | } | 
|  | main() { | 
|  | 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]) {} | 
|  | main() { | 
|  | 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() {} | 
|  | } | 
|  | main() { | 
|  | 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(); | 
|  | } | 
|  | main() { | 
|  | new A.!1 | 
|  | }''', <String>["1+_c", "1+c"]); | 
|  |  | 
|  | buildTests('testCompletion_privateElement_sameLibrary_member', ''' | 
|  | class A { | 
|  | _m() {} | 
|  | m() {} | 
|  | } | 
|  | main(A a) { | 
|  | a.!1 | 
|  | }''', <String>["1+_m", "1+m"]); | 
|  |  | 
|  | buildTests('testCompletion_propertyAccess_whenClassTarget', ''' | 
|  | class A { | 
|  | static int FIELD; | 
|  | int field; | 
|  | } | 
|  | main() { | 
|  | 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() {} | 
|  | } | 
|  | main() { | 
|  | 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; | 
|  | } | 
|  | main(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_super_superType', ''' | 
|  | class A { | 
|  | var fa; | 
|  | ma() {} | 
|  | } | 
|  | class B extends A { | 
|  | var fb; | 
|  | mb() {} | 
|  | main() { | 
|  | 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"], | 
|  | failingTests: '1'); | 
|  |  | 
|  | 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"], | 
|  | failingTests: '1'); | 
|  |  | 
|  | 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', | 
|  | ''' | 
|  | main() { | 
|  | 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() {} | 
|  | main() { | 
|  | 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 = new HashMap<String, String>(); | 
|  |  | 
|  | buildTests('test_export_ignoreIfThisLibraryExports', ''' | 
|  | export 'dart:math'; | 
|  | libFunction() {}; | 
|  | main() { | 
|  | !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; | 
|  | main() { | 
|  | p.!1 | 
|  | }''', | 
|  | <String>["1+cos", "1-sin", "1+libFunction"], | 
|  | extraFiles: sources, | 
|  | failingTests: '1'); | 
|  |  | 
|  | buildTests('test_importPrefix_hideCombinator', ''' | 
|  | import 'dart:math' as math hide PI; | 
|  | main() { | 
|  | math.!1 | 
|  | }''', <String>["1-PI", "1+LN10"]); | 
|  |  | 
|  | buildTests('test_importPrefix_showCombinator', ''' | 
|  | import 'dart:math' as math show PI; | 
|  | main() { | 
|  | 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'; | 
|  | main(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'; | 
|  | main() { | 
|  | 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'; | 
|  | main(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'; | 
|  | main() { | 
|  | 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;main(){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'; | 
|  | main() {!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'; | 
|  | main() { | 
|  | 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([Q.!3]) | 
|  | } | 
|  | 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; | 
|  | main() { | 
|  | 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 | 
|  | } | 
|  | } | 
|  | main() { | 
|  | A1 a = new A1(); | 
|  | a.field.!2 | 
|  | }''', | 
|  | <String>["1+round", "2+round"], | 
|  | failingTests: '12'); | 
|  |  | 
|  | buildTests( | 
|  | 'test037', | 
|  | ''' | 
|  | class HttpServer{} | 
|  | class HttpClient{} | 
|  | main() { | 
|  | 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"], | 
|  | failingTests: '2'); | 
|  |  | 
|  | // 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: ''}) { | 
|  | List<LocationSpec> 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"); | 
|  | }); | 
|  | } | 
|  | Set<String> allSpecIds = | 
|  | completionTests.map((LocationSpec spec) => spec.id).toSet(); | 
|  | for (String 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 (LocationSpec spec in completionTests) { | 
|  | String testName = '$baseName-${spec.id}'; | 
|  | if (failingTests.contains(spec.id)) { | 
|  | ++expectedFailCount; | 
|  | test("$testName (expected failure $expectedFailCount)", () { | 
|  | CompletionTestCase test = new CompletionTestCase(); | 
|  | return new Future(() => test.runTest(spec, extraFiles)).then((_) { | 
|  | fail('Test passed - expected to fail.'); | 
|  | }, onError: (_) {}); | 
|  | }); | 
|  | } else { | 
|  | ++expectedPassCount; | 
|  | test(testName, () { | 
|  | CompletionTestCase test = new CompletionTestCase(); | 
|  | return test.runTest(spec, extraFiles); | 
|  | }); | 
|  | } | 
|  | } | 
|  | } | 
|  | } |